Snap for 9470583 from 957bb244be to tm-qpr3-release

Change-Id: Ic1e1be05e71996e65df6d5054107df46978a86ea
This commit is contained in:
Android Build Coastguard Worker 2023-01-10 00:02:36 +00:00
commit 33bdd71063
86 changed files with 82845 additions and 76415 deletions

1
OWNERS Normal file
View file

@ -0,0 +1 @@
per-file powerhint.json = jychen@google.com,jenhaochen@google.com,wvw@google.com,joaodias@google.com

View file

@ -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)

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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"/>

View file

@ -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>

View file

@ -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>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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
1 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
2 off off off off off on 76 68 76 76 68 76 76 68 76 76 68 76
3 off off off off on on 76 68 76 76 68 76 76 68 76 76 68 76
4 off off off on off on 76 68 76 76 68 76 76 68 76 76 68 76
5 off off off on on on 56 56 56 56 56 56 56 56 56 56 56 56
6 off off on off off on 76 68 76 76 68 76 76 68 76 76 68 76
7 off off on off on on 56 56 56 56 56 56 56 56 56 56 56 56
8 off off on on off on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
9 off off on on on on 56 56 56 56 56 56 56 56 56 56 56 56
10 off on off off off on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
11 off on off off on on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
12 off on off on off on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
13 off on off on on on 56 56 56 56 56 56 56 56 56 56 56 56
14 off on on off off on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
15 off on on off on on 56 56 56 56 56 56 56 56 56 56 56 56
16 off on on on off on 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76 56 76 56 68 56 76
17 off on on on on on 56 56 56 56 56 56 56 56 56 56 56 56
18 on off off off off any 44 44 44 44 44 44 44 44 44 44 44 44
19 on off off off on any 44 44 44 44 44 44 44 44 44 44 44 44
20 on off off on off any 44 44 44 44 44 44 44 44 44 44 44 44
21 on off off on on any 44 44 44 44 44 44 44 44 44 44 44 44
22 on off on off off any 44 44 44 44 44 44 44 44 44 44 44 44
23 on off on off on any 44 44 44 44 44 44 44 44 44 44 44 44
24 on off on on off any 44 44 44 44 44 44 44 44 44 44 44 44
25 on off on on on any 44 44 44 44 44 44 44 44 44 44 44 44
26 on on off off off any 44 44 44 44 44 44 44 44 44 44 44 44
27 on on off off on any 44 44 44 44 44 44 44 44 44 44 44 44
28 on on off on off any 44 44 44 44 44 44 44 44 44 44 44 44
29 on on off on on any 44 44 44 44 44 44 44 44 44 44 44 44
30 on on on off off any 44 44 44 44 44 44 44 44 44 44 44 44
31 on on on off on any 44 44 44 44 44 44 44 44 44 44 44 44
32 on on on on off any 44 44 44 44 44 44 44 44 44 44 44 44
33 on on on on on any 44 44 44 44 44 44 44 44 44 44 44 44
34 off any any any any off 76 68 76 76 68 76 76 68 76 76 68 76

