Snap for 9470583 from 957bb244be
to tm-qpr3-release
Change-Id: Ic1e1be05e71996e65df6d5054107df46978a86ea
This commit is contained in:
commit
33bdd71063
86 changed files with 82845 additions and 76415 deletions
1
OWNERS
Normal file
1
OWNERS
Normal file
|
@ -0,0 +1 @@
|
|||
per-file powerhint.json = jychen@google.com,jenhaochen@google.com,wvw@google.com,joaodias@google.com
|
|
@ -19,7 +19,6 @@ TARGET_LINUX_KERNEL_VERSION := 5.10
|
|||
DEVICE_USES_NO_TRUSTY := true
|
||||
USE_SWIFTSHADER := true
|
||||
BOARD_USES_SWIFTSHADER := true
|
||||
BOARD_WITHOUT_RADIO := true
|
||||
|
||||
$(call inherit-product, device/google/gs201/aosp_common.mk)
|
||||
$(call inherit-product, device/google/lynx/device-lynx.mk)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<intf id="BE_VIRTUAL_VOICE_RX_TUNING" block_id="19"/>
|
||||
<intf id="BE_VIRTUAL_VOICE_TX_TUNING" block_id="19"/>
|
||||
<intf id="BE_HW_TX_INTF_0" block_id="134,128,137"/>
|
||||
<intf id="BE_VIRTUAL_CRYSTAL_CLEAR_AUDIO_TUNING" block_id="138"/>
|
||||
</hw_intf>
|
||||
|
||||
<product_lists>
|
||||
|
@ -198,8 +199,8 @@
|
|||
<!-- for input wit AUDIO_INPUT_FLAG_MMAP_NOIRQ 240 periods * 1ms buffer, 32-bit,2 ch, buffer size 92160 bytes -->
|
||||
<usecase id="UC_MMAP_RECORD" dev1="9" dyn_path="true" mmap="true" period="1" period_num="240"/>
|
||||
<!-- for hifi -->
|
||||
<usecase id="UC_HIFI_PLAYBACK" dev1="25"/>
|
||||
<usecase id="UC_HIFI_RECORD" dev1="26"/>
|
||||
<usecase id="UC_HIFI_PLAYBACK" dev1="25" period="20" period_num="4"/>
|
||||
<usecase id="UC_HIFI_RECORD" dev1="26" period="20" period_num="4"/>
|
||||
</usecase_attr>
|
||||
|
||||
<dsp_latency>
|
||||
|
@ -214,26 +215,29 @@
|
|||
<be_cfg be_id="OUT_SPEAKER_BE_CFG" latency="70000"/>
|
||||
<be_cfg be_id="OUT_USB_HEADSET_BE_CFG" latency="70000"/>
|
||||
<be_cfg be_id="OUT_USB_HEADPHONE_BE_CFG" latency="70000"/>
|
||||
<be_cfg be_id="OUT_A2DP_BE_CFG" latency="180000"/>
|
||||
<be_cfg be_id="OUT_A2DP_BE_CFG" latency="100000"/>
|
||||
</usecase>
|
||||
|
||||
<usecase id="UC_AUDIO_RECORD" type="capture">
|
||||
<be_cfg be_id="IN_CAMCORDER_LANDSCAPE_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_INVERT_LANDSCAPE_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_PORTRAIT_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_LANDSCAPE_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_PORTRAIT_BE_CFG" latency="160000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_BE_CFG" latency="40000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_NREC_BE_CFG" latency="40000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_WB_BE_CFG" latency="40000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_WB_NREC_BE_CFG" latency="40000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_LANDSCAPE_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_INVERT_LANDSCAPE_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_PORTRAIT_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_LANDSCAPE_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_SELFIE_PORTRAIT_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_MIC_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_CAMCORDER_TRIPLE_MIC_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_NREC_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_WB_BE_CFG" latency="100000"/>
|
||||
<be_cfg be_id="IN_BTSCO_MIC_WB_NREC_BE_CFG" latency="100000"/>
|
||||
</usecase>
|
||||
</dsp_latency>
|
||||
|
||||
<soundcard_name name="google,aoc-snd-card" />
|
||||
<features>
|
||||
<feature name="BatteryThrottle=Type:BCL_VOLTAGE,Name:BCL_AUDIO_BAACL,Strategy:MediaSpeakerAndScreenOn"/>
|
||||
<feature name="PlaybackThermalThrottle=PollWaitMs:20000,ThermistorName:VIRTUAL-SKIN,ThermistorType:SKIN,ThrottlingSeverity:MODERATE"/>
|
||||
</features>
|
||||
|
||||
<cfg_attr>
|
||||
|
@ -287,8 +291,9 @@
|
|||
|
||||
<external_module>
|
||||
<module libname="audio_spk_35l41.so" argu="AcousticShockProtection"/>
|
||||
<module libname="audio_waves_aoc.so" argu="Sink=SPK:1"/>
|
||||
<module libname="audio_fortemedia_aoc.so" argu="DL_CH=y VoIP_DLCHs=SPK:1,USB:1 VoIP_Rate=32000"/>
|
||||
<module libname="audio_waves_aoc.so" argu="Sink=SPK:1 ThermistorsName=VIRTUAL-SKIN"/>
|
||||
<module libname="audio_cca_aoc.so"/>
|
||||
<module libname="audio_fortemedia_aoc.so" argu="DL_CH=y VoIP_DLCHs=SPK:2,USB:2 VoIP_Rate=32000 BOOST_USB_SWB_CLK=y SHARED_MODULE=1130578253"/>
|
||||
<module libname="liboffloadeffect.so"/>
|
||||
<module libname="audio_amcs_ext.so"/>
|
||||
<module libname="audio_bluenote_aoc.so"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="compressed_offload" role="source"
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD">
|
||||
<profile name="" format="AUDIO_FORMAT_MP3"
|
||||
samplingRates="8000 16000 24000 32000 44100 48000"
|
||||
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="compressed_offload" role="source"
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD">
|
||||
<profile name="" format="AUDIO_FORMAT_MP3"
|
||||
samplingRates="8000 16000 24000 32000 44100 48000"
|
||||
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="compressed_offload" role="source"
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD">
|
||||
<profile name="" format="AUDIO_FORMAT_MP3"
|
||||
samplingRates="8000 16000 24000 32000 44100 48000"
|
||||
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="compressed_offload" role="source"
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
|
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD">
|
||||
<profile name="" format="AUDIO_FORMAT_MP3"
|
||||
samplingRates="8000 16000 24000 32000 44100 48000"
|
||||
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<!-- Volume section defines a volume curve for a given use case and device category.
|
||||
It contains a list of points of this curve expressing the attenuation in Millibels for a given
|
||||
volume index from 0 to 100.
|
||||
<volume stream=”AUDIO_STREAM_MUSIC” deviceCategory=””>
|
||||
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="">
|
||||
<point>0,-9600</point>
|
||||
<point>100,0</point>
|
||||
</volume>
|
||||
|
@ -82,11 +82,11 @@ volume index from 0 to 100.
|
|||
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
|
||||
<point>1,-6200</point>
|
||||
<point>28,-3800</point>
|
||||
<point>64,-2000</point>
|
||||
<point>68,-1800</point>
|
||||
<point>72,-1600</point>
|
||||
<point>76,-1400</point>
|
||||
<point>80,-1200</point>
|
||||
<point>64,-1900</point>
|
||||
<point>68,-1700</point>
|
||||
<point>72,-1500</point>
|
||||
<point>76,-1300</point>
|
||||
<point>80,-1150</point>
|
||||
<point>88,-850</point>
|
||||
<point>92,-650</point>
|
||||
<point>96,-400</point>
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
<ctl name="PCM Stream Wait Time in MSec" value="100"/>
|
||||
<ctl name="Voice PCM Stream Wait Time in MSec" value="500"/>
|
||||
|
||||
<!-- Enable it when AOC is ready to trim delay and padding -->
|
||||
<ctl name="Gapless Offload Enable" value="1"/>
|
||||
|
||||
<!-- TDM 0 setting -->
|
||||
<ctl name="TDM_0_RX Chan" value="Four"/>
|
||||
<ctl name="TDM_0_RX Format" value="S32_LE"/>
|
||||
|
@ -673,6 +676,14 @@
|
|||
<ctl name="R Fast Use Case Switch Enable" value="1" />
|
||||
</path>
|
||||
|
||||
<path name="speaker-amp1">
|
||||
<ctl name="Main AMP Enable Switch" value="1"/>
|
||||
</path>
|
||||
|
||||
<path name="speaker-amp2">
|
||||
<ctl name="R Main AMP Enable Switch" value="1"/>
|
||||
</path>
|
||||
|
||||
<path name="usb-tty-full">
|
||||
</path>
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@
|
|||
# Putting any value other than 1 would be equivalent to not supported.
|
||||
########################################################################################################
|
||||
[HAL_SUPPORTED_FEATURES]
|
||||
CUSTOM_ACTION_256=1
|
||||
CUSTOM_ACTION_260=1
|
||||
|
||||
########################################################################################################
|
||||
# This defined the options of supported sample rates.
|
||||
|
@ -26,10 +26,10 @@ OST_SPEAKER = 0:12,90:13,180:12,270:0|13
|
|||
# This should be configured by Waves only unless platform vendor is familiar with MPS structure.
|
||||
########################################################################################################
|
||||
[HAL_SUPPORTED_PRESETS]
|
||||
SPEAKER_MUSIC_THROTTLE= OM:1,SM:3,OST:OST_SPEAKER
|
||||
SPEAKER_SAFE_MUSIC_THROTTLE = OM:10,SM:3,OST:OST_SPEAKER
|
||||
SPEAKER_MUSIC = OM:1,SM:2,OST:OST_SPEAKER
|
||||
SPEAKER_SAFE_MUSIC = OM:10,SM:2,OST:OST_SPEAKER
|
||||
SPEAKER_SAFE_CALL = OM:10,SM:2,OST:OST_SPEAKER
|
||||
HEADSET_MUSIC = OM:2,SM:2
|
||||
|
||||
########################################################################################################
|
||||
# This defines available CONTROL configurations. Only define the CONTROL if you need it.
|
||||
|
@ -37,9 +37,7 @@ HEADSET_MUSIC = OM:2,SM:2
|
|||
# This can be configured by Waves or platform vendor.
|
||||
########################################################################################################
|
||||
[HAL_SUPPORTED_CONTROLS]
|
||||
SPEAKER_INSTANCE = INSTANCE:1,DEV:0,SR:SR_COMMON,PRESET:SPEAKER_MUSIC|SPEAKER_SAFE_MUSIC|SPEAKER_SAFE_CALL
|
||||
A2DP_INSTANCE = INSTANCE:2,DEV:0,SR:SR_COMMON,PRESET:HEADSET_MUSIC
|
||||
USB_HEADPHONE_INSTANCE = INSTANCE:4,DEV:0,SR:SR_COMMON,PRESET:HEADSET_MUSIC
|
||||
SPEAKER_INSTANCE = INSTANCE:1,DEV:0,SR:SR_COMMON,PRESET:SPEAKER_MUSIC|SPEAKER_SAFE_MUSIC|SPEAKER_MUSIC_THROTTLE|SPEAKER_SAFE_MUSIC_THROTTLE
|
||||
|
||||
[COEFS_CONVERTER_SETTING]
|
||||
AlgFxPath=/vendor/lib/libAlgFx_HiFi3z.so
|
||||
|
@ -52,7 +50,12 @@ AlgFxPath64=/vendor/lib64/libAlgFx_HiFi3z.so
|
|||
#AudioFormatSampleSize=4
|
||||
#AudioFormatIncrement=8
|
||||
|
||||
[CUSTOM_ACTION_256]
|
||||
CASE_1=PRIORITY:0,NUMBERS:2:0|1,PRESET:SPEAKER_MUSIC
|
||||
CASE_2=PRIORITY:1,NUMBERS:1|2|4194304:2|3|4,PRESET:SPEAKER_SAFE_CALL
|
||||
CASE_3=PRIORITY:2,NUMBERS:1|4194304:0|1,PRESET:SPEAKER_SAFE_MUSIC
|
||||
[CUSTOM_ACTION_260]
|
||||
CASE_1=PRIORITY:0,NUMBERS:2:0|1:1|2,PRESET:SPEAKER_MUSIC
|
||||
CASE_2=PRIORITY:1,NUMBERS:1|2|4194304:2|3|4:1|2,PRESET:SPEAKER_SAFE_MUSIC
|
||||
CASE_3=PRIORITY:2,NUMBERS:1|4194304:0|1:1|2,PRESET:SPEAKER_SAFE_MUSIC
|
||||
CASE_4=PRIORITY:3,NUMBERS:2:0|1:0,PRESET:SPEAKER_MUSIC_THROTTLE
|
||||
CASE_5=PRIORITY:4,NUMBERS:1|2|4194304:2|3|4:0,PRESET:SPEAKER_SAFE_MUSIC_THROTTLE
|
||||
CASE_6=PRIORITY:5,NUMBERS:1|4194304:0|1:0,PRESET:SPEAKER_SAFE_MUSIC_THROTTLE
|
||||
# Action 260 parameters: audio_devices_t, audio_mode_t, throttle_control_state_t
|
||||
# - throttle_control_state_t: 0 - Enabled, 1 - Disabled, 2 - Bypassed
|
||||
|
|
Binary file not shown.
|
@ -1,34 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,on,off,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
|
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_CA.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_CA.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
|
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_EU.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_EU.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,off,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,on,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,on,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,on,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,on,off,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,on,on,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,on,on,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,off,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,off,off,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,off,on,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,off,on,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,on,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,on,off,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,on,on,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,on,on,on,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,off,off,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,off,off,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,off,on,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,off,on,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,on,off,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,on,off,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,on,on,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,off,on,on,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,off,off,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,off,off,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,off,on,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,off,on,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,on,off,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,on,off,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,on,on,off,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
on,on,on,on,on,any,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,any,any,any,any,off,76,68,40,76,68,34,76,68,40,76,68,34
|
|
|
@ -1,34 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,off,on,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,on,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,off,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,on,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,on,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,off,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,off,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,on,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,on,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,on,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,any,any,any,any,off,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,any,any,any,any,off,72,68,40,72,68,40,72,68,40,72,68,40
|
|
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_US.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_G0DZQ_US.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
|
|
@ -1,34 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,off,on,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,on,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,off,on,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
off,off,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,off,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,on,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,off,on,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,off,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,off,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,on,off,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,off,on,on,on,any,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
on,on,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,any,any,any,any,off,76,68,40,76,68,40,76,68,40,76,68,40
|
||||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,off,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,off,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,off,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,off,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,on,on,on,on,on,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,off,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,off,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,off,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,off,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
on,on,on,on,on,any,72,68,40,72,68,40,72,68,40,72,68,40
|
||||
off,any,any,any,any,off,72,68,40,72,68,40,72,68,40,72,68,40
|
|
34
bluetooth/bluetooth_power_limits_Lynx_GHL1X_EU.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_GHL1X_EU.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,off,on,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,on,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,off,on,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,off,on,off,off,on,76,68,40,76,68,34,76,68,40,76,68,34
|
||||
off,off,on,off,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,off,on,on,off,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,off,on,on,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,on,off,off,off,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,on,off,off,on,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,on,off,on,off,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,on,off,on,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,on,on,off,off,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,on,on,off,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,on,on,on,off,on,72,68,40,72,68,34,72,68,40,72,68,34
|
||||
off,on,on,on,on,on,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,off,off,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,off,off,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,off,on,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,off,on,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,on,off,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,on,off,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,on,on,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,off,on,on,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,off,off,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,off,off,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,off,on,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,off,on,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,on,off,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,on,off,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,on,on,off,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
on,on,on,on,on,any,64,64,40,64,64,34,64,64,40,64,64,34
|
||||
off,any,any,any,any,off,76,68,40,76,68,34,76,68,40,76,68,34
|
|
34
bluetooth/bluetooth_power_limits_Lynx_GWKK3_CA.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_GWKK3_CA.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
|
34
bluetooth/bluetooth_power_limits_Lynx_GWKK3_US.csv
Normal file
34
bluetooth/bluetooth_power_limits_Lynx_GWKK3_US.csv
Normal file
|
@ -0,0 +1,34 @@
|
|||
Head,BTHotspot,WIFI5Ghz,HotspotVoice,Cell,IMU,BDR_Single_Chain_0,EDR_Single_Chain_0,BLE_Single_Chain_0,BDR_Single_Chain_1,EDR_Single_Chain_1,BLE_Single_Chain_1,BDR_Dual_Chain_0,EDR_Dual_Chain_0,BLE_Dual_Chain_0,BDR_Dual_Chain_1,EDR_Dual_Chain_1,BLE_Dual_Chain_1
|
||||
off,off,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,off,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,off,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,off,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,off,on,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,off,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,off,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,off,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
off,on,on,on,off,on,76,68,76,76,68,76,76,68,76,76,68,76
|
||||
off,on,on,on,on,on,56,56,56,56,56,56,56,56,56,56,56,56
|
||||
on,off,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,off,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,off,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,off,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,off,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
on,on,on,on,on,any,44,44,44,44,44,44,44,44,44,44,44,44
|
||||
off,any,any,any,any,off,76,68,76,76,68,76,76,68,76,76,68,76
|
|
84
bluetooth/le_audio_codec_capabilities.xml
Normal file
84
bluetooth/le_audio_codec_capabilities.xml
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!---
|
||||
This is an example to configure LE Audio hardware offload supported capability settings
|
||||
codecConfigurationList:
|
||||
Supported codec capability along with its parameter setting
|
||||
|
||||
strategyConfigurationList:
|
||||
ASE Configuration strategies
|
||||
|
||||
configurationList:
|
||||
For each configuration, there are two attributes
|
||||
- codecConfiguration
|
||||
- strategyConfiguration
|
||||
|
||||
scenarioList:
|
||||
There would be only one `scenarios` group
|
||||
For each scenario, the are two attributes
|
||||
- encode
|
||||
- decode
|
||||
If a scenario is unidirectional, mark another direction as `invalid`
|
||||
The configuration should be chosen from `configurationList`
|
||||
-->
|
||||
<leAudioOffloadSetting>
|
||||
<scenarioList>
|
||||
<!-- encode only -->
|
||||
<scenario encode="OneChanMono_16_1" decode="invalid"/>
|
||||
<scenario encode="TwoChanStereo_16_1" decode="invalid"/>
|
||||
<scenario encode="OneChanStereo_16_1" decode="invalid"/>
|
||||
<scenario encode="OneChanMono_16_2" decode="invalid"/>
|
||||
<scenario encode="TwoChanStereo_16_2" decode="invalid"/>
|
||||
<scenario encode="OneChanStereo_16_2" decode="invalid"/>
|
||||
<scenario encode="OneChanMono_24_2" decode="invalid"/>
|
||||
<scenario encode="TwoChanStereo_24_2" decode="invalid"/>
|
||||
<scenario encode="OneChanStereo_24_2" decode="invalid"/>
|
||||
<scenario encode="OneChanMono_32_2" decode="invalid"/>
|
||||
<scenario encode="TwoChanStereo_32_2" decode="invalid"/>
|
||||
<scenario encode="OneChanStereo_32_2" decode="invalid"/>
|
||||
<scenario encode="OneChanMono_48_4" decode="invalid"/>
|
||||
<scenario encode="TwoChanStereo_48_4" decode="invalid"/>
|
||||
<scenario encode="OneChanStereo_48_4" decode="invalid"/>
|
||||
<!-- encode and decode -->
|
||||
<scenario encode="OneChanStereo_16_1" decode="OneChanStereo_16_1"/>
|
||||
<scenario encode="OneChanStereo_16_1" decode="OneChanMono_16_1"/>
|
||||
<scenario encode="TwoChanStereo_16_1" decode="OneChanMono_16_1"/>
|
||||
<scenario encode="OneChanMono_16_1" decode="OneChanMono_16_1"/>
|
||||
<scenario encode="OneChanStereo_16_2" decode="OneChanStereo_16_2"/>
|
||||
<scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/>
|
||||
<scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/>
|
||||
<scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/>
|
||||
<scenario encode="OneChanStereo_32_2" decode="OneChanStereo_32_2"/>
|
||||
<scenario encode="OneChanStereo_32_2" decode="OneChanMono_32_2"/>
|
||||
<scenario encode="TwoChanStereo_32_2" decode="OneChanMono_32_2"/>
|
||||
<scenario encode="OneChanMono_32_2" decode="OneChanMono_32_2"/>
|
||||
</scenarioList>
|
||||
<configurationList>
|
||||
<configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="OneChanMono_24_2" codecConfiguration="LC3_24k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_24_2" codecConfiguration="LC3_24k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_24_2" codecConfiguration="LC3_24k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="OneChanMono_32_2" codecConfiguration="LC3_32k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_32_2" codecConfiguration="LC3_32k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_32_2" codecConfiguration="LC3_32k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="OneChanMono_48_4" codecConfiguration="LC3_48k_4" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
|
||||
<configuration name="TwoChanStereo_48_4" codecConfiguration="LC3_48k_4" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
|
||||
<configuration name="OneChanStereo_48_4" codecConfiguration="LC3_48k_4" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
|
||||
</configurationList>
|
||||
<codecConfigurationList>
|
||||
<codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
|
||||
<codecConfiguration name="LC3_16k_2" codec="LC3" samplingFrequency="16000" frameDurationUs="10000" octetsPerCodecFrame="40"/>
|
||||
<codecConfiguration name="LC3_24k_2" codec="LC3" samplingFrequency="24000" frameDurationUs="10000" octetsPerCodecFrame="60"/>
|
||||
<codecConfiguration name="LC3_32k_2" codec="LC3" samplingFrequency="32000" frameDurationUs="10000" octetsPerCodecFrame="80"/>
|
||||
<codecConfiguration name="LC3_48k_4" codec="LC3" samplingFrequency="48000" frameDurationUs="10000" octetsPerCodecFrame="120"/>
|
||||
</codecConfigurationList>
|
||||
<strategyConfigurationList>
|
||||
<strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/>
|
||||
<strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/>
|
||||
<strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/>
|
||||
</strategyConfigurationList>
|
||||
</leAudioOffloadSetting>
|
|
@ -24,17 +24,20 @@ PRODUCT_PRODUCT_PROPERTIES += \
|
|||
# Bluetooth LE Audio
|
||||
PRODUCT_PRODUCT_PROPERTIES += \
|
||||
ro.bluetooth.leaudio_switcher.supported=true \
|
||||
bluetooth.profile.bap.broadcast.source.enabled=true \
|
||||
bluetooth.profile.bap.broadcast.assist.enabled=true \
|
||||
bluetooth.profile.bap.unicast.client.enabled=true \
|
||||
bluetooth.profile.csip.set_coordinator.enabled=true \
|
||||
bluetooth.profile.hap.client.enabled=true \
|
||||
bluetooth.profile.mcp.server.enabled=true \
|
||||
bluetooth.profile.ccp.server.enabled=true \
|
||||
bluetooth.profile.vcp.controller.enabled=true \
|
||||
ro.bluetooth.leaudio_broadcast_switcher.supported=true \
|
||||
ro.bluetooth.leaudio_offload.supported=true \
|
||||
persist.bluetooth.leaudio_offload.disabled=false \
|
||||
ro.vendor.audio_hal.ble_use_stream_id=true
|
||||
ro.vendor.audio_hal.ble_use_stream_id=true \
|
||||
|
||||
# Bluetooth LE Audio CIS handover to SCO
|
||||
# Set the property only if the controller doesn't support CIS and SCO
|
||||
# simultaneously. More details in b/242908683.
|
||||
PRODUCT_PRODUCT_PROPERTIES += \
|
||||
persist.bluetooth.leaudio.notify.idle.during.call=true
|
||||
|
||||
# LE Auido Offload Capabilities setting
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/bluetooth/le_audio_codec_capabilities.xml:$(TARGET_COPY_OUT_VENDOR)/etc/le_audio_codec_capabilities.xml
|
||||
|
||||
# Bluetooth HAL and Pixel extension
|
||||
DEVICE_MANIFEST_FILE += \
|
||||
|
@ -49,9 +52,10 @@ TARGET_BLUETOOTH_HCI_V1_1 = true
|
|||
TARGET_BLUETOOTH_UART_DEVICE = "/dev/ttySAC18"
|
||||
UART_USE_TERMIOS_AFC = true
|
||||
TARGET_USE_QTI_BT_IBS = false
|
||||
TARGET_USE_QTI_BT_OBS = false
|
||||
TARGET_USE_QTI_BT_OBS = true
|
||||
TARGET_USE_QTI_BT_SAR_V1_1 = true
|
||||
TARGET_USE_QTI_BT_CHANNEL_AVOIDANCE = true
|
||||
TARGET_DROP_BYTES_BEFORE_SSR_DUMP = true
|
||||
|
||||
# IBluetoothHci @1.1 / @1.0
|
||||
ifeq ($(TARGET_BLUETOOTH_HCI_V1_1),true)
|
||||
|
@ -71,12 +75,18 @@ PRODUCT_PACKAGES += \
|
|||
|
||||
# Bluetooth SAR Tx power caps
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_L10_EU.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_EU.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_L10_JP.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_JP.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_L10_US.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_US.csv
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_G0DZQ_EU.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_G0DZQ_EU.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_GHL1X_EU.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_GHL1X_EU.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_G0DZQ_CA.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_G0DZQ_CA.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_G0DZQ_US.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_G0DZQ_US.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_GWKK3_CA.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_GWKK3_cA.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_GWKK3_US.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_GWKK3_US.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_G0DZQ_JP.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_G0DZQ_JP.csv \
|
||||
device/google/lynx/bluetooth/bluetooth_power_limits_Lynx_G82U8_JP.csv:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_power_limits_G82U8_JP.csv
|
||||
|
||||
# Bluetooth SAR test tools
|
||||
ifeq ($(TARGET_USE_QTI_BT_SAR_V1_1)$(TARGET_USE_QTI_BT_SAR),true)
|
||||
ifneq (,$(filter true, $(TARGET_USE_QTI_BT_SAR_V1_1) $(TARGET_USE_QTI_BT_SAR)))
|
||||
PRODUCT_PACKAGES_DEBUG += bluetooth_sar_test
|
||||
endif
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ on init
|
|||
# NFC streset tool name
|
||||
setprop persist.vendor.nfc.streset libstreset21
|
||||
setprop persist.vendor.se.streset libstreset21
|
||||
setprop dalvik.vm.dexopt.thermal-cutoff 1
|
||||
|
||||
# When ro.build.flavor=factory_lynx-userdebug, add vendor/bin/factory to default path
|
||||
on init && property:ro.build.flavor=factory_lynx-userdebug
|
||||
|
@ -54,6 +55,9 @@ on post-fs-data
|
|||
# Wifi
|
||||
on property:sys.boot_completed=1
|
||||
write /sys/bus/platform/drivers/cnss2/qcom,cnss-qca6490/fs_ready 1
|
||||
|
||||
on property:vendor.all.modules.ready=1 && property:vendor.all.devices.ready=1
|
||||
write /sys/bus/platform/drivers/cnss2/qcom,cnss-qca6490/fs_ready 1
|
||||
# Create directories for wifihal services
|
||||
mkdir /dev/socket/wifihal 0770 wifi wifi
|
||||
chmod 2777 /dev/socket/wifihal
|
||||
|
@ -77,3 +81,39 @@ on property:persist.vendor.touch_sensitivity_mode=0 && property:sys.boot_complet
|
|||
|
||||
on property:persist.vendor.touch_sensitivity_mode=1 && property:sys.boot_completed=1
|
||||
write /sys/devices/virtual/goog_touch_interface/gti.0/screen_protector_mode_enabled 1
|
||||
|
||||
# Touch
|
||||
on property:vendor.device.modules.ready=1
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/force_active
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/fw_ver
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ms_base
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ms_diff
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ms_raw
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/self_test
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ss_base
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ss_diff
|
||||
chown system system /sys/devices/virtual/goog_touch_interface/gti.0/ss_raw
|
||||
|
||||
# Override SF and RE uclamps to 0 on boot after being set elsewhere, for adpf cpu hints
|
||||
on property:sys.boot_completed=1
|
||||
trigger override-sf-uclamp
|
||||
|
||||
on property:vendor.powerhal.init=*
|
||||
write /dev/cpuset/background/cpus ${persist.device_config.vendor_system_native.background_cpuset:-0-3}
|
||||
|
||||
on override-sf-uclamp
|
||||
write /proc/vendor_sched/rt_uclamp_min 0
|
||||
write /proc/vendor_sched/sf_uclamp_min 0
|
||||
|
||||
# For Japan sku, always enforce camera shutter sound
|
||||
# Since this property is read by the audio server in system service,
|
||||
# it should be written by the system init.
|
||||
on property:ro.boot.hardware.sku=G82U8
|
||||
setprop audio.camerasound.force true
|
||||
|
||||
# Route vibrator.adaptive_haptics.enabled to persist
|
||||
on property:vibrator.adaptive_haptics.enabled=0
|
||||
setprop persist.vendor.vibrator.hal.context.enable false
|
||||
|
||||
on property:vibrator.adaptive_haptics.enabled=1
|
||||
setprop persist.vendor.vibrator.hal.context.enable true
|
||||
|
|
|
@ -22,13 +22,16 @@ $(call inherit-product-if-exists, vendor/google_devices/gs201/prebuilts/device-v
|
|||
$(call inherit-product-if-exists, vendor/google_devices/gs201/proprietary/device-vendor.mk)
|
||||
$(call inherit-product-if-exists, vendor/google_devices/lynx/proprietary/lynx/device-vendor-lynx.mk)
|
||||
$(call inherit-product-if-exists, vendor/google_devices/lynx/proprietary/device-vendor.mk)
|
||||
$(call inherit-product-if-exists, vendor/google_devices/lynx/proprietary/WallpapersLynx.mk)
|
||||
|
||||
DEVICE_PACKAGE_OVERLAYS += device/google/lynx/lynx/overlay
|
||||
|
||||
include device/google/lynx/audio/lynx/audio-tables.mk
|
||||
include device/google/gs201/device-shipping-common.mk
|
||||
include hardware/google/pixel/vibrator/cs40l26/device.mk
|
||||
include device/google/lynx/vibrator/cs40l26/device.mk
|
||||
|
||||
# go/lyric-soong-variables
|
||||
$(call soong_config_set,lyric,camera_hardware,lynx)
|
||||
$(call soong_config_set,lyric,tuning_product,lynx)
|
||||
$(call soong_config_set,google3a_config,target_device,lynx)
|
||||
|
||||
|
@ -48,6 +51,9 @@ PRODUCT_COPY_FILES += \
|
|||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/media_profiles_lynx.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml
|
||||
|
||||
# Media Performance Class 13
|
||||
PRODUCT_PROPERTY_OVERRIDES += ro.odm.build.media_performance_class=33
|
||||
|
||||
# Display Config
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/lynx/display_colordata_dev_cal0.pb:$(TARGET_COPY_OUT_VENDOR)/etc/display_colordata_dev_cal0.pb
|
||||
|
@ -56,6 +62,9 @@ PRODUCT_DEFAULT_PROPERTY_OVERRIDES += vendor.display.lbe.supported=1
|
|||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.set_idle_timer_ms=1500
|
||||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.ignore_hdr_camera_layers=true
|
||||
|
||||
#config of primary display frames to reach LHBM peak brightness
|
||||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += vendor.primarydisplay.lhbm.frames_to_reach_peak_brightness=2
|
||||
|
||||
# NFC
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.hardware.nfc.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.nfc.xml \
|
||||
|
@ -87,14 +96,17 @@ DEVICE_MANIFEST_FILE += \
|
|||
|
||||
# Thermal Config
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/thermal_info_config_lynx.json:$(TARGET_COPY_OUT_VENDOR)/etc/thermal_info_config.json
|
||||
device/google/lynx/thermal_info_config_lynx.json:$(TARGET_COPY_OUT_VENDOR)/etc/thermal_info_config.json \
|
||||
device/google/lynx/thermal_info_config_charge_lynx.json:$(TARGET_COPY_OUT_VENDOR)/etc/thermal_info_config_charge.json
|
||||
|
||||
# Power HAL config
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json
|
||||
|
||||
# PowerStats HAL
|
||||
PRODUCT_SOONG_NAMESPACES += device/google/lynx/powerstats
|
||||
PRODUCT_SOONG_NAMESPACES += \
|
||||
device/google/lynx/powerstats \
|
||||
device/google/lynx
|
||||
|
||||
# Bluetooth HAL and Pixel extension
|
||||
include device/google/lynx/bluetooth/qti_default.mk
|
||||
|
@ -140,7 +152,14 @@ endif
|
|||
|
||||
# Vibrator HAL
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
ro.vendor.vibrator.hal.supported_primitives=243
|
||||
ro.vendor.vibrator.hal.supported_primitives=243 \
|
||||
ro.vendor.vibrator.hal.f0.comp.enabled=1 \
|
||||
ro.vendor.vibrator.hal.redc.comp.enabled=0 \
|
||||
persist.vendor.vibrator.hal.context.enable=false \
|
||||
persist.vendor.vibrator.hal.context.scale=40 \
|
||||
persist.vendor.vibrator.hal.context.fade=true \
|
||||
persist.vendor.vibrator.hal.context.cooldowntime=1600 \
|
||||
persist.vendor.vibrator.hal.context.settlingtime=5000
|
||||
|
||||
# Trusty liboemcrypto.so
|
||||
PRODUCT_SOONG_NAMESPACES += vendor/google_devices/lynx/prebuilts
|
||||
|
@ -148,10 +167,14 @@ PRODUCT_SOONG_NAMESPACES += vendor/google_devices/lynx/prebuilts
|
|||
# GPS xml
|
||||
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/gps.xml.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/gps.xml
|
||||
device/google/lynx/location/gps.xml.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/gps.xml \
|
||||
device/google/lynx/location/lhd.conf.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/lhd.conf \
|
||||
device/google/lynx/location/scd.conf.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/scd.conf
|
||||
else
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/gps_user.xml.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/gps.xml
|
||||
device/google/lynx/location/gps_user.xml.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/gps.xml \
|
||||
device/google/lynx/location/lhd_user.conf.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/lhd.conf \
|
||||
device/google/lynx/location/scd_user.conf.l10:$(TARGET_COPY_OUT_VENDOR)/etc/gnss/scd.conf
|
||||
endif
|
||||
|
||||
# DCK properties based on target
|
||||
|
@ -182,23 +205,64 @@ PRODUCT_PRODUCT_PROPERTIES += \
|
|||
PRODUCT_PRODUCT_PROPERTIES += \
|
||||
ro.support_one_handed_mode=true
|
||||
|
||||
# Fingerprint als feed forward
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
persist.vendor.udfps.als_feed_forward_supported=true \
|
||||
persist.vendor.udfps.lhbm_controlled_in_hal_supported=true
|
||||
|
||||
# Hide cutout overlays
|
||||
PRODUCT_PACKAGES += \
|
||||
NoCutoutOverlay \
|
||||
AvoidAppsInCutoutOverlay
|
||||
|
||||
# MIPI Coex Configs
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/lynx/lynx/radio/lynx_display_primary_mipi_coex_table.csv:$(TARGET_COPY_OUT_VENDOR)/etc/modem/display_primary_mipi_coex_table.csv
|
||||
|
||||
# Camera
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
persist.vendor.camera.extended_launch_boost=1 \
|
||||
persist.vendor.camera.optimized_tnr_freq=1 \
|
||||
persist.vendor.camera.raise_buf_allocation_priority=1
|
||||
|
||||
# Enable camera 1080P 60FPS binning mode
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
persist.vendor.camera.1080P_60fps_binning=true
|
||||
|
||||
# Limit camera 1080P 60FPS binning mode to not rear main camera
|
||||
# Increase thread priority for nodes stop
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
persist.vendor.camera.1080P_60fps_binning_except_rear_main=true
|
||||
persist.vendor.camera.increase_thread_priority_nodes_stop=true
|
||||
|
||||
# OIS with system imu
|
||||
PRODUCT_VENDOR_PROPERTIES += \
|
||||
persist.vendor.camera.ois_with_system_imu=true
|
||||
|
||||
# Use GmsCorePrebuilt y2022w28
|
||||
USE_GMSCORE_PREBUILT_Y2022W28 := true
|
||||
|
||||
# Device features
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/handheld_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/handheld_core_hardware.xml
|
||||
|
||||
# Enable adpf cpu hint session for SurfaceFlinger
|
||||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
|
||||
debug.sf.enable_adpf_cpu_hint=true
|
||||
|
||||
# The default value of this variable is false and should only be set to true when
|
||||
# the device allows users to enable the seamless transfer feature.
|
||||
PRODUCT_PRODUCT_PROPERTIES += \
|
||||
euicc.seamless_transfer_enabled_in_non_qs=true
|
||||
|
||||
##Audio Vendor property
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
persist.vendor.audio.cca.enabled=true
|
||||
|
||||
# userdebug specific
|
||||
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/google/gs201/init.hardware.wlc.rc.userdebug:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.wlc.rc
|
||||
endif
|
||||
|
||||
# SKU specific RROs
|
||||
PRODUCT_PACKAGES += \
|
||||
SettingsOverlayG82U8
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
|
||||
SuplSslMethod="SSLv23_NO_TLSv1_2"
|
||||
SuplEnable="true"
|
||||
SuplUseApn="true"
|
||||
SuplUseApn="false"
|
||||
SuplUseApnNI="true"
|
||||
SuplUseFwCellInfo="false"
|
||||
SuplDummyCellInfo ="true"
|
||||
SuplTlsCertDirPath="/etc/security/cacerts"
|
||||
SuplTlsCertPath="/vendor/etc/gnss/gps.cer"
|
||||
SuplUT1Seconds="20"
|
||||
|
@ -50,15 +53,19 @@
|
|||
CpLppGuardTimeSec="1"
|
||||
IgnoreInjectedSystemTime="true"
|
||||
|
||||
AttributionAppPkgName="com.google.android.carrierlocation"
|
||||
|
||||
AssertEnabled="true"
|
||||
CpLppeCancelDbhOnAgnssProvideLoc="true"
|
||||
CpLppeUseAgnssLocForEmptyDbh="true"
|
||||
ReAidingOnHotStart="false"
|
||||
ReAidingIntervalSec="1200"
|
||||
RuntimeSwLteFilterEnable="true"
|
||||
PpsDevice="/sys/class/pps/pps0/assert_elapsed"
|
||||
/>
|
||||
|
||||
<gll
|
||||
PpsEnable="true"
|
||||
LogPriMask="LOG_INFO"
|
||||
LogFacMask="LOG_NMEA | LOG_GLLIOS | LOG_GLLAPI"
|
||||
FrqPlan="FRQ_PLAN_26MHZ_2PPM_49_152MHZ_300PPB"
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
SuplSslMethod="SSLv23_NO_TLSv1_2"
|
||||
SuplEnable="true"
|
||||
SuplUseApn="true"
|
||||
SuplUseApn="false"
|
||||
SuplUseApnNI="true"
|
||||
SuplUseFwCellInfo="false"
|
||||
SuplDummyCellInfo ="true"
|
||||
SuplTlsCertDirPath="/etc/security/cacerts"
|
||||
SuplTlsCertPath="/vendor/etc/gnss/gps.cer"
|
||||
SuplUT1Seconds="20"
|
||||
|
@ -49,15 +52,19 @@
|
|||
CpLppGuardTimeSec="1"
|
||||
IgnoreInjectedSystemTime="true"
|
||||
|
||||
AttributionAppPkgName="com.google.android.carrierlocation"
|
||||
|
||||
AssertEnabled="false"
|
||||
CpLppeCancelDbhOnAgnssProvideLoc="true"
|
||||
CpLppeUseAgnssLocForEmptyDbh="true"
|
||||
ReAidingOnHotStart="false"
|
||||
ReAidingIntervalSec="1200"
|
||||
RuntimeSwLteFilterEnable="true"
|
||||
PpsDevice="/sys/class/pps/pps0/assert_elapsed"
|
||||
/>
|
||||
|
||||
<gll
|
||||
PpsEnable="true"
|
||||
LogPriMask="LOG_INFO"
|
||||
LogFacMask="LOG_NMEA | LOG_GLLIOS | LOG_GLLAPI"
|
||||
FrqPlan="FRQ_PLAN_26MHZ_2PPM_49_152MHZ_300PPB"
|
34
location/lhd.conf.l10
Normal file
34
location/lhd.conf.l10
Normal file
|
@ -0,0 +1,34 @@
|
|||
LheName=bbd
|
||||
|
||||
LheRsmResetTimeoutMS=10000
|
||||
GpioNStdbyPath=/sys/devices/platform/10940000.spi/spi_master/spi5/spi5.0/nstandby
|
||||
|
||||
LhePatch=/vendor/firmware/SensorHub.patch
|
||||
Lhe477xDebugFlags=RPC:FACILITY=65535-dKP+CUST+LHE:STDOUT_PUTS:STDOUT_LOG
|
||||
LheConsole=/data/vendor/gps/LheConsole
|
||||
|
||||
LogEnabled=true
|
||||
Log=JAVA
|
||||
LogDirectory=/sdcard/gps/broadcom/storage
|
||||
|
||||
LheBbdPacket=/dev/ttyBCM
|
||||
|
||||
LheBbdControl=/dev/bbd_control
|
||||
|
||||
# LheBbdSensor=/dev/bbd_sensor
|
||||
|
||||
LheFailSafe=/data/vendor/gps/logs/esw-crash-dump.txt
|
||||
LogLevel=*:I
|
||||
|
||||
NvStorageDir=/data/vendor/gps/
|
||||
|
||||
# Enable BBD debugging at these stages:
|
||||
# LheDriverDebugFlags=PATCH_BBD:LHE_BBD:FSC_BBD
|
||||
|
||||
LheAutoBaudDelayMS=10
|
||||
TrafficLogEnabled=false
|
||||
SecondaryConfigPath=/data/vendor/gps/overlay/lhd_overlay.conf
|
||||
|
||||
SkipSensorWakeLock=true
|
||||
LoggerWakeLockEnable=false
|
||||
PpsEnable=true
|
32
location/lhd_user.conf.l10
Normal file
32
location/lhd_user.conf.l10
Normal file
|
@ -0,0 +1,32 @@
|
|||
LheName=bbd
|
||||
|
||||
LheRsmResetTimeoutMS=10000
|
||||
GpioNStdbyPath=/sys/devices/platform/10940000.spi/spi_master/spi5/spi5.0/nstandby
|
||||
|
||||
LhePatch=/vendor/firmware/SensorHub.patch
|
||||
Lhe477xDebugFlags=RPC:FACILITY=65535-dKP+CUST+LHE:STDOUT_PUTS:STDOUT_LOG
|
||||
# LheConsole=/data/vendor/gps/LheConsole
|
||||
|
||||
LogEnabled=false
|
||||
Log=JAVA
|
||||
LogDirectory=/sdcard/gps/broadcom/storage
|
||||
|
||||
LheBbdPacket=/dev/ttyBCM
|
||||
|
||||
LheBbdControl=/dev/bbd_control
|
||||
|
||||
# LheBbdSensor=/dev/bbd_sensor
|
||||
|
||||
# LheFailSafe=/data/vendor/gps/esw-crash-dump.txt
|
||||
|
||||
NvStorageDir=/data/vendor/gps/
|
||||
|
||||
# Enable BBD debugging at these stages:
|
||||
# LheDriverDebugFlags=PATCH_BBD:LHE_BBD:FSC_BBD
|
||||
|
||||
LheAutoBaudDelayMS=10
|
||||
TrafficLogEnabled=false
|
||||
|
||||
SkipSensorWakeLock=true
|
||||
LoggerWakeLockEnable=false
|
||||
PpsEnable=true
|
6
location/scd.conf.l10
Normal file
6
location/scd.conf.l10
Normal file
|
@ -0,0 +1,6 @@
|
|||
LogEnabled=true
|
||||
Log=JAVA
|
||||
LogDirectory=/sdcard/gps/broadcom/storage
|
||||
NvStorageDir=/data/vendor/gps/
|
||||
TcpConnectionTimeout=20
|
||||
SecondaryConfigPath=/data/vendor/gps/overlay/scd_overlay.conf
|
5
location/scd_user.conf.l10
Normal file
5
location/scd_user.conf.l10
Normal file
|
@ -0,0 +1,5 @@
|
|||
LogEnabled=false
|
||||
Log=JAVA
|
||||
LogDirectory=/sdcard/gps/broadcom/storage
|
||||
NvStorageDir=/data/vendor/gps/
|
||||
TcpConnectionTimeout=20
|
Binary file not shown.
BIN
lynx/display_golden_cal0.pb
Normal file
BIN
lynx/display_golden_cal0.pb
Normal file
Binary file not shown.
|
@ -66,6 +66,38 @@
|
|||
@left
|
||||
</string>
|
||||
|
||||
<!-- Not allow to switch to higher refresh rate when display brightness setting is
|
||||
equal or less than this value -->
|
||||
<integer-array name="config_brightnessThresholdsOfPeakRefreshRate">
|
||||
<!-- System brightness for 10 nits: round((10-2)/(1000-2)*(255-1)+1) = 3 -->
|
||||
<item>3</item> <!-- 20% UI brightness -->
|
||||
<!-- System brightness for 15 nits: round((15-2)/(1000-2)*(255-1)+1) = 4 -->
|
||||
<item>4</item> <!-- 24% UI brightness -->
|
||||
</integer-array>
|
||||
<integer-array name="config_ambientThresholdsOfPeakRefreshRate">
|
||||
<item>-1</item>
|
||||
<item>5</item>
|
||||
</integer-array>
|
||||
<!-- default refresh rate in the zone defined by birghtness and ambient thresholds -->
|
||||
<integer name="config_defaultRefreshRateInZone">90</integer>
|
||||
|
||||
<!-- Default refresh rate while the device has high brightness mode enabled for HDR. -->
|
||||
<integer name="config_defaultRefreshRateInHbmHdr">60</integer>
|
||||
|
||||
<!-- Switch to fixed refresh rate when display brightness setting is
|
||||
equal or more than this value -->
|
||||
<integer-array name="config_highDisplayBrightnessThresholdsOfFixedRefreshRate">
|
||||
<!-- System brightness for 500 nits: round((500-2)/(1000-2)*(255-1)+1) = 128 -->
|
||||
<item>128</item> <!--100% UI normal brightness -->
|
||||
</integer-array>
|
||||
|
||||
<integer-array name="config_highAmbientBrightnessThresholdsOfFixedRefreshRate">
|
||||
<item>50000</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- default refresh rate in the high zone defined by brightness and ambient thresholds -->
|
||||
<integer name="config_fixedRefreshRateInHighZone">60</integer>
|
||||
|
||||
<!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
|
||||
The N entries of this array define N 1 zones as follows:
|
||||
Zone 0: 0 <= LUX < array[0]
|
||||
|
@ -153,7 +185,10 @@
|
|||
<integer name="config_defaultRefreshRate">0</integer>
|
||||
|
||||
<!-- The default peak refresh rate. -->
|
||||
<integer name="config_defaultPeakRefreshRate">90</integer>
|
||||
<integer name="config_defaultPeakRefreshRate">60</integer>
|
||||
|
||||
<!-- the number of the max cached processes in the system. -->
|
||||
<integer name="config_customizedMaxCachedProcesses">64</integer>
|
||||
|
||||
<integer-array name="config_ambientThresholdLevels">
|
||||
<item>2</item>
|
||||
|
@ -250,7 +285,18 @@
|
|||
<!-- Type of the udfps long press sensor. Empty if long press is not supported. -->
|
||||
<string name="config_dozeUdfpsLongPressSensorType" translatable="false">com.google.sensor.long_press</string>
|
||||
|
||||
<!-- Type of the quick pickup sensor. Empty if quick pickup is not supported. -->
|
||||
<string name="config_quickPickupSensorType" translatable="false">com.google.sensor.quick_pickup</string>
|
||||
|
||||
<!-- UDFPS does not support gestures -->
|
||||
<bool name="config_fingerprintSupportsGestures">false</bool>
|
||||
|
||||
<!-- Boolean indicating if restoring network selection should be skipped -->
|
||||
<!-- The restoring is handled by modem if it is true -->
|
||||
<bool translatable="false" name="skip_restoring_network_selection">true</bool>
|
||||
|
||||
<!-- MMS user agent string -->
|
||||
<string name="config_mms_user_agent" translatable="false">gwkk3</string>
|
||||
<!-- MMS user agent profile url -->
|
||||
<string name="config_mms_user_agent_profile_url" translatable="false">http://www.gstatic.com/android/sms/GWKK3.xml</string>
|
||||
</resources>
|
||||
|
|
|
@ -81,5 +81,8 @@
|
|||
<string translatable="false" name="config_cameraProtectionExcludedPackages">com.google.android.as</string>
|
||||
|
||||
<bool name="config_enableDisplayCutoutProtection">true</bool>
|
||||
|
||||
<!-- The time (in ms) needed to trigger the lock icon view's long-press affordance -->
|
||||
<integer name="config_lockIconLongPress" translatable="false">100</integer>
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- These resources are around just to allow their values to be customized
|
||||
for different hardware and product builds. -->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<!-- set this to ./DevInfo/Mod -->
|
||||
<string translatable="false" name="config_devinfo_model">G0DZQ</string>
|
||||
</resources>
|
8
lynx/overlay_packages/SettingsOverlayG82U8/Android.bp
Normal file
8
lynx/overlay_packages/SettingsOverlayG82U8/Android.bp
Normal file
|
@ -0,0 +1,8 @@
|
|||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
runtime_resource_overlay {
|
||||
name: "SettingsOverlayG82U8",
|
||||
product_specific: true,
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settings.overlay.g82u8">
|
||||
<application android:hasCode="false" />
|
||||
<overlay android:targetPackage="com.android.settings"
|
||||
android:requiredSystemPropertyName="ro.boot.hardware.sku"
|
||||
android:requiredSystemPropertyValue="G82U8"
|
||||
android:isStatic="true" />
|
||||
</manifest>
|
Binary file not shown.
After Width: | Height: | Size: 230 KiB |
9
lynx/radio/lynx_display_primary_mipi_coex_table.csv
Normal file
9
lynx/radio/lynx_display_primary_mipi_coex_table.csv
Normal file
|
@ -0,0 +1,9 @@
|
|||
500000,551000
|
||||
|
||||
798000,836000,500000
|
||||
925000,960000,500000
|
||||
3311000,3313000,500000
|
||||
3578000,3589000,500000
|
||||
740000,768000,551000
|
||||
2124000,2126000,551000
|
||||
2479000,2481000,551000
|
|
|
@ -116,7 +116,7 @@
|
|||
<hal format="hidl">
|
||||
<name>vendor.google.whitechapel.audio.audioext</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>2.0</version>
|
||||
<version>4.0</version>
|
||||
<interface>
|
||||
<name>IAudioExt</name>
|
||||
<instance>default</instance>
|
||||
|
|
935
powerhint.json
935
powerhint.json
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,7 @@ soong_namespace {
|
|||
imports: [
|
||||
"hardware/google/pixel",
|
||||
"device/google/gs201/powerstats",
|
||||
"device/google/gs-common/powerstats",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -38,5 +39,6 @@ cc_binary {
|
|||
|
||||
shared_libs: [
|
||||
"android.hardware.power.stats-impl.gs201",
|
||||
"android.hardware.power.stats-impl.gs-common",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <dataproviders/DisplayStateResidencyDataProvider.h>
|
||||
#include <dataproviders/PowerStatsEnergyConsumer.h>
|
||||
#include <DevfreqStateResidencyDataProvider.h>
|
||||
#include <Gs201CommonDataProviders.h>
|
||||
#include <PowerStatsAidl.h>
|
||||
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include <android/binder_process.h>
|
||||
#include <log/log.h>
|
||||
|
||||
using aidl::android::hardware::power::stats::DevfreqStateResidencyDataProvider;
|
||||
using aidl::android::hardware::power::stats::DisplayStateResidencyDataProvider;
|
||||
using aidl::android::hardware::power::stats::EnergyConsumerType;
|
||||
using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
|
||||
|
@ -53,6 +55,39 @@ void addDisplay(std::shared_ptr<PowerStats> p) {
|
|||
{"On: 1080x2400@90", 3}}));
|
||||
}
|
||||
|
||||
void addGPUGs202(std::shared_ptr<PowerStats> p) {
|
||||
std::map<std::string, int32_t> stateCoeffs;
|
||||
|
||||
// Add GPU state residency
|
||||
p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
|
||||
"GPU",
|
||||
"/sys/devices/platform/28000000.mali"));
|
||||
|
||||
// Add GPU energy consumer
|
||||
stateCoeffs = {
|
||||
{"202000", 890},
|
||||
{"251000", 1102},
|
||||
{"302000", 1308},
|
||||
{"351000", 1522},
|
||||
{"400000", 1772},
|
||||
{"434000", 1931},
|
||||
{"471000", 2105},
|
||||
{"510000", 2292},
|
||||
{"572000", 2528},
|
||||
{"633000", 2811},
|
||||
{"701000", 3127},
|
||||
{"762000", 3452},
|
||||
{"848000", 4044}};
|
||||
|
||||
p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterAndAttrConsumer(
|
||||
p,
|
||||
EnergyConsumerType::OTHER,
|
||||
"GPU",
|
||||
{"S2S_VDD_G3D", "S8S_VDD_G3D_L2"},
|
||||
{{UID_TIME_IN_STATE, "/sys/devices/platform/28000000.mali/uid_time_in_state"}},
|
||||
stateCoeffs));
|
||||
}
|
||||
|
||||
int main() {
|
||||
LOG(INFO) << "Pixel PowerStats HAL AIDL Service is starting.";
|
||||
|
||||
|
@ -61,9 +96,22 @@ int main() {
|
|||
|
||||
std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
|
||||
|
||||
addGs201CommonDataProvidersQc(p);
|
||||
setEnergyMeter(p);
|
||||
addAoC(p);
|
||||
addCPUclusters(p);
|
||||
addDisplay(p);
|
||||
addSoC(p);
|
||||
addGNSS(p);
|
||||
addMobileRadio(p);
|
||||
addPCIe(p);
|
||||
addWlan(p);
|
||||
addTPU(p);
|
||||
addUfs(p);
|
||||
addNFC(p, "/sys/devices/platform/10970000.hsi2c/i2c-4/i2c-st21nfc/power_stats");
|
||||
addPowerDomains(p);
|
||||
addDevfreq(p);
|
||||
addGPUGs202(p);
|
||||
addDvfsStats(p);
|
||||
|
||||
const std::string instance = std::string() + PowerStats::descriptor + "/default";
|
||||
binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
|
||||
|
|
|
@ -109,9 +109,6 @@
|
|||
be checked via NL80211 interface -->
|
||||
<bool translatable="false" name="config_wifi11axSupportOverride">true</bool>
|
||||
|
||||
<!-- Wifi driver supports 6GHz band for softap -->
|
||||
<bool translatable="false" name="config_wifiSoftap6ghzSupported">true</bool>
|
||||
|
||||
<!-- Wifi driver supports WPA3 Simultaneous Authentication of Equals (WPA3-SAE) for softap -->
|
||||
<bool translatable="false" name="config_wifi_softap_sae_supported">true</bool>
|
||||
|
||||
|
|
294
thermal_info_config_charge_lynx.json
Normal file
294
thermal_info_config_charge_lynx.json
Normal file
|
@ -0,0 +1,294 @@
|
|||
{
|
||||
"Sensors":[
|
||||
{
|
||||
"Name":"battery",
|
||||
"Type":"BATTERY",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 60.0],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"neutral_therm",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/neutral_therm/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"gnss_tcxo_therm",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/gnss_tcxo_therm/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"usb_pwr_therm",
|
||||
"Type":"UNKNOWN",
|
||||
"HotThreshold":["NAN", 40.0, "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"TempPath":"/dev/thermal/tz-by-name/usb_pwr_therm/tz_temp",
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":60000,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
"Name":"usb_pwr_therm2",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/usb_pwr_therm2/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"skin_therm1",
|
||||
"Type":"UNKNOWN",
|
||||
"HotThreshold":["NAN", 29.9, "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"HotHysteresis":[0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
"TempPath":"/dev/thermal/tz-by-name/skin_therm1/tz_temp",
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":60000,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
"Name":"skin_therm2",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/skin_therm2/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"disp_therm",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/disp_therm/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"quiet_therm",
|
||||
"Type":"UNKNOWN",
|
||||
"TempPath":"/dev/thermal/tz-by-name/quiet_therm/tz_temp",
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["neutral_therm", "quiet_therm", "skin_therm1", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2", "gnss_tcxo_therm"],
|
||||
"Coefficient":[0.05, 0.05, 0.7, 0.05, 0.05, 0.05, 0.05],
|
||||
"Offset":-1500,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-QUT-SKIN2-USB-USB2-2",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["quiet_therm", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2"],
|
||||
"Coefficient":[0.15, 0.15, 0.15, 0.55],
|
||||
"Offset":-1000,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-QUT-SKIN2-USB-GNSS-3",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["quiet_therm", "skin_therm2", "usb_pwr_therm", "gnss_tcxo_therm"],
|
||||
"Coefficient":[0.166, 0.45, 0.217, 0.167],
|
||||
"Offset":-1950,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["neutral_therm", "quiet_therm", "skin_therm1", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2", "gnss_tcxo_therm"],
|
||||
"Coefficient":[-0.05, -0.05, 1.3, -0.05, -0.05, -0.05, -0.05],
|
||||
"Offset":-1950,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CHARGE",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 35.0, 39.0, 43.0, 45.0, 47.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", 700, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", 700, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", 5, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", 0, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", 1200, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", 300, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", 6000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", 2, "NAN", "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"ExcludedPowerInfo": [
|
||||
{
|
||||
"PowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerWeight": [0.5, 0.5, 0.8, 1.0, 1.0, 1.0, 1.0]
|
||||
}
|
||||
],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "fcc",
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"CdevCeiling": [0, 11, 11, 11, 12, 12, 12],
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 12, 12]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CHARGE-WLC",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["skin_therm2", "usb_pwr_therm2", "disp_therm"],
|
||||
"Coefficient":[0.51, 0.25, 0.24],
|
||||
"HotThreshold":["NAN", 35.0, 39.0, 43.0, 45.0, 47.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", 5, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", 0, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", 2000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", 300, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", 6000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", 2, "NAN", "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"ExcludedPowerInfo": [
|
||||
{
|
||||
"PowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerWeight": [0.5, 0.5, 0.8, 1.0, 1.0, 1.0, 1.0]
|
||||
}
|
||||
],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "dc_icl",
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"CdevCeiling": [0, 5, 8, 11, 12, 12, 12],
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 12, 12]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name":"USB-MINUS-SKIN2",
|
||||
"Type":"UNKNOWN",
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor": "usb_pwr_therm",
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["usb_pwr_therm", "skin_therm2"],
|
||||
"Coefficient":[1.0, -1.0],
|
||||
"HotThreshold":["NAN", "7.0", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "usbc-port",
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 0, 0]
|
||||
}
|
||||
],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":0,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-USB-THROTTLING",
|
||||
"Type":"USB_PORT",
|
||||
"Version":"0.1",
|
||||
"VirtualSensor":true,
|
||||
"Formula":"COUNT_THRESHOLD",
|
||||
"TriggerSensor": "usb_pwr_therm",
|
||||
"Combination":["usb_pwr_therm", "USB-MINUS-SKIN2"],
|
||||
"Coefficient":[40000, 10000],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "2.0", "NAN", "NAN"],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "usbc-port",
|
||||
"LimitInfo": [0, 0, 0, 0, 1, 1, 1]
|
||||
}
|
||||
],
|
||||
"VrThreshold":"NAN",
|
||||
"Multiplier":1,
|
||||
"PollingDelay":60000,
|
||||
"PassiveDelay":7000
|
||||
}
|
||||
],
|
||||
"CoolingDevices":[
|
||||
{
|
||||
"Name":"fcc",
|
||||
"Type":"BATTERY"
|
||||
},
|
||||
{
|
||||
"Name":"dc_icl",
|
||||
"Type":"BATTERY"
|
||||
},
|
||||
{
|
||||
"Name":"usbc-port",
|
||||
"Type":"BATTERY"
|
||||
}
|
||||
],
|
||||
"PowerRails":[
|
||||
{
|
||||
"Name":"VSYS_PWR_WLAN_BT"
|
||||
},
|
||||
{
|
||||
"Name":"VSYS_PWR_DISPLAY"
|
||||
},
|
||||
{
|
||||
"Name":"VSYS_PWR_MODEM"
|
||||
},
|
||||
{
|
||||
"Name":"S2M_VDD_CPUCL2",
|
||||
"PowerSampleDelay":7000,
|
||||
"PowerSampleCount":1
|
||||
|
||||
},
|
||||
{
|
||||
"Name":"S3M_VDD_CPUCL1",
|
||||
"PowerSampleDelay":7000,
|
||||
"PowerSampleCount":1
|
||||
},
|
||||
{
|
||||
"Name":"S4M_VDD_CPUCL0",
|
||||
"PowerSampleDelay":7000,
|
||||
"PowerSampleCount":1
|
||||
},
|
||||
{
|
||||
"Name":"S5M_VDD_INT"
|
||||
},
|
||||
{
|
||||
"Name":"S1M_VDD_MIF"
|
||||
},
|
||||
{
|
||||
"Name":"S2S_VDD_G3D",
|
||||
"PowerSampleDelay":7000,
|
||||
"PowerSampleCount":1
|
||||
},
|
||||
{
|
||||
"Name":"PARTIAL_SYSTEM_POWER",
|
||||
"VirtualRails":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["VSYS_PWR_MODEM", "S2M_VDD_CPUCL2", "S3M_VDD_CPUCL1", "S4M_VDD_CPUCL0", "S5M_VDD_INT", "S1M_VDD_MIF", "S2S_VDD_G3D", "VSYS_PWR_WLAN_BT", "VSYS_PWR_DISPLAY"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
|
||||
"PowerSampleDelay":14000,
|
||||
"PowerSampleCount":5
|
||||
}
|
||||
]
|
||||
}
|
|
@ -36,11 +36,11 @@
|
|||
{
|
||||
"Name":"skin_therm1",
|
||||
"Type":"UNKNOWN",
|
||||
"HotThreshold":["NAN", 29.9, "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"HotThreshold":["NAN", 27.9, "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"HotHysteresis":[0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
"TempPath":"/dev/thermal/tz-by-name/skin_therm1/tz_temp",
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":60000,
|
||||
"PollingDelay":60000,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
|
@ -62,38 +62,61 @@
|
|||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-QUIET-SKIN2-USB2",
|
||||
"Name":"VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["quiet_therm", "skin_therm2", "usb_pwr_therm2"],
|
||||
"Coefficient":[0.4, 0.3, 0.3],
|
||||
"Combination":["neutral_therm", "quiet_therm", "skin_therm1", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2", "gnss_tcxo_therm"],
|
||||
"Coefficient":[0.05, 0.05, 0.7, 0.05, 0.05, 0.05, 0.05],
|
||||
"Offset":-1500,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN2-SKIN1-GNSS-BATT",
|
||||
"Name":"VIRTUAL-QUT-SKIN2-USB-USB2-2",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["skin_therm2", "skin_therm1", "gnss_tcxo_therm", "battery"],
|
||||
"Coefficient":[0.2, 0.2, 0.1, 0.5],
|
||||
"Combination":["quiet_therm", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2"],
|
||||
"Coefficient":[0.15, 0.15, 0.15, 0.55],
|
||||
"Offset":-1000,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-QUT-SKIN2-USB-GNSS-3",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["quiet_therm", "skin_therm2", "usb_pwr_therm", "gnss_tcxo_therm"],
|
||||
"Coefficient":[0.166, 0.45, 0.217, 0.167],
|
||||
"Offset":-1950,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["neutral_therm", "quiet_therm", "skin_therm1", "skin_therm2", "usb_pwr_therm", "usb_pwr_therm2", "gnss_tcxo_therm"],
|
||||
"Coefficient":[-0.05, -0.05, 1.3, -0.05, -0.05, -0.05, -0.05],
|
||||
"Offset":-1950,
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN",
|
||||
"Type":"SKIN",
|
||||
"Version":"0.1",
|
||||
"Version":"0.7",
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-QUIET-SKIN2-USB2", "VIRTUAL-SKIN2-SKIN1-GNSS-BATT"],
|
||||
"Coefficient":[1.0, 1.0],
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 39.0, 43.0, 45.0, 47.0, 52.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"SendPowerHint":true,
|
||||
"Monitor":true,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
|
@ -105,30 +128,51 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CPU-GPU",
|
||||
"Name":"VIRTUAL-SKIN-HINT",
|
||||
"Type":"UNKNOWN",
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-QUIET-SKIN2-USB2", "VIRTUAL-SKIN2-SKIN1-GNSS-BATT"],
|
||||
"Coefficient":[1.0, 1.0],
|
||||
"HotThreshold":["NAN", 39.0, 43.0, 45.0, 47.0, 52.0, 55.0],
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 37.0, 43.0, 45.0, 47.0, 52.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"SendPowerHint":true,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CPU",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 37.0, 39.0, 41.0, 47.0, 52.0, 55.0],
|
||||
"HotHysteresis":[0.0, 0.9, 0.9, 0.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", 1800, 500, "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", 1800, 500, "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", 20, 5, "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", 0, 0, "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", 1500, 100, "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", 2500, 1300, "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", 2000, 800, "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", 10000, 4000, "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", 2, 0, "NAN", "NAN", "NAN"],
|
||||
"E_Integral_Default": 50
|
||||
"K_Po":["NAN", "NAN", "NAN", 400, "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", "NAN", 400, "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", "NAN", 5, "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", "NAN", 0, "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", "NAN", 300, "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", "NAN", 800, "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", "NAN", 800, "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", "NAN", 10000, "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", "NAN", 2, "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"ExcludedPowerInfo": [
|
||||
{
|
||||
"PowerRail": "VSYS_PWR_MODEM",
|
||||
"PowerWeight": [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]
|
||||
}
|
||||
],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "thermal-cpufreq-0",
|
||||
|
@ -136,6 +180,7 @@
|
|||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S4M_VDD_CPUCL0",
|
||||
"CdevCeiling": [0, 8, 8, 8, 8, 10, 10],
|
||||
"LimitInfo": [0, 0, 0, 0, 8, 10, 10]
|
||||
},
|
||||
{
|
||||
|
@ -144,6 +189,7 @@
|
|||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S3M_VDD_CPUCL1",
|
||||
"CdevCeiling": [0, 12, 12, 12, 12, 14, 14],
|
||||
"LimitInfo": [0, 0, 0, 0, 12, 14, 14]
|
||||
},
|
||||
{
|
||||
|
@ -152,6 +198,62 @@
|
|||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S2M_VDD_CPUCL2",
|
||||
"CdevCeiling": [0, 15, 15, 15, 15, 17, 17],
|
||||
"LimitInfo": [0, 0, 0, 0, 15, 17, 17]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CPU-GPU",
|
||||
"Type":"UNKNOWN",
|
||||
"Hidden":true,
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 37.0, 43.0, 45.0, 47, 52.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.4, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", "NAN", 300, "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", "NAN", 300, "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", "NAN", 5, "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", "NAN", 0, "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", "NAN", 700, "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", "NAN", 800, "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", "NAN", 0, "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", "NAN", 3900, "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", "NAN", 2, "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "thermal-cpufreq-0",
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S4M_VDD_CPUCL0",
|
||||
"CdevCeiling": [0, 8, 8, 8, 8, 10, 10],
|
||||
"LimitInfo": [0, 0, 0, 0, 8, 10, 10]
|
||||
},
|
||||
{
|
||||
"CdevRequest": "thermal-cpufreq-1",
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S3M_VDD_CPUCL1",
|
||||
"CdevCeiling": [0, 12, 12, 12, 12, 14, 14],
|
||||
"LimitInfo": [0, 0, 0, 0, 12, 14, 14]
|
||||
},
|
||||
{
|
||||
"CdevRequest": "thermal-cpufreq-2",
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S2M_VDD_CPUCL2",
|
||||
"CdevCeiling": [0, 15, 15, 15, 15, 17, 17],
|
||||
"LimitInfo": [0, 0, 0, 0, 15, 17, 17]
|
||||
},
|
||||
{
|
||||
|
@ -160,7 +262,8 @@
|
|||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"BindedPowerRail": "S2S_VDD_G3D",
|
||||
"LimitInfo": [0, 0, 0, 0, 10, 11, 11]
|
||||
"CdevCeiling": [0, 10, 10, 10, 10, 12, 12],
|
||||
"LimitInfo": [0, 0, 0, 0, 10, 12, 12]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -170,32 +273,79 @@
|
|||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-QUIET-SKIN2-USB2", "VIRTUAL-SKIN2-SKIN1-GNSS-BATT"],
|
||||
"Coefficient":[1.0, 1.0],
|
||||
"HotThreshold":["NAN", 39.0, 41.0, 43.0, 45.0, 47.0, 55.0],
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", 35.0, 39.0, 43.0, 45.0, 47.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"Monitor":true,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", 700, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", 700, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", 5, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", 0, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", 1200, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", 300, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", 6000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", 2, "NAN", "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"ExcludedPowerInfo": [
|
||||
{
|
||||
"PowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerWeight": [0.5, 0.5, 0.8, 1.0, 1.0, 1.0, 1.0]
|
||||
}
|
||||
],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "fcc",
|
||||
"LimitInfo": [0, 3, 6, 6, 8, 8, 8],
|
||||
"BindedPowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerThreshold": [500, 500, 500, 500, 0, 0, 0],
|
||||
"CdevFloorWithPowerLink": [0, 0, 3, 3, 8 ,8 ,8],
|
||||
"ReleaseLogic": "RELEASE_TO_FLOOR",
|
||||
"ThrottlingWithPowerLink":true
|
||||
},
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"CdevCeiling": [0, 11, 11, 11, 12, 12, 12],
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 12, 12]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-SKIN-CHARGE-WLC",
|
||||
"Type":"UNKNOWN",
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["skin_therm2", "usb_pwr_therm2", "disp_therm"],
|
||||
"Coefficient":[0.51, 0.25, 0.24],
|
||||
"HotThreshold":["NAN", 35.0, 39.0, 43.0, 45.0, 47.0, 55.0],
|
||||
"HotHysteresis":[0.0, 1.9, 1.9, 1.9, 1.9, 1.9, 1.9],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000,
|
||||
"PIDInfo": {
|
||||
"K_Po":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_Pu":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_I":["NAN", "NAN", 5, "NAN", "NAN", "NAN", "NAN"],
|
||||
"K_D":["NAN", "NAN", 0, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Max":["NAN", "NAN", 800, "NAN", "NAN", "NAN", "NAN"],
|
||||
"S_Power":["NAN", "NAN", 2000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MinAllocPower":["NAN", "NAN", 300, "NAN", "NAN", "NAN", "NAN"],
|
||||
"MaxAllocPower":["NAN", "NAN", 6000, "NAN", "NAN", "NAN", "NAN"],
|
||||
"I_Cutoff":["NAN", "NAN", 2, "NAN", "NAN", "NAN", "NAN"]
|
||||
},
|
||||
"ExcludedPowerInfo": [
|
||||
{
|
||||
"PowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerWeight": [0.5, 0.5, 0.8, 1.0, 1.0, 1.0, 1.0]
|
||||
}
|
||||
],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "dc_icl",
|
||||
"LimitInfo": [0, 1, 2, 3, 4, 4, 4],
|
||||
"BindedPowerRail": "PARTIAL_SYSTEM_POWER",
|
||||
"PowerThreshold": [500, 500, 500, 500, 0, 0, 0],
|
||||
"CdevFloorWithPowerLink": [0, 1, 2, 3, 4, 4, 4],
|
||||
"ReleaseLogic": "RELEASE_TO_FLOOR",
|
||||
"ThrottlingWithPowerLink":true
|
||||
"CdevWeightForPID": [1, 1, 1, 1, 1, 1, 1],
|
||||
"MaxReleaseStep": 1,
|
||||
"MaxThrottleStep": 1,
|
||||
"CdevCeiling": [0, 5, 8, 11, 12, 12, 12],
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 12, 12]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -205,12 +355,12 @@
|
|||
"VirtualSensor":true,
|
||||
"TriggerSensor":"skin_therm1",
|
||||
"Formula":"MAXIMUM",
|
||||
"Combination":["VIRTUAL-QUIET-SKIN2-USB2", "VIRTUAL-SKIN2-SKIN1-GNSS-BATT"],
|
||||
"Coefficient":[1.0, 1.0],
|
||||
"Combination":["VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-1", "VIRTUAL-QUT-SKIN2-USB-USB2-2", "VIRTUAL-QUT-SKIN2-USB-GNSS-3", "VIRTUAL-NEU-QUT-SKIN1-SKIN2-USB-USB2-GNSS-4"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", 54.0, "NAN"],
|
||||
"HotHysteresis":[0.0, 0.0, 0.0, 0.0, 0.0, 1.9, 0.0],
|
||||
"Multiplier":0.001,
|
||||
"Monitor":true,
|
||||
"SendCallback":true,
|
||||
"PollingDelay":300000,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
|
@ -218,10 +368,20 @@
|
|||
"Name":"USB-MINUS-SKIN2",
|
||||
"Type":"UNKNOWN",
|
||||
"VirtualSensor":true,
|
||||
"TriggerSensor": "usb_pwr_therm",
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["usb_pwr_therm", "skin_therm2"],
|
||||
"Coefficient":[1.0, -1.0],
|
||||
"Multiplier":0.001
|
||||
"HotThreshold":["NAN", "7.0", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "usbc-port",
|
||||
"LimitInfo": [0, 0, 0, 0, 0, 0, 0]
|
||||
}
|
||||
],
|
||||
"Multiplier":0.001,
|
||||
"PollingDelay":0,
|
||||
"PassiveDelay":7000
|
||||
},
|
||||
{
|
||||
"Name":"VIRTUAL-USB-THROTTLING",
|
||||
|
@ -263,31 +423,31 @@
|
|||
{
|
||||
"Name":"LITTLE",
|
||||
"Type":"CPU",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 115.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"MID",
|
||||
"Type":"CPU",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 115.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"BIG",
|
||||
"Type":"CPU",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 115.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"G3D",
|
||||
"Type":"GPU",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 115.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
"Name":"TPU",
|
||||
"Type":"NPU",
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", 115.0],
|
||||
"HotThreshold":["NAN", "NAN", "NAN", "NAN", "NAN", "NAN", "NAN"],
|
||||
"Multiplier":0.001
|
||||
},
|
||||
{
|
||||
|
@ -362,7 +522,7 @@
|
|||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 9, 9, 9]
|
||||
"LimitInfo": [0, 0, 0, 0, 11, 11, 11]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -381,7 +541,7 @@
|
|||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 9, 9, 9]
|
||||
"LimitInfo": [0, 0, 0, 0, 11, 11, 11]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -419,7 +579,7 @@
|
|||
"BindedCdevInfo": [
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 4, 4, 4]
|
||||
"LimitInfo": [0, 0, 0, 0, 5, 5, 5]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -458,7 +618,7 @@
|
|||
},
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 3, 3, 3]
|
||||
"LimitInfo": [0, 0, 0, 0, 4, 4, 4]
|
||||
},
|
||||
{
|
||||
"CdevRequest": "tpu_cooling",
|
||||
|
@ -512,7 +672,7 @@
|
|||
},
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 4, 4, 4]
|
||||
"LimitInfo": [0, 0, 0, 0, 5, 5, 5]
|
||||
},
|
||||
{
|
||||
"CdevRequest": "tpu_cooling",
|
||||
|
@ -533,7 +693,7 @@
|
|||
},
|
||||
{
|
||||
"CdevRequest": "thermal-gpufreq-0",
|
||||
"LimitInfo": [0, 0, 0, 0, 3, 3, 3]
|
||||
"LimitInfo": [0, 0, 0, 0, 4, 4, 4]
|
||||
},
|
||||
{
|
||||
"CdevRequest": "tpu_cooling",
|
||||
|
@ -651,10 +811,15 @@
|
|||
],
|
||||
"PowerRails":[
|
||||
{
|
||||
"Name":"PPVAR_VSYS_PWR_DISP"
|
||||
"Name":"VSYS_PWR_WLAN_BT"
|
||||
},
|
||||
{
|
||||
"Name":"VSYS_PWR_MODEM"
|
||||
"Name":"VSYS_PWR_DISPLAY"
|
||||
},
|
||||
{
|
||||
"Name":"VSYS_PWR_MODEM",
|
||||
"PowerSampleDelay":7000,
|
||||
"PowerSampleCount":1
|
||||
},
|
||||
{
|
||||
"Name":"S2M_VDD_CPUCL2",
|
||||
|
@ -687,8 +852,8 @@
|
|||
"Name":"PARTIAL_SYSTEM_POWER",
|
||||
"VirtualRails":true,
|
||||
"Formula":"WEIGHTED_AVG",
|
||||
"Combination":["VSYS_PWR_MODEM", "S2M_VDD_CPUCL2", "S3M_VDD_CPUCL1", "S4M_VDD_CPUCL0", "S5M_VDD_INT", "S1M_VDD_MIF", "S2S_VDD_G3D"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
|
||||
"Combination":["VSYS_PWR_MODEM", "S2M_VDD_CPUCL2", "S3M_VDD_CPUCL1", "S4M_VDD_CPUCL0", "S5M_VDD_INT", "S1M_VDD_MIF", "S2S_VDD_G3D", "VSYS_PWR_WLAN_BT", "VSYS_PWR_DISPLAY"],
|
||||
"Coefficient":[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
|
||||
"PowerSampleDelay":14000,
|
||||
"PowerSampleCount":5
|
||||
}
|
||||
|
|
52
vibrator/Android.bp
Normal file
52
vibrator/Android.bp
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Copyright (C) 2019 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "PixelVibratorDefaultsPrivateLynx",
|
||||
relative_install_path: "hw",
|
||||
static_libs: [
|
||||
"PixelVibratorCommonPrivateLynx",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"libhardware",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "PixelVibratorBinaryDefaultsPrivateLynx",
|
||||
defaults: ["PixelVibratorDefaultsPrivateLynx"],
|
||||
shared_libs: [
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "PixelVibratorTestDefaultsPrivateLynx",
|
||||
defaults: ["PixelVibratorDefaultsPrivateLynx"],
|
||||
static_libs: [
|
||||
"android.hardware.vibrator-V2-ndk",
|
||||
],
|
||||
test_suites: ["device-tests"],
|
||||
require_root: true,
|
||||
}
|
4
vibrator/OWNERS
Normal file
4
vibrator/OWNERS
Normal file
|
@ -0,0 +1,4 @@
|
|||
chasewu@google.com
|
||||
michaelwr@google.com
|
||||
taikuo@google.com
|
||||
chrispaulo@google.com
|
37
vibrator/common/Android.bp
Normal file
37
vibrator/common/Android.bp
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// Copyright (C) 2019 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "PixelVibratorCommonPrivateLynx",
|
||||
srcs: [
|
||||
"HardwareBase.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
cflags: [
|
||||
"-DATRACE_TAG=(ATRACE_TAG_VIBRATOR | ATRACE_TAG_HAL)",
|
||||
"-DLOG_TAG=\"android.hardware.vibrator@1.x-common\"",
|
||||
],
|
||||
export_include_dirs: ["."],
|
||||
vendor_available: true,
|
||||
}
|
136
vibrator/common/HardwareBase.cpp
Normal file
136
vibrator/common/HardwareBase.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 "HardwareBase.h"
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
HwApiBase::HwApiBase() {
|
||||
mPathPrefix = std::getenv("HWAPI_PATH_PREFIX") ?: "";
|
||||
if (mPathPrefix.empty()) {
|
||||
ALOGE("Failed get HWAPI path prefix!");
|
||||
}
|
||||
}
|
||||
|
||||
void HwApiBase::saveName(const std::string &name, const std::ios *stream) {
|
||||
mNames[stream] = name;
|
||||
}
|
||||
|
||||
bool HwApiBase::has(const std::ios &stream) {
|
||||
return !!stream;
|
||||
}
|
||||
|
||||
void HwApiBase::debug(int fd) {
|
||||
dprintf(fd, "Kernel:\n");
|
||||
|
||||
for (auto &entry : utils::pathsFromEnv("HWAPI_DEBUG_PATHS", mPathPrefix)) {
|
||||
auto &path = entry.first;
|
||||
auto &stream = entry.second;
|
||||
std::string line;
|
||||
|
||||
dprintf(fd, " %s:\n", path.c_str());
|
||||
while (std::getline(stream, line)) {
|
||||
dprintf(fd, " %s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
mRecordsMutex.lock();
|
||||
dprintf(fd, " Records:\n");
|
||||
for (auto &r : mRecords) {
|
||||
if (r == nullptr) {
|
||||
continue;
|
||||
}
|
||||
dprintf(fd, " %s\n", r->toString(mNames).c_str());
|
||||
}
|
||||
mRecordsMutex.unlock();
|
||||
}
|
||||
|
||||
HwCalBase::HwCalBase() {
|
||||
std::ifstream calfile;
|
||||
auto propertyPrefix = std::getenv("PROPERTY_PREFIX");
|
||||
|
||||
if (propertyPrefix != NULL) {
|
||||
mPropertyPrefix = std::string(propertyPrefix);
|
||||
} else {
|
||||
ALOGE("Failed get property prefix!");
|
||||
}
|
||||
|
||||
utils::fileFromEnv("CALIBRATION_FILEPATH", &calfile);
|
||||
|
||||
for (std::string line; std::getline(calfile, line);) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
std::istringstream is_line(line);
|
||||
std::string key, value;
|
||||
if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
|
||||
mCalData[utils::trim(key)] = utils::trim(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HwCalBase::debug(int fd) {
|
||||
std::ifstream stream;
|
||||
std::string path;
|
||||
std::string line;
|
||||
struct context {
|
||||
HwCalBase *obj;
|
||||
int fd;
|
||||
} context{this, fd};
|
||||
|
||||
dprintf(fd, "Properties:\n");
|
||||
|
||||
property_list(
|
||||
[](const char *key, const char *value, void *cookie) {
|
||||
struct context *context = static_cast<struct context *>(cookie);
|
||||
HwCalBase *obj = context->obj;
|
||||
int fd = context->fd;
|
||||
const std::string expect{obj->mPropertyPrefix};
|
||||
const std::string actual{key, std::min(strlen(key), expect.size())};
|
||||
if (actual == expect) {
|
||||
dprintf(fd, " %s:\n", key);
|
||||
dprintf(fd, " %s\n", value);
|
||||
}
|
||||
},
|
||||
&context);
|
||||
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Persist:\n");
|
||||
|
||||
utils::fileFromEnv("CALIBRATION_FILEPATH", &stream, &path);
|
||||
|
||||
dprintf(fd, " %s:\n", path.c_str());
|
||||
while (std::getline(stream, line)) {
|
||||
dprintf(fd, " %s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
221
vibrator/common/HardwareBase.h
Normal file
221
vibrator/common/HardwareBase.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <log/log.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
using ::android::base::unique_fd;
|
||||
|
||||
class HwApiBase {
|
||||
private:
|
||||
using NamesMap = std::map<const std::ios *, std::string>;
|
||||
|
||||
class RecordInterface {
|
||||
public:
|
||||
virtual std::string toString(const NamesMap &names) = 0;
|
||||
virtual ~RecordInterface() {}
|
||||
};
|
||||
template <typename T>
|
||||
class Record : public RecordInterface {
|
||||
public:
|
||||
Record(const char *func, const T &value, const std::ios *stream)
|
||||
: mFunc(func), mValue(value), mStream(stream) {}
|
||||
std::string toString(const NamesMap &names) override;
|
||||
|
||||
private:
|
||||
const char *mFunc;
|
||||
const T mValue;
|
||||
const std::ios *mStream;
|
||||
};
|
||||
using Records = std::list<std::unique_ptr<RecordInterface>>;
|
||||
|
||||
static constexpr uint32_t RECORDS_SIZE = 32;
|
||||
|
||||
public:
|
||||
HwApiBase();
|
||||
void debug(int fd);
|
||||
|
||||
protected:
|
||||
void saveName(const std::string &name, const std::ios *stream);
|
||||
template <typename T>
|
||||
void open(const std::string &name, T *stream);
|
||||
bool has(const std::ios &stream);
|
||||
template <typename T>
|
||||
bool get(T *value, std::istream *stream);
|
||||
template <typename T>
|
||||
bool set(const T &value, std::ostream *stream);
|
||||
template <typename T>
|
||||
bool poll(const T &value, std::istream *stream, const int32_t timeout = -1);
|
||||
template <typename T>
|
||||
void record(const char *func, const T &value, const std::ios *stream);
|
||||
|
||||
private:
|
||||
std::string mPathPrefix;
|
||||
NamesMap mNames;
|
||||
Records mRecords{RECORDS_SIZE};
|
||||
std::mutex mRecordsMutex;
|
||||
std::mutex mIoMutex;
|
||||
};
|
||||
|
||||
#define HWAPI_RECORD(args...) HwApiBase::record(__FUNCTION__, ##args)
|
||||
|
||||
template <typename T>
|
||||
void HwApiBase::open(const std::string &name, T *stream) {
|
||||
saveName(name, stream);
|
||||
utils::openNoCreate(mPathPrefix + name, stream);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool HwApiBase::get(T *value, std::istream *stream) {
|
||||
ATRACE_NAME("HwApi::get");
|
||||
std::scoped_lock ioLock{mIoMutex};
|
||||
bool ret;
|
||||
stream->seekg(0);
|
||||
*stream >> *value;
|
||||
if (!(ret = !!*stream)) {
|
||||
ALOGE("Failed to read %s (%d): %s", mNames[stream].c_str(), errno, strerror(errno));
|
||||
}
|
||||
stream->clear();
|
||||
HWAPI_RECORD(*value, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool HwApiBase::set(const T &value, std::ostream *stream) {
|
||||
ATRACE_NAME("HwApi::set");
|
||||
using utils::operator<<;
|
||||
std::scoped_lock ioLock{mIoMutex};
|
||||
bool ret;
|
||||
*stream << value << std::endl;
|
||||
if (!(ret = !!*stream)) {
|
||||
ALOGE("Failed to write %s (%d): %s", mNames[stream].c_str(), errno, strerror(errno));
|
||||
stream->clear();
|
||||
}
|
||||
HWAPI_RECORD(value, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool HwApiBase::poll(const T &value, std::istream *stream, const int32_t timeoutMs) {
|
||||
ATRACE_NAME("HwApi::poll");
|
||||
auto path = mPathPrefix + mNames[stream];
|
||||
unique_fd fileFd{::open(path.c_str(), O_RDONLY)};
|
||||
unique_fd epollFd{epoll_create(1)};
|
||||
epoll_event event = {
|
||||
.events = EPOLLPRI | EPOLLET,
|
||||
};
|
||||
T actual;
|
||||
bool ret;
|
||||
int epollRet;
|
||||
|
||||
if (timeoutMs < -1) {
|
||||
ALOGE("Invalid polling timeout!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fileFd, &event)) {
|
||||
ALOGE("Failed to poll %s (%d): %s", mNames[stream].c_str(), errno, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((ret = get(&actual, stream)) && (actual != value)) {
|
||||
epollRet = epoll_wait(epollFd, &event, 1, timeoutMs);
|
||||
if (epollRet <= 0) {
|
||||
ALOGE("Polling error or timeout! (%d)", epollRet);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HWAPI_RECORD(value, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void HwApiBase::record(const char *func, const T &value, const std::ios *stream) {
|
||||
std::lock_guard<std::mutex> lock(mRecordsMutex);
|
||||
mRecords.emplace_back(std::make_unique<Record<T>>(func, value, stream));
|
||||
mRecords.pop_front();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string HwApiBase::Record<T>::toString(const NamesMap &names) {
|
||||
using utils::operator<<;
|
||||
std::stringstream ret;
|
||||
|
||||
ret << mFunc << " '" << names.at(mStream) << "' = '" << mValue << "'";
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
class HwCalBase {
|
||||
public:
|
||||
HwCalBase();
|
||||
void debug(int fd);
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
bool getProperty(const char *key, T *value, const T defval);
|
||||
template <typename T>
|
||||
bool getPersist(const char *key, T *value);
|
||||
|
||||
private:
|
||||
std::string mPropertyPrefix;
|
||||
std::map<std::string, std::string> mCalData;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool HwCalBase::getProperty(const char *key, T *outval, const T defval) {
|
||||
ATRACE_NAME("HwCal::getProperty");
|
||||
*outval = utils::getProperty(mPropertyPrefix + key, defval);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool HwCalBase::getPersist(const char *key, T *value) {
|
||||
ATRACE_NAME("HwCal::getPersist");
|
||||
auto it = mCalData.find(key);
|
||||
if (it == mCalData.end()) {
|
||||
ALOGE("Missing %s config!", key);
|
||||
return false;
|
||||
}
|
||||
std::stringstream stream{it->second};
|
||||
utils::unpack(stream, value);
|
||||
if (!stream || !stream.eof()) {
|
||||
ALOGE("Invalid %s config!", key);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
173
vibrator/common/utils.h
Normal file
173
vibrator/common/utils.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <android-base/parsedouble.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
namespace utils {
|
||||
|
||||
template <typename T>
|
||||
class Is_Iterable {
|
||||
private:
|
||||
template <typename U>
|
||||
static std::true_type test(typename U::iterator *u);
|
||||
|
||||
template <typename U>
|
||||
static std::false_type test(U *u);
|
||||
|
||||
public:
|
||||
static const bool value = decltype(test<T>(0))::value;
|
||||
};
|
||||
|
||||
template <typename T, bool B>
|
||||
using Enable_If_Iterable = std::enable_if_t<Is_Iterable<T>::value == B>;
|
||||
|
||||
template <typename T, typename U = void>
|
||||
using Enable_If_Signed = std::enable_if_t<std::is_signed_v<T>, U>;
|
||||
|
||||
template <typename T, typename U = void>
|
||||
using Enable_If_Unsigned = std::enable_if_t<std::is_unsigned_v<T>, U>;
|
||||
|
||||
// override for default behavior of printing as a character
|
||||
inline std::ostream &operator<<(std::ostream &stream, const int8_t value) {
|
||||
return stream << +value;
|
||||
}
|
||||
// override for default behavior of printing as a character
|
||||
inline std::ostream &operator<<(std::ostream &stream, const uint8_t value) {
|
||||
return stream << +value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline auto toUnderlying(const T value) {
|
||||
return static_cast<std::underlying_type_t<T>>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Enable_If_Iterable<T, true> unpack(std::istream &stream, T *value) {
|
||||
for (auto &entry : *value) {
|
||||
stream >> entry;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Enable_If_Iterable<T, false> unpack(std::istream &stream, T *value) {
|
||||
stream >> *value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void unpack<std::string>(std::istream &stream, std::string *value) {
|
||||
*value = std::string(std::istreambuf_iterator(stream), {});
|
||||
stream.setstate(std::istream::eofbit);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Enable_If_Signed<T, T> getProperty(const std::string &key, const T def) {
|
||||
if (std::is_floating_point_v<T>) {
|
||||
float result;
|
||||
std::string value = ::android::base::GetProperty(key, "");
|
||||
if (!value.empty() && ::android::base::ParseFloat(value, &result)) {
|
||||
return result;
|
||||
}
|
||||
return def;
|
||||
} else {
|
||||
return ::android::base::GetIntProperty(key, def);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Enable_If_Unsigned<T, T> getProperty(const std::string &key, const T def) {
|
||||
return ::android::base::GetUintProperty(key, def);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool getProperty<bool>(const std::string &key, const bool def) {
|
||||
return ::android::base::GetBoolProperty(key, def);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void openNoCreate(const std::string &file, T *outStream) {
|
||||
auto mode = std::is_base_of_v<std::ostream, T> ? std::ios_base::out : std::ios_base::in;
|
||||
|
||||
// Force 'in' mode to prevent file creation
|
||||
outStream->open(file, mode | std::ios_base::in);
|
||||
if (!*outStream) {
|
||||
ALOGE("Failed to open %s (%d): %s", file.c_str(), errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void fileFromEnv(const char *env, T *outStream, std::string *outName = nullptr) {
|
||||
auto file = std::getenv(env);
|
||||
|
||||
if (file == nullptr) {
|
||||
ALOGE("Failed get env %s", env);
|
||||
return;
|
||||
}
|
||||
|
||||
if (outName != nullptr) {
|
||||
*outName = std::string(file);
|
||||
}
|
||||
|
||||
openNoCreate(file, outStream);
|
||||
}
|
||||
|
||||
static ATTRIBUTE_UNUSED auto pathsFromEnv(const char *env, const std::string &prefix = "") {
|
||||
std::map<std::string, std::ifstream> ret;
|
||||
auto value = std::getenv(env);
|
||||
|
||||
if (value == nullptr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::istringstream paths{value};
|
||||
std::string path;
|
||||
|
||||
while (paths >> path) {
|
||||
ret[path].open(prefix + path);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ATTRIBUTE_UNUSED std::string trim(const std::string &str,
|
||||
const std::string &whitespace = " \t") {
|
||||
const auto str_begin = str.find_first_not_of(whitespace);
|
||||
if (str_begin == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto str_end = str.find_last_not_of(whitespace);
|
||||
const auto str_range = str_end - str_begin + 1;
|
||||
|
||||
return str.substr(str_begin, str_range);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
107
vibrator/cs40l26/Android.bp
Normal file
107
vibrator/cs40l26/Android.bp
Normal file
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// Copyright (C) 2022 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "android.hardware.vibrator-defaults.cs40l26-private-lynx",
|
||||
cflags: [
|
||||
"-DATRACE_TAG=(ATRACE_TAG_VIBRATOR | ATRACE_TAG_HAL)",
|
||||
"-DLOG_TAG=\"android.hardware.vibrator-cs40l26\"",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "VibratorHalCs40l26BinaryDefaultsPrivateLynx",
|
||||
defaults: [
|
||||
"PixelVibratorBinaryDefaultsPrivateLynx",
|
||||
"android.hardware.vibrator-defaults.cs40l26-private-lynx",
|
||||
],
|
||||
include_dirs: [
|
||||
"external/tinyalsa/include",
|
||||
],
|
||||
shared_libs: [
|
||||
"libcutils",
|
||||
"libtinyalsa",
|
||||
],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "VibratorHalCs40l26TestDefaultsPrivateLynx",
|
||||
defaults: [
|
||||
"PixelVibratorTestDefaultsPrivateLynx",
|
||||
"android.hardware.vibrator-defaults.cs40l26-private-lynx",
|
||||
],
|
||||
static_libs: [
|
||||
"libtinyalsa",
|
||||
],
|
||||
shared_libs: ["android.hardware.vibrator-impl.cs40l26-private-lynx"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libvibecapo_proto_lynx",
|
||||
vendor_available: true,
|
||||
owner: "google",
|
||||
srcs: [
|
||||
"proto/capo.proto",
|
||||
],
|
||||
shared_libs: [
|
||||
"libprotobuf-cpp-full",
|
||||
],
|
||||
export_include_dirs: [
|
||||
"inc",
|
||||
],
|
||||
proto: {
|
||||
type: "lite",
|
||||
export_proto_headers: true,
|
||||
},
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.vibrator-impl.cs40l26-private-lynx",
|
||||
defaults: ["VibratorHalCs40l26BinaryDefaultsPrivateLynx"],
|
||||
srcs: [
|
||||
"Vibrator.cpp",
|
||||
"CapoDetector.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"chre_client",
|
||||
],
|
||||
shared_libs: [
|
||||
"libvibecapo_proto_lynx",
|
||||
"libprotobuf-cpp-full",
|
||||
],
|
||||
export_include_dirs: [
|
||||
".",
|
||||
"inc",
|
||||
],
|
||||
vendor_available: true,
|
||||
visibility: [":__subpackages__"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.vibrator-service.cs40l26-private-lynx",
|
||||
defaults: ["VibratorHalCs40l26BinaryDefaultsPrivateLynx"],
|
||||
init_rc: ["android.hardware.vibrator-service.cs40l26-private-lynx.rc"],
|
||||
vintf_fragments: ["android.hardware.vibrator-service.cs40l26-private-lynx.xml"],
|
||||
srcs: ["service.cpp"],
|
||||
shared_libs: ["android.hardware.vibrator-impl.cs40l26-private-lynx"],
|
||||
proprietary: true,
|
||||
}
|
215
vibrator/cs40l26/CapoDetector.cpp
Normal file
215
vibrator/cs40l26/CapoDetector.cpp
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC. All Rights Reserved.
|
||||
*
|
||||
* 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 "CapoDetector.h"
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "CapoDetector"
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
namespace chre {
|
||||
|
||||
namespace { // anonymous namespace for file-local definitions
|
||||
|
||||
/**
|
||||
* Called when onConnected() to send NanoappList request.
|
||||
*/
|
||||
void requestNanoappList(SocketClient &client) {
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
HostProtocolHost::encodeNanoappListRequest(builder);
|
||||
if (!client.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
|
||||
ALOGE("Failed to send NanoappList request");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* Called when initializing connection with CHRE socket.
|
||||
*/
|
||||
sp<CapoDetector> CapoDetector::start() {
|
||||
sp<CapoDetector> listener = new CapoDetector();
|
||||
if (!listener->connectInBackground(kChreSocketName, listener)) {
|
||||
ALOGE("Couldn't connect to CHRE socket");
|
||||
return nullptr;
|
||||
}
|
||||
ALOGI("%s connect to CHRE socket.", __func__);
|
||||
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the socket is successfully (re-)connected.
|
||||
* Reset the position and try to send NanoappList request.
|
||||
*/
|
||||
void CapoDetector::onConnected() {
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
|
||||
// Reset the last position type.
|
||||
last_position_type_ = capo::PositionType::UNKNOWN;
|
||||
requestNanoappList(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we have failed to (re-)connect the socket after many attempts
|
||||
* and are giving up.
|
||||
*/
|
||||
void CapoDetector::onConnectionAborted() {
|
||||
ALOGE("%s, Capo Aborting Connection!", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the socket is disconnected, and this connection loss was not
|
||||
* the result of an explicit call to disconnect().
|
||||
* Reset the position while disconnecting.
|
||||
*/
|
||||
|
||||
void CapoDetector::onDisconnected() {
|
||||
last_position_type_ = capo::PositionType::UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode unix socket msgs to CHRE messages, and call the appropriate
|
||||
* callback depending on the CHRE message.
|
||||
*/
|
||||
void CapoDetector::onMessageReceived(const void *data, size_t length) {
|
||||
if (!HostProtocolHost::decodeMessageFromChre(data, length, *this)) {
|
||||
ALOGE("Failed to decode message");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for messages from capo nanoapp and handle the message.
|
||||
*/
|
||||
void CapoDetector::handleNanoappMessage(const fbs::NanoappMessageT &message) {
|
||||
ALOGI("%s, Id %" PRIu64 ", type %d, size %d", __func__, message.app_id, message.message_type,
|
||||
static_cast<int>(message.message.size()));
|
||||
// Exclude the message with unmatched nanoapp id.
|
||||
if (message.app_id != kCapoNanoappId)
|
||||
return;
|
||||
|
||||
// Handle the message with message_type.
|
||||
switch (message.message_type) {
|
||||
case capo::MessageType::ACK_NOTIFICATION: {
|
||||
capo::AckNotification gd;
|
||||
gd.set_notification_type(static_cast<capo::NotificationType>(message.message[1]));
|
||||
ALOGD("%s, get notification event from capo nanoapp, type %d", __func__,
|
||||
gd.notification_type());
|
||||
break;
|
||||
}
|
||||
case capo::MessageType::POSITION_DETECTED: {
|
||||
capo::PositionDetected gd;
|
||||
gd.set_position_type(static_cast<capo::PositionType>(message.message[1]));
|
||||
ALOGD("%s, get position event from capo nanoapp, type %d", __func__,
|
||||
gd.position_type());
|
||||
|
||||
// Callback to function while getting carried position event.
|
||||
if (callback_func_ != nullptr) {
|
||||
last_position_type_ = gd.position_type();
|
||||
ALOGD("%s, sent position type %d to callback function", __func__,
|
||||
last_position_type_);
|
||||
callback_func_(last_position_type_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ALOGE("%s, get invalid message, type: %" PRIu32 ", from capo nanoapp.", __func__,
|
||||
message.message_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the response of a NanoappList request.
|
||||
* Ensure that capo nanoapp is running.
|
||||
*/
|
||||
void CapoDetector::handleNanoappListResponse(const fbs::NanoappListResponseT &response) {
|
||||
for (const std::unique_ptr<fbs::NanoappListEntryT> &nanoapp : response.nanoapps) {
|
||||
if (nanoapp->app_id == kCapoNanoappId) {
|
||||
if (nanoapp->enabled)
|
||||
enable();
|
||||
else
|
||||
ALOGE("Capo nanoapp not enabled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ALOGE("Capo nanoapp not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Send enabling message to the nanoapp.
|
||||
*/
|
||||
void CapoDetector::enable() {
|
||||
// Create CHRE message with serialized message
|
||||
flatbuffers::FlatBufferBuilder builder, config_builder, force_builder;
|
||||
|
||||
auto config_data = std::make_unique<capo::ConfigureDetector_ConfigData>();
|
||||
auto msg = std::make_unique<capo::ConfigureDetector>();
|
||||
|
||||
config_data->set_still_time_threshold_nanosecond(mCapoDetectorMDParameters.still_time_threshold_ns);
|
||||
config_data->set_window_width_nanosecond(mCapoDetectorMDParameters.window_width_ns);
|
||||
config_data->set_motion_confidence_threshold(mCapoDetectorMDParameters.motion_confidence_threshold);
|
||||
config_data->set_still_confidence_threshold(mCapoDetectorMDParameters.still_confidence_threshold);
|
||||
config_data->set_var_threshold(mCapoDetectorMDParameters.var_threshold);
|
||||
config_data->set_var_threshold_delta(mCapoDetectorMDParameters.var_threshold_delta);
|
||||
|
||||
msg->set_allocated_config_data(config_data.release());
|
||||
|
||||
auto pb_size = msg->ByteSizeLong();
|
||||
auto pb_data = std::make_unique<uint8_t[]>(pb_size);
|
||||
|
||||
if (!msg->SerializeToArray(pb_data.get(), pb_size)) {
|
||||
ALOGE("Failed to serialize message.");
|
||||
}
|
||||
|
||||
ALOGI("Configuring CapoDetector");
|
||||
// Configure the detector from host-side
|
||||
android::chre::HostProtocolHost::encodeNanoappMessage(
|
||||
config_builder, getNanoppAppId(), capo::MessageType::CONFIGURE_DETECTOR, getHostEndPoint(),
|
||||
pb_data.get(), pb_size);
|
||||
ALOGI("Sending capo config message to Nanoapp, %" PRIu32 " bytes", config_builder.GetSize());
|
||||
if (!sendMessage(config_builder.GetBufferPointer(), config_builder.GetSize())) {
|
||||
ALOGE("Failed to send config event for capo nanoapp");
|
||||
}
|
||||
|
||||
ALOGI("Enabling CapoDetector");
|
||||
android::chre::HostProtocolHost::encodeNanoappMessage(
|
||||
builder, getNanoppAppId(), capo::MessageType::ENABLE_DETECTOR, getHostEndPoint(),
|
||||
/*messageData*/ nullptr, /*messageDataLenbuffer*/ 0);
|
||||
ALOGI("Sending enable message to Nanoapp, %" PRIu32 " bytes", builder.GetSize());
|
||||
if (!sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
|
||||
ALOGE("Failed to send enable event for capo nanoapp");
|
||||
}
|
||||
|
||||
ALOGI("Forcing CapoDetector to update state");
|
||||
// Force an updated state upon connection
|
||||
android::chre::HostProtocolHost::encodeNanoappMessage(
|
||||
force_builder, getNanoppAppId(), capo::MessageType::FORCE_UPDATE, getHostEndPoint(),
|
||||
/*messageData*/ nullptr, /*messageDataLenbuffer*/ 0);
|
||||
ALOGI("Sending force-update message to Nanoapp, %" PRIu32 " bytes", force_builder.GetSize());
|
||||
if (!sendMessage(force_builder.GetBufferPointer(), force_builder.GetSize())) {
|
||||
ALOGE("Failed to send force-update event for capo nanoapp");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace chre
|
||||
} // namespace android
|
362
vibrator/cs40l26/Hardware.h
Normal file
362
vibrator/cs40l26/Hardware.h
Normal file
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "HardwareBase.h"
|
||||
#include "Vibrator.h"
|
||||
|
||||
#define PROC_SND_PCM "/proc/asound/pcm"
|
||||
#define HAPTIC_PCM_DEVICE_SYMBOL "haptic nohost playback"
|
||||
|
||||
static struct pcm_config haptic_nohost_config = {
|
||||
.channels = 1,
|
||||
.rate = 48000,
|
||||
.period_size = 80,
|
||||
.period_count = 2,
|
||||
.format = PCM_FORMAT_S16_LE,
|
||||
};
|
||||
|
||||
enum WaveformIndex : uint16_t {
|
||||
/* Physical waveform */
|
||||
WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
|
||||
WAVEFORM_RESERVED_INDEX_1 = 1,
|
||||
WAVEFORM_CLICK_INDEX = 2,
|
||||
WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
|
||||
WAVEFORM_THUD_INDEX = 4,
|
||||
WAVEFORM_SPIN_INDEX = 5,
|
||||
WAVEFORM_QUICK_RISE_INDEX = 6,
|
||||
WAVEFORM_SLOW_RISE_INDEX = 7,
|
||||
WAVEFORM_QUICK_FALL_INDEX = 8,
|
||||
WAVEFORM_LIGHT_TICK_INDEX = 9,
|
||||
WAVEFORM_LOW_TICK_INDEX = 10,
|
||||
WAVEFORM_RESERVED_MFG_1,
|
||||
WAVEFORM_RESERVED_MFG_2,
|
||||
WAVEFORM_RESERVED_MFG_3,
|
||||
WAVEFORM_MAX_PHYSICAL_INDEX,
|
||||
/* OWT waveform */
|
||||
WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
|
||||
WAVEFORM_PWLE,
|
||||
/*
|
||||
* Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
|
||||
* #define FF_GAIN 0x60 // 96 in decimal
|
||||
* #define FF_MAX_EFFECTS FF_GAIN
|
||||
*/
|
||||
WAVEFORM_MAX_INDEX,
|
||||
};
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
class HwApi : public Vibrator::HwApi, private HwApiBase {
|
||||
public:
|
||||
HwApi() {
|
||||
open("calibration/f0_stored", &mF0);
|
||||
open("default/f0_offset", &mF0Offset);
|
||||
open("calibration/redc_stored", &mRedc);
|
||||
open("calibration/q_stored", &mQ);
|
||||
open("default/vibe_state", &mVibeState);
|
||||
open("default/num_waves", &mEffectCount);
|
||||
open("default/owt_free_space", &mOwtFreeSpace);
|
||||
open("default/f0_comp_enable", &mF0CompEnable);
|
||||
open("default/redc_comp_enable", &mRedcCompEnable);
|
||||
open("default/delay_before_stop_playback_us", &mMinOnOffInterval);
|
||||
}
|
||||
|
||||
bool setF0(std::string value) override { return set(value, &mF0); }
|
||||
bool setF0Offset(uint32_t value) override { return set(value, &mF0Offset); }
|
||||
bool setRedc(std::string value) override { return set(value, &mRedc); }
|
||||
bool setQ(std::string value) override { return set(value, &mQ); }
|
||||
bool getEffectCount(uint32_t *value) override { return get(value, &mEffectCount); }
|
||||
bool pollVibeState(uint32_t value, int32_t timeoutMs) override {
|
||||
return poll(value, &mVibeState, timeoutMs);
|
||||
}
|
||||
bool hasOwtFreeSpace() override { return has(mOwtFreeSpace); }
|
||||
bool getOwtFreeSpace(uint32_t *value) override { return get(value, &mOwtFreeSpace); }
|
||||
bool setF0CompEnable(bool value) override { return set(value, &mF0CompEnable); }
|
||||
bool setRedcCompEnable(bool value) override { return set(value, &mRedcCompEnable); }
|
||||
bool setMinOnOffInterval(uint32_t value) override { return set(value, &mMinOnOffInterval); }
|
||||
uint32_t getContextScale() override {
|
||||
return utils::getProperty("persist.vendor.vibrator.hal.context.scale", 100);
|
||||
}
|
||||
bool getContextEnable() override {
|
||||
return utils::getProperty("persist.vendor.vibrator.hal.context.enable", false);
|
||||
}
|
||||
uint32_t getContextSettlingTime() override {
|
||||
return utils::getProperty("persist.vendor.vibrator.hal.context.settlingtime", 3000);
|
||||
}
|
||||
uint32_t getContextCooldownTime() override {
|
||||
return utils::getProperty("persist.vendor.vibrator.hal.context.cooldowntime", 1000);
|
||||
}
|
||||
bool getContextFadeEnable() override {
|
||||
return utils::getProperty("persist.vendor.vibrator.hal.context.fade", false);
|
||||
}
|
||||
|
||||
// TODO(b/234338136): Need to add the force feedback HW API test cases
|
||||
bool setFFGain(int fd, uint16_t value) override {
|
||||
struct input_event gain = {
|
||||
.type = EV_FF,
|
||||
.code = FF_GAIN,
|
||||
.value = value,
|
||||
};
|
||||
if (write(fd, (const void *)&gain, sizeof(gain)) != sizeof(gain)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) override {
|
||||
if (((*effect).replay.length != timeoutMs) || (ioctl(fd, EVIOCSFF, effect) < 0)) {
|
||||
ALOGE("setFFEffect fail");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool setFFPlay(int fd, int8_t index, bool value) override {
|
||||
struct input_event play = {
|
||||
.type = EV_FF,
|
||||
.code = static_cast<uint16_t>(index),
|
||||
.value = value,
|
||||
};
|
||||
if (write(fd, (const void *)&play, sizeof(play)) != sizeof(play)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool getHapticAlsaDevice(int *card, int *device) override {
|
||||
std::string line;
|
||||
std::ifstream myfile(PROC_SND_PCM);
|
||||
if (myfile.is_open()) {
|
||||
while (getline(myfile, line)) {
|
||||
if (line.find(HAPTIC_PCM_DEVICE_SYMBOL) != std::string::npos) {
|
||||
std::stringstream ss(line);
|
||||
std::string currentToken;
|
||||
std::getline(ss, currentToken, ':');
|
||||
sscanf(currentToken.c_str(), "%d-%d", card, device);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
myfile.close();
|
||||
} else {
|
||||
ALOGE("Failed to read file: %s", PROC_SND_PCM);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device) override {
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
*haptic_pcm = pcm_open(card, device, PCM_OUT, &haptic_nohost_config);
|
||||
if (!pcm_is_ready(*haptic_pcm)) {
|
||||
ALOGE("cannot open pcm_out driver: %s", pcm_get_error(*haptic_pcm));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = pcm_prepare(*haptic_pcm);
|
||||
if (ret < 0) {
|
||||
ALOGE("cannot prepare haptic_pcm: %s", pcm_get_error(*haptic_pcm));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = pcm_start(*haptic_pcm);
|
||||
if (ret < 0) {
|
||||
ALOGE("cannot start haptic_pcm: %s", pcm_get_error(*haptic_pcm));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (*haptic_pcm) {
|
||||
pcm_close(*haptic_pcm);
|
||||
*haptic_pcm = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fail:
|
||||
pcm_close(*haptic_pcm);
|
||||
*haptic_pcm = NULL;
|
||||
return false;
|
||||
}
|
||||
bool uploadOwtEffect(int fd, uint8_t *owtData, uint32_t numBytes, struct ff_effect *effect,
|
||||
uint32_t *outEffectIndex, int *status) override {
|
||||
(*effect).u.periodic.custom_len = numBytes / sizeof(uint16_t);
|
||||
delete[] ((*effect).u.periodic.custom_data);
|
||||
(*effect).u.periodic.custom_data = new int16_t[(*effect).u.periodic.custom_len]{0x0000};
|
||||
if ((*effect).u.periodic.custom_data == nullptr) {
|
||||
ALOGE("Failed to allocate memory for custom data\n");
|
||||
*status = EX_NULL_POINTER;
|
||||
return false;
|
||||
}
|
||||
memcpy((*effect).u.periodic.custom_data, owtData, numBytes);
|
||||
|
||||
if ((*effect).id != -1) {
|
||||
ALOGE("(*effect).id != -1");
|
||||
}
|
||||
|
||||
/* Create a new OWT waveform to update the PWLE or composite effect. */
|
||||
(*effect).id = -1;
|
||||
if (ioctl(fd, EVIOCSFF, effect) < 0) {
|
||||
ALOGE("Failed to upload effect %d (%d): %s", *outEffectIndex, errno, strerror(errno));
|
||||
delete[] ((*effect).u.periodic.custom_data);
|
||||
*status = EX_ILLEGAL_STATE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((*effect).id >= FF_MAX_EFFECTS || (*effect).id < 0) {
|
||||
ALOGE("Invalid waveform index after upload OWT effect: %d", (*effect).id);
|
||||
*status = EX_ILLEGAL_ARGUMENT;
|
||||
return false;
|
||||
}
|
||||
*outEffectIndex = (*effect).id;
|
||||
*status = 0;
|
||||
return true;
|
||||
}
|
||||
bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override {
|
||||
uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0;
|
||||
|
||||
if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
|
||||
ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (effectIndex < WAVEFORM_MAX_INDEX) {
|
||||
/* Normal situation. Only erase the effect which we just played. */
|
||||
if (ioctl(fd, EVIOCRMFF, effectIndex) < 0) {
|
||||
ALOGE("Failed to erase effect %d (%d): %s", effectIndex, errno, strerror(errno));
|
||||
}
|
||||
for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
|
||||
if ((*effect)[i].id == effectIndex) {
|
||||
(*effect)[i].id = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Flush all non-prestored effects of ff-core and driver. */
|
||||
getEffectCount(&effectCountBefore);
|
||||
for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < FF_MAX_EFFECTS; i++) {
|
||||
if (ioctl(fd, EVIOCRMFF, i) >= 0) {
|
||||
successFlush++;
|
||||
}
|
||||
}
|
||||
getEffectCount(&effectCountAfter);
|
||||
ALOGW("Flushed effects: ff: %d; driver: %d -> %d; success: %d", effectIndex,
|
||||
effectCountBefore, effectCountAfter, successFlush);
|
||||
/* Reset all OWT effect index of HAL. */
|
||||
for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
|
||||
(*effect)[i].id = -1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void debug(int fd) override { HwApiBase::debug(fd); }
|
||||
|
||||
private:
|
||||
std::ofstream mF0;
|
||||
std::ofstream mF0Offset;
|
||||
std::ofstream mRedc;
|
||||
std::ofstream mQ;
|
||||
std::ifstream mEffectCount;
|
||||
std::ifstream mVibeState;
|
||||
std::ifstream mOwtFreeSpace;
|
||||
std::ofstream mF0CompEnable;
|
||||
std::ofstream mRedcCompEnable;
|
||||
std::ofstream mMinOnOffInterval;
|
||||
};
|
||||
|
||||
class HwCal : public Vibrator::HwCal, private HwCalBase {
|
||||
private:
|
||||
static constexpr char VERSION[] = "version";
|
||||
static constexpr char F0_CONFIG[] = "f0_measured";
|
||||
static constexpr char REDC_CONFIG[] = "redc_measured";
|
||||
static constexpr char Q_CONFIG[] = "q_measured";
|
||||
static constexpr char TICK_VOLTAGES_CONFIG[] = "v_tick";
|
||||
static constexpr char CLICK_VOLTAGES_CONFIG[] = "v_click";
|
||||
static constexpr char LONG_VOLTAGES_CONFIG[] = "v_long";
|
||||
|
||||
static constexpr uint32_t VERSION_DEFAULT = 2;
|
||||
static constexpr int32_t DEFAULT_FREQUENCY_SHIFT = 0;
|
||||
static constexpr std::array<uint32_t, 2> V_TICK_DEFAULT = {1, 100};
|
||||
static constexpr std::array<uint32_t, 2> V_CLICK_DEFAULT = {1, 100};
|
||||
static constexpr std::array<uint32_t, 2> V_LONG_DEFAULT = {1, 100};
|
||||
|
||||
public:
|
||||
HwCal() {}
|
||||
|
||||
bool getVersion(uint32_t *value) override {
|
||||
if (getPersist(VERSION, value)) {
|
||||
return true;
|
||||
}
|
||||
*value = VERSION_DEFAULT;
|
||||
return true;
|
||||
}
|
||||
bool getLongFrequencyShift(int32_t *value) override {
|
||||
return getProperty("long.frequency.shift", value, DEFAULT_FREQUENCY_SHIFT);
|
||||
}
|
||||
bool getF0(std::string *value) override { return getPersist(F0_CONFIG, value); }
|
||||
bool getRedc(std::string *value) override { return getPersist(REDC_CONFIG, value); }
|
||||
bool getQ(std::string *value) override { return getPersist(Q_CONFIG, value); }
|
||||
bool getTickVolLevels(std::array<uint32_t, 2> *value) override {
|
||||
if (getPersist(TICK_VOLTAGES_CONFIG, value)) {
|
||||
return true;
|
||||
}
|
||||
*value = V_TICK_DEFAULT;
|
||||
return true;
|
||||
}
|
||||
bool getClickVolLevels(std::array<uint32_t, 2> *value) override {
|
||||
if (getPersist(CLICK_VOLTAGES_CONFIG, value)) {
|
||||
return true;
|
||||
}
|
||||
*value = V_CLICK_DEFAULT;
|
||||
return true;
|
||||
}
|
||||
bool getLongVolLevels(std::array<uint32_t, 2> *value) override {
|
||||
if (getPersist(LONG_VOLTAGES_CONFIG, value)) {
|
||||
return true;
|
||||
}
|
||||
*value = V_LONG_DEFAULT;
|
||||
return true;
|
||||
}
|
||||
bool isChirpEnabled() override {
|
||||
bool value;
|
||||
getProperty("chirp.enabled", &value, false);
|
||||
return value;
|
||||
}
|
||||
bool getSupportedPrimitives(uint32_t *value) override {
|
||||
return getProperty("supported_primitives", value, (uint32_t)0);
|
||||
}
|
||||
bool isF0CompEnabled() override {
|
||||
bool value;
|
||||
getProperty("f0.comp.enabled", &value, true);
|
||||
return value;
|
||||
}
|
||||
bool isRedcCompEnabled() override {
|
||||
bool value;
|
||||
getProperty("redc.comp.enabled", &value, true);
|
||||
return value;
|
||||
}
|
||||
void debug(int fd) override { HwCalBase::debug(fd); }
|
||||
};
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
10
vibrator/cs40l26/TEST_MAPPING
Normal file
10
vibrator/cs40l26/TEST_MAPPING
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "VibratorHalCs40l26TestSuite",
|
||||
"keywords": [
|
||||
"nextgen"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
1441
vibrator/cs40l26/Vibrator.cpp
Normal file
1441
vibrator/cs40l26/Vibrator.cpp
Normal file
File diff suppressed because it is too large
Load diff
235
vibrator/cs40l26/Vibrator.h
Normal file
235
vibrator/cs40l26/Vibrator.h
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/vibrator/BnVibrator.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <linux/input.h>
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
class Vibrator : public BnVibrator {
|
||||
public:
|
||||
// APIs for interfacing with the kernel driver.
|
||||
class HwApi {
|
||||
public:
|
||||
virtual ~HwApi() = default;
|
||||
// Stores the LRA resonant frequency to be used for PWLE playback
|
||||
// and click compensation.
|
||||
virtual bool setF0(std::string value) = 0;
|
||||
// Stores the frequency offset for long vibrations.
|
||||
virtual bool setF0Offset(uint32_t value) = 0;
|
||||
// Stores the LRA series resistance to be used for click
|
||||
// compensation.
|
||||
virtual bool setRedc(std::string value) = 0;
|
||||
// Stores the LRA Q factor to be used for Q-dependent waveform
|
||||
// selection.
|
||||
virtual bool setQ(std::string value) = 0;
|
||||
// Reports the number of effect waveforms loaded in firmware.
|
||||
virtual bool getEffectCount(uint32_t *value) = 0;
|
||||
// Blocks until timeout or vibrator reaches desired state
|
||||
// (2 = ASP enabled, 1 = haptic enabled, 0 = disabled).
|
||||
virtual bool pollVibeState(uint32_t value, int32_t timeoutMs = -1) = 0;
|
||||
// Reports whether getOwtFreeSpace() is supported.
|
||||
virtual bool hasOwtFreeSpace() = 0;
|
||||
// Reports the available OWT bytes.
|
||||
virtual bool getOwtFreeSpace(uint32_t *value) = 0;
|
||||
// Enables/Disables F0 compensation enable status
|
||||
virtual bool setF0CompEnable(bool value) = 0;
|
||||
// Enables/Disables Redc compensation enable status
|
||||
virtual bool setRedcCompEnable(bool value) = 0;
|
||||
// Stores the minumun delay time between playback and stop effects.
|
||||
virtual bool setMinOnOffInterval(uint32_t value) = 0;
|
||||
// Gets the scaling factor for contextual haptic events.
|
||||
virtual uint32_t getContextScale() = 0;
|
||||
// Gets the enable status for contextual haptic events.
|
||||
virtual bool getContextEnable() = 0;
|
||||
// Gets the settling time for contextual haptic events.
|
||||
// This will allow the device to stay face up for the duration given,
|
||||
// even if InMotion events were detected.
|
||||
virtual uint32_t getContextSettlingTime() = 0;
|
||||
// Gets the cooldown time for contextual haptic events.
|
||||
// This is used to avoid changing the scale of close playback events.
|
||||
virtual uint32_t getContextCooldownTime() = 0;
|
||||
// Checks the enable status for contextual haptics fade feature. When enabled
|
||||
// this feature will cause the scaling factor to fade back up to max over
|
||||
// the setting time set, instead of instantaneously changing it back to max.
|
||||
virtual bool getContextFadeEnable() = 0;
|
||||
// Indicates the number of 0.125-dB steps of attenuation to apply to
|
||||
// waveforms triggered in response to vibration calls from the
|
||||
// Android vibrator HAL.
|
||||
virtual bool setFFGain(int fd, uint16_t value) = 0;
|
||||
// Create/modify custom effects for all physical waveforms.
|
||||
virtual bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) = 0;
|
||||
// Activates/deactivates the effect index after setFFGain() and setFFEffect().
|
||||
virtual bool setFFPlay(int fd, int8_t index, bool value) = 0;
|
||||
// Get the Alsa device for the audio coupled haptics effect
|
||||
virtual bool getHapticAlsaDevice(int *card, int *device) = 0;
|
||||
// Set haptics PCM amplifier before triggering audio haptics feature
|
||||
virtual bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card,
|
||||
int device) = 0;
|
||||
// Set OWT waveform for compose or compose PWLE request
|
||||
virtual bool uploadOwtEffect(int fd, uint8_t *owtData, uint32_t numBytes,
|
||||
struct ff_effect *effect, uint32_t *outEffectIndex,
|
||||
int *status) = 0;
|
||||
// Erase OWT waveform
|
||||
virtual bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) = 0;
|
||||
// Emit diagnostic information to the given file.
|
||||
virtual void debug(int fd) = 0;
|
||||
};
|
||||
|
||||
// APIs for obtaining calibration/configuration data from persistent memory.
|
||||
class HwCal {
|
||||
public:
|
||||
virtual ~HwCal() = default;
|
||||
// Obtain the calibration version
|
||||
virtual bool getVersion(uint32_t *value) = 0;
|
||||
// Obtains the LRA resonant frequency to be used for PWLE playback
|
||||
// and click compensation.
|
||||
virtual bool getF0(std::string *value) = 0;
|
||||
// Obtains the LRA series resistance to be used for click
|
||||
// compensation.
|
||||
virtual bool getRedc(std::string *value) = 0;
|
||||
// Obtains the LRA Q factor to be used for Q-dependent waveform
|
||||
// selection.
|
||||
virtual bool getQ(std::string *value) = 0;
|
||||
// Obtains frequency shift for long vibrations.
|
||||
virtual bool getLongFrequencyShift(int32_t *value) = 0;
|
||||
// Obtains the v0/v1(min/max) voltage levels to be applied for
|
||||
// tick/click/long in units of 1%.
|
||||
virtual bool getTickVolLevels(std::array<uint32_t, 2> *value) = 0;
|
||||
virtual bool getClickVolLevels(std::array<uint32_t, 2> *value) = 0;
|
||||
virtual bool getLongVolLevels(std::array<uint32_t, 2> *value) = 0;
|
||||
// Checks if the chirp feature is enabled.
|
||||
virtual bool isChirpEnabled() = 0;
|
||||
// Obtains the supported primitive effects.
|
||||
virtual bool getSupportedPrimitives(uint32_t *value) = 0;
|
||||
// Checks if the f0 compensation feature needs to be enabled.
|
||||
virtual bool isF0CompEnabled() = 0;
|
||||
// Checks if the redc compensation feature needs to be enabled.
|
||||
virtual bool isRedcCompEnabled() = 0;
|
||||
// Emit diagnostic information to the given file.
|
||||
virtual void debug(int fd) = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal);
|
||||
|
||||
ndk::ScopedAStatus getCapabilities(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus off() override;
|
||||
ndk::ScopedAStatus on(int32_t timeoutMs,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect> *_aidl_return) override;
|
||||
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
||||
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||
ndk::ScopedAStatus getCompositionDelayMax(int32_t *maxDelayMs);
|
||||
ndk::ScopedAStatus getCompositionSizeMax(int32_t *maxSize);
|
||||
ndk::ScopedAStatus getSupportedPrimitives(std::vector<CompositePrimitive> *supported) override;
|
||||
ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
|
||||
int32_t *durationMs) override;
|
||||
ndk::ScopedAStatus compose(const std::vector<CompositeEffect> &composite,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
|
||||
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
|
||||
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
|
||||
ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override;
|
||||
ndk::ScopedAStatus getQFactor(float *qFactor) override;
|
||||
ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override;
|
||||
ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override;
|
||||
ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
|
||||
ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override;
|
||||
ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override;
|
||||
ndk::ScopedAStatus getSupportedBraking(std::vector<Braking> *supported) override;
|
||||
ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
|
||||
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
|
||||
|
||||
private:
|
||||
ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch,
|
||||
const std::shared_ptr<IVibratorCallback> &callback);
|
||||
// set 'amplitude' based on an arbitrary scale determined by 'maximum'
|
||||
ndk::ScopedAStatus setEffectAmplitude(float amplitude, float maximum, bool scalable);
|
||||
ndk::ScopedAStatus setGlobalAmplitude(bool set);
|
||||
// 'simple' effects are those precompiled and loaded into the controller
|
||||
ndk::ScopedAStatus getSimpleDetails(Effect effect, EffectStrength strength,
|
||||
uint32_t *outEffectIndex, uint32_t *outTimeMs,
|
||||
uint32_t *outVolLevel);
|
||||
// 'compound' effects are those composed by stringing multiple 'simple' effects
|
||||
ndk::ScopedAStatus getCompoundDetails(Effect effect, EffectStrength strength,
|
||||
uint32_t *outTimeMs, struct dspmem_chunk *outCh);
|
||||
ndk::ScopedAStatus getPrimitiveDetails(CompositePrimitive primitive, uint32_t *outEffectIndex);
|
||||
ndk::ScopedAStatus performEffect(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *outTimeMs);
|
||||
ndk::ScopedAStatus performEffect(uint32_t effectIndex, uint32_t volLevel,
|
||||
struct dspmem_chunk *ch,
|
||||
const std::shared_ptr<IVibratorCallback> &callback);
|
||||
ndk::ScopedAStatus setPwle(const std::string &pwleQueue);
|
||||
bool isUnderExternalControl();
|
||||
void waitForComplete(std::shared_ptr<IVibratorCallback> &&callback);
|
||||
uint32_t intensityToVolLevel(float intensity, uint32_t effectIndex);
|
||||
bool findHapticAlsaDevice(int *card, int *device);
|
||||
bool hasHapticAlsaDevice();
|
||||
bool enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device);
|
||||
uint16_t amplitudeToScale(float amplitude, float maximum, bool scalable);
|
||||
void updateContext();
|
||||
|
||||
std::unique_ptr<HwApi> mHwApi;
|
||||
std::unique_ptr<HwCal> mHwCal;
|
||||
uint32_t mF0Offset;
|
||||
std::array<uint32_t, 2> mTickEffectVol;
|
||||
std::array<uint32_t, 2> mClickEffectVol;
|
||||
std::array<uint32_t, 2> mLongEffectVol;
|
||||
std::vector<ff_effect> mFfEffects;
|
||||
std::vector<uint32_t> mEffectDurations;
|
||||
std::future<void> mAsyncHandle;
|
||||
::android::base::unique_fd mInputFd;
|
||||
int8_t mActiveId{-1};
|
||||
struct pcm *mHapticPcm;
|
||||
int mCard;
|
||||
int mDevice;
|
||||
bool mHasHapticAlsaDevice{false};
|
||||
bool mIsUnderExternalControl;
|
||||
float mLongEffectScale = 1.0;
|
||||
bool mIsChirpEnabled;
|
||||
uint32_t mScaleTime;
|
||||
bool mFadeEnable;
|
||||
uint32_t mScalingFactor;
|
||||
uint32_t mScaleCooldown;
|
||||
bool mContextEnable;
|
||||
uint32_t mSupportedPrimitivesBits = 0x0;
|
||||
std::vector<CompositePrimitive> mSupportedPrimitives;
|
||||
bool mConfigHapticAlsaDeviceDone{false};
|
||||
};
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
|
@ -0,0 +1,47 @@
|
|||
on property:vendor.all.modules.ready=1
|
||||
wait /sys/bus/i2c/devices/i2c-cs40l26a/calibration/redc_cal_time_ms
|
||||
|
||||
mkdir /mnt/vendor/persist/haptics 0770 system system
|
||||
chmod 770 /mnt/vendor/persist/haptics
|
||||
chmod 440 /mnt/vendor/persist/haptics/cs40l26.cal
|
||||
chown system system /mnt/vendor/persist/haptics
|
||||
chown system system /mnt/vendor/persist/haptics/cs40l26.cal
|
||||
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/calibration/f0_stored
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/calibration/q_stored
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/calibration/redc_stored
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/vibe_state
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/num_waves
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/f0_offset
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/owt_free_space
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/f0_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/redc_comp_enable
|
||||
chown system system /sys/bus/i2c/devices/i2c-cs40l26a/default/delay_before_stop_playback_us
|
||||
|
||||
enable vendor.vibrator.cs40l26
|
||||
|
||||
service vendor.vibrator.cs40l26 /vendor/bin/hw/android.hardware.vibrator-service.cs40l26-private-lynx
|
||||
class hal
|
||||
user system
|
||||
group system input context_hub
|
||||
|
||||
setenv INPUT_EVENT_NAME cs40l26_input
|
||||
setenv INPUT_EVENT_PATH /dev/input/event*
|
||||
setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
|
||||
setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l26.cal
|
||||
|
||||
setenv HWAPI_PATH_PREFIX /sys/bus/i2c/devices/i2c-cs40l26a/
|
||||
setenv HWAPI_DEBUG_PATHS "
|
||||
calibration/f0_stored
|
||||
calibration/redc_stored
|
||||
calibration/q_stored
|
||||
default/vibe_state
|
||||
default/num_waves
|
||||
default/f0_offset
|
||||
default/owt_free_space
|
||||
default/f0_comp_enable
|
||||
default/redc_comp_enable
|
||||
default/delay_before_stop_playback_us
|
||||
"
|
||||
|
||||
disabled
|
|
@ -0,0 +1,7 @@
|
|||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>2</version>
|
||||
<fqname>IVibrator/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
6
vibrator/cs40l26/device.mk
Normal file
6
vibrator/cs40l26/device.mk
Normal file
|
@ -0,0 +1,6 @@
|
|||
PRODUCT_PACKAGES += \
|
||||
android.hardware.vibrator-service.cs40l26-private-lynx
|
||||
|
||||
BOARD_SEPOLICY_DIRS += \
|
||||
hardware/google/pixel-sepolicy/vibrator/common \
|
||||
hardware/google/pixel-sepolicy/vibrator/cs40l26
|
107
vibrator/cs40l26/inc/CapoDetector.h
Normal file
107
vibrator/cs40l26/inc/CapoDetector.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC. All Rights Reserved.
|
||||
*
|
||||
* 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 <chre_host/host_protocol_host.h>
|
||||
#include <chre_host/socket_client.h>
|
||||
|
||||
#include "proto/capo.pb.h"
|
||||
|
||||
using android::sp;
|
||||
using android::chre::HostProtocolHost;
|
||||
using android::chre::IChreMessageHandlers;
|
||||
using android::chre::SocketClient;
|
||||
|
||||
// following convention of CHRE code.
|
||||
namespace fbs = ::chre::fbs;
|
||||
|
||||
namespace android {
|
||||
namespace chre {
|
||||
|
||||
#define NS_FROM_MS(x) ((x)*1000000)
|
||||
|
||||
struct CapoMDParams {
|
||||
uint64_t still_time_threshold_ns;
|
||||
uint32_t window_width_ns;
|
||||
float motion_confidence_threshold;
|
||||
float still_confidence_threshold;
|
||||
float var_threshold;
|
||||
float var_threshold_delta;
|
||||
};
|
||||
|
||||
class CapoDetector : public android::chre::SocketClient::ICallbacks,
|
||||
public android::chre::IChreMessageHandlers,
|
||||
public android::chre::SocketClient {
|
||||
public:
|
||||
// Typedef declaration for callback function.
|
||||
typedef std::function<void(uint8_t)> cb_fn_t;
|
||||
|
||||
// Called when initializing connection with CHRE socket.
|
||||
static android::sp<CapoDetector> start();
|
||||
// Called when the socket is successfully (re-)connected.
|
||||
// Reset the position and try to send NanoappList request.
|
||||
void onConnected() override;
|
||||
// Called when we have failed to (re-)connect the socket after many attempts
|
||||
// and are giving up.
|
||||
void onConnectionAborted() override;
|
||||
// Invoked when the socket is disconnected, and this connection loss
|
||||
// was not the result of an explicit call to disconnect().
|
||||
// Reset the position while disconnecting.
|
||||
void onDisconnected() override;
|
||||
// Decode unix socket msgs to CHRE messages, and call the appropriate
|
||||
// callback depending on the CHRE message.
|
||||
void onMessageReceived(const void *data, size_t length) override;
|
||||
// Listen for messages from capo nanoapp and handle the message.
|
||||
void handleNanoappMessage(const ::chre::fbs::NanoappMessageT &message) override;
|
||||
// Handle the response of a NanoappList request.
|
||||
// Ensure that capo nanoapp is running.
|
||||
void handleNanoappListResponse(const ::chre::fbs::NanoappListResponseT &response) override;
|
||||
// Send enabling message to the nanoapp.
|
||||
void enable();
|
||||
|
||||
// Get last carried position type.
|
||||
uint8_t getCarriedPosition() { return last_position_type_; }
|
||||
// Get the host endpoint.
|
||||
uint16_t getHostEndPoint() { return kHostEndpoint; }
|
||||
// Get the capo nanoapp ID.
|
||||
uint64_t getNanoppAppId() { return kCapoNanoappId; }
|
||||
// Set up callback_func_ if needed.
|
||||
void setCallback(cb_fn_t cb) { callback_func_ = cb; }
|
||||
|
||||
private:
|
||||
// Nanoapp ID of capo, ref: go/nanoapp-id-tracker.
|
||||
static constexpr uint64_t kCapoNanoappId = 0x476f6f676c001020ULL;
|
||||
// String of socket name for connecting chre.
|
||||
static constexpr char kChreSocketName[] = "chre";
|
||||
// The host endpoint we use when sending message.
|
||||
// Set with 0x9020 based on 0x8000 AND capo_app_id(1020).
|
||||
// Ref: go/host-endpoint-id-tracker.
|
||||
static constexpr uint16_t kHostEndpoint = 0x9020;
|
||||
// Using for hal layer callback function.
|
||||
cb_fn_t callback_func_ = nullptr;
|
||||
// Last carried position received from the nano app
|
||||
capo::PositionType last_position_type_ = capo::PositionType::UNKNOWN;
|
||||
// Motion detector parameters for host-driven capo config
|
||||
const struct CapoMDParams mCapoDetectorMDParameters {
|
||||
.still_time_threshold_ns = NS_FROM_MS(500),
|
||||
.window_width_ns = NS_FROM_MS(100),
|
||||
.motion_confidence_threshold = 0.98f,
|
||||
.still_confidence_threshold = 0.99f,
|
||||
.var_threshold = 0.0125f,
|
||||
.var_threshold_delta = 0.0125f,
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace chre
|
||||
} // namespace android
|
148
vibrator/cs40l26/proto/capo.proto
Normal file
148
vibrator/cs40l26/proto/capo.proto
Normal file
|
@ -0,0 +1,148 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package capo;
|
||||
|
||||
// The message types used in capo nanoapp. Some of them are H2C
|
||||
// (Host-To-CHRE) and others are C2H (CHRE-To-Host). One message type must be
|
||||
// either H2C or C2H. Each message type can choose to have payload or not.
|
||||
enum MessageType {
|
||||
// Explicitly prevents 0 from being used as a valid message type.
|
||||
// Doing so protects from obscure bugs caused by default-initialized values.
|
||||
INVALID = 0;
|
||||
|
||||
// Detector configuration related message start from 100.
|
||||
// Signal for host to acknowledge the notification.
|
||||
// It contains AckNotification payload.
|
||||
ACK_NOTIFICATION = 100;
|
||||
|
||||
// Signal to enable the carried position detector for device. No payload.
|
||||
ENABLE_DETECTOR = 101;
|
||||
|
||||
// Signal to disable the carried position detector for device. No payload.
|
||||
DISABLE_DETECTOR = 102;
|
||||
|
||||
// Signal to request most recent carried position detector state. No payload.
|
||||
REQUEST_UPDATE = 103;
|
||||
|
||||
// Signal to force carried position detector to refresh state. No payload.
|
||||
FORCE_UPDATE = 104;
|
||||
|
||||
// Configure the detector with desired parameters. ConfigureDetector payload.
|
||||
CONFIGURE_DETECTOR = 105;
|
||||
|
||||
// Position Detection related message start from 200.
|
||||
// Signal while carried position of device detected.
|
||||
// It contains PositionDetected payload.
|
||||
POSITION_DETECTED = 200;
|
||||
}
|
||||
|
||||
// Notification Type.
|
||||
enum NotificationType {
|
||||
// Explicitly prevents 0 from being used as a valid notification type.
|
||||
// Doing so protects from obscure bugs caused by default-initialized values.
|
||||
INVALID_NOTIFICATION = 0;
|
||||
|
||||
// Notification of enabling the carried position detector for device.
|
||||
ENABLE_NOTIFICATION = 1;
|
||||
|
||||
// Notification of disabling the carried position detector for device.
|
||||
DISABLE_NOTIFICATION = 2;
|
||||
|
||||
// Notification of request update from the carried position detector.
|
||||
REQUEST_UPDATE_NOTIFICATION = 3;
|
||||
|
||||
// Notification of force update from the carried position detector.
|
||||
FORCE_UPDATE_NOTIFICATION = 4;
|
||||
|
||||
// Notification of configure message.
|
||||
CONFIGURE_NOTIFICATION = 5;
|
||||
}
|
||||
|
||||
// This message type used for host to acknowledge the notification.
|
||||
message AckNotification {
|
||||
// Sent a notification type for host to acknowledge.
|
||||
NotificationType notification_type = 1;
|
||||
}
|
||||
|
||||
// Position type.
|
||||
enum PositionType {
|
||||
// Explicitly prevents 0 from being used as a valid carried position type.
|
||||
// Doing so protects from obscure bugs caused by default-initialized values.
|
||||
UNKNOWN = 0;
|
||||
|
||||
// Carried position while device is in motion.
|
||||
IN_MOTION = 1;
|
||||
|
||||
// Carried position while device is on table and faces up.
|
||||
ON_TABLE_FACE_UP = 2;
|
||||
|
||||
// Carried position while device is on table and faces down.
|
||||
ON_TABLE_FACE_DOWN = 3;
|
||||
|
||||
// Carried position while device is stationary in unknown orientation.
|
||||
STATIONARY_UNKNOWN = 4;
|
||||
}
|
||||
|
||||
// This message type used to notify host a position was a detected.
|
||||
message PositionDetected {
|
||||
// Sent a position type that is defined in PositionTypes.
|
||||
PositionType position_type = 1;
|
||||
}
|
||||
|
||||
// Predefined configurations for detector.
|
||||
enum ConfigPresetType {
|
||||
// Explicitly prevents 0 from being used as a valid type.
|
||||
// Doing so protects from obscure bugs caused by default-initialized values.
|
||||
CONFIG_PRESET_UNSPECIFIED = 0;
|
||||
|
||||
// Default preset.
|
||||
CONFIG_PRESET_DEFAULT = 1;
|
||||
|
||||
// Preset for sticky-stationary behavior.
|
||||
CONFIG_PRESET_STICKY_STATIONARY = 2;
|
||||
}
|
||||
|
||||
message ConfigureDetector {
|
||||
// Ref: cs/location/lbs/contexthub/nanoapps/motiondetector/motion_detector.h
|
||||
message ConfigData {
|
||||
// These algo parameters are exposed to enable tuning via server flags.
|
||||
// The amount of time that the algorithm's computed stillness confidence
|
||||
// must exceed still_confidence_threshold before entering the stationary
|
||||
// state. Increasing this value will make the algorithm take longer to
|
||||
// transition from the in motion state to the stationary state.
|
||||
uint64 still_time_threshold_nanosecond = 1;
|
||||
|
||||
// The amount of time in which the variance should be averaged. Increasing
|
||||
// this value will effectively smooth the input data, making the algorithm
|
||||
// less likely to transition between states.
|
||||
uint32 window_width_nanosecond = 2;
|
||||
|
||||
// The required confidence that the device is in motion before entering the
|
||||
// motion state. Valid range is [0.0, 1.0], where 1.0 indicates that the
|
||||
// algorithm must be 100% certain that the device is moving before entering
|
||||
// the motion state. If the Instant Motion sensor is triggered, this value
|
||||
// is ignored and the algorithm is immediately transitioned into the in
|
||||
// motion state.
|
||||
float motion_confidence_threshold = 3;
|
||||
|
||||
// The required confidence that the device is stationary before entering the
|
||||
// stationary state. Valid range is [0.0, 1.0], where 1.0 indicates that the
|
||||
// algorithm must be 100% certain that the device is stationary before
|
||||
// entering the stationary state.
|
||||
float still_confidence_threshold = 4;
|
||||
|
||||
// The variance threshold for the StillnessDetector algorithm. Increasing
|
||||
// this value causes the algorithm to be less likely to detect motion.
|
||||
float var_threshold = 5;
|
||||
|
||||
// The variance threshold delta for the StillnessDetector algorithm about
|
||||
// which the stationary confidence is calculated. Valid range is
|
||||
// [0.0, var_threshold].
|
||||
float var_threshold_delta = 6;
|
||||
}
|
||||
|
||||
oneof type {
|
||||
ConfigPresetType preset_type = 1;
|
||||
ConfigData config_data = 2;
|
||||
}
|
||||
}
|
55
vibrator/cs40l26/service.cpp
Normal file
55
vibrator/cs40l26/service.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2021 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 <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include "Hardware.h"
|
||||
#include "Vibrator.h"
|
||||
|
||||
using ::aidl::android::hardware::vibrator::HwApi;
|
||||
using ::aidl::android::hardware::vibrator::HwCal;
|
||||
using ::aidl::android::hardware::vibrator::Vibrator;
|
||||
using ::android::defaultServiceManager;
|
||||
using ::android::ProcessState;
|
||||
using ::android::sp;
|
||||
using ::android::String16;
|
||||
|
||||
#if !defined(VIBRATOR_NAME)
|
||||
#define VIBRATOR_NAME "default"
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
auto svc = ndk::SharedRefBase::make<Vibrator>(std::make_unique<HwApi>(),
|
||||
std::make_unique<HwCal>());
|
||||
const auto svcName = std::string() + svc->descriptor + "/" + VIBRATOR_NAME;
|
||||
|
||||
ProcessState::initWithDriver("/dev/vndbinder");
|
||||
|
||||
auto svcBinder = svc->asBinder();
|
||||
binder_status_t status = AServiceManager_addService(svcBinder.get(), svcName.c_str());
|
||||
LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
|
||||
|
||||
ProcessState::self()->setThreadPoolMaxThreadCount(1);
|
||||
ProcessState::self()->startThreadPool();
|
||||
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
ABinderProcess_joinThreadPool();
|
||||
|
||||
return EXIT_FAILURE; // should not reach
|
||||
}
|
35
vibrator/cs40l26/tests/Android.bp
Normal file
35
vibrator/cs40l26/tests/Android.bp
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// Copyright (C) 2022 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VibratorHalCs40l26TestSuitePrivateLynx",
|
||||
defaults: ["VibratorHalCs40l26TestDefaultsPrivateLynx"],
|
||||
srcs: [
|
||||
"test-hwcal.cpp",
|
||||
"test-hwapi.cpp",
|
||||
"test-vibrator.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"libc++fs",
|
||||
"libgmock",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
],
|
||||
}
|
85
vibrator/cs40l26/tests/mocks.h
Normal file
85
vibrator/cs40l26/tests/mocks.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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_VIBRATOR_TEST_MOCKS_H
|
||||
#define ANDROID_HARDWARE_VIBRATOR_TEST_MOCKS_H
|
||||
|
||||
#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
|
||||
|
||||
#include "Vibrator.h"
|
||||
|
||||
class MockApi : public ::aidl::android::hardware::vibrator::Vibrator::HwApi {
|
||||
public:
|
||||
MOCK_METHOD0(destructor, void());
|
||||
MOCK_METHOD1(setF0, bool(std::string value));
|
||||
MOCK_METHOD1(setF0Offset, bool(uint32_t value));
|
||||
MOCK_METHOD1(setRedc, bool(std::string value));
|
||||
MOCK_METHOD1(setQ, bool(std::string value));
|
||||
MOCK_METHOD1(getEffectCount, bool(uint32_t *value));
|
||||
MOCK_METHOD2(pollVibeState, bool(uint32_t value, int32_t timeoutMs));
|
||||
MOCK_METHOD0(hasOwtFreeSpace, bool());
|
||||
MOCK_METHOD1(getOwtFreeSpace, bool(uint32_t *value));
|
||||
MOCK_METHOD1(setF0CompEnable, bool(bool value));
|
||||
MOCK_METHOD1(setRedcCompEnable, bool(bool value));
|
||||
MOCK_METHOD1(setMinOnOffInterval, bool(uint32_t value));
|
||||
MOCK_METHOD0(getContextScale, uint32_t());
|
||||
MOCK_METHOD0(getContextEnable, bool());
|
||||
MOCK_METHOD0(getContextSettlingTime, uint32_t());
|
||||
MOCK_METHOD0(getContextCooldownTime, uint32_t());
|
||||
MOCK_METHOD0(getContextFadeEnable, bool());
|
||||
MOCK_METHOD2(setFFGain, bool(int fd, uint16_t value));
|
||||
MOCK_METHOD3(setFFEffect, bool(int fd, struct ff_effect *effect, uint16_t timeoutMs));
|
||||
MOCK_METHOD3(setFFPlay, bool(int fd, int8_t index, bool value));
|
||||
MOCK_METHOD2(getHapticAlsaDevice, bool(int *card, int *device));
|
||||
MOCK_METHOD4(setHapticPcmAmp, bool(struct pcm **haptic_pcm, bool enable, int card, int device));
|
||||
MOCK_METHOD6(uploadOwtEffect,
|
||||
bool(int fd, uint8_t *owtData, uint32_t numBytes, struct ff_effect *effect,
|
||||
uint32_t *outEffectIndex, int *status));
|
||||
MOCK_METHOD3(eraseOwtEffect, bool(int fd, int8_t effectIndex, std::vector<ff_effect> *effect));
|
||||
MOCK_METHOD1(debug, void(int fd));
|
||||
|
||||
~MockApi() override { destructor(); };
|
||||
};
|
||||
|
||||
class MockCal : public ::aidl::android::hardware::vibrator::Vibrator::HwCal {
|
||||
public:
|
||||
MOCK_METHOD0(destructor, void());
|
||||
MOCK_METHOD1(getVersion, bool(uint32_t *value));
|
||||
MOCK_METHOD1(getF0, bool(std::string &value));
|
||||
MOCK_METHOD1(getRedc, bool(std::string &value));
|
||||
MOCK_METHOD1(getQ, bool(std::string &value));
|
||||
MOCK_METHOD1(getLongFrequencyShift, bool(int32_t *value));
|
||||
MOCK_METHOD1(getTickVolLevels, bool(std::array<uint32_t, 2> *value));
|
||||
MOCK_METHOD1(getClickVolLevels, bool(std::array<uint32_t, 2> *value));
|
||||
MOCK_METHOD1(getLongVolLevels, bool(std::array<uint32_t, 2> *value));
|
||||
MOCK_METHOD0(isChirpEnabled, bool());
|
||||
MOCK_METHOD1(getSupportedPrimitives, bool(uint32_t *value));
|
||||
MOCK_METHOD0(isF0CompEnabled, bool());
|
||||
MOCK_METHOD0(isRedcCompEnabled, bool());
|
||||
MOCK_METHOD1(debug, void(int fd));
|
||||
|
||||
~MockCal() override { destructor(); };
|
||||
// b/132668253: Workaround gMock Compilation Issue
|
||||
bool getF0(std::string *value) { return getF0(*value); }
|
||||
bool getRedc(std::string *value) { return getRedc(*value); }
|
||||
bool getQ(std::string *value) { return getQ(*value); }
|
||||
};
|
||||
|
||||
class MockVibratorCallback : public aidl::android::hardware::vibrator::BnVibratorCallback {
|
||||
public:
|
||||
MOCK_METHOD(ndk::ScopedAStatus, onComplete, ());
|
||||
};
|
||||
|
||||
#endif // ANDROID_HARDWARE_VIBRATOR_TEST_MOCKS_H
|
288
vibrator/cs40l26/tests/test-hwapi.cpp
Normal file
288
vibrator/cs40l26/tests/test-hwapi.cpp
Normal file
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <android-base/file.h>
|
||||
#include <cutils/fs.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
|
||||
#include "Hardware.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::TestParamInfo;
|
||||
using ::testing::ValuesIn;
|
||||
using ::testing::WithParamInterface;
|
||||
|
||||
class HwApiTest : public Test {
|
||||
private:
|
||||
static constexpr const char *FILE_NAMES[]{
|
||||
"calibration/f0_stored",
|
||||
"default/f0_offset",
|
||||
"calibration/redc_stored",
|
||||
"calibration/q_stored",
|
||||
"default/f0_comp_enable",
|
||||
"default/redc_comp_enable",
|
||||
"default/owt_free_space",
|
||||
"default/num_waves",
|
||||
"default/delay_before_stop_playback_us",
|
||||
};
|
||||
|
||||
public:
|
||||
void SetUp() override {
|
||||
std::string prefix;
|
||||
for (auto n : FILE_NAMES) {
|
||||
auto name = std::filesystem::path(n);
|
||||
auto path = std::filesystem::path(mFilesDir.path) / name;
|
||||
fs_mkdirs(path.c_str(), S_IRWXU);
|
||||
std::ofstream touch{path};
|
||||
mFileMap[name] = path;
|
||||
}
|
||||
prefix = std::filesystem::path(mFilesDir.path) / "";
|
||||
setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
|
||||
mHwApi = std::make_unique<HwApi>();
|
||||
|
||||
for (auto n : FILE_NAMES) {
|
||||
auto name = std::filesystem::path(n);
|
||||
auto path = std::filesystem::path(mEmptyDir.path) / name;
|
||||
}
|
||||
prefix = std::filesystem::path(mEmptyDir.path) / "";
|
||||
setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
|
||||
mNoApi = std::make_unique<HwApi>();
|
||||
}
|
||||
|
||||
void TearDown() override { verifyContents(); }
|
||||
|
||||
static auto ParamNameFixup(std::string str) {
|
||||
std::replace(str.begin(), str.end(), '/', '_');
|
||||
return str;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Set expected file content for a test.
|
||||
template <typename T>
|
||||
void expectContent(const std::string &name, const T &value) {
|
||||
mExpectedContent[name] << value << std::endl;
|
||||
}
|
||||
|
||||
// Set actual file content for an input test.
|
||||
template <typename T>
|
||||
void updateContent(const std::string &name, const T &value) {
|
||||
std::ofstream(mFileMap[name]) << value << std::endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void expectAndUpdateContent(const std::string &name, const T &value) {
|
||||
expectContent(name, value);
|
||||
updateContent(name, value);
|
||||
}
|
||||
|
||||
// Compare all file contents against expected contents.
|
||||
void verifyContents() {
|
||||
for (auto &a : mFileMap) {
|
||||
std::ifstream file{a.second};
|
||||
std::string expect = mExpectedContent[a.first].str();
|
||||
std::string actual = std::string(std::istreambuf_iterator<char>(file),
|
||||
std::istreambuf_iterator<char>());
|
||||
EXPECT_EQ(expect, actual) << a.first;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Vibrator::HwApi> mHwApi;
|
||||
std::unique_ptr<Vibrator::HwApi> mNoApi;
|
||||
std::map<std::string, std::string> mFileMap;
|
||||
TemporaryDir mFilesDir;
|
||||
TemporaryDir mEmptyDir;
|
||||
std::map<std::string, std::stringstream> mExpectedContent;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class HwApiTypedTest : public HwApiTest,
|
||||
public WithParamInterface<std::tuple<std::string, std::function<T>>> {
|
||||
public:
|
||||
static auto PrintParam(const TestParamInfo<typename HwApiTypedTest::ParamType> &info) {
|
||||
return ParamNameFixup(std::get<0>(info.param));
|
||||
}
|
||||
static auto MakeParam(std::string name, std::function<T> func) {
|
||||
return std::make_tuple(name, func);
|
||||
}
|
||||
};
|
||||
|
||||
using HasTest = HwApiTypedTest<bool(Vibrator::HwApi &)>;
|
||||
|
||||
TEST_P(HasTest, success_returnsTrue) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi));
|
||||
}
|
||||
|
||||
TEST_P(HasTest, success_returnsFalse) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
|
||||
EXPECT_FALSE(func(*mNoApi));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(HwApiTests, HasTest,
|
||||
ValuesIn({
|
||||
HasTest::MakeParam("default/owt_free_space",
|
||||
&Vibrator::HwApi::hasOwtFreeSpace),
|
||||
}),
|
||||
HasTest::PrintParam);
|
||||
|
||||
using GetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t *)>;
|
||||
|
||||
TEST_P(GetUint32Test, success) {
|
||||
auto param = GetParam();
|
||||
auto name = std::get<0>(param);
|
||||
auto func = std::get<1>(param);
|
||||
uint32_t expect = std::rand();
|
||||
uint32_t actual = ~expect;
|
||||
|
||||
expectAndUpdateContent(name, expect);
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi, &actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_P(GetUint32Test, failure) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
uint32_t value;
|
||||
|
||||
EXPECT_FALSE(func(*mNoApi, &value));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(HwApiTests, GetUint32Test,
|
||||
ValuesIn({
|
||||
GetUint32Test::MakeParam("default/num_waves",
|
||||
&Vibrator::HwApi::getEffectCount),
|
||||
GetUint32Test::MakeParam("default/owt_free_space",
|
||||
&Vibrator::HwApi::getOwtFreeSpace),
|
||||
}),
|
||||
GetUint32Test::PrintParam);
|
||||
|
||||
using SetBoolTest = HwApiTypedTest<bool(Vibrator::HwApi &, bool)>;
|
||||
|
||||
TEST_P(SetBoolTest, success_returnsTrue) {
|
||||
auto param = GetParam();
|
||||
auto name = std::get<0>(param);
|
||||
auto func = std::get<1>(param);
|
||||
|
||||
expectContent(name, "1");
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi, true));
|
||||
}
|
||||
|
||||
TEST_P(SetBoolTest, success_returnsFalse) {
|
||||
auto param = GetParam();
|
||||
auto name = std::get<0>(param);
|
||||
auto func = std::get<1>(param);
|
||||
|
||||
expectContent(name, "0");
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi, false));
|
||||
}
|
||||
|
||||
TEST_P(SetBoolTest, failure) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
|
||||
EXPECT_FALSE(func(*mNoApi, true));
|
||||
EXPECT_FALSE(func(*mNoApi, false));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(HwApiTests, SetBoolTest,
|
||||
ValuesIn({
|
||||
SetBoolTest::MakeParam("default/f0_comp_enable",
|
||||
&Vibrator::HwApi::setF0CompEnable),
|
||||
SetBoolTest::MakeParam("default/redc_comp_enable",
|
||||
&Vibrator::HwApi::setRedcCompEnable),
|
||||
}),
|
||||
SetBoolTest::PrintParam);
|
||||
|
||||
using SetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t)>;
|
||||
|
||||
TEST_P(SetUint32Test, success) {
|
||||
auto param = GetParam();
|
||||
auto name = std::get<0>(param);
|
||||
auto func = std::get<1>(param);
|
||||
uint32_t value = std::rand();
|
||||
|
||||
expectContent(name, value);
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi, value));
|
||||
}
|
||||
|
||||
TEST_P(SetUint32Test, failure) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
uint32_t value = std::rand();
|
||||
|
||||
EXPECT_FALSE(func(*mNoApi, value));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(HwApiTests, SetUint32Test,
|
||||
ValuesIn({
|
||||
SetUint32Test::MakeParam("default/f0_offset",
|
||||
&Vibrator::HwApi::setF0Offset),
|
||||
SetUint32Test::MakeParam("default/delay_before_stop_playback_us",
|
||||
&Vibrator::HwApi::setMinOnOffInterval),
|
||||
}),
|
||||
SetUint32Test::PrintParam);
|
||||
|
||||
using SetStringTest = HwApiTypedTest<bool(Vibrator::HwApi &, std::string)>;
|
||||
|
||||
TEST_P(SetStringTest, success) {
|
||||
auto param = GetParam();
|
||||
auto name = std::get<0>(param);
|
||||
auto func = std::get<1>(param);
|
||||
std::string value = TemporaryFile().path;
|
||||
|
||||
expectContent(name, value);
|
||||
|
||||
EXPECT_TRUE(func(*mHwApi, value));
|
||||
}
|
||||
|
||||
TEST_P(SetStringTest, failure) {
|
||||
auto param = GetParam();
|
||||
auto func = std::get<1>(param);
|
||||
std::string value = TemporaryFile().path;
|
||||
|
||||
EXPECT_FALSE(func(*mNoApi, value));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HwApiTests, SetStringTest,
|
||||
ValuesIn({
|
||||
SetStringTest::MakeParam("calibration/f0_stored", &Vibrator::HwApi::setF0),
|
||||
SetStringTest::MakeParam("calibration/redc_stored", &Vibrator::HwApi::setRedc),
|
||||
SetStringTest::MakeParam("calibration/q_stored", &Vibrator::HwApi::setQ),
|
||||
}),
|
||||
SetStringTest::PrintParam);
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
386
vibrator/cs40l26/tests/test-hwcal.cpp
Normal file
386
vibrator/cs40l26/tests/test-hwcal.cpp
Normal file
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <android-base/file.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "Hardware.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
using ::testing::Test;
|
||||
|
||||
class HwCalTest : public Test {
|
||||
protected:
|
||||
static constexpr std::array<uint32_t, 2> V_TICK_DEFAULT = {1, 100};
|
||||
static constexpr std::array<uint32_t, 2> V_CLICK_DEFAULT = {1, 100};
|
||||
static constexpr std::array<uint32_t, 2> V_LONG_DEFAULT = {1, 100};
|
||||
|
||||
public:
|
||||
void SetUp() override { setenv("CALIBRATION_FILEPATH", mCalFile.path, true); }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static void pack(std::ostream &stream, const T &value, std::string lpad, std::string rpad) {
|
||||
stream << lpad << value << rpad;
|
||||
}
|
||||
|
||||
template <typename T, typename std::array<T, 0>::size_type N>
|
||||
static void pack(std::ostream &stream, const std::array<T, N> &value, std::string lpad,
|
||||
std::string rpad) {
|
||||
for (auto &entry : value) {
|
||||
pack(stream, entry, lpad, rpad);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void createHwCal() { mHwCal = std::make_unique<HwCal>(); }
|
||||
|
||||
template <typename T>
|
||||
void write(const std::string key, const T &value, std::string lpad = " ",
|
||||
std::string rpad = "") {
|
||||
std::ofstream calfile{mCalFile.path, std::ios_base::app};
|
||||
calfile << key << ":";
|
||||
pack(calfile, value, lpad, rpad);
|
||||
calfile << std::endl;
|
||||
}
|
||||
|
||||
void unlink() { ::unlink(mCalFile.path); }
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Vibrator::HwCal> mHwCal;
|
||||
TemporaryFile mCalFile;
|
||||
};
|
||||
|
||||
TEST_F(HwCalTest, f0_measured) {
|
||||
uint32_t randInput = std::rand();
|
||||
std::string expect = std::to_string(randInput);
|
||||
std::string actual = std::to_string(~randInput);
|
||||
|
||||
write("f0_measured", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getF0(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, f0_missing) {
|
||||
std::string actual;
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_FALSE(mHwCal->getF0(&actual));
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, redc_measured) {
|
||||
uint32_t randInput = std::rand();
|
||||
std::string expect = std::to_string(randInput);
|
||||
std::string actual = std::to_string(~randInput);
|
||||
|
||||
write("redc_measured", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getRedc(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, redc_missing) {
|
||||
std::string actual;
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_FALSE(mHwCal->getRedc(&actual));
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, q_measured) {
|
||||
uint32_t randInput = std::rand();
|
||||
std::string expect = std::to_string(randInput);
|
||||
std::string actual = std::to_string(~randInput);
|
||||
|
||||
write("q_measured", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getQ(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, q_missing) {
|
||||
std::string actual;
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_FALSE(mHwCal->getQ(&actual));
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, v_levels) {
|
||||
std::array<uint32_t, 2> expect;
|
||||
std::array<uint32_t, 2> actual;
|
||||
|
||||
// voltage for tick effects
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
|
||||
write("v_tick", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
// voltage for click effects
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
|
||||
write("v_click", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
// voltage for long effects
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
|
||||
write("v_long", expect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, v_missing) {
|
||||
std::array<uint32_t, 2> expect = V_TICK_DEFAULT;
|
||||
std::array<uint32_t, 2> actual;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_CLICK_DEFAULT;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_LONG_DEFAULT;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, v_short) {
|
||||
std::array<uint32_t, 2> expect = V_TICK_DEFAULT;
|
||||
std::array<uint32_t, 2> actual;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
write("v_tick", std::array<uint32_t, expect.size() - 1>());
|
||||
write("v_click", std::array<uint32_t, expect.size() - 1>());
|
||||
write("v_long", std::array<uint32_t, expect.size() - 1>());
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_CLICK_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_LONG_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, v_long) {
|
||||
std::array<uint32_t, 2> expect = V_TICK_DEFAULT;
|
||||
std::array<uint32_t, 2> actual;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
write("v_tick", std::array<uint32_t, expect.size() + 1>());
|
||||
write("v_click", std::array<uint32_t, expect.size() + 1>());
|
||||
write("v_long", std::array<uint32_t, expect.size() + 1>());
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_CLICK_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_LONG_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, v_nofile) {
|
||||
std::array<uint32_t, 2> expect = V_TICK_DEFAULT;
|
||||
std::array<uint32_t, 2> actual;
|
||||
|
||||
std::transform(expect.begin(), expect.end(), actual.begin(), [](uint32_t &e) { return ~e; });
|
||||
|
||||
write("v_tick", actual);
|
||||
write("v_click", actual);
|
||||
write("v_long", actual);
|
||||
unlink();
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_CLICK_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
|
||||
expect = V_LONG_DEFAULT;
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&actual));
|
||||
EXPECT_EQ(expect, actual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, multiple) {
|
||||
uint32_t randInput = std::rand();
|
||||
std::string f0Expect = std::to_string(randInput);
|
||||
std::string f0Actual = std::to_string(~randInput);
|
||||
randInput = std::rand();
|
||||
std::string redcExpect = std::to_string(randInput);
|
||||
std::string redcActual = std::to_string(~randInput);
|
||||
randInput = std::rand();
|
||||
std::string qExpect = std::to_string(randInput);
|
||||
std::string qActual = std::to_string(~randInput);
|
||||
std::array<uint32_t, 2> volTickExpect, volClickExpect, volLongExpect;
|
||||
std::array<uint32_t, 2> volActual;
|
||||
|
||||
std::transform(volTickExpect.begin(), volTickExpect.end(), volActual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
|
||||
write("f0_measured", f0Expect);
|
||||
write("redc_measured", redcExpect);
|
||||
write("q_measured", qExpect);
|
||||
write("v_tick", volTickExpect);
|
||||
std::transform(volClickExpect.begin(), volClickExpect.end(), volActual.begin(),
|
||||
[](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
write("v_click", volClickExpect);
|
||||
std::transform(volLongExpect.begin(), volLongExpect.end(), volActual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
write("v_long", volLongExpect);
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getF0(&f0Actual));
|
||||
EXPECT_EQ(f0Expect, f0Actual);
|
||||
EXPECT_TRUE(mHwCal->getRedc(&redcActual));
|
||||
EXPECT_EQ(redcExpect, redcActual);
|
||||
EXPECT_TRUE(mHwCal->getQ(&qActual));
|
||||
EXPECT_EQ(qExpect, qActual);
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&volActual));
|
||||
EXPECT_EQ(volTickExpect, volActual);
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&volActual));
|
||||
EXPECT_EQ(volClickExpect, volActual);
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&volActual));
|
||||
EXPECT_EQ(volLongExpect, volActual);
|
||||
}
|
||||
|
||||
TEST_F(HwCalTest, trimming) {
|
||||
uint32_t randInput = std::rand();
|
||||
std::string f0Expect = std::to_string(randInput);
|
||||
std::string f0Actual = std::to_string(~randInput);
|
||||
randInput = std::rand();
|
||||
std::string redcExpect = std::to_string(randInput);
|
||||
std::string redcActual = std::to_string(randInput);
|
||||
randInput = std::rand();
|
||||
std::string qExpect = std::to_string(randInput);
|
||||
std::string qActual = std::to_string(randInput);
|
||||
std::array<uint32_t, 2> volTickExpect, volClickExpect, volLongExpect;
|
||||
std::array<uint32_t, 2> volActual;
|
||||
|
||||
std::transform(volTickExpect.begin(), volTickExpect.end(), volActual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
|
||||
write("f0_measured", f0Expect, " \t", "\t ");
|
||||
write("redc_measured", redcExpect, " \t", "\t ");
|
||||
write("q_measured", qExpect, " \t", "\t ");
|
||||
write("v_tick", volTickExpect, " \t", "\t ");
|
||||
std::transform(volClickExpect.begin(), volClickExpect.end(), volActual.begin(),
|
||||
[](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
write("v_click", volClickExpect, " \t", "\t ");
|
||||
std::transform(volLongExpect.begin(), volLongExpect.end(), volActual.begin(), [](uint32_t &e) {
|
||||
e = std::rand();
|
||||
return ~e;
|
||||
});
|
||||
write("v_long", volLongExpect, " \t", "\t ");
|
||||
|
||||
createHwCal();
|
||||
|
||||
EXPECT_TRUE(mHwCal->getF0(&f0Actual));
|
||||
EXPECT_EQ(f0Expect, f0Actual);
|
||||
EXPECT_TRUE(mHwCal->getRedc(&redcActual));
|
||||
EXPECT_EQ(redcExpect, redcActual);
|
||||
EXPECT_TRUE(mHwCal->getQ(&qActual));
|
||||
EXPECT_EQ(qExpect, qActual);
|
||||
EXPECT_TRUE(mHwCal->getTickVolLevels(&volActual));
|
||||
EXPECT_EQ(volTickExpect, volActual);
|
||||
EXPECT_TRUE(mHwCal->getClickVolLevels(&volActual));
|
||||
EXPECT_EQ(volClickExpect, volActual);
|
||||
EXPECT_TRUE(mHwCal->getLongVolLevels(&volActual));
|
||||
EXPECT_EQ(volLongExpect, volActual);
|
||||
}
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
692
vibrator/cs40l26/tests/test-vibrator.cpp
Normal file
692
vibrator/cs40l26/tests/test-vibrator.cpp
Normal file
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <aidl/android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uinput.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
#include "Vibrator.h"
|
||||
#include "mocks.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::Assign;
|
||||
using ::testing::AtLeast;
|
||||
using ::testing::AtMost;
|
||||
using ::testing::Combine;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::DoDefault;
|
||||
using ::testing::Exactly;
|
||||
using ::testing::Expectation;
|
||||
using ::testing::ExpectationSet;
|
||||
using ::testing::Ge;
|
||||
using ::testing::Mock;
|
||||
using ::testing::MockFunction;
|
||||
using ::testing::Range;
|
||||
using ::testing::Return;
|
||||
using ::testing::Sequence;
|
||||
using ::testing::SetArgPointee;
|
||||
using ::testing::SetArgReferee;
|
||||
using ::testing::Test;
|
||||
using ::testing::TestParamInfo;
|
||||
using ::testing::ValuesIn;
|
||||
using ::testing::WithParamInterface;
|
||||
|
||||
// Forward Declarations
|
||||
|
||||
static EffectQueue Queue(const QueueEffect &effect);
|
||||
static EffectQueue Queue(const QueueDelay &delay);
|
||||
template <typename T, typename U, typename... Args>
|
||||
static EffectQueue Queue(const T &first, const U &second, Args... rest);
|
||||
|
||||
static EffectLevel Level(float intensity, float levelLow, float levelHigh);
|
||||
static EffectScale Scale(float intensity, float levelLow, float levelHigh);
|
||||
|
||||
// Constants With Arbitrary Values
|
||||
|
||||
static constexpr uint32_t CAL_VERSION = 2;
|
||||
static constexpr std::array<EffectLevel, 2> V_TICK_DEFAULT = {1, 100};
|
||||
static constexpr std::array<EffectLevel, 2> V_CLICK_DEFAULT{1, 100};
|
||||
static constexpr std::array<EffectLevel, 2> V_LONG_DEFAULT{1, 100};
|
||||
static constexpr std::array<EffectDuration, 14> EFFECT_DURATIONS{
|
||||
0, 100, 30, 1000, 300, 130, 150, 500, 100, 15, 20, 1000, 1000, 1000};
|
||||
|
||||
// Constants With Prescribed Values
|
||||
|
||||
static const std::map<Effect, EffectIndex> EFFECT_INDEX{
|
||||
{Effect::CLICK, 2},
|
||||
{Effect::TICK, 2},
|
||||
{Effect::HEAVY_CLICK, 2},
|
||||
{Effect::TEXTURE_TICK, 9},
|
||||
};
|
||||
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500;
|
||||
static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
|
||||
static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
|
||||
static constexpr auto POLLING_TIMEOUT = 20;
|
||||
enum WaveformIndex : uint16_t {
|
||||
/* Physical waveform */
|
||||
WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
|
||||
WAVEFORM_RESERVED_INDEX_1 = 1,
|
||||
WAVEFORM_CLICK_INDEX = 2,
|
||||
WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
|
||||
WAVEFORM_THUD_INDEX = 4,
|
||||
WAVEFORM_SPIN_INDEX = 5,
|
||||
WAVEFORM_QUICK_RISE_INDEX = 6,
|
||||
WAVEFORM_SLOW_RISE_INDEX = 7,
|
||||
WAVEFORM_QUICK_FALL_INDEX = 8,
|
||||
WAVEFORM_LIGHT_TICK_INDEX = 9,
|
||||
WAVEFORM_LOW_TICK_INDEX = 10,
|
||||
WAVEFORM_RESERVED_MFG_1,
|
||||
WAVEFORM_RESERVED_MFG_2,
|
||||
WAVEFORM_RESERVED_MFG_3,
|
||||
WAVEFORM_MAX_PHYSICAL_INDEX,
|
||||
/* OWT waveform */
|
||||
WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
|
||||
WAVEFORM_PWLE,
|
||||
/*
|
||||
* Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
|
||||
* #define FF_GAIN 0x60 // 96 in decimal
|
||||
* #define FF_MAX_EFFECTS FF_GAIN
|
||||
*/
|
||||
WAVEFORM_MAX_INDEX,
|
||||
};
|
||||
|
||||
static const EffectScale ON_GLOBAL_SCALE{levelToScale(V_LONG_DEFAULT[1])};
|
||||
static const EffectIndex ON_EFFECT_INDEX{0};
|
||||
|
||||
static const std::map<EffectTuple, EffectScale> EFFECT_SCALE{
|
||||
{{Effect::TICK, EffectStrength::LIGHT},
|
||||
Scale(0.5f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::TICK, EffectStrength::MEDIUM},
|
||||
Scale(0.5f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::TICK, EffectStrength::STRONG},
|
||||
Scale(0.5f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::CLICK, EffectStrength::LIGHT},
|
||||
Scale(0.7f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::CLICK, EffectStrength::MEDIUM},
|
||||
Scale(0.7f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::CLICK, EffectStrength::STRONG},
|
||||
Scale(0.7f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::HEAVY_CLICK, EffectStrength::LIGHT},
|
||||
Scale(1.0f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::HEAVY_CLICK, EffectStrength::MEDIUM},
|
||||
Scale(1.0f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::HEAVY_CLICK, EffectStrength::STRONG},
|
||||
Scale(1.0f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
{{Effect::TEXTURE_TICK, EffectStrength::LIGHT},
|
||||
Scale(0.5f * 0.5f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
|
||||
{{Effect::TEXTURE_TICK, EffectStrength::MEDIUM},
|
||||
Scale(0.5f * 0.7f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
|
||||
{{Effect::TEXTURE_TICK, EffectStrength::STRONG},
|
||||
Scale(0.5f * 1.0f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
|
||||
};
|
||||
|
||||
static const std::map<EffectTuple, EffectQueue> EFFECT_QUEUE{
|
||||
{{Effect::DOUBLE_CLICK, EffectStrength::LIGHT},
|
||||
Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(0.7f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
100,
|
||||
QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(1.0f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
|
||||
{{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM},
|
||||
Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(0.7f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
100,
|
||||
QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(1.0f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
|
||||
{{Effect::DOUBLE_CLICK, EffectStrength::STRONG},
|
||||
Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(0.7f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
|
||||
100,
|
||||
QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
|
||||
Level(1.0f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
|
||||
};
|
||||
|
||||
EffectQueue Queue(const QueueEffect &effect) {
|
||||
auto index = std::get<0>(effect);
|
||||
auto level = std::get<1>(effect);
|
||||
auto string = std::to_string(index) + "." + std::to_string(level);
|
||||
auto duration = EFFECT_DURATIONS[index];
|
||||
return {string, duration};
|
||||
}
|
||||
|
||||
EffectQueue Queue(const QueueDelay &delay) {
|
||||
auto string = std::to_string(delay);
|
||||
return {string, delay};
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename... Args>
|
||||
EffectQueue Queue(const T &first, const U &second, Args... rest) {
|
||||
auto head = Queue(first);
|
||||
auto tail = Queue(second, rest...);
|
||||
auto string = std::get<0>(head) + "," + std::get<0>(tail);
|
||||
auto duration = std::get<1>(head) + std::get<1>(tail);
|
||||
return {string, duration};
|
||||
}
|
||||
|
||||
static EffectLevel Level(float intensity, float levelLow, float levelHigh) {
|
||||
return std::lround(intensity * (levelHigh - levelLow)) + levelLow;
|
||||
}
|
||||
|
||||
static EffectScale Scale(float intensity, float levelLow, float levelHigh) {
|
||||
return levelToScale(Level(intensity, levelLow, levelHigh));
|
||||
}
|
||||
|
||||
class VibratorTest : public Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
setenv("INPUT_EVENT_NAME", "CS40L26TestSuite", true);
|
||||
std::unique_ptr<MockApi> mockapi;
|
||||
std::unique_ptr<MockCal> mockcal;
|
||||
|
||||
createMock(&mockapi, &mockcal);
|
||||
createVibrator(std::move(mockapi), std::move(mockcal));
|
||||
}
|
||||
|
||||
void TearDown() override { deleteVibrator(); }
|
||||
|
||||
protected:
|
||||
void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal) {
|
||||
*mockapi = std::make_unique<MockApi>();
|
||||
*mockcal = std::make_unique<MockCal>();
|
||||
|
||||
mMockApi = mockapi->get();
|
||||
mMockCal = mockcal->get();
|
||||
|
||||
ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));
|
||||
|
||||
ON_CALL(*mMockApi, setFFGain(_, _)).WillByDefault(Return(true));
|
||||
ON_CALL(*mMockApi, setFFEffect(_, _, _)).WillByDefault(Return(true));
|
||||
ON_CALL(*mMockApi, setFFPlay(_, _, _)).WillByDefault(Return(true));
|
||||
ON_CALL(*mMockApi, pollVibeState(_, _)).WillByDefault(Return(true));
|
||||
ON_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _)).WillByDefault(Return(true));
|
||||
ON_CALL(*mMockApi, eraseOwtEffect(_, _, _)).WillByDefault(Return(true));
|
||||
|
||||
ON_CALL(*mMockApi, getOwtFreeSpace(_))
|
||||
.WillByDefault(DoAll(SetArgPointee<0>(11504), Return(true)));
|
||||
|
||||
ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
|
||||
|
||||
ON_CALL(*mMockCal, getVersion(_))
|
||||
.WillByDefault(DoAll(SetArgPointee<0>(CAL_VERSION), Return(true)));
|
||||
|
||||
ON_CALL(*mMockCal, getTickVolLevels(_))
|
||||
.WillByDefault(DoAll(SetArgPointee<0>(V_TICK_DEFAULT), Return(true)));
|
||||
ON_CALL(*mMockCal, getClickVolLevels(_))
|
||||
.WillByDefault(DoAll(SetArgPointee<0>(V_CLICK_DEFAULT), Return(true)));
|
||||
ON_CALL(*mMockCal, getLongVolLevels(_))
|
||||
.WillByDefault(DoAll(SetArgPointee<0>(V_LONG_DEFAULT), Return(true)));
|
||||
|
||||
relaxMock(false);
|
||||
}
|
||||
|
||||
void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
|
||||
bool relaxed = true) {
|
||||
if (relaxed) {
|
||||
relaxMock(true);
|
||||
}
|
||||
mVibrator = ndk::SharedRefBase::make<Vibrator>(std::move(mockapi), std::move(mockcal));
|
||||
if (relaxed) {
|
||||
relaxMock(false);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteVibrator(bool relaxed = true) {
|
||||
if (relaxed) {
|
||||
relaxMock(true);
|
||||
}
|
||||
mVibrator.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
void relaxMock(bool relax) {
|
||||
auto times = relax ? AnyNumber() : Exactly(0);
|
||||
|
||||
Mock::VerifyAndClearExpectations(mMockApi);
|
||||
Mock::VerifyAndClearExpectations(mMockCal);
|
||||
|
||||
EXPECT_CALL(*mMockApi, destructor()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setF0(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setF0Offset(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setRedc(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setQ(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setF0CompEnable(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setRedcCompEnable(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, pollVibeState(_, _)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, _)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setFFEffect(_, _, _)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setFFPlay(_, _, _)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setMinOnOffInterval(_)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getContextScale()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getContextEnable()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getContextSettlingTime()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getContextCooldownTime()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getContextFadeEnable()).Times(times);
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).Times(times);
|
||||
EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, _, _, _)).Times(times);
|
||||
|
||||
EXPECT_CALL(*mMockApi, debug(_)).Times(times);
|
||||
|
||||
EXPECT_CALL(*mMockCal, destructor()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getF0(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getRedc(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getQ(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getTickVolLevels(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getClickVolLevels(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getLongVolLevels(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isChirpEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isF0CompEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, isRedcCompEnabled()).Times(times);
|
||||
EXPECT_CALL(*mMockCal, debug(_)).Times(times);
|
||||
}
|
||||
|
||||
protected:
|
||||
MockApi *mMockApi;
|
||||
MockCal *mMockCal;
|
||||
std::shared_ptr<IVibrator> mVibrator;
|
||||
uint32_t mEffectIndex;
|
||||
};
|
||||
|
||||
TEST_F(VibratorTest, Constructor) {
|
||||
std::unique_ptr<MockApi> mockapi;
|
||||
std::unique_ptr<MockCal> mockcal;
|
||||
std::string f0Val = std::to_string(std::rand());
|
||||
std::string redcVal = std::to_string(std::rand());
|
||||
std::string qVal = std::to_string(std::rand());
|
||||
uint32_t calVer;
|
||||
uint32_t supportedPrimitivesBits = 0x0;
|
||||
Expectation volGet;
|
||||
Sequence f0Seq, redcSeq, qSeq, supportedPrimitivesSeq;
|
||||
|
||||
EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
|
||||
|
||||
deleteVibrator(false);
|
||||
|
||||
createMock(&mockapi, &mockcal);
|
||||
|
||||
EXPECT_CALL(*mMockCal, getF0(_))
|
||||
.InSequence(f0Seq)
|
||||
.WillOnce(DoAll(SetArgReferee<0>(f0Val), Return(true)));
|
||||
EXPECT_CALL(*mMockApi, setF0(f0Val)).InSequence(f0Seq).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mMockCal, getRedc(_))
|
||||
.InSequence(redcSeq)
|
||||
.WillOnce(DoAll(SetArgReferee<0>(redcVal), Return(true)));
|
||||
EXPECT_CALL(*mMockApi, setRedc(redcVal)).InSequence(redcSeq).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mMockCal, getQ(_))
|
||||
.InSequence(qSeq)
|
||||
.WillOnce(DoAll(SetArgReferee<0>(qVal), Return(true)));
|
||||
EXPECT_CALL(*mMockApi, setQ(qVal)).InSequence(qSeq).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).WillOnce(Return(true));
|
||||
|
||||
mMockCal->getVersion(&calVer);
|
||||
if (calVer == 2) {
|
||||
volGet = EXPECT_CALL(*mMockCal, getTickVolLevels(_)).WillOnce(DoDefault());
|
||||
volGet = EXPECT_CALL(*mMockCal, getClickVolLevels(_)).WillOnce(DoDefault());
|
||||
volGet = EXPECT_CALL(*mMockCal, getLongVolLevels(_)).WillOnce(DoDefault());
|
||||
}
|
||||
|
||||
EXPECT_CALL(*mMockCal, isF0CompEnabled()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setF0CompEnable(true)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockCal, isRedcCompEnabled()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setRedcCompEnable(true)).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*mMockCal, isChirpEnabled()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockCal, getSupportedPrimitives(_))
|
||||
.InSequence(supportedPrimitivesSeq)
|
||||
.WillOnce(DoAll(SetArgPointee<0>(supportedPrimitivesBits), Return(true)));
|
||||
|
||||
EXPECT_CALL(*mMockApi, setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, getContextScale()).WillOnce(Return(0));
|
||||
EXPECT_CALL(*mMockApi, getContextEnable()).WillOnce(Return(false));
|
||||
EXPECT_CALL(*mMockApi, getContextSettlingTime()).WillOnce(Return(0));
|
||||
EXPECT_CALL(*mMockApi, getContextCooldownTime()).WillOnce(Return(0));
|
||||
EXPECT_CALL(*mMockApi, getContextFadeEnable()).WillOnce(Return(false));
|
||||
createVibrator(std::move(mockapi), std::move(mockcal), false);
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, on) {
|
||||
Sequence s1, s2;
|
||||
uint16_t duration = std::rand() + 1;
|
||||
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockApi, setFFEffect(_, _, duration + MAX_COLD_START_LATENCY_MS))
|
||||
.InSequence(s2)
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockApi, setFFPlay(_, ON_EFFECT_INDEX, true))
|
||||
.InSequence(s1, s2)
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_TRUE(mVibrator->on(duration, nullptr).isOk());
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, off) {
|
||||
Sequence s1;
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
|
||||
EXPECT_TRUE(mVibrator->off().isOk());
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, supportsAmplitudeControl_supported) {
|
||||
int32_t capabilities;
|
||||
EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_GT(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, supportsExternalAmplitudeControl_unsupported) {
|
||||
int32_t capabilities;
|
||||
EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, 0);
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, setAmplitude_supported) {
|
||||
EffectAmplitude amplitude = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
|
||||
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, amplitudeToScale(amplitude))).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->setAmplitude(amplitude).isOk());
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, supportsExternalControl_supported) {
|
||||
int32_t capabilities;
|
||||
EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_GT(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, supportsExternalControl_unsupported) {
|
||||
int32_t capabilities;
|
||||
EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(false));
|
||||
|
||||
EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
|
||||
EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, setExternalControl_enable) {
|
||||
Sequence s1, s2;
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _))
|
||||
.InSequence(s1, s2)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
|
||||
}
|
||||
|
||||
TEST_F(VibratorTest, setExternalControl_disable) {
|
||||
Sequence s1, s2, s3, s4;
|
||||
|
||||
// The default mIsUnderExternalControl is false, so it needs to turn on the External Control
|
||||
// to make mIsUnderExternalControl become true.
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
|
||||
.InSequence(s1)
|
||||
.InSequence(s1)
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
|
||||
EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _)).InSequence(s3).WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
|
||||
|
||||
EXPECT_CALL(*mMockApi, setFFGain(_, levelToScale(VOLTAGE_SCALE_MAX)))
|
||||
.InSequence(s4)
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, false, _, _))
|
||||
.InSequence(s1, s2, s3, s4)
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(mVibrator->setExternalControl(false).isOk());
|
||||
}
|
||||
|
||||
class EffectsTest : public VibratorTest, public WithParamInterface<EffectTuple> {
|
||||
public:
|
||||
static auto PrintParam(const TestParamInfo<ParamType> &info) {
|
||||
auto param = info.param;
|
||||
auto effect = std::get<0>(param);
|
||||
auto strength = std::get<1>(param);
|
||||
return toString(effect) + "_" + toString(strength);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(EffectsTest, perform) {
|
||||
auto param = GetParam();
|
||||
auto effect = std::get<0>(param);
|
||||
auto strength = std::get<1>(param);
|
||||
auto scale = EFFECT_SCALE.find(param);
|
||||
auto queue = EFFECT_QUEUE.find(param);
|
||||
EffectDuration duration;
|
||||
auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
|
||||
std::promise<void> promise;
|
||||
std::future<void> future{promise.get_future()};
|
||||
auto complete = [&promise] {
|
||||
promise.set_value();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
};
|
||||
bool composeEffect;
|
||||
|
||||
ExpectationSet eSetup;
|
||||
Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;
|
||||
|
||||
if (scale != EFFECT_SCALE.end()) {
|
||||
EffectIndex index = EFFECT_INDEX.at(effect);
|
||||
duration = EFFECT_DURATIONS[index];
|
||||
|
||||
eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, levelToScale(scale->second)))
|
||||
.WillOnce(DoDefault());
|
||||
eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, index, true))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
} else if (queue != EFFECT_QUEUE.end()) {
|
||||
duration = std::get<1>(queue->second);
|
||||
eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
|
||||
eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, WAVEFORM_COMPOSE, true))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
composeEffect = true;
|
||||
} else {
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
if (duration) {
|
||||
ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
|
||||
.After(eActivate)
|
||||
.WillOnce(DoDefault());
|
||||
ePollStop = EXPECT_CALL(*mMockApi, pollVibeState(0, -1))
|
||||
.After(ePollHaptics)
|
||||
.WillOnce(DoDefault());
|
||||
if (composeEffect) {
|
||||
eEraseDone = EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _, _))
|
||||
.After(ePollStop)
|
||||
.WillOnce(DoDefault());
|
||||
EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);
|
||||
} else {
|
||||
EXPECT_CALL(*callback, onComplete()).After(ePollStop).WillOnce(complete);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t lengthMs;
|
||||
ndk::ScopedAStatus status = mVibrator->perform(effect, strength, callback, &lengthMs);
|
||||
if (status.isOk()) {
|
||||
EXPECT_LE(duration, lengthMs);
|
||||
} else {
|
||||
EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
|
||||
EXPECT_EQ(0, lengthMs);
|
||||
}
|
||||
|
||||
if (duration) {
|
||||
EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
|
||||
ndk::enum_range<Effect>().end()};
|
||||
const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
|
||||
ndk::enum_range<EffectStrength>().end()};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
|
||||
Combine(ValuesIn(kEffects.begin(), kEffects.end()),
|
||||
ValuesIn(kEffectStrengths.begin(), kEffectStrengths.end())),
|
||||
EffectsTest::PrintParam);
|
||||
|
||||
struct PrimitiveParam {
|
||||
CompositePrimitive primitive;
|
||||
EffectIndex index;
|
||||
};
|
||||
|
||||
class PrimitiveTest : public VibratorTest, public WithParamInterface<PrimitiveParam> {
|
||||
public:
|
||||
static auto PrintParam(const TestParamInfo<ParamType> &info) {
|
||||
return toString(info.param.primitive);
|
||||
}
|
||||
};
|
||||
|
||||
const std::vector<PrimitiveParam> kPrimitiveParams = {
|
||||
{CompositePrimitive::CLICK, 2}, {CompositePrimitive::THUD, 4},
|
||||
{CompositePrimitive::SPIN, 5}, {CompositePrimitive::QUICK_RISE, 6},
|
||||
{CompositePrimitive::SLOW_RISE, 7}, {CompositePrimitive::QUICK_FALL, 8},
|
||||
{CompositePrimitive::LIGHT_TICK, 9}, {CompositePrimitive::LOW_TICK, 10},
|
||||
};
|
||||
|
||||
TEST_P(PrimitiveTest, getPrimitiveDuration) {
|
||||
auto param = GetParam();
|
||||
auto primitive = param.primitive;
|
||||
auto index = param.index;
|
||||
int32_t duration;
|
||||
|
||||
EXPECT_EQ(EX_NONE, mVibrator->getPrimitiveDuration(primitive, &duration).getExceptionCode());
|
||||
EXPECT_EQ(EFFECT_DURATIONS[index], duration);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VibratorTests, PrimitiveTest,
|
||||
ValuesIn(kPrimitiveParams.begin(), kPrimitiveParams.end()),
|
||||
PrimitiveTest::PrintParam);
|
||||
|
||||
struct ComposeParam {
|
||||
std::string name;
|
||||
std::vector<CompositeEffect> composite;
|
||||
EffectQueue queue;
|
||||
};
|
||||
|
||||
class ComposeTest : public VibratorTest, public WithParamInterface<ComposeParam> {
|
||||
public:
|
||||
static auto PrintParam(const TestParamInfo<ParamType> &info) { return info.param.name; }
|
||||
};
|
||||
|
||||
TEST_P(ComposeTest, compose) {
|
||||
auto param = GetParam();
|
||||
auto composite = param.composite;
|
||||
auto queue = std::get<0>(param.queue);
|
||||
ExpectationSet eSetup;
|
||||
Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;
|
||||
auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
|
||||
std::promise<void> promise;
|
||||
std::future<void> future{promise.get_future()};
|
||||
auto complete = [&promise] {
|
||||
promise.set_value();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
};
|
||||
|
||||
eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
|
||||
eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, WAVEFORM_COMPOSE, true))
|
||||
.After(eSetup)
|
||||
.WillOnce(DoDefault());
|
||||
|
||||
ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
|
||||
.After(eActivate)
|
||||
.WillOnce(DoDefault());
|
||||
ePollStop =
|
||||
EXPECT_CALL(*mMockApi, pollVibeState(0, -1)).After(ePollHaptics).WillOnce(DoDefault());
|
||||
eEraseDone =
|
||||
EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _, _)).After(ePollStop).WillOnce(DoDefault());
|
||||
EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);
|
||||
|
||||
EXPECT_EQ(EX_NONE, mVibrator->compose(composite, callback).getExceptionCode());
|
||||
|
||||
EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
|
||||
}
|
||||
|
||||
const std::vector<ComposeParam> kComposeParams = {
|
||||
{"click",
|
||||
{{0, CompositePrimitive::CLICK, 1.0f}},
|
||||
Queue(QueueEffect(2, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
|
||||
{"thud",
|
||||
{{1, CompositePrimitive::THUD, 0.8f}},
|
||||
Queue(1, QueueEffect(4, Level(0.8f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
|
||||
{"spin",
|
||||
{{2, CompositePrimitive::SPIN, 0.6f}},
|
||||
Queue(2, QueueEffect(5, Level(0.6f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
|
||||
{"quick_rise",
|
||||
{{3, CompositePrimitive::QUICK_RISE, 0.4f}},
|
||||
Queue(3, QueueEffect(6, Level(0.4f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
|
||||
{"slow_rise",
|
||||
{{4, CompositePrimitive::SLOW_RISE, 0.0f}},
|
||||
Queue(4, QueueEffect(7, Level(0.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
|
||||
{"quick_fall",
|
||||
{{5, CompositePrimitive::QUICK_FALL, 1.0f}},
|
||||
Queue(5, QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
|
||||
{"pop",
|
||||
{{6, CompositePrimitive::SLOW_RISE, 1.0f}, {50, CompositePrimitive::THUD, 1.0f}},
|
||||
Queue(6, QueueEffect(7, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 50,
|
||||
QueueEffect(4, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
|
||||
{"snap",
|
||||
{{7, CompositePrimitive::QUICK_RISE, 1.0f}, {0, CompositePrimitive::QUICK_FALL, 1.0f}},
|
||||
Queue(7, QueueEffect(6, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])),
|
||||
QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
|
||||
ValuesIn(kComposeParams.begin(), kComposeParams.end()),
|
||||
ComposeTest::PrintParam);
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
33
vibrator/cs40l26/tests/types.h
Normal file
33
vibrator/cs40l26/tests/types.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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_VIBRATOR_TEST_TYPES_H
|
||||
#define ANDROID_HARDWARE_VIBRATOR_TEST_TYPES_H
|
||||
|
||||
#include <aidl/android/hardware/vibrator/IVibrator.h>
|
||||
|
||||
using EffectIndex = uint16_t;
|
||||
using EffectLevel = uint32_t;
|
||||
using EffectAmplitude = float;
|
||||
using EffectScale = uint16_t;
|
||||
using EffectDuration = uint32_t;
|
||||
using EffectQueue = std::tuple<std::string, EffectDuration>;
|
||||
using EffectTuple = std::tuple<::aidl::android::hardware::vibrator::Effect,
|
||||
::aidl::android::hardware::vibrator::EffectStrength>;
|
||||
|
||||
using QueueEffect = std::tuple<EffectIndex, EffectLevel>;
|
||||
using QueueDelay = uint32_t;
|
||||
|
||||
#endif // ANDROID_HARDWARE_VIBRATOR_TEST_TYPES_H
|
46
vibrator/cs40l26/tests/utils.h
Normal file
46
vibrator/cs40l26/tests/utils.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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_VIBRATOR_TEST_UTILS_H
|
||||
#define ANDROID_HARDWARE_VIBRATOR_TEST_UTILS_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
static inline EffectScale toScale(float amplitude, float maximum) {
|
||||
float ratio = 100; /* Unit: % */
|
||||
if (maximum != 0)
|
||||
ratio = amplitude / maximum * 100;
|
||||
|
||||
if (maximum == 0 || ratio > 100)
|
||||
ratio = 100;
|
||||
|
||||
return std::round(ratio);
|
||||
}
|
||||
|
||||
static inline EffectScale levelToScale(EffectLevel level) {
|
||||
return toScale(level, 100);
|
||||
}
|
||||
|
||||
static inline EffectScale amplitudeToScale(EffectAmplitude amplitude) {
|
||||
return toScale(amplitude, 1.0f);
|
||||
}
|
||||
|
||||
static inline uint32_t msToCycles(EffectDuration ms) {
|
||||
return ms * 48;
|
||||
}
|
||||
|
||||
#endif // ANDROID_HARDWARE_VIBRATOR_TEST_UTILS_H
|
Loading…
Add table
Add a link
Reference in a new issue