View 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 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
2 off off off off off on 76 68 76 76 68 76 76 68 76 76 68 76
3 off off off off on on 76 68 76 76 68 76 76 68 76 76 68 76
4 off off off on off on 76 68 76 76 68 76 76 68 76 76 68 76
5 off off off on on on 56 56 56 56 56 56 56 56 56 56 56 56
6 off off on off off on 76 68 76 76 68 76 76 68 76 76 68 76
7 off off on off on on 56 56 56 56 56 56 56 56 56 56 56 56
8 off off on on off on 76 68 76 76 68 76 76 68 76 76 68 76
9 off off on on on on 56 56 56 56 56 56 56 56 56 56 56 56
10 off on off off off on 76 68 76 76 68 76 76 68 76 76 68 76
11 off on off off on on 76 68 76 76 68 76 76 68 76 76 68 76
12 off on off on off on 76 68 76 76 68 76 76 68 76 76 68 76
13 off on off on on on 56 56 56 56 56 56 56 56 56 56 56 56
14 off on on off off on 76 68 76 76 68 76 76 68 76 76 68 76
15 off on on off on on 56 56 56 56 56 56 56 56 56 56 56 56
16 off on on on off on 76 68 76 76 68 76 76 68 76 76 68 76
17 off on on on on on 56 56 56 56 56 56 56 56 56 56 56 56
18 on off off off off any 44 44 44 44 44 44 44 44 44 44 44 44
19 on off off off on any 44 44 44 44 44 44 44 44 44 44 44 44
20 on off off on off any 44 44 44 44 44 44 44 44 44 44 44 44
21 on off off on on any 44 44 44 44 44 44 44 44 44 44 44 44
22 on off on off off any 44 44 44 44 44 44 44 44 44 44 44 44
23 on off on off on any 44 44 44 44 44 44 44 44 44 44 44 44
24 on off on on off any 44 44 44 44 44 44 44 44 44 44 44 44
25 on off on on on any 44 44 44 44 44 44 44 44 44 44 44 44
26 on on off off off any 44 44 44 44 44 44 44 44 44 44 44 44
27 on on off off on any 44 44 44 44 44 44 44 44 44 44 44 44
28 on on off on off any 44 44 44 44 44 44 44 44 44 44 44 44
29 on on off on on any 44 44 44 44 44 44 44 44 44 44 44 44
30 on on on off off any 44 44 44 44 44 44 44 44 44 44 44 44
31 on on on off on any 44 44 44 44 44 44 44 44 44 44 44 44
32 on on on on off any 44 44 44 44 44 44 44 44 44 44 44 44
33 on on on on on any 44 44 44 44 44 44 44 44 44 44 44 44
34 off any any any any off 76 68 76 76 68 76 76 68 76 76 68 76

View 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 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
2 off off off off off on 76 68 40 76 68 34 76 68 40 76 68 34
3 off off off off on on 76 68 40 76 68 34 76 68 40 76 68 34
4 off off off on off on 76 68 40 76 68 34 76 68 40 76 68 34
5 off off off on on on 76 68 40 76 68 34 76 68 40 76 68 34
6 off off on off off on 76 68 40 76 68 34 76 68 40 76 68 34
7 off off on off on on 76 68 40 76 68 34 76 68 40 76 68 34
8 off off on on off on 76 68 40 76 68 34 76 68 40 76 68 34
9 off off on on on on 76 68 40 76 68 34 76 68 40 76 68 34
10 off on off off off on 76 68 40 76 68 34 76 68 40 76 68 34
11 off on off off on on 76 68 40 76 68 34 76 68 40 76 68 34
12 off on off on off on 76 68 40 76 68 34 76 68 40 76 68 34
13 off on off on on on 76 68 40 76 68 34 76 68 40 76 68 34
14 off on on off off on 76 68 40 76 68 34 76 68 40 76 68 34
15 off on on off on on 76 68 40 76 68 34 76 68 40 76 68 34
16 off on on on off on 76 68 40 76 68 34 76 68 40 76 68 34
17 off on on on on on 76 68 40 76 68 34 76 68 40 76 68 34
18 on off off off off any 76 68 40 76 68 34 76 68 40 76 68 34
19 on off off off on any 76 68 40 76 68 34 76 68 40 76 68 34
20 on off off on off any 76 68 40 76 68 34 76 68 40 76 68 34
21 on off off on on any 76 68 40 76 68 34 76 68 40 76 68 34
22 on off on off off any 76 68 40 76 68 34 76 68 40 76 68 34
23 on off on off on any 76 68 40 76 68 34 76 68 40 76 68 34
24 on off on on off any 76 68 40 76 68 34 76 68 40 76 68 34
25 on off on on on any 76 68 40 76 68 34 76 68 40 76 68 34
26 on on off off off any 76 68 40 76 68 34 76 68 40 76 68 34
27 on on off off on any 76 68 40 76 68 34 76 68 40 76 68 34
28 on on off on off any 76 68 40 76 68 34 76 68 40 76 68 34
29 on on off on on any 76 68 40 76 68 34 76 68 40 76 68 34
30 on on on off off any 76 68 40 76 68 34 76 68 40 76 68 34
31 on on on off on any 76 68 40 76 68 34 76 68 40 76 68 34
32 on on on on off any 76 68 40 76 68 34 76 68 40 76 68 34
33 on on on on on any 76 68 40 76 68 34 76 68 40 76 68 34
34 off any any any any off 76 68 40 76 68 34 76 68 40 76 68 34

View file

@ -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
1 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
2 off off off off off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
3 off off off off on on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
4 off off off on off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
5 off off off on on on 72 68 40 72 68 40 72 68 40 72 68 40
6 off off on off off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
7 off off on off on on 72 68 40 72 68 40 72 68 40 72 68 40
8 off off on on off on 72 68 40 72 68 40 72 68 40 72 68 40
9 off off on on on on 72 68 40 72 68 40 72 68 40 72 68 40
10 off on off off off on 72 68 40 72 68 40 72 68 40 72 68 40
11 off on off off on on 72 68 40 72 68 40 72 68 40 72 68 40
12 off on off on off on 72 68 40 72 68 40 72 68 40 72 68 40
13 off on off on on on 72 68 40 72 68 40 72 68 40 72 68 40
14 off on on off off on 72 68 40 72 68 40 72 68 40 72 68 40
15 off on on off on on 72 68 40 72 68 40 72 68 40 72 68 40
16 off on on on off on 72 68 40 72 68 40 72 68 40 72 68 40
17 off on on on on on 72 68 40 72 68 40 72 68 40 72 68 40
18 on off off off off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
19 on off off off on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
20 on off off on off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
21 on off off on on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
22 on off on off off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
23 on off on off on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
24 on off on on off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
25 on off on on on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
26 on on off off off any 72 68 40 72 68 40 72 68 40 72 68 40
27 on on off off on any 72 68 40 72 68 40 72 68 40 72 68 40
28 on on off on off any 72 68 40 72 68 40 72 68 40 72 68 40
29 on on off on on any 72 68 40 72 68 40 72 68 40 72 68 40
30 on on on off off any 72 68 40 72 68 40 72 68 40 72 68 40
31 on on on off on any 72 68 40 72 68 40 72 68 40 72 68 40
32 on on on on off any 72 68 40 72 68 40 72 68 40 72 68 40
33 on on on on on any 72 68 40 72 68 40 72 68 40 72 68 40
34 off any any any any off 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40

View 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 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
2 off off off off off on 76 68 76 76 68 76 76 68 76 76 68 76
3 off off off off on on 76 68 76 76 68 76 76 68 76 76 68 76
4 off off off on off on 76 68 76 76 68 76 76 68 76 76 68 76
5 off off off on on on 56 56 56 56 56 56 56 56 56 56 56 56
6 off off on off off on 76 68 76 76 68 76 76 68 76 76 68 76
7 off off on off on on 56 56 56 56 56 56 56 56 56 56 56 56
8 off off on on off on 76 68 76 76 68 76 76 68 76 76 68 76
9 off off on on on on 56 56 56 56 56 56 56 56 56 56 56 56
10 off on off off off on 76 68 76 76 68 76 76 68 76 76 68 76
11 off on off off on on 76 68 76 76 68 76 76 68 76 76 68 76
12 off on off on off on 76 68 76 76 68 76 76 68 76 76 68 76
13 off on off on on on 56 56 56 56 56 56 56 56 56 56 56 56
14 off on on off off on 76 68 76 76 68 76 76 68 76 76 68 76
15 off on on off on on 56 56 56 56 56 56 56 56 56 56 56 56
16 off on on on off on 76 68 76 76 68 76 76 68 76 76 68 76
17 off on on on on on 56 56 56 56 56 56 56 56 56 56 56 56
18 on off off off off any 44 44 44 44 44 44 44 44 44 44 44 44
19 on off off off on any 44 44 44 44 44 44 44 44 44 44 44 44
20 on off off on off any 44 44 44 44 44 44 44 44 44 44 44 44
21 on off off on on any 44 44 44 44 44 44 44 44 44 44 44 44
22 on off on off off any 44 44 44 44 44 44 44 44 44 44 44 44
23 on off on off on any 44 44 44 44 44 44 44 44 44 44 44 44
24 on off on on off any 44 44 44 44 44 44 44 44 44 44 44 44
25 on off on on on any 44 44 44 44 44 44 44 44 44 44 44 44
26 on on off off off any 44 44 44 44 44 44 44 44 44 44 44 44
27 on on off off on any 44 44 44 44 44 44 44 44 44 44 44 44
28 on on off on off any 44 44 44 44 44 44 44 44 44 44 44 44
29 on on off on on any 44 44 44 44 44 44 44 44 44 44 44 44
30 on on on off off any 44 44 44 44 44 44 44 44 44 44 44 44
31 on on on off on any 44 44 44 44 44 44 44 44 44 44 44 44
32 on on on on off any 44 44 44 44 44 44 44 44 44 44 44 44
33 on on on on on any 44 44 44 44 44 44 44 44 44 44 44 44
34 off any any any any off 76 68 76 76 68 76 76 68 76 76 68 76

View file

@ -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
1 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
2 off off off off off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
3 off off off off on on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
4 off off off on off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
5 off off off on on on 72 68 40 72 68 40 72 68 40 72 68 40
6 off off on off off on 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
7 off off on off on on 72 68 40 72 68 40 72 68 40 72 68 40
8 off off on on off on 72 68 40 72 68 40 72 68 40 72 68 40
9 off off on on on on 72 68 40 72 68 40 72 68 40 72 68 40
10 off on off off off on 72 68 40 72 68 40 72 68 40 72 68 40
11 off on off off on on 72 68 40 72 68 40 72 68 40 72 68 40
12 off on off on off on 72 68 40 72 68 40 72 68 40 72 68 40
13 off on off on on on 72 68 40 72 68 40 72 68 40 72 68 40
14 off on on off off on 72 68 40 72 68 40 72 68 40 72 68 40
15 off on on off on on 72 68 40 72 68 40 72 68 40 72 68 40
16 off on on on off on 72 68 40 72 68 40 72 68 40 72 68 40
17 off on on on on on 72 68 40 72 68 40 72 68 40 72 68 40
18 on off off off off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
19 on off off off on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
20 on off off on off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
21 on off off on on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
22 on off on off off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
23 on off on off on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
24 on off on on off any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
25 on off on on on any 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40
26 on on off off off any 72 68 40 72 68 40 72 68 40 72 68 40
27 on on off off on any 72 68 40 72 68 40 72 68 40 72 68 40
28 on on off on off any 72 68 40 72 68 40 72 68 40 72 68 40
29 on on off on on any 72 68 40 72 68 40 72 68 40 72 68 40
30 on on on off off any 72 68 40 72 68 40 72 68 40 72 68 40
31 on on on off on any 72 68 40 72 68 40 72 68 40 72 68 40
32 on on on on off any 72 68 40 72 68 40 72 68 40 72 68 40
33 on on on on on any 72 68 40 72 68 40 72 68 40 72 68 40
34 off any any any any off 76 72 68 40 76 72 68 40 76 72 68 40 76 72 68 40

View 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
1 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
2 off off off off off on 76 68 40 76 68 34 76 68 40 76 68 34
3 off off off off on on 76 68 40 76 68 34 76 68 40 76 68 34
4 off off off on off on 76 68 40 76 68 34 76 68 40 76 68 34
5 off off off on on on 64 64 40 64 64 34 64 64 40 64 64 34
6 off off on off off on 76 68 40 76 68 34 76 68 40 76 68 34
7 off off on off on on 64 64 40 64 64 34 64 64 40 64 64 34
8 off off on on off on 72 68 40 72 68 34 72 68 40 72 68 34
9 off off on on on on 64 64 40 64 64 34 64 64 40 64 64 34
10 off on off off off on 72 68 40 72 68 34 72 68 40 72 68 34
11 off on off off on on 72 68 40 72 68 34 72 68 40 72 68 34
12 off on off on off on 72 68 40 72 68 34 72 68 40 72 68 34
13 off on off on on on 64 64 40 64 64 34 64 64 40 64 64 34
14 off on on off off on 72 68 40 72 68 34 72 68 40 72 68 34
15 off on on off on on 64 64 40 64 64 34 64 64 40 64 64 34
16 off on on on off on 72 68 40 72 68 34 72 68 40 72 68 34
17 off on on on on on 64 64 40 64 64 34 64 64 40 64 64 34
18 on off off off off any 64 64 40 64 64 34 64 64 40 64 64 34
19 on off off off on any 64 64 40 64 64 34 64 64 40 64 64 34
20 on off off on off any 64 64 40 64 64 34 64 64 40 64 64 34
21 on off off on on any 64 64 40 64 64 34 64 64 40 64 64 34
22 on off on off off any 64 64 40 64 64 34 64 64 40 64 64 34
23 on off on off on any 64 64 40 64 64 34 64 64 40 64 64 34
24 on off on on off any 64 64 40 64 64 34 64 64 40 64 64 34
25 on off on on on any 64 64 40 64 64 34 64 64 40 64 64 34
26 on on off off off any 64 64 40 64 64 34 64 64 40 64 64 34
27 on on off off on any 64 64 40 64 64 34 64 64 40 64 64 34
28 on on off on off any 64 64 40 64 64 34 64 64 40 64 64 34
29 on on off on on any 64 64 40 64 64 34 64 64 40 64 64 34
30 on on on off off any 64 64 40 64 64 34 64 64 40 64 64 34
31 on on on off on any 64 64 40 64 64 34 64 64 40 64 64 34
32 on on on on off any 64 64 40 64 64 34 64 64 40 64 64 34
33 on on on on on any 64 64 40 64 64 34 64 64 40 64 64 34
34 off any any any any off 76 68 40 76 68 34 76 68 40 76 68 34

View 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 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
2 off off off off off on 76 68 76 76 68 76 76 68 76 76 68 76
3 off off off off on on 76 68 76 76 68 76 76 68 76 76 68 76
4 off off off on off on 76 68 76 76 68 76 76 68 76 76 68 76
5 off off off on on on 56 56 56 56 56 56 56 56 56 56 56 56
6 off off on off off on 76 68 76 76 68 76 76 68 76 76 68 76
7 off off on off on on 56 56 56 56 56 56 56 56 56 56 56 56
8 off off on on off on 76 68 76 76 68 76 76 68 76 76 68 76
9 off off on on on on 56 56 56 56 56 56 56 56 56 56 56 56
10 off on off off off on 76 68 76 76 68 76 76 68 76 76 68 76
11 off on off off on on 76 68 76 76 68 76 76 68 76 76 68 76
12 off on off on off on 76 68 76 76 68 76 76 68 76 76 68 76
13 off on off on on on 56 56 56 56 56 56 56 56 56 56 56 56
14 off on on off off on 76 68 76 76 68 76 76 68 76 76 68 76
15 off on on off on on 56 56 56 56 56 56 56 56 56 56 56 56
16 off on on on off on 76 68 76 76 68 76 76 68 76 76 68 76
17 off on on on on on 56 56 56 56 56 56 56 56 56 56 56 56
18 on off off off off any 44 44 44 44 44 44 44 44 44 44 44 44
19 on off off off on any 44 44 44 44 44 44 44 44 44 44 44 44
20 on off off on off any 44 44 44 44 44 44 44 44 44 44 44 44
21 on off off on on any 44 44 44 44 44 44 44 44 44 44 44 44
22 on off on off off any 44 44 44 44 44 44 44 44 44 44 44 44
23 on off on off on any 44 44 44 44 44 44 44 44 44 44 44 44
24 on off on on off any 44 44 44 44 44 44 44 44 44 44 44 44
25 on off on on on any 44 44 44 44 44 44 44 44 44 44 44 44
26 on on off off off any 44 44 44 44 44 44 44 44 44 44 44 44
27 on on off off on any 44 44 44 44 44 44 44 44 44 44 44 44
28 on on off on off any 44 44 44 44 44 44 44 44 44 44 44 44
29 on on off on on any 44 44 44 44 44 44 44 44 44 44 44 44
30 on on on off off any 44 44 44 44 44 44 44 44 44 44 44 44
31 on on on off on any 44 44 44 44 44 44 44 44 44 44 44 44
32 on on on on off any 44 44 44 44 44 44 44 44 44 44 44 44
33 on on on on on any 44 44 44 44 44 44 44 44 44 44 44 44
34 off any any any any off 76 68 76 76 68 76 76 68 76 76 68 76

View 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 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
2 off off off off off on 76 68 76 76 68 76 76 68 76 76 68 76
3 off off off off on on 76 68 76 76 68 76 76 68 76 76 68 76
4 off off off on off on 76 68 76 76 68 76 76 68 76 76 68 76
5 off off off on on on 56 56 56 56 56 56 56 56 56 56 56 56
6 off off on off off on 76 68 76 76 68 76 76 68 76 76 68 76
7 off off on off on on 56 56 56 56 56 56 56 56 56 56 56 56
8 off off on on off on 76 68 76 76 68 76 76 68 76 76 68 76
9 off off on on on on 56 56 56 56 56 56 56 56 56 56 56 56
10 off on off off off on 76 68 76 76 68 76 76 68 76 76 68 76
11 off on off off on on 76 68 76 76 68 76 76 68 76 76 68 76
12 off on off on off on 76 68 76 76 68 76 76 68 76 76 68 76
13 off on off on on on 56 56 56 56 56 56 56 56 56 56 56 56
14 off on on off off on 76 68 76 76 68 76 76 68 76 76 68 76
15 off on on off on on 56 56 56 56 56 56 56 56 56 56 56 56
16 off on on on off on 76 68 76 76 68 76 76 68 76 76 68 76
17 off on on on on on 56 56 56 56 56 56 56 56 56 56 56 56
18 on off off off off any 44 44 44 44 44 44 44 44 44 44 44 44
19 on off off off on any 44 44 44 44 44 44 44 44 44 44 44 44
20 on off off on off any 44 44 44 44 44 44 44 44 44 44 44 44
21 on off off on on any 44 44 44 44 44 44 44 44 44 44 44 44
22 on off on off off any 44 44 44 44 44 44 44 44 44 44 44 44
23 on off on off on any 44 44 44 44 44 44 44 44 44 44 44 44
24 on off on on off any 44 44 44 44 44 44 44 44 44 44 44 44
25 on off on on on any 44 44 44 44 44 44 44 44 44 44 44 44
26 on on off off off any 44 44 44 44 44 44 44 44 44 44 44 44
27 on on off off on any 44 44 44 44 44 44 44 44 44 44 44 44
28 on on off on off any 44 44 44 44 44 44 44 44 44 44 44 44
29 on on off on on any 44 44 44 44 44 44 44 44 44 44 44 44
30 on on on off off any 44 44 44 44 44 44 44 44 44 44 44 44
31 on on on off on any 44 44 44 44 44 44 44 44 44 44 44 44
32 on on on on off any 44 44 44 44 44 44 44 44 44 44 44 44
33 on on on on on any 44 44 44 44 44 44 44 44 44 44 44 44
34 off any any any any off 76 68 76 76 68 76 76 68 76 76 68 76

View 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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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
View 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

View 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
View 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

View 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

Binary file not shown.

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,8 @@
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
runtime_resource_overlay {
name: "SettingsOverlayG82U8",
product_specific: true,
}

View file

@ -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

View 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
1 500000,551000
2 798000,836000,500000
3 925000,960000,500000
4 3311000,3313000,500000
5 3578000,3589000,500000
6 740000,768000,551000
7 2124000,2126000,551000
8 2479000,2481000,551000

View file

@ -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>

File diff suppressed because it is too large Load diff

View file

@ -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",
],
}

View file

@ -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());

View file

@ -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>

View 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
}
]
}

View file

@ -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
View 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
View file

@ -0,0 +1,4 @@
chasewu@google.com
michaelwr@google.com
taikuo@google.com
chrispaulo@google.com

View 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,
}

View 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

View 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
View 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
View 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,
}

View 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
View 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

View file

@ -0,0 +1,10 @@
{
"presubmit": [
{
"name": "VibratorHalCs40l26TestSuite",
"keywords": [
"nextgen"
]
}
]
}

File diff suppressed because it is too large Load diff

235
vibrator/cs40l26/Vibrator.h Normal file
View 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

View file

@ -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

View file

@ -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>

View 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

View 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

View 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;
}
}

View 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
}

View 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",
],
}

View 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

View 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

View 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

View 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

View 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

View 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