replace common qcom sources with samsung ones
This commit is contained in:
143
qcom/opensource/pal/utils/inc/ACDPlatformInfo.h
Executable file
143
qcom/opensource/pal/utils/inc/ACDPlatformInfo.h
Executable file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef ACD_PLATFORM_INFO_H
|
||||
#define ACD_PLATFORM_INFO_H
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "SoundTriggerPlatformInfo.h"
|
||||
|
||||
class ACDStreamConfig;
|
||||
|
||||
class ACDContextInfo
|
||||
{
|
||||
public:
|
||||
ACDContextInfo(uint32_t context_id, uint32_t type);
|
||||
uint32_t GetContextId() const { return context_id_; }
|
||||
uint32_t GetContextType() const { return context_type_; }
|
||||
|
||||
private:
|
||||
uint32_t context_id_;
|
||||
uint32_t context_type_;
|
||||
};
|
||||
|
||||
class ACDSoundModelInfo : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
ACDSoundModelInfo(ACDStreamConfig *sm_cfg);
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
std::string GetModelType() const { return model_type_; }
|
||||
std::string GetModelBinName() const { return model_bin_name_; }
|
||||
uint32_t GetModelUUID() const { return model_uuid_; }
|
||||
uint32_t GetModelId() const { return model_id_; }
|
||||
size_t GetNumContexts() const { return acd_context_info_list_.size(); }
|
||||
std::vector<std::shared_ptr<ACDContextInfo>> GetSupportedContextList()const {
|
||||
return acd_context_info_list_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string model_type_;
|
||||
std::string model_bin_name_;
|
||||
uint32_t model_id_;
|
||||
uint32_t model_uuid_;
|
||||
bool is_parsing_contexts;
|
||||
ACDStreamConfig *sm_cfg_;
|
||||
std::vector<std::shared_ptr<ACDContextInfo>> acd_context_info_list_;
|
||||
};
|
||||
|
||||
class ACDStreamConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
ACDStreamConfig();
|
||||
ACDStreamConfig(ACDStreamConfig &rhs) = delete;
|
||||
ACDStreamConfig & operator=(ACDStreamConfig &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
UUID GetUUID() const { return vendor_uuid_; }
|
||||
std::string GetStreamConfigName() const { return name_; }
|
||||
std::shared_ptr<ACDSoundModelInfo> GetSoundModelInfoByModelId(uint32_t model_id);
|
||||
std::shared_ptr<ACDSoundModelInfo> GetSoundModelInfoByContextId(uint32_t context_id);
|
||||
void UpdateContextModelMap(uint32_t context_id);
|
||||
uint32_t GetSampleRate() const { return sample_rate_; }
|
||||
uint32_t GetBitWidth() const { return bit_width_; }
|
||||
uint32_t GetOutChannels() const { return out_channels_; }
|
||||
std::vector<std::shared_ptr<ACDSoundModelInfo>> GetSoundModelList() const {
|
||||
return acd_soundmodel_info_list_;
|
||||
}
|
||||
std::shared_ptr<CaptureProfile> GetCaptureProfile(
|
||||
std::pair<StOperatingModes, StInputModes> mode_pair) const {
|
||||
return acd_op_modes_.at(mode_pair);
|
||||
}
|
||||
uint32_t GetAndUpdateSndMdlCnt() { return sound_model_cnt++; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
UUID vendor_uuid_;
|
||||
uint32_t sample_rate_;
|
||||
uint32_t bit_width_;
|
||||
uint32_t out_channels_;
|
||||
st_op_modes_t acd_op_modes_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
std::vector<std::shared_ptr<ACDSoundModelInfo>> acd_soundmodel_info_list_;
|
||||
std::map<uint32_t, std::shared_ptr<ACDSoundModelInfo>> context_model_map_;
|
||||
std::map<uint32_t, std::shared_ptr<ACDSoundModelInfo>> acd_modelinfo_map_;
|
||||
uint32_t sound_model_cnt;
|
||||
};
|
||||
|
||||
class ACDPlatformInfo : public SoundTriggerPlatformInfo
|
||||
{
|
||||
public:
|
||||
ACDPlatformInfo();
|
||||
ACDPlatformInfo(ACDStreamConfig &rhs) = delete;
|
||||
ACDPlatformInfo & operator=(ACDPlatformInfo &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
static std::shared_ptr<ACDPlatformInfo> GetInstance();
|
||||
bool IsACDEnabled() const { return acd_enable_; }
|
||||
std::shared_ptr<ACDStreamConfig> GetStreamConfig(const UUID& uuid) const;
|
||||
|
||||
private:
|
||||
bool acd_enable_;
|
||||
static std::shared_ptr<ACDPlatformInfo> me_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
std::map<UUID, std::shared_ptr<ACDStreamConfig>> acd_cfg_list_;
|
||||
};
|
||||
#endif
|
||||
125
qcom/opensource/pal/utils/inc/ASRPlatformInfo.h
Executable file
125
qcom/opensource/pal/utils/inc/ASRPlatformInfo.h
Executable file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef ASR_PLATFORM_INFO_H
|
||||
#define ASR_PLATFORM_INFO_H
|
||||
|
||||
#define OUT_BUF_SIZE_DEFAULT 3072 /* In bytes. Around 30sec of text */
|
||||
#define VAD_HANG_OVER_DURTION_DEFAULT_MS 1000
|
||||
|
||||
#include "ResourceManager.h"
|
||||
|
||||
typedef enum asr_param_id_type {
|
||||
ASR_INPUT_CONFIG = 0,
|
||||
ASR_OUTPUT_CONFIG,
|
||||
ASR_INPUT_BUF_DURATON,
|
||||
ASR_OUTPUT,
|
||||
ASR_FORCE_OUTPUT,
|
||||
ASR_MAX_PARAM_IDS
|
||||
}asr_param_id_type_t;
|
||||
|
||||
class ASRCommonConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
ASRCommonConfig();
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
size_t GetInputBufferSize() const { return input_buffer_size_; }
|
||||
size_t GetPartialModeInputBufferSize() const { return partial_mode_input_buffer_size_; }
|
||||
size_t GetBufferingModeOutBufferSize() const { return buffering_mode_out_buffer_size_; }
|
||||
uint32_t GetCommandModeTimeout() const { return command_mode_timeout_; }
|
||||
uint32_t GetInputBufferSize(int mode);
|
||||
uint32_t GetOutputBufferSize(int mode);
|
||||
|
||||
private:
|
||||
size_t input_buffer_size_;
|
||||
size_t partial_mode_input_buffer_size_;
|
||||
size_t buffering_mode_out_buffer_size_;
|
||||
uint32_t command_mode_timeout_;
|
||||
};
|
||||
|
||||
class ASRStreamConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
ASRStreamConfig();
|
||||
ASRStreamConfig(ACDStreamConfig &rhs) = delete;
|
||||
ASRStreamConfig & operator=(ACDStreamConfig &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
std::string GetStreamConfigName() const { return name_; }
|
||||
uint32_t GetModuleTagId(asr_param_id_type_t param_id) const {
|
||||
return module_tag_ids_[param_id];
|
||||
}
|
||||
uint32_t GetParamId(asr_param_id_type_t param_id) const {
|
||||
return param_ids_[param_id];
|
||||
}
|
||||
std::shared_ptr<CaptureProfile> GetCaptureProfile(
|
||||
std::pair<StOperatingModes, StInputModes> mode_pair) const {
|
||||
return asr_op_modes_.at(mode_pair);
|
||||
}
|
||||
UUID GetUUID() const { return vendor_uuid_; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
st_op_modes_t asr_op_modes_;
|
||||
UUID vendor_uuid_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
uint32_t module_tag_ids_[ASR_MAX_PARAM_IDS];
|
||||
uint32_t param_ids_[ASR_MAX_PARAM_IDS];
|
||||
};
|
||||
|
||||
class ASRPlatformInfo : public SoundTriggerPlatformInfo
|
||||
{
|
||||
public:
|
||||
ASRPlatformInfo();
|
||||
ASRPlatformInfo(ASRStreamConfig &rhs) = delete;
|
||||
ASRPlatformInfo & operator=(ASRPlatformInfo &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
static std::shared_ptr<ASRPlatformInfo> GetInstance();
|
||||
std::shared_ptr<ASRStreamConfig> GetStreamConfig(const UUID& uuid) const;
|
||||
std::shared_ptr<ASRCommonConfig> GetCommonConfig() const { return cm_cfg_; }
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ASRPlatformInfo> me_;
|
||||
std::map<UUID, std::shared_ptr<ASRStreamConfig>> stream_cfg_list_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
std::shared_ptr<ASRCommonConfig> cm_cfg_;
|
||||
};
|
||||
#endif
|
||||
112
qcom/opensource/pal/utils/inc/AudioHapticsInterface.h
Normal file
112
qcom/opensource/pal/utils/inc/AudioHapticsInterface.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_HAPTICS_INTERFACE_H
|
||||
#define AUDIO_HAPTICS_INTERFACE_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <expat.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "PalDefs.h"
|
||||
#include "PalCommon.h"
|
||||
#include "kvh2xml.h"
|
||||
|
||||
typedef enum {
|
||||
TAG_HAPTICSCNFGXML_ROOT,
|
||||
TAG_PREDEFINED_EFFECT,
|
||||
TAG_HAPTICS_EFFECT,
|
||||
TAG_ONESHOT_EFFECT,
|
||||
TAG_RINGTONE_EFFECT,
|
||||
TAG_COMPOSE_EFFECT,
|
||||
} haptics_xml_tag;
|
||||
|
||||
struct haptics_wave_designer_config_t {
|
||||
// Waveform designer mode parameters
|
||||
int8_t num_channels;
|
||||
int8_t channel_mask;
|
||||
int8_t wave_design_mode;
|
||||
int32_t auto_overdrive_brake_en;
|
||||
int32_t f0_tracking_en;
|
||||
int32_t f0_tracking_param_reset_flag;
|
||||
uint32_t override_flag;
|
||||
int32_t tracked_freq_warmup_time_ms;
|
||||
int32_t settling_time_ms;
|
||||
int32_t delay_time_ms;
|
||||
int32_t wavegen_fstart_hz_q20;
|
||||
int32_t repetition_count;
|
||||
int32_t repetition_period_ms;
|
||||
uint32_t pilot_tone_en;
|
||||
int32_t low_pulse_intensity;
|
||||
int32_t mid_pulse_intensity;
|
||||
int32_t high_pulse_intensity;
|
||||
int32_t pulse_width_ms;
|
||||
int32_t pulse_sharpness;
|
||||
int32_t num_pwl;
|
||||
int32_t *pwl_time;
|
||||
int32_t *pwl_acc;
|
||||
};
|
||||
|
||||
struct haptics_xml_data{
|
||||
char data_buf[1024];
|
||||
size_t offs;
|
||||
haptics_xml_tag hapticstag;
|
||||
};
|
||||
|
||||
class AudioHapticsInterface
|
||||
{
|
||||
public:
|
||||
AudioHapticsInterface();
|
||||
~AudioHapticsInterface();
|
||||
static int XmlParser(std::string xmlFile);
|
||||
static void endTag(void *userdata, const XML_Char *tag_name);
|
||||
static void startTag(void *userdata, const XML_Char *tag_name, const XML_Char **attr);
|
||||
static void handleData(void *userdata, const char *s, int len);
|
||||
static void resetDataBuf(struct haptics_xml_data *data);
|
||||
static void process_haptics_info(struct haptics_xml_data *data, const XML_Char *tag_name);
|
||||
void getTouchHapticsEffectConfiguration(int effect_id, bool isCompose, haptics_wave_designer_config_t **HConfig);
|
||||
int getRingtoneHapticsEffectConfiguration() {return ringtone_haptics_wave_design_mode;}
|
||||
static int init();
|
||||
static std::shared_ptr<AudioHapticsInterface> GetInstance();
|
||||
private:
|
||||
static std::vector<haptics_wave_designer_config_t> predefined_haptics_info;
|
||||
static std::vector<haptics_wave_designer_config_t> compose_haptics_info;
|
||||
static std::vector<haptics_wave_designer_config_t> oneshot_haptics_info;
|
||||
static std::shared_ptr<AudioHapticsInterface> me_;
|
||||
static int ringtone_haptics_wave_design_mode;
|
||||
};
|
||||
#endif
|
||||
144
qcom/opensource/pal/utils/inc/ChargerListener.h
Normal file
144
qcom/opensource/pal/utils/inc/ChargerListener.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Linux Foundation. All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _CHARGER_LISTENER_H_
|
||||
#define _CHARGER_LISTENER_H_
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#ifdef ANDROID
|
||||
#include <bits/epoll_event.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
#define MAX_EVENTS 3
|
||||
|
||||
typedef enum {
|
||||
OFFLINE = 0,
|
||||
ONLINE
|
||||
} charger_state_t;
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
CHARGING,
|
||||
DISCHARGING,
|
||||
NOT_CHARGING,
|
||||
FULL
|
||||
} batt_state_t;
|
||||
|
||||
enum {
|
||||
PIPE_EVENT,
|
||||
U_EVENT
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN_EVENT = -1,
|
||||
CHARGER_EVENT,
|
||||
BATTERY_EVENT
|
||||
} uevent_type_t;
|
||||
|
||||
struct charger_info {
|
||||
struct epoll_event events[MAX_EVENTS];
|
||||
int event_count;
|
||||
int epoll_fd;
|
||||
int uevent_fd;
|
||||
charger_state_t c_state;
|
||||
batt_state_t b_state;
|
||||
};
|
||||
|
||||
class ChargerListenerImpl {
|
||||
typedef void (*func_ptr)(void *context, struct charger_info *info);
|
||||
typedef std::function<void(int, int, bool)> cb_fn_t;
|
||||
cb_fn_t mcb;
|
||||
int intPipe[2];
|
||||
int pipe_status;
|
||||
std::thread poll_thread, dispatcher_thread;
|
||||
std::mutex mlock;
|
||||
struct charger_info *info;
|
||||
int readSysfsPath(const char *path, int flag, int length, char *state);
|
||||
int getInitialStatus();
|
||||
void getStateUpdate(int type);
|
||||
static void readEvent(void * context, struct charger_info *info);
|
||||
int addEvent(func_ptr event_func, int event_type ,int fd);
|
||||
int initEvent();
|
||||
void chargerMonitor();
|
||||
void CLImplInit();
|
||||
int getConcurrentState();
|
||||
public:
|
||||
ChargerListenerImpl (cb_fn_t cb);
|
||||
~ChargerListenerImpl ();
|
||||
int setConcurrentState(bool is_boost_enable);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \param[in] uevent_type - Charger or Battery Event.
|
||||
* \param[in] status - status of charger or battery based on uevent.
|
||||
* \param[in] concurrent_state - Handle ASR case only for charger event. No
|
||||
* Need to set Concurrent bit by pal when bit
|
||||
* is 1.
|
||||
*/
|
||||
typedef void (*charger_status_change_fn_t)(int, int, bool);
|
||||
typedef void (*cl_init_t)(charger_status_change_fn_t);
|
||||
typedef void (*cl_deinit_t)();
|
||||
typedef int (*cl_set_boost_state_t)(bool);
|
||||
|
||||
/**
|
||||
* \brief - Initialise, register uevent and pipe in epoll.
|
||||
* Spawn new thread to Monitor change in event.
|
||||
* \param[in] charger_status_change_fn_t - CB will be executed on initial
|
||||
* status and during uevent change
|
||||
* to configure pal.
|
||||
*/
|
||||
void chargerPropertiesListenerInit(charger_status_change_fn_t fn);
|
||||
|
||||
/**
|
||||
* \brief - As RM deinit, main thread will write Q on pipe and epoll
|
||||
* thread will be unblocked.
|
||||
*/
|
||||
void chargerPropertiesListenerDeinit();
|
||||
|
||||
/**
|
||||
* \brief - Notify PMIC driver by writing 0/1 on concurrent sysfs
|
||||
* node to start charging.
|
||||
*
|
||||
* \param[in] status - concurrent state to set.
|
||||
* \return - 0 on success, error code otherwise.
|
||||
*/
|
||||
int chargerPropertiesListenerSetBoostState(bool status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CHARGER_LISTENER_H_ */
|
||||
22
qcom/opensource/pal/utils/inc/MemLogBuilder.h
Normal file
22
qcom/opensource/pal/utils/inc/MemLogBuilder.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef MEMLOG_BUILDER_H
|
||||
#define MEMLOG_BUILDER_H
|
||||
|
||||
#include "mem_logger.h"
|
||||
#include "pal_state_queue.h"
|
||||
#include "kpi_queue.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Stream.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
int palStateQueueBuilder(pal_state_queue &que, Stream *s, pal_state_queue_state state, int32_t error);
|
||||
int palStateEnqueue(Stream *s, pal_state_queue_state state, int32_t error);
|
||||
int palStateEnqueue(Stream *s, pal_state_queue_state state, int32_t error, union pal_mlog_str_info str_info);
|
||||
pal_mlog_acdstr_info palStateACDStreamBuilder(Stream *s);
|
||||
void kpiEnqueue(const char name[], bool isEnter);
|
||||
|
||||
#endif
|
||||
84
qcom/opensource/pal/utils/inc/MetadataParser.h
Normal file
84
qcom/opensource/pal/utils/inc/MetadataParser.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef METADATA_PARSER_H
|
||||
#define METADATA_PARSER_H
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "media_fmt_api_basic.h"
|
||||
#include "metadata_api.h"
|
||||
#include "wr_sh_mem_ep_api.h"
|
||||
#include "rd_sh_mem_ep_api.h"
|
||||
|
||||
#define ALIGN(num, to) (((num) + (to-1)) & (~(to-1)))
|
||||
|
||||
static constexpr uint32_t BYTES_PER_SAMPLE(uint32_t x) { return (x / 8); }
|
||||
static constexpr uint32_t GET_LSW(uint64_t num) { return static_cast<uint32_t>(num & UINT32_MAX); }
|
||||
static constexpr uint32_t GET_MSW(uint64_t num) { return static_cast<uint32_t>((num & ~UINT32_MAX) >> 32); }
|
||||
|
||||
struct ChannelHelper {
|
||||
static constexpr const int MAX_NUM_CHANNELS = 16;
|
||||
};
|
||||
|
||||
enum MetadataType: uint8_t {
|
||||
START_METADATA = 0,
|
||||
END_METADATA,
|
||||
MEDIA_FORMAT_EVENT
|
||||
};
|
||||
|
||||
size_t START_METADATA_SIZE() {
|
||||
return sizeof(metadata_header_t) + sizeof(module_cmn_md_buffer_start_t);
|
||||
}
|
||||
|
||||
size_t END_METADATA_SIZE() {
|
||||
return sizeof(metadata_header_t) + sizeof(module_cmn_md_buffer_end_t);
|
||||
}
|
||||
|
||||
size_t MEDIA_FORMAT_METADATA_SIZE() {
|
||||
return sizeof(metadata_header_t)
|
||||
+ sizeof(struct media_format_t)
|
||||
+ sizeof(payload_media_fmt_pcm_t)
|
||||
+ (ChannelHelper::MAX_NUM_CHANNELS*sizeof(int8_t));
|
||||
}
|
||||
|
||||
//update applicable lists for new metadata item added above
|
||||
static std::vector<size_t> WRITE_METADATA_ITEM_SIZES = {
|
||||
START_METADATA_SIZE(),
|
||||
END_METADATA_SIZE()
|
||||
};
|
||||
|
||||
static std::vector<size_t> READ_METADATA_ITEM_SIZES = {
|
||||
START_METADATA_SIZE(),
|
||||
END_METADATA_SIZE(),
|
||||
MEDIA_FORMAT_METADATA_SIZE()
|
||||
};
|
||||
|
||||
class MetadataParser {
|
||||
public:
|
||||
static size_t WRITE_METADATA_MAX_SIZE() {
|
||||
return std::accumulate(WRITE_METADATA_ITEM_SIZES.begin(),
|
||||
WRITE_METADATA_ITEM_SIZES.end(), 0);
|
||||
}
|
||||
|
||||
static size_t READ_METADATA_MAX_SIZE() {
|
||||
return std::accumulate(READ_METADATA_ITEM_SIZES.begin(),
|
||||
READ_METADATA_ITEM_SIZES.end(), 0);
|
||||
}
|
||||
|
||||
int parseMetadata(uint8_t* metadata, size_t metadataSize,
|
||||
pal_clbk_buffer_info *bufferInfo);
|
||||
void fillMetaData(uint8_t *metadata,
|
||||
uint64_t frameIndex, size_t filledLength,
|
||||
pal_media_config *streamMediaConfig);
|
||||
};
|
||||
|
||||
#endif
|
||||
146
qcom/opensource/pal/utils/inc/PalRingBuffer.h
Normal file
146
qcom/opensource/pal/utils/inc/PalRingBuffer.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include "Stream.h"
|
||||
|
||||
#ifndef PALRINGBUFFER_H_
|
||||
#define PALRINGBUFFER_H_
|
||||
|
||||
#define DEFAULT_PAL_RING_BUFFER_SIZE 4096 * 10
|
||||
|
||||
typedef enum {
|
||||
READER_DISABLED = 0,
|
||||
READER_ENABLED = 1,
|
||||
READER_PREPARED = 2,
|
||||
} pal_ring_buffer_reader_state;
|
||||
|
||||
/*
|
||||
* startIdx/endIdx: index compared to beginning of the detection
|
||||
* ftrtSize: linear increased during buffering, used to confirm
|
||||
* if keyword data is read from adsp
|
||||
*/
|
||||
struct kwdConfig {
|
||||
uint32_t startIdx;
|
||||
uint32_t endIdx;
|
||||
uint32_t ftrtSize;
|
||||
};
|
||||
|
||||
class PalRingBuffer;
|
||||
|
||||
class PalRingBufferReader {
|
||||
public:
|
||||
PalRingBufferReader(PalRingBuffer *buffer)
|
||||
: ringBuffer_(buffer),
|
||||
unreadSize_(0),
|
||||
readOffset_(0),
|
||||
requestedSize_(0),
|
||||
state_(READER_DISABLED) {}
|
||||
|
||||
~PalRingBufferReader() {};
|
||||
|
||||
size_t advanceReadOffset(size_t advanceSize);
|
||||
int32_t read(void* readBuffer, size_t readSize);
|
||||
void updateState(pal_ring_buffer_reader_state state);
|
||||
void getIndices(Stream *s,
|
||||
uint32_t *startIdx, uint32_t *endIdx, uint32_t *ftrtSize);
|
||||
int32_t getKwData(Stream *s, uint8_t *data, uint32_t size);
|
||||
size_t getUnreadSize();
|
||||
size_t getBufferSize();
|
||||
void reset();
|
||||
bool isEnabled() { return state_ == READER_ENABLED; }
|
||||
bool isPrepared() { return state_ == READER_PREPARED; }
|
||||
bool waitForBuffers(uint32_t buffer_size);
|
||||
|
||||
friend class PalRingBuffer;
|
||||
|
||||
protected:
|
||||
PalRingBuffer *ringBuffer_;
|
||||
size_t unreadSize_;
|
||||
size_t readOffset_;
|
||||
pal_ring_buffer_reader_state state_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cv_;
|
||||
uint32_t requestedSize_;
|
||||
};
|
||||
|
||||
class PalRingBuffer {
|
||||
public:
|
||||
explicit PalRingBuffer(size_t bufferSize)
|
||||
: buffer_((char*)(new char[bufferSize])),
|
||||
writeOffset_(0),
|
||||
bufferEnd_(bufferSize) {}
|
||||
|
||||
~PalRingBuffer() {
|
||||
if (buffer_)
|
||||
delete buffer_;
|
||||
|
||||
for (int i = 0; i < readers_.size(); i++)
|
||||
delete readers_[i];
|
||||
}
|
||||
|
||||
PalRingBufferReader* newReader();
|
||||
|
||||
int32_t removeReader(PalRingBufferReader *reader);
|
||||
size_t read(std::shared_ptr<PalRingBufferReader>reader, void* readBuffer,
|
||||
size_t readSize);
|
||||
size_t write(void* writeBuffer, size_t writeSize);
|
||||
size_t getFreeSize();
|
||||
void updateKwdConfig(Stream *s, uint32_t startIdx, uint32_t endIdx,
|
||||
uint32_t preRoll);
|
||||
void getIndices(Stream *s,
|
||||
uint32_t *startIdx, uint32_t *endIdx, uint32_t *ftrtSize);
|
||||
void reset();
|
||||
size_t getBufferSize() { return bufferEnd_; };
|
||||
void resizeRingBuffer(size_t bufferSize);
|
||||
|
||||
protected:
|
||||
std::mutex mutex_;
|
||||
char* buffer_;
|
||||
std::unordered_map<Stream*, struct kwdConfig> kwCfg_;
|
||||
size_t writeOffset_;
|
||||
size_t bufferEnd_;
|
||||
std::vector<PalRingBufferReader*> readers_;
|
||||
void updateUnReadSize(size_t writtenSize);
|
||||
friend class PalRingBufferReader;
|
||||
};
|
||||
#endif
|
||||
59
qcom/opensource/pal/utils/inc/PerfLock.h
Normal file
59
qcom/opensource/pal/utils/inc/PerfLock.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
struct PerfLockConfig {
|
||||
bool usePerfLock = false;
|
||||
std::string libraryName;
|
||||
std::vector<int> perfLockOpts;
|
||||
};
|
||||
|
||||
/**
|
||||
* A Scoped object for real perf lock.
|
||||
* Only one among the existing PerfLock instances possibly acquires real perf lock.
|
||||
**/
|
||||
class PerfLock final {
|
||||
public:
|
||||
// All Public APIs are gaurded by sMutex
|
||||
PerfLock(const std::string &);
|
||||
~PerfLock();
|
||||
// Read config from resource_manager and set configs
|
||||
static void setPerfLockOpt(const PerfLockConfig & config);
|
||||
|
||||
private:
|
||||
// disable copy
|
||||
PerfLock(const PerfLock&) = delete;
|
||||
PerfLock& operator=(const PerfLock& x) = delete;
|
||||
|
||||
// disable move
|
||||
PerfLock(PerfLock&& other) = delete;
|
||||
PerfLock& operator=(PerfLock&& other) = delete;
|
||||
|
||||
// function mapping for dlsym
|
||||
using AcquirePerfLock = int (*)(int, int, int*, int);
|
||||
using ReleasePerfLock = int (*)(int);
|
||||
|
||||
inline static AcquirePerfLock sAcquirePerfLock{nullptr};
|
||||
inline static ReleasePerfLock sReleasePerfLock{nullptr};
|
||||
// this mutex is a class Mutex
|
||||
inline static std::mutex sMutex;
|
||||
inline static bool sIsAcquired = false;
|
||||
inline static int kPerfLockOptsSize = 0;
|
||||
inline static int sPerfLockCounter = 0;
|
||||
inline static std::vector<int> kPerfLockOpts;
|
||||
inline static int sHandle{0};
|
||||
inline static bool usePerfLock;
|
||||
inline static std::string sLibraryName;
|
||||
|
||||
std::string mCaller;
|
||||
static bool init();
|
||||
|
||||
// Below functions needs to be called with sMutex lock held
|
||||
void acquire_l();
|
||||
void release_l();
|
||||
};
|
||||
81
qcom/opensource/pal/utils/inc/SignalHandler.h
Normal file
81
qcom/opensource/pal/utils/inc/SignalHandler.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted (subject to the limitations in the
|
||||
* disclaimer below) provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
||||
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SIGNAL_HANDLER_H
|
||||
#define SIGNAL_HANDLER_H
|
||||
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <signal.h>
|
||||
#include <map>
|
||||
|
||||
#ifndef __SIGRTMIN
|
||||
#define __SIGRTMIN 32
|
||||
#endif
|
||||
|
||||
static const constexpr int DEBUGGER_SIGNAL = (__SIGRTMIN + 3);
|
||||
static const constexpr uint32_t kDefaultSignalPendingTries = 10;
|
||||
static const constexpr uint32_t kDefaultRegistrationDelayMs = 500;
|
||||
|
||||
static const std::map<uint32_t, std::string> sigToName {
|
||||
{DEBUGGER_SIGNAL, std::string{"<debuggerd signal>"}},
|
||||
{SIGABRT, std::string{"SIGABRT"}},
|
||||
{SIGSEGV, std::string{"SIGSEGV"}},
|
||||
};
|
||||
|
||||
|
||||
struct SignalHandler {
|
||||
static std::shared_ptr<SignalHandler> getInstance();
|
||||
static void setClientCallback(std::function<void(int, pid_t, uid_t)> cb);
|
||||
static void asyncRegister(int signal);
|
||||
static void invokeDefaultHandler(std::shared_ptr<struct sigaction> sAct,
|
||||
int code, struct siginfo *si, void *sc);
|
||||
static void customSignalHandler(int code, struct siginfo *si, void *sc);
|
||||
static std::vector<int> getRegisteredSignals();
|
||||
void registerSignalHandler(std::vector<int> signalsToRegister);
|
||||
static void setBuildDebuggable(bool debuggable) { sBuildDebuggable = debuggable;}
|
||||
static bool isBuildDebuggable() { return sBuildDebuggable;}
|
||||
static std::mutex sDefaultSigMapLock;
|
||||
static std::unordered_map<int, std::shared_ptr<struct sigaction>> sDefaultSigMap;
|
||||
static std::function<void(int, pid_t, uid_t)> sClientCb;
|
||||
static std::mutex sAsyncRegisterLock;
|
||||
static std::future<void> sAsyncHandle;
|
||||
static bool sBuildDebuggable;
|
||||
};
|
||||
|
||||
#endif
|
||||
173
qcom/opensource/pal/utils/inc/SoundTriggerPlatformInfo.h
Normal file
173
qcom/opensource/pal/utils/inc/SoundTriggerPlatformInfo.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef SOUND_TRIGGER_PLATFORM_INFO_H
|
||||
#define SOUND_TRIGGER_PLATFORM_INFO_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "PalDefs.h"
|
||||
#include "kvh2xml.h"
|
||||
#include "SoundTriggerUtils.h"
|
||||
|
||||
#define MAX_MODULE_CHANNELS 4
|
||||
|
||||
#define CAPTURE_PROFILE_PRIORITY_HIGH 1
|
||||
#define CAPTURE_PROFILE_PRIORITY_LOW -1
|
||||
#define CAPTURE_PROFILE_PRIORITY_SAME 0
|
||||
|
||||
enum StOperatingModes {
|
||||
ST_OPERATING_MODE_LOW_POWER,
|
||||
ST_OPERATING_MODE_LOW_POWER_NS,
|
||||
ST_OPERATING_MODE_LOW_POWER_TX_MACRO,
|
||||
ST_OPERATING_MODE_HIGH_PERF,
|
||||
ST_OPERATING_MODE_HIGH_PERF_NS,
|
||||
ST_OPERATING_MODE_HIGH_PERF_TX_MACRO,
|
||||
ST_OPERATING_MODE_HIGH_PERF_AND_CHARGING
|
||||
};
|
||||
|
||||
enum StInputModes {
|
||||
ST_INPUT_MODE_HANDSET,
|
||||
ST_INPUT_MODE_HEADSET
|
||||
};
|
||||
|
||||
class SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
virtual void HandleStartTag(const char *tag, const char **attribs) = 0;
|
||||
virtual void HandleEndTag(struct xml_userdata *data __unused, const char *tag __unused) {};
|
||||
virtual void HandleCharData(const char *data __unused) {};
|
||||
virtual ~SoundTriggerXml() {};
|
||||
};
|
||||
|
||||
class SoundTriggerUUID {
|
||||
public:
|
||||
SoundTriggerUUID();
|
||||
SoundTriggerUUID & operator=(SoundTriggerUUID &rhs);
|
||||
bool operator<(const SoundTriggerUUID &rhs) const;
|
||||
bool CompareUUID(const struct st_uuid uuid) const;
|
||||
static int StringToUUID(const char* str, SoundTriggerUUID& UUID);
|
||||
uint32_t timeLow;
|
||||
uint16_t timeMid;
|
||||
uint16_t timeHiAndVersion;
|
||||
uint16_t clockSeq;
|
||||
uint8_t node[6];
|
||||
|
||||
};
|
||||
|
||||
class CaptureProfile : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
CaptureProfile(std::string name);
|
||||
CaptureProfile() = delete;
|
||||
CaptureProfile(CaptureProfile &rhs) = delete;
|
||||
CaptureProfile & operator=(CaptureProfile &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char* tag, const char* * attribs) override;
|
||||
|
||||
std::string GetName() const { return name_; }
|
||||
pal_device_id_t GetDevId() const { return device_id_; }
|
||||
uint32_t GetSampleRate() const { return sample_rate_; }
|
||||
uint32_t GetBitWidth() const { return bitwidth_; }
|
||||
uint32_t GetChannels() const { return channels_; }
|
||||
std::string GetSndName() const { return snd_name_; }
|
||||
std::string GetBackend() const { return backend_; }
|
||||
bool isECRequired() const { return is_ec_req_; }
|
||||
void SetSampleRate(uint32_t sample_rate) { sample_rate_ = sample_rate; }
|
||||
void SetBitWidth(uint32_t bit_width) { bitwidth_ = bit_width; }
|
||||
void SetChannels(uint32_t channels) { channels_ = channels; }
|
||||
void SetSndName(std::string snd_name) { snd_name_ = snd_name; }
|
||||
std::pair<uint32_t,uint32_t> GetDevicePpKv() const { return device_pp_kv_; }
|
||||
|
||||
int32_t ComparePriority(std::shared_ptr<CaptureProfile> cap_prof);
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
pal_device_id_t device_id_;
|
||||
uint32_t sample_rate_;
|
||||
uint32_t channels_;
|
||||
uint32_t bitwidth_;
|
||||
std::pair<uint32_t,uint32_t> device_pp_kv_;
|
||||
std::string snd_name_;
|
||||
bool is_ec_req_;
|
||||
std::string backend_;
|
||||
};
|
||||
|
||||
using UUID = SoundTriggerUUID;
|
||||
using st_cap_profile_map_t = std::map<std::string, std::shared_ptr<CaptureProfile>>;
|
||||
using st_op_modes_t = std::map<std::pair<StOperatingModes, StInputModes>, std::shared_ptr<CaptureProfile>>;
|
||||
|
||||
class SoundTriggerPlatformInfo : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
SoundTriggerPlatformInfo();
|
||||
SoundTriggerPlatformInfo(SoundTriggerPlatformInfo &rhs) = delete;
|
||||
SoundTriggerPlatformInfo & operator=(SoundTriggerPlatformInfo &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
static std::shared_ptr<SoundTriggerPlatformInfo> GetInstance();
|
||||
static bool GetLpiEnable() { return lpi_enable_; }
|
||||
static bool GetSupportNLPISwitch() { return support_nlpi_switch_; }
|
||||
static bool GetSupportDevSwitch() { return support_device_switch_; }
|
||||
static bool GetEnableDebugDumps() { return enable_debug_dumps_; }
|
||||
static bool GetConcurrentCaptureEnable() { return concurrent_capture_; }
|
||||
static bool GetConcurrentVoiceCallEnable() { return concurrent_voice_call_; }
|
||||
static bool GetConcurrentVoipCallEnable() { return concurrent_voip_call_; }
|
||||
static bool GetLowLatencyBargeinEnable() { return low_latency_bargein_enable_; }
|
||||
|
||||
/* reads capture profile names into member variables */
|
||||
void ReadCapProfileNames(StOperatingModes mode, const char **attribs, st_op_modes_t& op_modes);
|
||||
/* use capture profile name to retrieve capture profile from capture_profile_map_ */
|
||||
std::shared_ptr<CaptureProfile> GetCaptureProfileFromMap(std::string cap_prof_name);
|
||||
|
||||
private:
|
||||
static bool lpi_enable_;
|
||||
static bool support_nlpi_switch_;
|
||||
static bool support_device_switch_;
|
||||
static bool enable_debug_dumps_;
|
||||
static bool concurrent_capture_;
|
||||
static bool concurrent_voice_call_;
|
||||
static bool concurrent_voip_call_;
|
||||
static bool low_latency_bargein_enable_;
|
||||
static std::shared_ptr<SoundTriggerPlatformInfo> me_;
|
||||
st_cap_profile_map_t capture_profile_map_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
};
|
||||
#endif
|
||||
232
qcom/opensource/pal/utils/inc/VoiceUIPlatformInfo.h
Normal file
232
qcom/opensource/pal/utils/inc/VoiceUIPlatformInfo.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted (subject to the limitations in the
|
||||
* disclaimer below) provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
||||
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VOICE_UI_PLATFORM_INFO_H
|
||||
#define VOICE_UI_PLATFORM_INFO_H
|
||||
|
||||
#include "SoundTriggerPlatformInfo.h"
|
||||
|
||||
#define MAX_MODULE_CHANNELS 4
|
||||
|
||||
class VUISecondStageConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
VUISecondStageConfig();
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
|
||||
st_sound_model_type_t GetDetectionType() const { return detection_type_; }
|
||||
std::string GetLibName() const { return module_lib_; }
|
||||
uint32_t GetSoundModelID() const { return sm_id_; }
|
||||
uint32_t GetSampleRate() const { return sample_rate_; }
|
||||
uint32_t GetBitWidth() const { return bit_width_; }
|
||||
uint32_t GetChannels() const { return channels_; }
|
||||
|
||||
private:
|
||||
st_sound_model_type_t detection_type_;
|
||||
uint32_t sm_id_;
|
||||
std::string module_lib_;
|
||||
uint32_t sample_rate_;
|
||||
uint32_t bit_width_;
|
||||
uint32_t channels_;
|
||||
};
|
||||
|
||||
class VUIFirstStageConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
VUIFirstStageConfig();
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
|
||||
st_module_type_t GetModuleType() const { return module_type_; }
|
||||
std::string GetModuleName() const { return module_name_; }
|
||||
bool IsLpiSupported() const { return lpi_supported_; }
|
||||
uint32_t GetModuleTagId(st_param_id_type_t param_id) const {
|
||||
return module_tag_ids_[param_id];
|
||||
}
|
||||
uint32_t GetParamId(st_param_id_type_t param_id) const {
|
||||
return param_ids_[param_id];
|
||||
}
|
||||
|
||||
private:
|
||||
bool lpi_supported_;
|
||||
st_module_type_t module_type_;
|
||||
std::string module_name_;
|
||||
uint32_t module_tag_ids_[MAX_PARAM_IDS];
|
||||
uint32_t param_ids_[MAX_PARAM_IDS];
|
||||
};
|
||||
|
||||
class VUIStreamConfig : public SoundTriggerXml
|
||||
{
|
||||
public:
|
||||
VUIStreamConfig();
|
||||
VUIStreamConfig(VUIStreamConfig &rhs) = delete;
|
||||
VUIStreamConfig & operator=(VUIStreamConfig &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
UUID GetUUID() const { return vendor_uuid_; }
|
||||
std::string GetVUIIntfPluginLib() const { return vui_intf_plugin_lib_name_; }
|
||||
bool GetModuleVersionSupported() const {
|
||||
return get_module_version_supported_;
|
||||
}
|
||||
bool GetMergeFirstStageSoundModels() const {
|
||||
return merge_first_stage_sound_models_;
|
||||
}
|
||||
bool isSingleInstanceStage1() const { return supported_first_stage_engine_count_ == 1; }
|
||||
bool isQCVAUUID() const { return is_qcva_uuid_; }
|
||||
uint32_t GetKwDuration() const { return capture_keyword_; }
|
||||
uint32_t GetCaptureReadDelay() const { return client_capture_read_delay_; }
|
||||
uint32_t GetPreRollDuration() const { return pre_roll_duration_; }
|
||||
uint32_t GetKwStartTolerance() const { return kw_start_tolerance_; }
|
||||
uint32_t GetKwEndTolerance() const { return kw_end_tolerance_; }
|
||||
uint32_t GetDataBeforeKwStart() const { return data_before_kw_start_; }
|
||||
uint32_t GetDataAfterKwEnd() const { return data_after_kw_end_; }
|
||||
uint32_t GetSampleRate() const { return sample_rate_; }
|
||||
uint32_t GetBitWidth() const { return bit_width_; }
|
||||
uint32_t GetOutChannels() const { return out_channels_; }
|
||||
uint32_t GetSupportedEngineCount() const {
|
||||
return supported_first_stage_engine_count_; }
|
||||
bool GetConcurrentEventCapture() const { return enable_concurrent_event_capture_; }
|
||||
st_module_type_t GetVUIModuleType();
|
||||
std::shared_ptr<VUISecondStageConfig> GetVUISecondStageConfig(
|
||||
const listen_model_indicator_enum& sm_type) const;
|
||||
std::shared_ptr<VUIFirstStageConfig> GetVUIFirstStageConfig(const uint32_t type) const;
|
||||
std::shared_ptr<VUIFirstStageConfig> GetVUIFirstStageConfig();
|
||||
std::string GetVUIModuleName();
|
||||
std::string GetVUIModuleName(st_module_type_t type) const {
|
||||
return GetVUIFirstStageConfig(type)->GetModuleName();
|
||||
}
|
||||
std::shared_ptr<CaptureProfile> GetCaptureProfile(
|
||||
std::pair<StOperatingModes, StInputModes> mode_pair) const {
|
||||
return vui_op_modes_.at(mode_pair);
|
||||
}
|
||||
void GetDetectionPropertyList(std::vector<uint32_t> &list);
|
||||
void ReadDetectionPropertyList(const char *prop_string);
|
||||
bool IsDetPropSupported(uint32_t prop) const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
UUID vendor_uuid_;
|
||||
std::string vui_intf_plugin_lib_name_;
|
||||
bool is_qcva_uuid_;
|
||||
bool get_module_version_supported_;
|
||||
bool merge_first_stage_sound_models_;
|
||||
uint32_t capture_keyword_;
|
||||
uint32_t client_capture_read_delay_;
|
||||
uint32_t pre_roll_duration_;
|
||||
uint32_t kw_start_tolerance_;
|
||||
uint32_t kw_end_tolerance_;
|
||||
uint32_t data_before_kw_start_;
|
||||
uint32_t data_after_kw_end_;
|
||||
uint32_t sample_rate_;
|
||||
uint32_t bit_width_;
|
||||
uint32_t out_channels_;
|
||||
uint32_t supported_first_stage_engine_count_;
|
||||
bool enable_concurrent_event_capture_;
|
||||
st_op_modes_t vui_op_modes_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
std::map<uint32_t, std::shared_ptr<VUISecondStageConfig>> vui_2nd_stage_cfg_list_;
|
||||
std::map<uint32_t, std::shared_ptr<VUIFirstStageConfig>> vui_1st_stage_cfg_list_;
|
||||
std::map<UUID, std::shared_ptr<VUIFirstStageConfig>> vui_uuid_1st_stage_cfg_list_;
|
||||
std::vector<uint32_t> ext_det_prop_list_;
|
||||
};
|
||||
|
||||
class VoiceUIPlatformInfo : public SoundTriggerPlatformInfo
|
||||
{
|
||||
public:
|
||||
VoiceUIPlatformInfo();
|
||||
VoiceUIPlatformInfo(VUIStreamConfig &rhs) = delete;
|
||||
VoiceUIPlatformInfo & operator=(VoiceUIPlatformInfo &rhs) = delete;
|
||||
|
||||
void HandleStartTag(const char *tag, const char **attribs) override;
|
||||
void HandleEndTag(struct xml_userdata *data, const char *tag) override;
|
||||
|
||||
static std::shared_ptr<VoiceUIPlatformInfo> GetInstance();
|
||||
std::string GetSoundModelLib() const { return sound_model_lib_; }
|
||||
bool GetEnableFailureDetection() const { return enable_failure_detection_; }
|
||||
bool GetTransitToNonLpiOnCharging() const {
|
||||
return transit_to_non_lpi_on_charging_;
|
||||
}
|
||||
bool GetMmapEnable() const { return mmap_enable_; }
|
||||
bool GetNotifySecondStageFailure() { return notify_second_stage_failure_; }
|
||||
uint32_t GetVersion() const { return vui_version_; }
|
||||
uint32_t GetMmapBufferDuration() const { return mmap_buffer_duration_; }
|
||||
uint32_t GetMmapFrameLength() const { return mmap_frame_length_; }
|
||||
std::shared_ptr<VUIStreamConfig> GetStreamConfig(const UUID& uuid) const;
|
||||
void GetStreamConfigForVersionQuery(std::vector<std::shared_ptr<VUIStreamConfig>> &sm_cfg_list) const;
|
||||
|
||||
private:
|
||||
static std::shared_ptr<VoiceUIPlatformInfo> me_;
|
||||
uint32_t vui_version_;
|
||||
bool enable_failure_detection_;
|
||||
bool transit_to_non_lpi_on_charging_;
|
||||
bool notify_second_stage_failure_;
|
||||
bool mmap_enable_;
|
||||
uint32_t mmap_buffer_duration_;
|
||||
uint32_t mmap_frame_length_;
|
||||
std::string sound_model_lib_;
|
||||
std::map<UUID, std::shared_ptr<VUIStreamConfig>> stream_cfg_list_;
|
||||
std::shared_ptr<SoundTriggerXml> curr_child_;
|
||||
};
|
||||
#endif
|
||||
314
qcom/opensource/pal/utils/src/ACDPlatformInfo.cpp
Normal file
314
qcom/opensource/pal/utils/src/ACDPlatformInfo.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "ACDPlatformInfo.h"
|
||||
|
||||
#define LOG_TAG "PAL: ACDPlatformInfo"
|
||||
|
||||
ACDContextInfo::ACDContextInfo(uint32_t context_id, uint32_t type) :
|
||||
context_id_(context_id),
|
||||
context_type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
ACDSoundModelInfo::ACDSoundModelInfo(ACDStreamConfig *sm_cfg) :
|
||||
model_bin_name_(""),
|
||||
is_parsing_contexts(false),
|
||||
sm_cfg_(sm_cfg)
|
||||
{
|
||||
}
|
||||
|
||||
void ACDSoundModelInfo::HandleStartTag(const char* tag, const char** attribs __unused)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (is_parsing_contexts) {
|
||||
if (!strcmp(tag, "context")) {
|
||||
uint32_t i = 0;
|
||||
uint32_t id;
|
||||
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "id")) {
|
||||
std::string tagid(attribs[++i]);
|
||||
id = ResourceManager::convertCharToHex(tagid);
|
||||
std::shared_ptr<ACDContextInfo> context_info =
|
||||
std::make_shared<ACDContextInfo>(id, model_id_);
|
||||
acd_context_info_list_.push_back(context_info);
|
||||
sm_cfg_->UpdateContextModelMap(id);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "contexts"))
|
||||
is_parsing_contexts = true;
|
||||
}
|
||||
|
||||
void ACDSoundModelInfo::HandleEndTag(struct xml_userdata *data, const char* tag_name)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag_name);
|
||||
|
||||
if (!strcmp(tag_name, "contexts"))
|
||||
is_parsing_contexts = false;
|
||||
|
||||
if (data->offs <= 0)
|
||||
return;
|
||||
|
||||
data->data_buf[data->offs] = '\0';
|
||||
|
||||
if (!strcmp(tag_name, "name")) {
|
||||
std::string type(data->data_buf);
|
||||
|
||||
if (!strstr(type.c_str(), "ACD_SOUND_MODEL")) {
|
||||
PAL_ERR(LOG_TAG, "Error:%d invalid sound model: %s", type.c_str());
|
||||
} else {
|
||||
model_type_ = type;
|
||||
model_id_ = sm_cfg_->GetAndUpdateSndMdlCnt();
|
||||
PAL_INFO(LOG_TAG, "Sound model type: %s\t\tid: %d\n", model_type_.c_str(), model_id_);
|
||||
}
|
||||
} else if (!strcmp(tag_name, "bin")) {
|
||||
std::string bin_name(data->data_buf);
|
||||
model_bin_name_ = bin_name;
|
||||
} else if (!strcmp(tag_name, "uuid")) {
|
||||
std::string uuid(data->data_buf);
|
||||
model_uuid_ = ResourceManager::convertCharToHex(uuid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ACDStreamConfig::ACDStreamConfig() :
|
||||
curr_child_(nullptr),
|
||||
sound_model_cnt(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ACDStreamConfig::UpdateContextModelMap(uint32_t context_id)
|
||||
{
|
||||
std::shared_ptr<ACDSoundModelInfo> sm_info(
|
||||
std::static_pointer_cast<ACDSoundModelInfo>(curr_child_));
|
||||
context_model_map_.insert(std::make_pair(context_id, sm_info));
|
||||
}
|
||||
|
||||
std::shared_ptr<ACDSoundModelInfo> ACDStreamConfig::GetSoundModelInfoByContextId(uint32_t context_id)
|
||||
{
|
||||
auto contextModel = context_model_map_.find(context_id);
|
||||
|
||||
if (contextModel != context_model_map_.end())
|
||||
return contextModel->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<ACDSoundModelInfo> ACDStreamConfig::GetSoundModelInfoByModelId(uint32_t model_id)
|
||||
{
|
||||
auto modelInfo = acd_modelinfo_map_.find(model_id);
|
||||
|
||||
if (modelInfo != acd_modelinfo_map_.end())
|
||||
return modelInfo->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ACDStreamConfig::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "sound_model")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<ACDSoundModelInfo>(this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "operating_modes") || !strcmp(tag, "sound_model_info")
|
||||
|| !strcmp(tag, "name")) {
|
||||
PAL_DBG(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SoundTriggerPlatformInfo> st_info = SoundTriggerPlatformInfo::GetInstance();
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "vendor_uuid")) {
|
||||
UUID::StringToUUID(attribs[++i], vendor_uuid_);
|
||||
} else if (!strcmp(attribs[i], "sample_rate")) {
|
||||
sample_rate_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "bit_width")) {
|
||||
bit_width_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "out_channels")) {
|
||||
if (std::stoi(attribs[++i]) <= MAX_MODULE_CHANNELS)
|
||||
out_channels_ = std::stoi(attribs[i]);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else if (!strcmp(tag, "low_power")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_LOW_POWER, attribs, acd_op_modes_);
|
||||
} else if (!strcmp(tag, "low_power_ns")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_LOW_POWER_NS, attribs, acd_op_modes_);
|
||||
} else if (!strcmp(tag, "low_power_tx_macro")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_LOW_POWER_TX_MACRO, attribs, acd_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF, attribs, acd_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance_ns")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF_NS, attribs, acd_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance_tx_macro")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF_TX_MACRO, attribs, acd_op_modes_);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", (char *)tag);
|
||||
}
|
||||
}
|
||||
|
||||
void ACDStreamConfig::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "sound_model")) {
|
||||
std::shared_ptr<ACDSoundModelInfo> acd_sm_info(
|
||||
std::static_pointer_cast<ACDSoundModelInfo>(curr_child_));
|
||||
acd_soundmodel_info_list_.push_back(acd_sm_info);
|
||||
acd_modelinfo_map_.insert(std::make_pair(acd_sm_info->GetModelId(), acd_sm_info));
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "name")) {
|
||||
if (data->offs <= 0)
|
||||
return;
|
||||
data->data_buf[data->offs] = '\0';
|
||||
|
||||
std::string name(data->data_buf);
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<ACDPlatformInfo> ACDPlatformInfo::me_ = nullptr;
|
||||
|
||||
ACDPlatformInfo::ACDPlatformInfo() :
|
||||
acd_enable_(true),
|
||||
curr_child_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<ACDStreamConfig> ACDPlatformInfo::GetStreamConfig(const UUID& uuid) const
|
||||
{
|
||||
auto streamCfg = acd_cfg_list_.find(uuid);
|
||||
|
||||
if (streamCfg != acd_cfg_list_.end())
|
||||
return streamCfg->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<ACDPlatformInfo> ACDPlatformInfo::GetInstance()
|
||||
{
|
||||
if (!me_)
|
||||
me_ = std::shared_ptr<ACDPlatformInfo> (new ACDPlatformInfo);
|
||||
|
||||
return me_;
|
||||
}
|
||||
|
||||
void ACDPlatformInfo::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<ACDStreamConfig>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "config")) {
|
||||
PAL_DBG(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!attribs[i]) {
|
||||
PAL_ERR(LOG_TAG, "Error:%d missing attrib value for tag %s", -EINVAL, tag);
|
||||
} else if (!strcmp(attribs[i], "acd_enable")) {
|
||||
acd_enable_ = !strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
}
|
||||
|
||||
void ACDPlatformInfo::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
std::shared_ptr<ACDStreamConfig> acd_cfg(
|
||||
std::static_pointer_cast<ACDStreamConfig>(curr_child_));
|
||||
const auto res = acd_cfg_list_.insert(
|
||||
std::make_pair(acd_cfg->GetUUID(), acd_cfg));
|
||||
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Error:%d Failed to insert to map", -EINVAL);
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_)
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
|
||||
return;
|
||||
}
|
||||
247
qcom/opensource/pal/utils/src/ASRPlatformInfo.cpp
Normal file
247
qcom/opensource/pal/utils/src/ASRPlatformInfo.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "ASRPlatformInfo.h"
|
||||
#include "asr_module_calibration_api.h"
|
||||
|
||||
#define LOG_TAG "PAL: ASRPlatformInfo"
|
||||
|
||||
|
||||
void ASRCommonConfig::HandleStartTag(const char* tag, const char** attribs __unused)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "asr_input_buffer_size")) {
|
||||
input_buffer_size_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "asr_input_buffer_size_partial_mode")) {
|
||||
partial_mode_input_buffer_size_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "buffering_mode_out_buf_size")) {
|
||||
buffering_mode_out_buffer_size_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "command_mode_timeout")) {
|
||||
command_mode_timeout_ = std::stoi(attribs[++i]);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[++i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASRCommonConfig::HandleEndTag(struct xml_userdata *data, const char* tag_name)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Got end tag %s, nothing to handle here.", tag_name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ASRCommonConfig::ASRCommonConfig():
|
||||
input_buffer_size_(0),
|
||||
partial_mode_input_buffer_size_(0),
|
||||
buffering_mode_out_buffer_size_(0),
|
||||
command_mode_timeout_(0)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ASRCommonConfig::GetOutputBufferSize(int mode) {
|
||||
|
||||
if (mode == BUFFERED)
|
||||
return GetBufferingModeOutBufferSize();
|
||||
|
||||
return OUT_BUF_SIZE_DEFAULT;
|
||||
}
|
||||
|
||||
uint32_t ASRCommonConfig::GetInputBufferSize(int mode) {
|
||||
|
||||
if (mode == BUFFERED)
|
||||
return GetInputBufferSize();
|
||||
|
||||
return GetPartialModeInputBufferSize();
|
||||
|
||||
}
|
||||
|
||||
void ASRStreamConfig::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "operating_modes") || !strcmp(tag, "module_Info")
|
||||
|| !strcmp(tag, "name")) {
|
||||
PAL_DBG(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SoundTriggerPlatformInfo> st_info = SoundTriggerPlatformInfo::GetInstance();
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
uint32_t index = 0;
|
||||
if (!strcmp(attribs[i], "vendor_uuid")) {
|
||||
UUID::StringToUUID(attribs[++i], vendor_uuid_);
|
||||
} else {
|
||||
if (!strcmp(attribs[i], "asr_input_config_id")) {
|
||||
index = ASR_INPUT_CONFIG;
|
||||
} else if (!strcmp(attribs[i], "asr_output_config_id")) {
|
||||
index = ASR_OUTPUT_CONFIG;
|
||||
} else if (!strcmp(attribs[i], "asr_input_buffer_duration_id")) {
|
||||
index = ASR_INPUT_BUF_DURATON;
|
||||
} else if (!strcmp(attribs[i], "asr_output_id")) {
|
||||
index = ASR_OUTPUT;
|
||||
} else if (!strcmp(attribs[i], "asr_force_output_id")) {
|
||||
index = ASR_FORCE_OUTPUT;
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
sscanf(attribs[++i], "%x, %x", &module_tag_ids_[index], ¶m_ids_[index]);
|
||||
PAL_DBG(LOG_TAG, "index : %u, module_id : %x, param : %x",
|
||||
index, module_tag_ids_[index], param_ids_[index]);
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!strcmp(tag, "low_power")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_LOW_POWER, attribs, asr_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF, attribs, asr_op_modes_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASRStreamConfig::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "module_Info") || !strcmp(tag, "operating_modes")) {
|
||||
PAL_INFO(LOG_TAG, "Exit, Nothing to do for this %s tag.", tag);
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "name")) {
|
||||
if (data->offs <= 0)
|
||||
return;
|
||||
data->data_buf[data->offs] = '\0';
|
||||
|
||||
std::string name(data->data_buf);
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
PAL_INFO(LOG_TAG, "Exit, for %s tag.", tag);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASRPlatformInfo> ASRPlatformInfo::me_ = nullptr;
|
||||
|
||||
ASRStreamConfig::ASRStreamConfig() :
|
||||
curr_child_(nullptr)
|
||||
{
|
||||
for (int i = 0; i < ASR_MAX_PARAM_IDS; i++) {
|
||||
module_tag_ids_[i] = 0;
|
||||
param_ids_[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ASRPlatformInfo::ASRPlatformInfo() :
|
||||
curr_child_(nullptr),
|
||||
cm_cfg_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<ASRPlatformInfo> ASRPlatformInfo::GetInstance()
|
||||
{
|
||||
if (!me_)
|
||||
me_ = std::shared_ptr<ASRPlatformInfo> (new ASRPlatformInfo);
|
||||
|
||||
return me_;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASRStreamConfig> ASRPlatformInfo::GetStreamConfig(const UUID& uuid) const
|
||||
{
|
||||
auto smCfg = stream_cfg_list_.find(uuid);
|
||||
|
||||
if (smCfg != stream_cfg_list_.end())
|
||||
return smCfg->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ASRPlatformInfo::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<ASRStreamConfig>());
|
||||
return;
|
||||
} else if (!strcmp(tag, "common_config")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<ASRCommonConfig>());
|
||||
return;
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
|
||||
PAL_INFO(LOG_TAG, "Exit for tag %s.", tag);
|
||||
}
|
||||
|
||||
void ASRPlatformInfo::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_INFO(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
std::shared_ptr<ASRStreamConfig> sm_cfg(
|
||||
std::static_pointer_cast<ASRStreamConfig>(curr_child_));
|
||||
const auto res = stream_cfg_list_.insert(
|
||||
std::make_pair(sm_cfg->GetUUID(), sm_cfg));
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Failed to insert to map");
|
||||
curr_child_ = nullptr;
|
||||
} else if (!strcmp(tag, "common_config")) {
|
||||
std::shared_ptr<ASRCommonConfig> cm_cfg(
|
||||
std::static_pointer_cast<ASRCommonConfig>(curr_child_));
|
||||
cm_cfg_ = cm_cfg;
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_)
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
|
||||
PAL_DBG(LOG_TAG, "Exit for tag %s.", tag);
|
||||
|
||||
return;
|
||||
}
|
||||
523
qcom/opensource/pal/utils/src/AudioHapticsInterface.cpp
Normal file
523
qcom/opensource/pal/utils/src/AudioHapticsInterface.cpp
Normal file
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "AudioHapticsInterface.h"
|
||||
|
||||
#define LOG_TAG "PAL: AudioHapticsInterface"
|
||||
#define HAPTICS_XML_FILE "/vendor/etc/Hapticsconfig.xml"
|
||||
#include "rx_haptics_api.h"
|
||||
#include "wsa_haptics_vi_api.h"
|
||||
|
||||
std::shared_ptr<AudioHapticsInterface> AudioHapticsInterface::me_ = nullptr;
|
||||
std::vector<haptics_wave_designer_config_t> AudioHapticsInterface::compose_haptics_info;
|
||||
std::vector<haptics_wave_designer_config_t> AudioHapticsInterface::predefined_haptics_info;
|
||||
std::vector<haptics_wave_designer_config_t> AudioHapticsInterface::oneshot_haptics_info;
|
||||
int AudioHapticsInterface::ringtone_haptics_wave_design_mode;
|
||||
|
||||
AudioHapticsInterface::AudioHapticsInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AudioHapticsInterface::~AudioHapticsInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<AudioHapticsInterface> AudioHapticsInterface::GetInstance()
|
||||
{
|
||||
if (!me_)
|
||||
me_ = std::shared_ptr<AudioHapticsInterface>(new AudioHapticsInterface);
|
||||
return me_;
|
||||
}
|
||||
|
||||
int AudioHapticsInterface::init()
|
||||
{
|
||||
int ret = 0;
|
||||
int bytes_read;
|
||||
predefined_haptics_info.clear();
|
||||
oneshot_haptics_info.clear();
|
||||
|
||||
ret = AudioHapticsInterface::XmlParser(HAPTICS_XML_FILE);
|
||||
if (ret) {
|
||||
PAL_ERR(LOG_TAG, "error in haptics xml parsing ret %d", ret);
|
||||
throw std::runtime_error("error in haptics xml parsing");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::startTag(void *userdata, const XML_Char *tag_name,
|
||||
const XML_Char **attr)
|
||||
{
|
||||
struct haptics_xml_data *data = ( struct haptics_xml_data *)userdata;
|
||||
resetDataBuf(data);
|
||||
if (!strcmp(tag_name, "haptics_param_values")) {
|
||||
data->hapticstag = TAG_HAPTICSCNFGXML_ROOT;
|
||||
} else if (!strcmp(tag_name, "predefined_effect")) {
|
||||
data->hapticstag = TAG_PREDEFINED_EFFECT;
|
||||
} else if (!strcmp(tag_name, "oneshot_effect")) {
|
||||
data->hapticstag = TAG_ONESHOT_EFFECT;
|
||||
} else if (!strcmp(tag_name, "ringtone_effect")) {
|
||||
data->hapticstag = TAG_RINGTONE_EFFECT;
|
||||
} else if (!strcmp(tag_name, "compose_effect")) {
|
||||
data->hapticstag = TAG_COMPOSE_EFFECT;
|
||||
} else {
|
||||
PAL_INFO(LOG_TAG, "No matching Tag found");
|
||||
}
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::endTag(void *userdata, const XML_Char *tag_name)
|
||||
{
|
||||
struct haptics_xml_data *data = ( struct haptics_xml_data *)userdata;
|
||||
int size = -1;
|
||||
|
||||
process_haptics_info(data, tag_name);
|
||||
resetDataBuf(data);
|
||||
return;
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::resetDataBuf(struct haptics_xml_data *data)
|
||||
{
|
||||
data->offs = 0;
|
||||
data->data_buf[data->offs] = '\0';
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::handleData(void *userdata, const char *s, int len)
|
||||
{
|
||||
struct haptics_xml_data *data = (struct haptics_xml_data *)userdata;
|
||||
if (len + data->offs >= sizeof(data->data_buf) ) {
|
||||
data->offs += len;
|
||||
/* string length overflow, return */
|
||||
return;
|
||||
} else {
|
||||
memcpy(data->data_buf + data->offs, s, len);
|
||||
data->offs += len;
|
||||
}
|
||||
}
|
||||
|
||||
int AudioHapticsInterface::XmlParser(std::string xmlFile) {
|
||||
XML_Parser parser;
|
||||
FILE *file = NULL;
|
||||
int ret = 0;
|
||||
int bytes_read;
|
||||
void *buf = NULL;
|
||||
struct haptics_xml_data data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
PAL_INFO(LOG_TAG, "XML parsing started %s", xmlFile.c_str());
|
||||
file = fopen(xmlFile.c_str(), "r");
|
||||
if (!file) {
|
||||
PAL_ERR(LOG_TAG, "Failed to open xml");
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
parser = XML_ParserCreate(NULL);
|
||||
if (!parser) {
|
||||
PAL_ERR(LOG_TAG, "Failed to create XML");
|
||||
goto closeFile;
|
||||
}
|
||||
XML_SetUserData(parser,&data);
|
||||
XML_SetElementHandler(parser, startTag, endTag);
|
||||
XML_SetCharacterDataHandler(parser, handleData);
|
||||
|
||||
while (1) {
|
||||
buf = XML_GetBuffer(parser, 1024);
|
||||
if (buf == NULL) {
|
||||
PAL_ERR(LOG_TAG, "XML_Getbuffer failed");
|
||||
ret = -EINVAL;
|
||||
goto freeParser;
|
||||
}
|
||||
|
||||
bytes_read = fread(buf, 1, 1024, file);
|
||||
if (bytes_read < 0) {
|
||||
PAL_ERR(LOG_TAG, "fread failed");
|
||||
ret = -EINVAL;
|
||||
goto freeParser;
|
||||
}
|
||||
|
||||
if (XML_ParseBuffer(parser, bytes_read, bytes_read == 0) == XML_STATUS_ERROR) {
|
||||
PAL_ERR(LOG_TAG, "XML ParseBuffer failed ");
|
||||
ret = -EINVAL;
|
||||
goto freeParser;
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
freeParser:
|
||||
XML_ParserFree(parser);
|
||||
closeFile:
|
||||
fclose(file);
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::process_haptics_info(struct haptics_xml_data *data,
|
||||
const XML_Char *tag_name)
|
||||
{
|
||||
int size = 0;
|
||||
struct haptics_wave_designer_config_t HapticsCnfg = {};
|
||||
|
||||
if (data->hapticstag == TAG_PREDEFINED_EFFECT) {
|
||||
if (!strcmp(tag_name, "num_channels")) {
|
||||
HapticsCnfg.num_channels = atoi(data->data_buf);
|
||||
predefined_haptics_info.push_back(HapticsCnfg);
|
||||
} else if (!strcmp(tag_name, "channel_mask")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].channel_mask = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "wave_design_mode")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].wave_design_mode = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "auto_overdrive_brake_en")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].auto_overdrive_brake_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "f0_tracking_en")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].f0_tracking_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "f0_tracking_param_reset_flag")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].f0_tracking_param_reset_flag = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "override_flag")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].override_flag = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "tracked_freq_warmup_time_ms")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].tracked_freq_warmup_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "settling_time_ms")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].settling_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "delay_time_ms")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].delay_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "wavegen_fstart_hz_q20")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].wavegen_fstart_hz_q20 = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "repetition_count")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].repetition_count = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "repetition_period_ms")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].repetition_period_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pilot_tone_en")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].pilot_tone_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "low_pulse_intensity")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].low_pulse_intensity = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "mid_pulse_intensity")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].mid_pulse_intensity = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "high_pulse_intensity")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].high_pulse_intensity = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pulse_width_ms")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].pulse_width_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pulse_sharpness")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].pulse_sharpness = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "num_pwl")) {
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].num_pwl = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pwl_time")) {
|
||||
int j = 0;
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].pwl_time = (int32_t *) calloc(predefined_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i=0; i<predefined_haptics_info[size].num_pwl ;i++) {
|
||||
predefined_haptics_info[size].pwl_time[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwltime :%d", predefined_haptics_info[size].pwl_time[i]);
|
||||
for (; j<strlen(data->data_buf) ;j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(tag_name, "pwl_acc")) {
|
||||
int j = 0;
|
||||
size = predefined_haptics_info.size() - 1;
|
||||
predefined_haptics_info[size].pwl_acc = (int32_t *) calloc(predefined_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i=0; i<predefined_haptics_info[size].num_pwl ;i++) {
|
||||
predefined_haptics_info[size].pwl_acc[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwlacc :%d", predefined_haptics_info[size].pwl_acc[i]);
|
||||
for (; j<strlen(data->data_buf) ;j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->hapticstag == TAG_COMPOSE_EFFECT) {
|
||||
if (!strcmp(tag_name, "num_channels")) {
|
||||
HapticsCnfg.num_channels = atoi(data->data_buf);
|
||||
compose_haptics_info.push_back(HapticsCnfg);
|
||||
}
|
||||
else if (!strcmp(tag_name, "channel_mask")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].channel_mask = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "wave_design_mode")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].wave_design_mode = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "auto_overdrive_brake_en")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].auto_overdrive_brake_en = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "f0_tracking_en")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].f0_tracking_en = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "f0_tracking_param_reset_flag")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].f0_tracking_param_reset_flag = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "override_flag")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].override_flag = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "tracked_freq_warmup_time_ms")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].tracked_freq_warmup_time_ms = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "settling_time_ms")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].settling_time_ms = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "delay_time_ms")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].delay_time_ms = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "wavegen_fstart_hz_q20")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].wavegen_fstart_hz_q20 = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "repetition_count")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].repetition_count = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "repetition_period_ms")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].repetition_period_ms = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "pilot_tone_en")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].pilot_tone_en = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "low_pulse_intensity")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].low_pulse_intensity = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "mid_pulse_intensity")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].mid_pulse_intensity = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "high_pulse_intensity")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].high_pulse_intensity = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "pulse_width_ms")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].pulse_width_ms = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "pulse_sharpness")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].pulse_sharpness = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "num_pwl")) {
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].num_pwl = atoi(data->data_buf);
|
||||
}
|
||||
else if (!strcmp(tag_name, "pwl_time")) {
|
||||
int j = 0;
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].pwl_time = (int32_t*)calloc(compose_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i = 0; i < compose_haptics_info[size].num_pwl; i++) {
|
||||
compose_haptics_info[size].pwl_time[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwltime :%d", compose_haptics_info[size].pwl_time[i]);
|
||||
for (; j < strlen(data->data_buf); j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(tag_name, "pwl_acc")) {
|
||||
int j = 0;
|
||||
size = compose_haptics_info.size() - 1;
|
||||
compose_haptics_info[size].pwl_acc = (int32_t*)calloc(compose_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i = 0; i < compose_haptics_info[size].num_pwl; i++) {
|
||||
compose_haptics_info[size].pwl_acc[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwlacc :%d", compose_haptics_info[size].pwl_acc[i]);
|
||||
for (; j < strlen(data->data_buf); j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->hapticstag == TAG_ONESHOT_EFFECT) {
|
||||
if (!strcmp(tag_name, "num_channels")) {
|
||||
HapticsCnfg.num_channels = atoi(data->data_buf);
|
||||
oneshot_haptics_info.push_back(HapticsCnfg);
|
||||
} else if (!strcmp(tag_name, "channel_mask")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].channel_mask = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "wave_design_mode")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].wave_design_mode = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "auto_overdrive_brake_en")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].auto_overdrive_brake_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "f0_tracking_en")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].f0_tracking_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "f0_tracking_param_reset_flag")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].f0_tracking_param_reset_flag = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "override_flag")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].override_flag = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "wavegen_fstart_hz_q20")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].wavegen_fstart_hz_q20 = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "tracked_freq_warmup_time_ms")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].tracked_freq_warmup_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "settling_time_ms")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].settling_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "delay_time_ms")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].delay_time_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "repetition_count")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].repetition_count = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "repetition_period_ms")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].repetition_period_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pilot_tone_en")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].pilot_tone_en = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "low_pulse_intensity")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].low_pulse_intensity = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pulse_width_ms")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].pulse_width_ms = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pulse_sharpness")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].pulse_sharpness = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "num_pwl")) {
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].num_pwl = atoi(data->data_buf);
|
||||
} else if (!strcmp(tag_name, "pwl_time")) {
|
||||
int j = 0;
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].pwl_time = (int32_t *) calloc(oneshot_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i=0; i < oneshot_haptics_info[size].num_pwl ;i++) {
|
||||
oneshot_haptics_info[size].pwl_time[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwltime :%d", oneshot_haptics_info[size].pwl_time[i]);
|
||||
for (; j<strlen(data->data_buf) ;j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(tag_name, "pwl_acc")) {
|
||||
int j = 0;
|
||||
size = oneshot_haptics_info.size() - 1;
|
||||
oneshot_haptics_info[size].pwl_acc = (int32_t *) calloc(oneshot_haptics_info[size].num_pwl,
|
||||
sizeof(int32_t));
|
||||
for (int i=0; i < oneshot_haptics_info[size].num_pwl ;i++) {
|
||||
oneshot_haptics_info[size].pwl_acc[i] = atoi(&data->data_buf[j]);
|
||||
PAL_DBG(LOG_TAG, "pwlacc :%d", oneshot_haptics_info[size].pwl_acc[i]);
|
||||
for (; j<strlen(data->data_buf) ;j++) {
|
||||
if (data->data_buf[j] == ',') {
|
||||
j = j+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->hapticstag == TAG_RINGTONE_EFFECT) {
|
||||
if (!strcmp(tag_name, "wave_design_mode")) {
|
||||
ringtone_haptics_wave_design_mode = atoi(data->data_buf);
|
||||
}
|
||||
}
|
||||
PAL_ERR(LOG_TAG, "%s \n", data->data_buf);
|
||||
}
|
||||
|
||||
void AudioHapticsInterface::getTouchHapticsEffectConfiguration(int effect_id, bool isCompose, haptics_wave_designer_config_t **HConfig)
|
||||
{
|
||||
if (effect_id >= 0) {
|
||||
if (*HConfig == NULL) {
|
||||
if (isCompose) {
|
||||
*HConfig = (haptics_wave_designer_config_t*)calloc(1, sizeof(compose_haptics_info[effect_id]));
|
||||
if (*HConfig)
|
||||
memcpy(*HConfig, &compose_haptics_info[effect_id],
|
||||
sizeof(compose_haptics_info[effect_id]));
|
||||
} else {
|
||||
*HConfig = (haptics_wave_designer_config_t*)calloc(1, sizeof(predefined_haptics_info[effect_id]));
|
||||
if (*HConfig)
|
||||
memcpy(*HConfig, &predefined_haptics_info[effect_id],
|
||||
sizeof(predefined_haptics_info[effect_id]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (*HConfig == NULL) {
|
||||
*HConfig = (haptics_wave_designer_config_t *) calloc(1, sizeof(oneshot_haptics_info[0]));
|
||||
if (*HConfig)
|
||||
memcpy(*HConfig, &oneshot_haptics_info[0],
|
||||
sizeof(oneshot_haptics_info[0]));
|
||||
}
|
||||
}
|
||||
PAL_DBG(LOG_TAG, "getTouchHapticsEffectConfiguration exit\n");
|
||||
}
|
||||
490
qcom/opensource/pal/utils/src/ChargerListener.cpp
Normal file
490
qcom/opensource/pal/utils/src/ChargerListener.cpp
Normal file
@@ -0,0 +1,490 @@
|
||||
/*
|
||||
* Copyright (C) 2015, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a contribution.
|
||||
*
|
||||
* Copyright (C) 2011, 2017 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.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following
|
||||
* license:
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted (subject to the limitations in the
|
||||
* disclaimer below) provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of Qualcomm Innovation Center, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
||||
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <log/log.h>
|
||||
#include <cutils/uevent.h>
|
||||
#include "ChargerListener.h"
|
||||
|
||||
#define N_OF_EVNT_REG 2
|
||||
#define MAX_BUFFER_LEN 16
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
#define UEVENT_SOCKET_RCVBUF_SIZE 64 * 1024
|
||||
#define SET_BOOST_CONCURRENT_BIT "1"
|
||||
#define RESET_BOOST_CONCURRENT_BIT "0"
|
||||
#define CHARGER_STATE_BUFF_MAX_LEN 2
|
||||
#define CHARGING_STATUS_BUFF_MAX_LEN 16
|
||||
#define CHARGER_PRESENCE_PATH "/sys/class/power_supply/usb/present"
|
||||
#define CHARGING_STATUS_PATH "/sys/class/power_supply/battery/status"
|
||||
#define BOOST_CONCURRENT_PATH "/sys/class/qcom-smb/boost_concurrent_mode"
|
||||
|
||||
int ChargerListenerImpl::readSysfsPath(const char *path, int flag, int length,
|
||||
char *state)
|
||||
{
|
||||
int fd = -1, ret = -EINVAL;
|
||||
ssize_t bytes;
|
||||
|
||||
if (!path || !state)
|
||||
goto exit;
|
||||
|
||||
fd = ::open(path, flag);
|
||||
if (fd == -1) {
|
||||
ALOGE("%s %d, Failed to open fd in read mode: %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
goto exit;
|
||||
}
|
||||
bytes = read(fd, state, length);
|
||||
if (bytes <= 0) {
|
||||
ALOGD("%s %d, Failed to get current state", __func__, __LINE__);
|
||||
} else {
|
||||
state[(bytes/(sizeof(char))) - 1] = '\0';
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (ret && state)
|
||||
state[0] = '\0';
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ChargerListenerImpl::getInitialStatus()
|
||||
{
|
||||
char state[MAX_BUFFER_LEN];
|
||||
int status = 0;
|
||||
int charger_state;
|
||||
bool concurrent_state;
|
||||
|
||||
if (!info) {
|
||||
return -EINVAL;
|
||||
} else {
|
||||
status = readSysfsPath(CHARGER_PRESENCE_PATH, O_RDONLY,
|
||||
CHARGER_STATE_BUFF_MAX_LEN, state);
|
||||
if (0 != status) {
|
||||
ALOGE("%s %d, Failed to get Initial state for charger_presence %d",
|
||||
__func__, __LINE__, status);
|
||||
return status;
|
||||
} else {
|
||||
if (!strncmp(state, "0", strlen(state)))
|
||||
charger_state = OFFLINE;
|
||||
else
|
||||
charger_state = ONLINE;
|
||||
|
||||
int status_bit = getConcurrentState();
|
||||
concurrent_state = (status_bit == 1) ? true : false;
|
||||
info->c_state = (charger_state_t)charger_state;
|
||||
mcb(CHARGER_EVENT, charger_state, concurrent_state);
|
||||
}
|
||||
// No callback registered for battery_status for now
|
||||
status = readSysfsPath(CHARGING_STATUS_PATH, O_RDONLY,
|
||||
CHARGING_STATUS_BUFF_MAX_LEN, state);
|
||||
|
||||
if (0 != status)
|
||||
ALOGE("%s %d, Failed to get Initial state for charging_status %d",
|
||||
__func__, __LINE__, status);
|
||||
// Not handling Error status for charging status.
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void ChargerListenerImpl::getStateUpdate(int type)
|
||||
{
|
||||
char state[MAX_BUFFER_LEN];
|
||||
bool concurrent_state;
|
||||
int charger_state, status = 0;
|
||||
|
||||
switch (type) {
|
||||
case CHARGER_EVENT:
|
||||
status = readSysfsPath(CHARGER_PRESENCE_PATH, O_RDONLY,
|
||||
CHARGER_STATE_BUFF_MAX_LEN, state);
|
||||
if (0 == status) {
|
||||
if (!strncmp(state, "0", strlen(state)))
|
||||
charger_state = OFFLINE;
|
||||
else
|
||||
charger_state = ONLINE;
|
||||
|
||||
if (info->c_state != charger_state) {
|
||||
ALOGD("%s %d, charger state change: %d from last state %d",
|
||||
__func__, __LINE__, charger_state, info->c_state);
|
||||
info->c_state = (charger_state_t)charger_state;
|
||||
int status_bit = getConcurrentState();
|
||||
concurrent_state = (status_bit == 1) ? true : false;
|
||||
mcb(CHARGER_EVENT, charger_state, concurrent_state);
|
||||
//TODO dispatcher_thread = std::thread (mcb, CHARGER_EVENT, charger_state, concurrent_state);
|
||||
//TODO dispatcher_thread.detach();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BATTERY_EVENT:
|
||||
readSysfsPath(CHARGING_STATUS_PATH, O_RDONLY,
|
||||
CHARGING_STATUS_BUFF_MAX_LEN, state);
|
||||
//Add cb to Process for battery event change.
|
||||
break;
|
||||
default :
|
||||
ALOGI("%s %d, Unknown event", __func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ChargerListenerImpl::readEvent(void *context, struct charger_info *info)
|
||||
{
|
||||
/* Max size allowed for UEVENT_MSG_LEN is 2048 */
|
||||
char msg_info [UEVENT_MSG_LEN];
|
||||
int size_rcv;
|
||||
int uevent_type;
|
||||
|
||||
size_rcv = uevent_kernel_multicast_recv(info->uevent_fd,
|
||||
msg_info, sizeof(msg_info));
|
||||
/* underflow and overflow condition*/
|
||||
if (size_rcv <= 0 ||
|
||||
size_rcv >= sizeof(msg_info)) {
|
||||
ALOGE("%s %d, rcv size is not under size limit", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
msg_info[size_rcv] = '\0';
|
||||
|
||||
/* update specified uevent properties */
|
||||
if (strstr(msg_info, "battery"))
|
||||
uevent_type = BATTERY_EVENT;
|
||||
else if (strstr(msg_info, "usb"))
|
||||
uevent_type = CHARGER_EVENT;
|
||||
else
|
||||
uevent_type = UNKNOWN_EVENT;
|
||||
|
||||
/* Customize condition for other event*/
|
||||
if (uevent_type == CHARGER_EVENT)
|
||||
reinterpret_cast<ChargerListenerImpl*>(context)->getStateUpdate(uevent_type);
|
||||
}
|
||||
|
||||
int ChargerListenerImpl::addEvent(func_ptr event_fun, int event_type, int fd)
|
||||
{
|
||||
int status = 0;
|
||||
struct epoll_event reg_event;
|
||||
|
||||
ALOGD("%s %d, Enter :", __func__, __LINE__);
|
||||
|
||||
switch(event_type) {
|
||||
case PIPE_EVENT:
|
||||
reg_event.data.fd = fd;
|
||||
reg_event.events = EPOLLIN | EPOLLWAKEUP;
|
||||
|
||||
if (epoll_ctl(info->epoll_fd, EPOLL_CTL_ADD, fd, ®_event) == -1) {
|
||||
ALOGE("%s %d, Failed to add non uevent :%s\n", __func__,
|
||||
__LINE__, strerror(errno));
|
||||
status = -errno;
|
||||
} else {
|
||||
info->event_count++;
|
||||
}
|
||||
break;
|
||||
case U_EVENT:
|
||||
reg_event.data.ptr = (void *)event_fun;
|
||||
reg_event.events = EPOLLIN | EPOLLWAKEUP;
|
||||
|
||||
if (epoll_ctl(info->epoll_fd, EPOLL_CTL_ADD, fd, ®_event) == -1) {
|
||||
ALOGE("%s %d, Failed to add uevent :%s\n", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
status = -errno;
|
||||
} else {
|
||||
info->event_count++;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
ALOGI("%s %d, Unknown event", __func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
ALOGD("%s %d, Exit status %d", __func__, __LINE__, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
int ChargerListenerImpl::initEvent()
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
ALOGD("%s %d, Enter ", __func__, __LINE__);
|
||||
|
||||
pipe_status = pipe(intPipe);
|
||||
|
||||
if (pipe_status < 0) {
|
||||
ALOGE("%s %d, Failed to open_pipe: %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
status = -errno;
|
||||
goto exit;
|
||||
}
|
||||
/* Adding pipe Event in Interested List to unblock epoll thread*/
|
||||
fcntl(intPipe[0], F_SETFL, O_NONBLOCK);
|
||||
status = addEvent(ChargerListenerImpl::readEvent, PIPE_EVENT, intPipe[0]);
|
||||
if (status < 0) {
|
||||
ALOGE("%s %d, Failed to add pipe event: %d", __func__, __LINE__, errno);
|
||||
goto close_pipe;
|
||||
}
|
||||
|
||||
info->uevent_fd = uevent_open_socket(UEVENT_SOCKET_RCVBUF_SIZE, true);
|
||||
|
||||
if (info->uevent_fd < 0) {
|
||||
ALOGE("%s %d, Failed to open_uevent_socket: %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
status = -errno;
|
||||
goto close_pipe;
|
||||
}
|
||||
/* Adding U-Event Event in Interested List */
|
||||
fcntl(info->uevent_fd, F_SETFL, O_NONBLOCK);
|
||||
status = addEvent(ChargerListenerImpl::readEvent, U_EVENT, info->uevent_fd);
|
||||
if (status < 0) {
|
||||
ALOGE("%s %d, Failed to add U-Event: %d", __func__, __LINE__, errno);
|
||||
goto close_uevent;
|
||||
}
|
||||
goto exit;
|
||||
|
||||
close_uevent:
|
||||
if (info->uevent_fd) {
|
||||
close(info->uevent_fd);
|
||||
info->uevent_fd = 0;
|
||||
}
|
||||
close_pipe:
|
||||
if (intPipe[0]) {
|
||||
close(intPipe[0]);
|
||||
intPipe[0] = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
ALOGD("%s %d, Exit status %d", __func__, __LINE__, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
void ChargerListenerImpl::chargerMonitor()
|
||||
{
|
||||
func_ptr event_cb = NULL;
|
||||
/**
|
||||
*Initialise buf with "P" to continue poll unless set as "Q" to unblock
|
||||
*charger monitor thread when rm deinit happen.
|
||||
**/
|
||||
char buf[2] = "P";
|
||||
|
||||
ALOGD("%s %d, Enter chargerMonitor", __func__, __LINE__);
|
||||
|
||||
while (1) {
|
||||
int no_events = epoll_wait(info->epoll_fd, info->events,
|
||||
info->event_count, -1);
|
||||
if (no_events == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ALOGE("%s %d, epoll_wait failed: %d", __func__,
|
||||
__LINE__, errno);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < no_events; ++i) {
|
||||
/* Unblock Polling Thread */
|
||||
if (info->events[i].data.fd && info->events[i].data.fd == intPipe[0]) {
|
||||
read(info->events[i].data.fd, buf, 1);
|
||||
if (!strncmp(buf, "Q", strlen(buf)))
|
||||
return;
|
||||
} else {
|
||||
event_cb = (func_ptr)info->events[i].data.ptr;
|
||||
event_cb(this, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
ALOGD("%s %d, Exit : ChargerMonitor is unblocked from poll", __func__, __LINE__);
|
||||
}
|
||||
|
||||
void ChargerListenerImpl::CLImplInit()
|
||||
{
|
||||
/* Create poll fd */
|
||||
info->epoll_fd = epoll_create(MAX_EVENTS);
|
||||
if (info->epoll_fd == -1) {
|
||||
ALOGE("%s %d, Failed to epoll_create: %s\n", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
/* Init for uevent */
|
||||
if (initEvent() < 0) {
|
||||
ALOGE("%s %d, Failed to init uevent: %s\n", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
goto close_epoll_fd;
|
||||
}
|
||||
/* Initial state is setup for all event */
|
||||
if (getInitialStatus() < 0) {
|
||||
ALOGE("%s %d, Failed to determine init status: %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
goto close_epoll_fd;
|
||||
}
|
||||
|
||||
ALOGI("%s %d, Charger Listener Impl init is successful", __func__, __LINE__);
|
||||
|
||||
poll_thread = std::thread (&ChargerListenerImpl::chargerMonitor, this);
|
||||
goto exit;
|
||||
|
||||
close_epoll_fd:
|
||||
if (info->epoll_fd) {
|
||||
close(info->epoll_fd);
|
||||
info->epoll_fd = 0;
|
||||
}
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
int ChargerListenerImpl::getConcurrentState()
|
||||
{
|
||||
int status_bit = -EINVAL;
|
||||
char state[22];
|
||||
|
||||
mlock.lock();
|
||||
if (0 != readSysfsPath(BOOST_CONCURRENT_PATH, O_RDONLY, 2, state)) {
|
||||
ALOGE("%s %d, read Concurrency bit failed %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
} else {
|
||||
sscanf(state, "%d", &status_bit);
|
||||
}
|
||||
mlock.unlock();
|
||||
return status_bit;
|
||||
}
|
||||
|
||||
int ChargerListenerImpl::setConcurrentState(bool is_boost_enable)
|
||||
{
|
||||
int intfd;
|
||||
int status = 0;
|
||||
int status_bit;
|
||||
|
||||
mlock.lock();
|
||||
intfd = ::open(BOOST_CONCURRENT_PATH, O_WRONLY);
|
||||
if (intfd == -1) {
|
||||
ALOGE("%s %d, Failed to open sysnode: %s", __func__,
|
||||
__LINE__, strerror(errno));
|
||||
status = -errno;
|
||||
} else {
|
||||
if (is_boost_enable)
|
||||
status_bit = write(intfd, SET_BOOST_CONCURRENT_BIT, 1);
|
||||
else
|
||||
status_bit = write(intfd, RESET_BOOST_CONCURRENT_BIT, 1);
|
||||
|
||||
if (status_bit == -1) {
|
||||
ALOGE("%s %d, failed to Write concurrency bit: %s ", __func__,
|
||||
__LINE__, strerror(errno));
|
||||
status = -errno;
|
||||
} else {
|
||||
ALOGD("%s %d, Success on setting charger + boost concurr. bit %d", __func__,
|
||||
__LINE__, is_boost_enable);
|
||||
}
|
||||
|
||||
close(intfd);
|
||||
}
|
||||
mlock.unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
ChargerListenerImpl::ChargerListenerImpl(cb_fn_t cb) :
|
||||
mcb(cb)
|
||||
{
|
||||
info = (struct charger_info *)calloc(sizeof(struct charger_info), 1);
|
||||
if (!info) {
|
||||
ALOGE("%s %d, Calloc failed for charger_info %s", __func__, __LINE__,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
CLImplInit();
|
||||
|
||||
}
|
||||
|
||||
ChargerListenerImpl *chargerListener = NULL;
|
||||
ChargerListenerImpl::~ChargerListenerImpl()
|
||||
{ /*TODO
|
||||
if (dispatcher_thread.joinable())
|
||||
dispatcher_thread.join();
|
||||
*/
|
||||
if (0 == pipe_status) {
|
||||
write(intPipe[1], "Q", 1);
|
||||
if (poll_thread.joinable()) {
|
||||
poll_thread.join();
|
||||
}
|
||||
if (intPipe[0])
|
||||
close(intPipe[0]);
|
||||
if (intPipe[1])
|
||||
close(intPipe[1]);
|
||||
}
|
||||
//Deallocating charger info
|
||||
if (info) {
|
||||
if (info->epoll_fd)
|
||||
close(info->epoll_fd);
|
||||
if (info->uevent_fd)
|
||||
close(info->uevent_fd);
|
||||
free(info);
|
||||
info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void chargerPropertiesListenerInit(charger_status_change_fn_t fn)
|
||||
{
|
||||
chargerListener = new ChargerListenerImpl(fn);
|
||||
}
|
||||
|
||||
void chargerPropertiesListenerDeinit()
|
||||
{
|
||||
delete chargerListener;
|
||||
}
|
||||
|
||||
int chargerPropertiesListenerSetBoostState(bool is_boost_enable)
|
||||
{
|
||||
return(chargerListener->setConcurrentState(is_boost_enable));
|
||||
}
|
||||
} // extern C
|
||||
127
qcom/opensource/pal/utils/src/MemLogBuilder.cpp
Normal file
127
qcom/opensource/pal/utils/src/MemLogBuilder.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "MemLogBuilder.h"
|
||||
#include "Device.h"
|
||||
#include <hwbinder/IPCThreadState.h>
|
||||
|
||||
#define LOG_TAG "PAL: memLoggerBuilder"
|
||||
|
||||
int palStateQueueBuilder(pal_state_queue &que, Stream *s, pal_state_queue_state state, int32_t error)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Entered PAL State Queue Builder");
|
||||
int ret = 0;
|
||||
std::vector <std::shared_ptr<Device>> aDevices;
|
||||
struct pal_stream_attributes sAttr;
|
||||
struct pal_device strDevAttr;
|
||||
pal_stream_type_t type;
|
||||
|
||||
if (!memLoggerIsQueueInitialized())
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "queues failed to initialize");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = s->getAssociatedDevices(aDevices);
|
||||
if(ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "getStreamType failed with status = %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = s->getStreamType(&type);
|
||||
if(ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "getStreamType failed with status = %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(&que, 0, sizeof(que));
|
||||
s->getStreamAttributes(&sAttr);
|
||||
que.stream_handle = (uint64_t) s; // array to store queue element
|
||||
que.stream_type = type;
|
||||
que.direction = sAttr.direction;
|
||||
que.state = state;
|
||||
que.error = error;
|
||||
|
||||
PAL_DBG(LOG_TAG, "Stream handle = " "%" PRId64 "\n", s);
|
||||
|
||||
memset(que.device_attr, 0, sizeof(que.device_attr));
|
||||
|
||||
for(int i=0; i<aDevices.size(); i++)
|
||||
{
|
||||
if(i < STATE_DEVICE_MAX_SIZE)
|
||||
{
|
||||
aDevices[i]->getDeviceAttributes(&strDevAttr, s);
|
||||
que.device_attr[i].device = strDevAttr.id;
|
||||
que.device_attr[i].sample_rate = strDevAttr.config.sample_rate;
|
||||
que.device_attr[i].bit_width = strDevAttr.config.bit_width;
|
||||
que.device_attr[i].channels = strDevAttr.config.ch_info.channels;
|
||||
}
|
||||
}
|
||||
|
||||
que.timestamp = memLoggerFetchTimestamp();
|
||||
|
||||
PAL_DBG(LOG_TAG, "TIME IS:" "%" PRId64 "\n", que.timestamp);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int palStateEnqueue(Stream *s, pal_state_queue_state state, int32_t error)
|
||||
{
|
||||
int ret = 0;
|
||||
struct pal_state_queue que;
|
||||
ret = palStateQueueBuilder(que, s, state, error);
|
||||
if (ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "palStateQueueBuilder failed with status = %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = memLoggerEnqueue(PAL_STATE_Q, (void*) &que);
|
||||
if (ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "memLoggerEnqueue failed with status = %d", ret);
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int palStateEnqueue(Stream *s, pal_state_queue_state state, int32_t error, pal_mlog_str_info str_info)
|
||||
{
|
||||
int ret = 0;
|
||||
struct pal_state_queue que;
|
||||
ret = palStateQueueBuilder(que, s, state, error);
|
||||
if (ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "palStateQueueBuilder failed with status = %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
memcpy(&(que.str_info), &str_info, sizeof(que.str_info));
|
||||
|
||||
ret = memLoggerEnqueue(PAL_STATE_Q, (void*) &que);
|
||||
if (ret != 0)
|
||||
{
|
||||
PAL_ERR(LOG_TAG, "memLoggerEnqueue failed with status = %d", ret);
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kpiEnqueue(const char name[], bool isEnter)
|
||||
{
|
||||
struct kpi_queue que;
|
||||
|
||||
strlcpy(que.func_name, name, sizeof(que.func_name));
|
||||
que.pid = ::android::hardware::IPCThreadState::self()->getCallingPid();
|
||||
que.timestamp = memLoggerFetchTimestamp();
|
||||
que.type = isEnter;
|
||||
|
||||
memLoggerEnqueue(KPI_Q, (void*) &que);
|
||||
}
|
||||
189
qcom/opensource/pal/utils/src/MetadataParser.cpp
Normal file
189
qcom/opensource/pal/utils/src/MetadataParser.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#define LOG_TAG "PAL: MetadataParser"
|
||||
|
||||
#include <string>
|
||||
#include <log/log.h>
|
||||
#include <unistd.h>
|
||||
#include "PalDefs.h"
|
||||
#include "MetadataParser.h"
|
||||
|
||||
int MetadataParser::parseMetadata(uint8_t* metadata, size_t metadataSize,
|
||||
pal_clbk_buffer_info *bufferInfo) {
|
||||
size_t mdBytesRead = 0;
|
||||
|
||||
if (!metadata || metadataSize < std::min(START_METADATA_SIZE(), END_METADATA_SIZE())) {
|
||||
//TODO: may not work for multiple frames/buffer
|
||||
ALOGE("%s: Metadata payload smaller than expected, bytes 0x%x, expected 0x%x",
|
||||
__func__, mdBytesRead, std::min(START_METADATA_SIZE(), END_METADATA_SIZE()));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (mdBytesRead < metadataSize) {
|
||||
metadata_header_t* metadataItem =
|
||||
reinterpret_cast<metadata_header_t*>(metadata + mdBytesRead);
|
||||
if (!metadataItem) {
|
||||
return 0;
|
||||
}
|
||||
mdBytesRead += sizeof(metadata_header_t);
|
||||
|
||||
switch (metadataItem->metadata_id) {
|
||||
//TODO: check if 2 start metadata/2 end metadata is present
|
||||
case MODULE_CMN_MD_ID_BUFFER_START: {
|
||||
size_t startMetadataPayloadSize = metadataItem->payload_size;
|
||||
if (mdBytesRead + startMetadataPayloadSize > metadataSize) {
|
||||
ALOGE("%s: Metadata item payload size larger than advertized metadata size"
|
||||
" metadata id 0x%x, mdBytesRead = 0x%x, item payload size 0x%x,"
|
||||
" metadata size = 0x%x ", __func__, metadataItem->metadata_id,
|
||||
mdBytesRead, startMetadataPayloadSize, metadataSize);
|
||||
return -EINVAL;
|
||||
}
|
||||
module_cmn_md_buffer_start_t* startMetadata =
|
||||
reinterpret_cast<module_cmn_md_buffer_start_t*>(metadata + mdBytesRead);
|
||||
if (!startMetadata) {
|
||||
ALOGE("%s: Metadata start payload not found at offset 0x%x",
|
||||
__func__, mdBytesRead);
|
||||
return -EINVAL;
|
||||
}
|
||||
bufferInfo->frame_index = static_cast<uint64_t>((static_cast<uint64_t>(
|
||||
startMetadata->buffer_index_msw) << 32) | startMetadata->buffer_index_lsw);
|
||||
ALOGV("%s: startMetadata frame_index %llu", __func__, bufferInfo->frame_index);
|
||||
mdBytesRead += sizeof(module_cmn_md_buffer_start_t);
|
||||
break;
|
||||
}
|
||||
case MODULE_CMN_MD_ID_BUFFER_END: {
|
||||
size_t endMetadataPayloadSize = metadataItem->payload_size;
|
||||
if (mdBytesRead + endMetadataPayloadSize > metadataSize) {
|
||||
ALOGE("%s: Metadata item payload size larger than advertized metadata size,"
|
||||
" metadata id 0x%x, mdBytesRead = 0x%x, item payload size 0x%x,"
|
||||
" metadata size = 0x%x ", __func__, metadataItem->metadata_id,
|
||||
mdBytesRead, endMetadataPayloadSize, static_cast<uint32_t>(metadataSize));
|
||||
return -EINVAL;
|
||||
}
|
||||
module_cmn_md_buffer_end_t* endMetadata =
|
||||
reinterpret_cast<module_cmn_md_buffer_end_t*>(metadata + mdBytesRead);
|
||||
if (!endMetadata) {
|
||||
ALOGE("%s: Metadata end payload not found at offset 0x%x",
|
||||
__func__, mdBytesRead);
|
||||
return -EINVAL;
|
||||
}
|
||||
// TODO: compare previous input buffer index from start metadata,
|
||||
// treat different values as error
|
||||
bufferInfo->frame_index = static_cast<uint64_t>((static_cast<uint64_t>(
|
||||
endMetadata->buffer_index_msw) << 32) | endMetadata->buffer_index_lsw);
|
||||
|
||||
if (endMetadata->flags) {
|
||||
ALOGV("%s: End Metdata Flags=0x%x", __func__, endMetadata->flags);
|
||||
if (((endMetadata->flags & MD_END_PAYLOAD_FLAGS_BIT_MASK_ERROR_RECOVERY_DONE)
|
||||
>> MD_END_PAYLOAD_FLAGS_SHIFT_ERROR_RECOVERY_DONE)
|
||||
== MD_END_RESULT_ERROR_RECOVERY_DONE ) {
|
||||
ALOGI("%s: Error detected in input buffer and recovery attempted", __func__);
|
||||
} else if ( ((endMetadata->flags & MD_END_PAYLOAD_FLAGS_BIT_MASK_ERROR_RESULT)
|
||||
>> MD_END_PAYLOAD_FLAGS_SHIFT_ERROR_RESULT) == MD_END_RESULT_FAILED ) {
|
||||
ALOGI("%s: Non-recoverable error detected in input buffer", __func__);
|
||||
}
|
||||
}
|
||||
mdBytesRead += sizeof(module_cmn_md_buffer_end_t);
|
||||
break;
|
||||
}
|
||||
case MODULE_CMN_MD_ID_MEDIA_FORMAT: {
|
||||
size_t mfMetadataPayloadSize = metadataItem->payload_size;
|
||||
if (mdBytesRead + mfMetadataPayloadSize > metadataSize){
|
||||
ALOGE("%s: Metadata item payload size larger than advertized metadata size,"
|
||||
" metadata id 0x%x, mdBytesRead = 0x%x, item payload size 0x%x,"
|
||||
" metadata size = 0x%x ", __func__, metadataItem->metadata_id,
|
||||
mdBytesRead, mfMetadataPayloadSize, metadataSize);
|
||||
return -EINVAL;
|
||||
}
|
||||
media_format_t* mfPayload =
|
||||
reinterpret_cast<media_format_t*>(metadata + mdBytesRead);
|
||||
mdBytesRead += sizeof(media_format_t);
|
||||
|
||||
if (!mfPayload) {
|
||||
ALOGE("%s: Media metadata payload not found at offset 0x%x",
|
||||
__func__, mdBytesRead);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (mfPayload->fmt_id != MEDIA_FMT_ID_PCM) {
|
||||
ALOGE("%s: Format ID within Media metadata payload not PCM,"
|
||||
" fmt_id=x%x, offset=0x%x", __func__, mfPayload->fmt_id,
|
||||
(uint32_t)offsetof(media_format_t, fmt_id));
|
||||
return -EINVAL;
|
||||
}
|
||||
payload_media_fmt_pcm_t* pcmPayload =
|
||||
reinterpret_cast<payload_media_fmt_pcm_t*>(metadata + mdBytesRead);
|
||||
bufferInfo->sample_rate = pcmPayload->sample_rate;
|
||||
bufferInfo->channel_count = pcmPayload->num_channels;
|
||||
ALOGI("%s: sample_rate=%u, channel_count=%u", __func__,
|
||||
bufferInfo->sample_rate, bufferInfo->channel_count);
|
||||
mdBytesRead +=
|
||||
ALIGN(sizeof(payload_media_fmt_pcm_t) +
|
||||
pcmPayload->num_channels * sizeof(int8_t), 4);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ALOGE("%s: Unknown Metadata marker found at offset 0x%x, Metadata ID=0x%x",
|
||||
__func__, mdBytesRead, metadataItem->metadata_id);
|
||||
// increment bytes read
|
||||
mdBytesRead += metadataItem->payload_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ALOGV("%s: mdBytesRead=%zu, metadataSize=%zu", __func__, mdBytesRead, metadataSize);
|
||||
} // end while
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MetadataParser::fillMetaData(uint8_t *metadata,
|
||||
uint64_t frameIndex, size_t filledLength,
|
||||
pal_media_config *streamMediaConfig) {
|
||||
bool isEncode = false;
|
||||
|
||||
if (streamMediaConfig->aud_fmt_id == PAL_AUDIO_FMT_PCM_S8 ||
|
||||
streamMediaConfig->aud_fmt_id == PAL_AUDIO_FMT_PCM_S16_LE ||
|
||||
streamMediaConfig->aud_fmt_id == PAL_AUDIO_FMT_PCM_S24_LE ||
|
||||
streamMediaConfig->aud_fmt_id == PAL_AUDIO_FMT_PCM_S24_3LE ||
|
||||
streamMediaConfig->aud_fmt_id == PAL_AUDIO_FMT_PCM_S32_LE) {
|
||||
isEncode = true;
|
||||
}
|
||||
|
||||
auto getOffsetForEndMetadata = [&](uint32_t bufSize)
|
||||
{
|
||||
uint32_t sampleSizePerCh =
|
||||
BYTES_PER_SAMPLE(streamMediaConfig->bit_width) *
|
||||
streamMediaConfig->ch_info.channels;
|
||||
return (isEncode) ? (bufSize / sampleSizePerCh) : bufSize;
|
||||
};
|
||||
|
||||
// Fill start metadata
|
||||
metadata_header_t* startMetadata = reinterpret_cast<metadata_header_t*>(metadata);
|
||||
startMetadata->metadata_id = MODULE_CMN_MD_ID_BUFFER_START;
|
||||
startMetadata->flags = static_cast<uint32_t>(MD_HEADER_FLAGS_BUFFER_ASSOCIATED << 4);
|
||||
startMetadata->offset = 0;
|
||||
startMetadata->payload_size = sizeof(module_cmn_md_buffer_start_t);
|
||||
metadata += sizeof(metadata_header_t);
|
||||
module_cmn_md_buffer_start_t startMetadataPayload = {GET_LSW(frameIndex),
|
||||
GET_MSW(frameIndex)};
|
||||
memcpy(reinterpret_cast<void*>(metadata),
|
||||
reinterpret_cast<const void*>(&startMetadataPayload),
|
||||
sizeof(module_cmn_md_buffer_start_t));
|
||||
metadata += startMetadata->payload_size;
|
||||
|
||||
// Fill end metadata
|
||||
metadata_header_t* endMetadata = reinterpret_cast<metadata_header_t*>(metadata);
|
||||
endMetadata->metadata_id = MODULE_CMN_MD_ID_BUFFER_END;
|
||||
endMetadata->flags = static_cast<uint32_t>(MD_HEADER_FLAGS_BUFFER_ASSOCIATED << 4);
|
||||
endMetadata->offset = getOffsetForEndMetadata(filledLength);
|
||||
endMetadata->payload_size = sizeof(module_cmn_md_buffer_end_t);
|
||||
metadata += sizeof(metadata_header_t);
|
||||
module_cmn_md_buffer_end_t endMetadataPayload = {GET_LSW(frameIndex),
|
||||
GET_MSW(frameIndex),
|
||||
0};
|
||||
memcpy(reinterpret_cast<void*>(metadata),
|
||||
reinterpret_cast<const void*>(&endMetadataPayload),
|
||||
sizeof(module_cmn_md_buffer_end_t));
|
||||
}
|
||||
369
qcom/opensource/pal/utils/src/PalRingBuffer.cpp
Normal file
369
qcom/opensource/pal/utils/src/PalRingBuffer.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
*
|
||||
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#define LOG_TAG "PAL: PalRingBuffer"
|
||||
|
||||
#ifdef LINUX_ENABLED
|
||||
#include <algorithm>
|
||||
#endif
|
||||
#include "PalRingBuffer.h"
|
||||
#include "PalCommon.h"
|
||||
#include "StreamSoundTrigger.h"
|
||||
|
||||
int32_t PalRingBuffer::removeReader(PalRingBufferReader *reader)
|
||||
{
|
||||
auto iter = std::find(readers_.begin(), readers_.end(), reader);
|
||||
if (iter != readers_.end())
|
||||
readers_.erase(iter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t PalRingBuffer::read(std::shared_ptr<PalRingBufferReader>reader __unused,
|
||||
void* readBuffer __unused, size_t readSize __unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t PalRingBuffer::getFreeSize()
|
||||
{
|
||||
|
||||
size_t freeSize = bufferEnd_;
|
||||
std::vector<PalRingBufferReader*>::iterator it;
|
||||
|
||||
for (it = readers_.begin(); it != readers_.end(); it++) {
|
||||
if ((*(it))->state_ == READER_ENABLED)
|
||||
freeSize = std::min(freeSize, bufferEnd_ - (*(it))->unreadSize_);
|
||||
}
|
||||
return freeSize;
|
||||
}
|
||||
|
||||
void PalRingBuffer::updateUnReadSize(size_t writtenSize)
|
||||
{
|
||||
int32_t i = 0;
|
||||
std::vector<PalRingBufferReader*>::iterator it;
|
||||
|
||||
for (it = readers_.begin(); it != readers_.end(); it++, i++) {
|
||||
(*(it))->unreadSize_ += writtenSize;
|
||||
PAL_VERBOSE(LOG_TAG, "Reader (%d), unreadSize(%zu)", i, (*(it))->unreadSize_);
|
||||
|
||||
if ((*(it))->requestedSize_ > 0 &&
|
||||
(*(it))->unreadSize_ >= (*(it))->requestedSize_) {
|
||||
(*(it))->cv_.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PalRingBuffer::updateKwdConfig(Stream *s, uint32_t startIdx, uint32_t endIdx,
|
||||
uint32_t preRoll)
|
||||
{
|
||||
uint32_t sz = 0;
|
||||
struct kwdConfig kc;
|
||||
std::vector<PalRingBufferReader *> readers = dynamic_cast<StreamSoundTrigger *>(s)->GetReaders();
|
||||
|
||||
std::lock_guard<std::mutex> lck(mutex_);
|
||||
/*
|
||||
* If the buffer is shared across concurrent detections, the first keyword
|
||||
* offset is almost equal or close (depends on the max pre-roll in shared scenario)
|
||||
* to the begining of the buffer. For the subsequent keyword, it can be
|
||||
* far from the begining of the buffer relative to start of the keyword within
|
||||
* the buffer. Since the unreadSize_ of subsequent detections is linearly
|
||||
* increased from the first detection itself, adjust its starting from its
|
||||
* pre-roll position in the buffer.
|
||||
*/
|
||||
sz = startIdx >= preRoll ? startIdx - preRoll : 0;
|
||||
for (auto reader : readers) {
|
||||
if (reader->unreadSize_ > sz) {
|
||||
reader->unreadSize_ -= sz;
|
||||
PAL_DBG(LOG_TAG, "adjusted unread size %zu", reader->unreadSize_);
|
||||
}
|
||||
reader->unreadSize_ %= bufferEnd_;
|
||||
reader->readOffset_ = sz % bufferEnd_;
|
||||
}
|
||||
kc.startIdx = startIdx - sz;
|
||||
kc.endIdx = endIdx - sz;
|
||||
kc.ftrtSize = endIdx;
|
||||
kwCfg_[s] = kc;
|
||||
}
|
||||
|
||||
void PalRingBuffer::getIndices(Stream *s,
|
||||
uint32_t *startIdx, uint32_t *endIdx, uint32_t *ftrtSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(mutex_);
|
||||
*startIdx = kwCfg_[s].startIdx;
|
||||
*endIdx = kwCfg_[s].endIdx;
|
||||
*ftrtSize = kwCfg_[s].ftrtSize;
|
||||
}
|
||||
|
||||
size_t PalRingBuffer::write(void* writeBuffer, size_t writeSize)
|
||||
{
|
||||
/* update the unread size for each reader*/
|
||||
size_t freeSize = getFreeSize();
|
||||
size_t writtenSize = 0;
|
||||
size_t i = 0;
|
||||
size_t sizeToCopy = 0;
|
||||
|
||||
std::lock_guard<std::mutex> lck(mutex_);
|
||||
|
||||
#ifndef SEC_AUDIO_ADD_FOR_DEBUG
|
||||
PAL_DBG(LOG_TAG, "Enter. freeSize(%zu), writeOffset(%zu)", freeSize, writeOffset_);
|
||||
#endif
|
||||
|
||||
if (writeSize <= freeSize)
|
||||
sizeToCopy = writeSize;
|
||||
else
|
||||
sizeToCopy = freeSize;
|
||||
|
||||
if (sizeToCopy) {
|
||||
//buffer wrapped around
|
||||
if (writeOffset_ + sizeToCopy > bufferEnd_) {
|
||||
i = bufferEnd_ - writeOffset_;
|
||||
|
||||
ar_mem_cpy(buffer_ + writeOffset_, i, writeBuffer, i);
|
||||
writtenSize += i;
|
||||
sizeToCopy -= writtenSize;
|
||||
ar_mem_cpy(buffer_, sizeToCopy, (char*)writeBuffer + writtenSize,
|
||||
sizeToCopy);
|
||||
writtenSize += sizeToCopy;
|
||||
writeOffset_ = sizeToCopy;
|
||||
} else {
|
||||
ar_mem_cpy(buffer_ + writeOffset_, sizeToCopy, writeBuffer,
|
||||
sizeToCopy);
|
||||
writeOffset_ += sizeToCopy;
|
||||
writtenSize = sizeToCopy;
|
||||
}
|
||||
}
|
||||
updateUnReadSize(writtenSize);
|
||||
writeOffset_ = writeOffset_ % bufferEnd_;
|
||||
#ifndef SEC_AUDIO_ADD_FOR_DEBUG
|
||||
PAL_DBG(LOG_TAG, "Exit. writeOffset(%zu)", writeOffset_);
|
||||
#endif
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
void PalRingBuffer::reset()
|
||||
{
|
||||
std::vector<PalRingBufferReader*>::iterator it;
|
||||
|
||||
mutex_.lock();
|
||||
kwCfg_.clear();
|
||||
writeOffset_ = 0;
|
||||
mutex_.unlock();
|
||||
|
||||
/* Reset all the associated readers */
|
||||
for (it = readers_.begin(); it != readers_.end(); it++)
|
||||
(*(it))->reset();
|
||||
}
|
||||
|
||||
void PalRingBuffer::resizeRingBuffer(size_t bufferSize)
|
||||
{
|
||||
if (buffer_) {
|
||||
delete[] buffer_;
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
buffer_ = (char *)new char[bufferSize];
|
||||
bufferEnd_ = bufferSize;
|
||||
}
|
||||
|
||||
bool PalRingBufferReader::waitForBuffers(uint32_t buffer_size)
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(mutex_);
|
||||
if (state_ == READER_ENABLED) {
|
||||
if (unreadSize_ >= buffer_size)
|
||||
goto exit;
|
||||
requestedSize_ = buffer_size;
|
||||
cv_.wait_for(lck, std::chrono::milliseconds(3000));
|
||||
}
|
||||
|
||||
exit:
|
||||
requestedSize_ = 0;
|
||||
return unreadSize_ >= buffer_size;
|
||||
}
|
||||
|
||||
int32_t PalRingBufferReader::getKwData(Stream *s, uint8_t *data, uint32_t size)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
std::lock_guard<std::mutex> lck(ringBuffer_->mutex_);
|
||||
|
||||
// assume that we always have enough data after 2nd stage done
|
||||
if (readOffset_ + size > ringBuffer_->bufferEnd_) {
|
||||
offset = ringBuffer_->bufferEnd_ - readOffset_;
|
||||
ar_mem_cpy(data, offset,
|
||||
ringBuffer_->buffer_ + readOffset_, offset);
|
||||
ar_mem_cpy(data + offset, size - offset,
|
||||
ringBuffer_->buffer_, size - offset);
|
||||
} else {
|
||||
ar_mem_cpy(data, size,
|
||||
ringBuffer_->buffer_ + readOffset_, size);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t PalRingBufferReader::read(void* readBuffer, size_t bufferSize)
|
||||
{
|
||||
int32_t readSize = 0;
|
||||
|
||||
if (state_ == READER_DISABLED) {
|
||||
return -EINVAL;
|
||||
} else if (state_ == READER_PREPARED) {
|
||||
state_ = READER_ENABLED;
|
||||
}
|
||||
|
||||
// Return 0 when no data can be read for current reader
|
||||
if (unreadSize_ == 0)
|
||||
return 0;
|
||||
|
||||
std::lock_guard<std::mutex> lck(ringBuffer_->mutex_);
|
||||
|
||||
// when writeOffset leads readOffset
|
||||
if (ringBuffer_->writeOffset_ > readOffset_) {
|
||||
unreadSize_ = ringBuffer_->writeOffset_ - readOffset_;
|
||||
|
||||
if (bufferSize >= unreadSize_) {
|
||||
ar_mem_cpy(readBuffer, unreadSize_, ringBuffer_->buffer_ +
|
||||
readOffset_, unreadSize_);
|
||||
readOffset_ += unreadSize_;
|
||||
readSize = unreadSize_;
|
||||
unreadSize_ = 0;
|
||||
} else {
|
||||
ar_mem_cpy(readBuffer, unreadSize_, ringBuffer_->buffer_ +
|
||||
readOffset_, bufferSize);
|
||||
readOffset_ += bufferSize;
|
||||
readSize = bufferSize;
|
||||
unreadSize_ = ringBuffer_->writeOffset_ - readOffset_;
|
||||
}
|
||||
} else {
|
||||
//When readOffset leads WriteOffset
|
||||
int32_t freeClientSize = bufferSize;
|
||||
int32_t i = ringBuffer_->bufferEnd_ - readOffset_;
|
||||
|
||||
if (bufferSize >= i) {
|
||||
ar_mem_cpy(readBuffer, i, (char*)(ringBuffer_->buffer_ +
|
||||
readOffset_), i);
|
||||
readSize = i;
|
||||
freeClientSize -= readSize;
|
||||
unreadSize_ = ringBuffer_->writeOffset_;
|
||||
readOffset_ = 0;
|
||||
//copy remaining unread buffer
|
||||
if (freeClientSize > unreadSize_) {
|
||||
ar_mem_cpy((char *)readBuffer + readSize, unreadSize_,
|
||||
ringBuffer_->buffer_, unreadSize_);
|
||||
readSize += unreadSize_;
|
||||
readOffset_ = unreadSize_;
|
||||
unreadSize_ = 0;
|
||||
} else {
|
||||
//copy whatever we can
|
||||
ar_mem_cpy((char *)readBuffer + readSize, freeClientSize,
|
||||
ringBuffer_->buffer_, freeClientSize);
|
||||
readSize += freeClientSize;
|
||||
readOffset_ = freeClientSize;
|
||||
unreadSize_ = ringBuffer_->writeOffset_ - readOffset_;
|
||||
}
|
||||
|
||||
} else {
|
||||
ar_mem_cpy(readBuffer, bufferSize, ringBuffer_->buffer_ +
|
||||
readOffset_, bufferSize);
|
||||
readSize = bufferSize;
|
||||
readOffset_ += bufferSize;
|
||||
unreadSize_ = ringBuffer_->bufferEnd_ - readOffset_ +
|
||||
ringBuffer_->writeOffset_;
|
||||
}
|
||||
}
|
||||
return readSize;
|
||||
}
|
||||
|
||||
size_t PalRingBufferReader::advanceReadOffset(size_t advanceSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(ringBuffer_->mutex_);
|
||||
|
||||
readOffset_ = (readOffset_ + advanceSize) % ringBuffer_->bufferEnd_;
|
||||
|
||||
/*
|
||||
* If the buffer is shared across concurrent detections, the second keyword
|
||||
* can start anywhere in the buffer and possibly wrap around to the begining.
|
||||
* For this case, advanceSize representing the start of keyword position in the
|
||||
* buffer can be bigger than unReadSize_ which is aleady adjusted.
|
||||
*/
|
||||
if (unreadSize_ > advanceSize) {
|
||||
unreadSize_ -= advanceSize;
|
||||
} else {
|
||||
PAL_DBG(LOG_TAG, "Warning: trying to advance read offset over write offset");
|
||||
}
|
||||
PAL_INFO(LOG_TAG, "offset %zu, advanced %zu, unread %zu", readOffset_, advanceSize, unreadSize_);
|
||||
return advanceSize;
|
||||
}
|
||||
|
||||
void PalRingBufferReader::updateState(pal_ring_buffer_reader_state state)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "update reader state to %d", state);
|
||||
std::lock_guard<std::mutex> lock(ringBuffer_->mutex_);
|
||||
state_ = state;
|
||||
}
|
||||
|
||||
void PalRingBufferReader::getIndices(Stream *s,
|
||||
uint32_t *startIdx, uint32_t *endIdx, uint32_t *ftrtSize)
|
||||
{
|
||||
ringBuffer_->getIndices(s, startIdx, endIdx, ftrtSize);
|
||||
}
|
||||
|
||||
size_t PalRingBufferReader::getUnreadSize()
|
||||
{
|
||||
PAL_VERBOSE(LOG_TAG, "unread size %zu", unreadSize_);
|
||||
return unreadSize_;
|
||||
}
|
||||
|
||||
size_t PalRingBufferReader::getBufferSize()
|
||||
{
|
||||
return ringBuffer_->getBufferSize();
|
||||
}
|
||||
|
||||
void PalRingBufferReader::reset()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(ringBuffer_->mutex_);
|
||||
readOffset_ = 0;
|
||||
unreadSize_ = 0;
|
||||
state_ = READER_DISABLED;
|
||||
requestedSize_ = 0;
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
PalRingBufferReader* PalRingBuffer::newReader()
|
||||
{
|
||||
PalRingBufferReader* reader =
|
||||
new PalRingBufferReader(this);
|
||||
readers_.push_back(reader);
|
||||
return reader;
|
||||
}
|
||||
87
qcom/opensource/pal/utils/src/PerfLock.cpp
Normal file
87
qcom/opensource/pal/utils/src/PerfLock.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
#define NDEBUG 0
|
||||
#define LOG_TAG "PAL: PerfLock"
|
||||
#include <dlfcn.h>
|
||||
#include "PalCommon.h"
|
||||
#include "PerfLock.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
PerfLock::PerfLock(const std::string &caller) : mCaller(caller) {
|
||||
static bool isInit = init();
|
||||
std::scoped_lock lock (sMutex);
|
||||
acquire_l();
|
||||
}
|
||||
|
||||
PerfLock::~PerfLock() {
|
||||
std::scoped_lock lock (sMutex);
|
||||
release_l();
|
||||
}
|
||||
|
||||
void PerfLock::acquire_l() {
|
||||
++sPerfLockCounter;
|
||||
if (!sIsAcquired && sAcquirePerfLock != nullptr) {
|
||||
sHandle = sAcquirePerfLock(0, 0, kPerfLockOpts.data(), kPerfLockOptsSize);
|
||||
if (sHandle > 0) {
|
||||
sIsAcquired = true;
|
||||
PAL_VERBOSE(LOG_TAG, "succesful perf_lock_acq for %s", mCaller.c_str());
|
||||
} else {
|
||||
PAL_VERBOSE(LOG_TAG, "failed perf_lock_acq for %s", mCaller.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerfLock::release_l() {
|
||||
--sPerfLockCounter;
|
||||
if (sHandle > 0 && sReleasePerfLock != nullptr && (sPerfLockCounter == 0)) {
|
||||
sReleasePerfLock(sHandle);
|
||||
sIsAcquired = false;
|
||||
PAL_VERBOSE(LOG_TAG, "succesful perf_lock_rel for %s", mCaller.c_str());
|
||||
} else {
|
||||
PAL_VERBOSE(LOG_TAG, "failed perf_lock_rel for %s", mCaller.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void PerfLock::setPerfLockOpt(const PerfLockConfig & config) {
|
||||
if (config.usePerfLock) {
|
||||
kPerfLockOptsSize = config.perfLockOpts.size();
|
||||
kPerfLockOpts = config.perfLockOpts;
|
||||
sLibraryName = config.libraryName;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool PerfLock::init() {
|
||||
void* libHandle = dlopen(sLibraryName.c_str(), RTLD_LAZY);
|
||||
if (libHandle == nullptr) {
|
||||
const char* error = dlerror();
|
||||
PAL_ERR(LOG_TAG, "Failed to dlopen %s error %s", sLibraryName.c_str(), error);
|
||||
return false;
|
||||
}
|
||||
sAcquirePerfLock = reinterpret_cast<AcquirePerfLock>(dlsym(libHandle, "perf_lock_acq"));
|
||||
if (sAcquirePerfLock == nullptr) {
|
||||
PAL_ERR(LOG_TAG, "failed to find perf_lock_acq ");
|
||||
dlclose(libHandle);
|
||||
return false;
|
||||
}
|
||||
sReleasePerfLock = reinterpret_cast<ReleasePerfLock>(dlsym(libHandle, "perf_lock_rel"));
|
||||
if (sReleasePerfLock == nullptr) {
|
||||
PAL_ERR(LOG_TAG, "failed to find perf_lock_rel ");
|
||||
dlclose(libHandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream hexStream;
|
||||
|
||||
for (const auto i : kPerfLockOpts) {
|
||||
hexStream << std::hex << i << " ";
|
||||
}
|
||||
|
||||
PAL_INFO(LOG_TAG, "initialized perflock library %s size %d, locks %s", sLibraryName.c_str(),
|
||||
kPerfLockOptsSize, hexStream.str().c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
161
qcom/opensource/pal/utils/src/SignalHandler.cpp
Normal file
161
qcom/opensource/pal/utils/src/SignalHandler.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted (subject to the limitations in the
|
||||
* disclaimer below) provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
|
||||
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "PAL: SignalHandler"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <log/log.h>
|
||||
#include <chrono>
|
||||
#include "SignalHandler.h"
|
||||
|
||||
#ifdef _ANDROID_
|
||||
#include <utils/ProcessCallStack.h>
|
||||
#include <cutils/android_filesystem_config.h>
|
||||
#endif
|
||||
|
||||
std::mutex SignalHandler::sDefaultSigMapLock;
|
||||
std::unordered_map<int, std::shared_ptr<struct sigaction>> SignalHandler::sDefaultSigMap;
|
||||
std::function<void(int, pid_t, uid_t)> SignalHandler::sClientCb;
|
||||
std::mutex SignalHandler::sAsyncRegisterLock;
|
||||
std::future<void> SignalHandler::sAsyncHandle;
|
||||
bool SignalHandler::sBuildDebuggable;
|
||||
|
||||
// static
|
||||
void SignalHandler::asyncRegister(int signal) {
|
||||
std::lock_guard<std::mutex> lock(sAsyncRegisterLock);
|
||||
sigset_t pendingSigMask;
|
||||
uint32_t tries = kDefaultSignalPendingTries;
|
||||
// Delay registration to let default signal handler complete
|
||||
do {
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::milliseconds(kDefaultRegistrationDelayMs));
|
||||
sigpending(&pendingSigMask);
|
||||
--tries;
|
||||
} while (tries > 0 && sigismember(&pendingSigMask, signal) == 1);
|
||||
|
||||
// Register custom handler only if signal is not pending
|
||||
if (!sigismember(&pendingSigMask, signal)) {
|
||||
std::vector<int> signals({ signal });
|
||||
getInstance()->registerSignalHandler(signals);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void SignalHandler::setClientCallback(std::function<void(int, pid_t, uid_t)> cb) {
|
||||
sClientCb = cb;
|
||||
}
|
||||
|
||||
// static
|
||||
std::shared_ptr<SignalHandler> SignalHandler::getInstance() {
|
||||
static std::shared_ptr<SignalHandler> instance(new SignalHandler());
|
||||
return instance;
|
||||
}
|
||||
|
||||
// static
|
||||
void SignalHandler::invokeDefaultHandler(std::shared_ptr<struct sigaction> sAct,
|
||||
int code, struct siginfo *si, void *sc) {
|
||||
ALOGE("%s: invoke default handler for signal %d", __func__, code);
|
||||
// Remove custom handler so that default handler is invoked
|
||||
sigaction(code, sAct.get(), NULL);
|
||||
|
||||
int status = 0;
|
||||
if (si->si_code == SI_QUEUE) {
|
||||
ALOGE("signal %d (%s), code -1 "
|
||||
"(SI_QUEUE from pid %d, uid %d)",
|
||||
code, sigToName.at(code).c_str(),
|
||||
si->si_pid, si->si_uid);
|
||||
status = sigqueue(getpid(), code, si->si_value);
|
||||
#ifdef _ANDROID_
|
||||
if(isBuildDebuggable() && si->si_uid == AID_AUDIOSERVER) {
|
||||
std::string prefix = "audioserver_" + std::to_string(si->si_pid) + " ";
|
||||
android::ProcessCallStack pcs;
|
||||
pcs.update();
|
||||
pcs.log(LOG_TAG, ANDROID_LOG_FATAL, prefix.c_str());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
status = raise(code);
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
ALOGW("%s: Sending signal %d failed with error %d",
|
||||
__func__, code, errno);
|
||||
}
|
||||
|
||||
// Register custom handler back asynchronously
|
||||
sAsyncHandle = std::async(std::launch::async, SignalHandler::asyncRegister, code);
|
||||
}
|
||||
|
||||
// static
|
||||
void SignalHandler::customSignalHandler(
|
||||
int code, struct siginfo *si, void *sc) {
|
||||
ALOGV("%s: enter", __func__);
|
||||
std::lock_guard<std::mutex> lock(sDefaultSigMapLock);
|
||||
if (sClientCb) {
|
||||
sClientCb(code, si->si_pid, si->si_uid);
|
||||
}
|
||||
// Invoke default handler
|
||||
auto it = sDefaultSigMap.find(code);
|
||||
if (it != sDefaultSigMap.end()) {
|
||||
invokeDefaultHandler(it->second, code, si, sc);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
std::vector<int> SignalHandler::getRegisteredSignals() {
|
||||
std::vector<int> registeredSignals;
|
||||
std::lock_guard<std::mutex> lock(sDefaultSigMapLock);
|
||||
for (const auto& element : sDefaultSigMap) {
|
||||
registeredSignals.push_back(element.first);
|
||||
}
|
||||
return registeredSignals;
|
||||
}
|
||||
|
||||
void SignalHandler::registerSignalHandler(std::vector<int> signalsToRegister) {
|
||||
ALOGV("%s: enter", __func__);
|
||||
struct sigaction regAction = {};
|
||||
regAction.sa_sigaction = customSignalHandler;
|
||||
regAction.sa_flags = SA_SIGINFO | SA_NODEFER;
|
||||
std::lock_guard<std::mutex> lock(sDefaultSigMapLock);
|
||||
for (int signal : signalsToRegister) {
|
||||
ALOGV("%s: register signal %d", __func__, signal);
|
||||
auto oldSigAction = std::make_shared<struct sigaction>();
|
||||
if (sigaction(signal, ®Action, oldSigAction.get()) < 0) {
|
||||
ALOGW("%s: Failed to register handler with error code %d for signal %d",
|
||||
__func__, errno, signal);
|
||||
}
|
||||
sDefaultSigMap.emplace(signal, oldSigAction);
|
||||
}
|
||||
}
|
||||
396
qcom/opensource/pal/utils/src/SoundTriggerPlatformInfo.cpp
Normal file
396
qcom/opensource/pal/utils/src/SoundTriggerPlatformInfo.cpp
Normal file
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "ACDPlatformInfo.h"
|
||||
#include "VoiceUIPlatformInfo.h"
|
||||
#include "ASRPlatformInfo.h"
|
||||
#include "SoundTriggerPlatformInfo.h"
|
||||
#include "PalCommon.h"
|
||||
|
||||
#define LOG_TAG "PAL: SoundTriggerPlatformInfo"
|
||||
|
||||
SoundTriggerUUID::SoundTriggerUUID() :
|
||||
timeLow(0),
|
||||
timeMid(0),
|
||||
timeHiAndVersion(0),
|
||||
clockSeq(0) {
|
||||
}
|
||||
|
||||
bool SoundTriggerUUID::operator<(const SoundTriggerUUID& rhs) const {
|
||||
if (timeLow > rhs.timeLow)
|
||||
return false;
|
||||
else if (timeLow < rhs.timeLow)
|
||||
return true;
|
||||
/* timeLow is equal */
|
||||
|
||||
if (timeMid > rhs.timeMid)
|
||||
return false;
|
||||
else if (timeMid < rhs.timeMid)
|
||||
return true;
|
||||
/* timeLow and timeMid are equal */
|
||||
|
||||
if (timeHiAndVersion > rhs.timeHiAndVersion)
|
||||
return false;
|
||||
else if (timeHiAndVersion < rhs.timeHiAndVersion)
|
||||
return true;
|
||||
/* timeLow, timeMid and timeHiAndVersion are equal */
|
||||
|
||||
if (clockSeq > rhs.clockSeq)
|
||||
return false;
|
||||
else if (clockSeq < rhs.clockSeq)
|
||||
return true;
|
||||
|
||||
//check node
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (node[i] > rhs.node[i]) {
|
||||
return false;
|
||||
}
|
||||
else if(node[i] < rhs.node[i]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* everything is equal */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SoundTriggerUUID& SoundTriggerUUID::operator = (SoundTriggerUUID& rhs) {
|
||||
this->clockSeq = rhs.clockSeq;
|
||||
this->timeLow = rhs.timeLow;
|
||||
this->timeMid = rhs.timeMid;
|
||||
this->timeHiAndVersion = rhs.timeHiAndVersion;
|
||||
memcpy(node, rhs.node, sizeof(node));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SoundTriggerUUID::CompareUUID(const struct st_uuid uuid) const {
|
||||
if (uuid.timeLow != timeLow ||
|
||||
uuid.timeMid != timeMid ||
|
||||
uuid.timeHiAndVersion != timeHiAndVersion ||
|
||||
uuid.clockSeq != clockSeq)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (uuid.node[i] != node[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int SoundTriggerUUID::StringToUUID(const char* str,
|
||||
SoundTriggerUUID& UUID) {
|
||||
int tmp[10];
|
||||
|
||||
if (str == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
|
||||
tmp, tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5, tmp + 6,
|
||||
tmp + 7, tmp + 8, tmp + 9) < 10) {
|
||||
return -EINVAL;
|
||||
}
|
||||
UUID.timeLow = (uint32_t)tmp[0];
|
||||
UUID.timeMid = (uint16_t)tmp[1];
|
||||
UUID.timeHiAndVersion = (uint16_t)tmp[2];
|
||||
UUID.clockSeq = (uint16_t)tmp[3];
|
||||
UUID.node[0] = (uint8_t)tmp[4];
|
||||
UUID.node[1] = (uint8_t)tmp[5];
|
||||
UUID.node[2] = (uint8_t)tmp[6];
|
||||
UUID.node[3] = (uint8_t)tmp[7];
|
||||
UUID.node[4] = (uint8_t)tmp[8];
|
||||
UUID.node[5] = (uint8_t)tmp[9];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CaptureProfile::CaptureProfile(const std::string name) :
|
||||
name_(name),
|
||||
device_id_(PAL_DEVICE_IN_MIN),
|
||||
sample_rate_(16000),
|
||||
channels_(1),
|
||||
bitwidth_(16),
|
||||
device_pp_kv_(std::make_pair(0, 0)),
|
||||
snd_name_("va-mic"),
|
||||
is_ec_req_(false),
|
||||
backend_("va_macro")
|
||||
{
|
||||
}
|
||||
|
||||
void CaptureProfile::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "device_id")) {
|
||||
auto itr = deviceIdLUT.find(attribs[++i]);
|
||||
if (itr == deviceIdLUT.end()) {
|
||||
PAL_ERR(LOG_TAG, "could not find key %s in lookup table",
|
||||
attribs[i]);
|
||||
} else {
|
||||
device_id_ = itr->second;
|
||||
}
|
||||
} else if (!strcmp(attribs[i], "sample_rate")) {
|
||||
sample_rate_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "bit_width")) {
|
||||
bitwidth_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "channels")) {
|
||||
channels_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "snd_name")) {
|
||||
snd_name_ = attribs[++i];
|
||||
} else if (!strcmp(attribs[i], "ec_ref")) {
|
||||
is_ec_req_ = !strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "backend")) {
|
||||
backend_ = attribs[++i];
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", (char *)tag);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Priority compare result indicated by return value as below:
|
||||
* 1. CAPTURE_PROFILE_PRIORITY_HIGH
|
||||
* current capture profile has higher priority than cap_prof
|
||||
* 2. CAPTURE_PROFILE_PRIORITY_LOW
|
||||
* current capture profile has lower priority than cap_prof
|
||||
* 3. CAPTURE_PROFILE_PRIORITY_SAME
|
||||
* current capture profile has same priority than cap_prof
|
||||
*/
|
||||
int32_t CaptureProfile::ComparePriority(std::shared_ptr<CaptureProfile> cap_prof)
|
||||
{
|
||||
int32_t priority_check = 0;
|
||||
|
||||
if (!cap_prof) {
|
||||
priority_check = CAPTURE_PROFILE_PRIORITY_HIGH;
|
||||
} else {
|
||||
/* Comparing channel numbers, sample rate,
|
||||
* and bitwidth together to check priority.
|
||||
*/
|
||||
if (backend_.compare(cap_prof->GetBackend()) != 0) {
|
||||
PAL_DBG(LOG_TAG, "Skip priority comparison between %s and %s",
|
||||
backend_.c_str(), cap_prof->GetBackend().c_str());
|
||||
priority_check = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (channels_ != cap_prof->GetChannels()) {
|
||||
channels_ > cap_prof->GetChannels() ? priority_check++ : priority_check--;
|
||||
}
|
||||
|
||||
if (sample_rate_ != cap_prof->GetSampleRate()) {
|
||||
sample_rate_ > cap_prof->GetSampleRate() ? priority_check++ : priority_check--;
|
||||
}
|
||||
|
||||
if (bitwidth_ != cap_prof->GetBitWidth()) {
|
||||
bitwidth_ > cap_prof->GetBitWidth() ? priority_check++ : priority_check--;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return priority_check;
|
||||
}
|
||||
|
||||
std::shared_ptr<SoundTriggerPlatformInfo> SoundTriggerPlatformInfo::me_ = nullptr;
|
||||
bool SoundTriggerPlatformInfo::lpi_enable_ = true;
|
||||
bool SoundTriggerPlatformInfo::support_nlpi_switch_ = true;
|
||||
bool SoundTriggerPlatformInfo::support_device_switch_ = false;
|
||||
bool SoundTriggerPlatformInfo::enable_debug_dumps_ = false;
|
||||
bool SoundTriggerPlatformInfo::concurrent_capture_ = false;
|
||||
bool SoundTriggerPlatformInfo::concurrent_voice_call_ = false;
|
||||
bool SoundTriggerPlatformInfo::concurrent_voip_call_ = false;
|
||||
bool SoundTriggerPlatformInfo::low_latency_bargein_enable_ = false;
|
||||
|
||||
SoundTriggerPlatformInfo::SoundTriggerPlatformInfo() : curr_child_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<SoundTriggerPlatformInfo> SoundTriggerPlatformInfo::GetInstance()
|
||||
{
|
||||
if (!me_)
|
||||
me_ = std::shared_ptr<SoundTriggerPlatformInfo>(new SoundTriggerPlatformInfo);
|
||||
return me_;
|
||||
}
|
||||
|
||||
void SoundTriggerPlatformInfo::ReadCapProfileNames(StOperatingModes mode,
|
||||
const char** attribs,
|
||||
st_op_modes_t& op_modes)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "capture_profile_handset")) {
|
||||
op_modes[std::make_pair(mode, ST_INPUT_MODE_HANDSET)] =
|
||||
capture_profile_map_.at(std::string(attribs[++i]));
|
||||
} else if(!strcmp(attribs[i], "capture_profile_headset")) {
|
||||
op_modes[std::make_pair(mode, ST_INPUT_MODE_HEADSET)] =
|
||||
capture_profile_map_.at(std::string(attribs[++i]));
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Error:%d got unexpected attribute: %s",
|
||||
-EINVAL, attribs[i]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
}
|
||||
|
||||
void SoundTriggerPlatformInfo::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "vui_platform_info")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
VoiceUIPlatformInfo::GetInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "acd_platform_info")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
ACDPlatformInfo::GetInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "asr_platform_info")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
ASRPlatformInfo::GetInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "capture_profile")) {
|
||||
if (attribs[0] && !strcmp(attribs[0], "name")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<CaptureProfile>(attribs[1]));
|
||||
return;
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG,"missing name attrib for tag %s", tag);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "common_config") || !strcmp(tag, "capture_profile_list")) {
|
||||
PAL_VERBOSE(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
|
||||
while (attribs[i]) {
|
||||
if (!attribs[i]) {
|
||||
PAL_ERR(LOG_TAG,"missing attrib value for tag %s", tag);
|
||||
} else if (!strcmp(attribs[i], "lpi_enable")) {
|
||||
lpi_enable_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "support_nlpi_switch")) {
|
||||
support_nlpi_switch_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "support_device_switch")) {
|
||||
support_device_switch_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "enable_debug_dumps")) {
|
||||
enable_debug_dumps_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "concurrent_capture")) {
|
||||
concurrent_capture_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "concurrent_voice_call") &&
|
||||
concurrent_capture_) {
|
||||
concurrent_voice_call_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "concurrent_voip_call") &&
|
||||
concurrent_capture_) {
|
||||
concurrent_voip_call_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "low_latency_bargein_enable")) {
|
||||
low_latency_bargein_enable_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
}
|
||||
|
||||
void SoundTriggerPlatformInfo::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "capture_profile")) {
|
||||
std::shared_ptr<CaptureProfile> cap_prof(
|
||||
std::static_pointer_cast<CaptureProfile>(curr_child_));
|
||||
|
||||
const auto res = capture_profile_map_.insert(
|
||||
std::make_pair(cap_prof->GetName(), cap_prof));
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Failed to insert to map");
|
||||
curr_child_ = nullptr;
|
||||
} else if (!strcmp(tag, "acd_platform_info") ||
|
||||
!strcmp(tag, "vui_platform_info") ||
|
||||
!strcmp(tag, "asr_platform_info")) {
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_)
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<CaptureProfile> SoundTriggerPlatformInfo::GetCaptureProfileFromMap(std::string cap_prof_name)
|
||||
{
|
||||
st_cap_profile_map_t::iterator it;
|
||||
|
||||
it = capture_profile_map_.find(cap_prof_name);
|
||||
if (it != capture_profile_map_.end())
|
||||
return it->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
513
qcom/opensource/pal/utils/src/VoiceUIPlatformInfo.cpp
Normal file
513
qcom/opensource/pal/utils/src/VoiceUIPlatformInfo.cpp
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "VoiceUIPlatformInfo.h"
|
||||
#include "PalCommon.h"
|
||||
#include "SoundTriggerUtils.h"
|
||||
|
||||
#define LOG_TAG "PAL: VoiceUIPlatformInfo"
|
||||
|
||||
static const struct st_uuid qcva_uuid =
|
||||
{ 0x68ab2d40, 0xe860, 0x11e3, 0x95ef, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
|
||||
|
||||
VUISecondStageConfig::VUISecondStageConfig() :
|
||||
detection_type_(ST_SM_TYPE_NONE),
|
||||
sm_id_(0),
|
||||
module_lib_(""),
|
||||
sample_rate_(16000),
|
||||
bit_width_(16),
|
||||
channels_(1)
|
||||
{
|
||||
}
|
||||
|
||||
void VUISecondStageConfig::HandleStartTag(const char *tag, const char **attribs)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "sm_detection_type")) {
|
||||
i++;
|
||||
if (!strcmp(attribs[i], "KEYWORD_DETECTION")) {
|
||||
detection_type_ = ST_SM_TYPE_KEYWORD_DETECTION;
|
||||
} else if (!strcmp(attribs[i], "USER_VERIFICATION")) {
|
||||
detection_type_ = ST_SM_TYPE_USER_VERIFICATION;
|
||||
} else if (!strcmp(attribs[i], "CUSTOM_DETECTION")) {
|
||||
detection_type_ = ST_SM_TYPE_CUSTOM_DETECTION;
|
||||
}
|
||||
} else if (!strcmp(attribs[i], "sm_id")) {
|
||||
sm_id_ = std::strtoul(attribs[++i], nullptr, 16);
|
||||
} else if (!strcmp(attribs[i], "module_lib")) {
|
||||
module_lib_ = attribs[++i];
|
||||
} else if (!strcmp(attribs[i], "sample_rate")) {
|
||||
sample_rate_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "bit_width")) {
|
||||
bit_width_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "channel_count")) {
|
||||
channels_ = std::stoi(attribs[++i]);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
}
|
||||
|
||||
VUIFirstStageConfig::VUIFirstStageConfig() :
|
||||
module_type_(ST_MODULE_TYPE_GMM),
|
||||
module_name_("GMM"),
|
||||
lpi_supported_(true)
|
||||
{
|
||||
for (int i = 0; i < MAX_PARAM_IDS; i++) {
|
||||
module_tag_ids_[i] = 0;
|
||||
param_ids_[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VUIFirstStageConfig::HandleStartTag(const char *tag, const char **attribs)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "module_type")) {
|
||||
i++;
|
||||
module_name_ = attribs[i];
|
||||
if (!strcmp(attribs[i], "GMM")) {
|
||||
module_type_ = ST_MODULE_TYPE_GMM;
|
||||
} else if (!strcmp(attribs[i], "PDK")) {
|
||||
module_type_ = ST_MODULE_TYPE_PDK;
|
||||
} else if (!strcmp(attribs[i], "HOTWORD")) {
|
||||
module_type_ = ST_MODULE_TYPE_HW;
|
||||
} else if (!strcmp(attribs[i], "CUSTOM1")) {
|
||||
module_type_ = ST_MODULE_TYPE_CUSTOM_1;
|
||||
} else if (!strcmp(attribs[i], "CUSTOM2")) {
|
||||
module_type_ = ST_MODULE_TYPE_CUSTOM_2;
|
||||
} else if (!strcmp(attribs[i], "MMA")) {
|
||||
module_type_ = ST_MODULE_TYPE_MMA;
|
||||
}
|
||||
PAL_DBG(LOG_TAG, "Module name:%s, type:%d",
|
||||
module_name_.c_str(), module_type_);
|
||||
} else if (!strcmp(attribs[i], "lpi_supported")) {
|
||||
lpi_supported_ = !strcmp(attribs[++i], "true");
|
||||
} else {
|
||||
uint32_t index = 0;
|
||||
|
||||
if (!strcmp(attribs[i], "load_sound_model_ids")) {
|
||||
index = LOAD_SOUND_MODEL;
|
||||
} else if (!strcmp(attribs[i], "unload_sound_model_ids")) {
|
||||
index = UNLOAD_SOUND_MODEL;
|
||||
} else if (!strcmp(attribs[i], "wakeup_config_ids")) {
|
||||
index = WAKEUP_CONFIG;
|
||||
} else if (!strcmp(attribs[i], "buffering_config_ids")) {
|
||||
index = BUFFERING_CONFIG;
|
||||
} else if (!strcmp(attribs[i], "engine_reset_ids")) {
|
||||
index = ENGINE_RESET;
|
||||
} else if (!strcmp(attribs[i], "custom_config_ids")) {
|
||||
index = CUSTOM_CONFIG;
|
||||
} else if (!strcmp(attribs[i], "version_ids")) {
|
||||
index = MODULE_VERSION;
|
||||
} else if (!strcmp(attribs[i], "engine_per_model_reset_ids")) {
|
||||
index = ENGINE_PER_MODEL_RESET;
|
||||
}
|
||||
sscanf(attribs[++i], "%x, %x", &module_tag_ids_[index],
|
||||
¶m_ids_[index]);
|
||||
PAL_DBG(LOG_TAG, "index : %u, module_id : %x, param : %x",
|
||||
index, module_tag_ids_[index], param_ids_[index]);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
}
|
||||
|
||||
VUIStreamConfig::VUIStreamConfig() :
|
||||
vui_intf_plugin_lib_name_(""),
|
||||
is_qcva_uuid_(false),
|
||||
merge_first_stage_sound_models_(false),
|
||||
capture_keyword_(2000),
|
||||
client_capture_read_delay_(2000),
|
||||
pre_roll_duration_(0),
|
||||
supported_first_stage_engine_count_(1),
|
||||
enable_concurrent_event_capture_(false),
|
||||
curr_child_(nullptr)
|
||||
{
|
||||
ext_det_prop_list_.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Below functions GetVUIFirstStageConfig(), GetVUIModuleType(),
|
||||
* and GetVUIModuleName() are to be used only for getting module
|
||||
* info and module type/name for third party or custom sound model
|
||||
* engines. It assumes only one module type per vendor UUID.
|
||||
*/
|
||||
std::shared_ptr<VUIFirstStageConfig> VUIStreamConfig::GetVUIFirstStageConfig()
|
||||
{
|
||||
auto smCfg = vui_uuid_1st_stage_cfg_list_.find(vendor_uuid_);
|
||||
|
||||
if(smCfg != vui_uuid_1st_stage_cfg_list_.end())
|
||||
return smCfg->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
st_module_type_t VUIStreamConfig::GetVUIModuleType()
|
||||
{
|
||||
std::shared_ptr<VUIFirstStageConfig> sTModuleInfo = GetVUIFirstStageConfig();
|
||||
|
||||
if (sTModuleInfo != nullptr)
|
||||
return sTModuleInfo->GetModuleType();
|
||||
else
|
||||
return ST_MODULE_TYPE_NONE;
|
||||
}
|
||||
|
||||
std::string VUIStreamConfig::GetVUIModuleName()
|
||||
{
|
||||
std::shared_ptr<VUIFirstStageConfig> sTModuleInfo = GetVUIFirstStageConfig();
|
||||
|
||||
if (sTModuleInfo != nullptr)
|
||||
return sTModuleInfo->GetModuleName();
|
||||
else
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::shared_ptr<VUISecondStageConfig> VUIStreamConfig::GetVUISecondStageConfig(
|
||||
const listen_model_indicator_enum& sm_type) const
|
||||
{
|
||||
uint32_t sm_id = static_cast<uint32_t>(sm_type);
|
||||
auto ss_config = vui_2nd_stage_cfg_list_.find(sm_id);
|
||||
|
||||
if (ss_config != vui_2nd_stage_cfg_list_.end())
|
||||
return ss_config->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VUIFirstStageConfig> VUIStreamConfig::GetVUIFirstStageConfig(const uint32_t type) const
|
||||
{
|
||||
uint32_t module_type = type;
|
||||
|
||||
PAL_DBG(LOG_TAG, "search module for model type %u", type);
|
||||
if (IS_MODULE_TYPE_PDK(type)) {
|
||||
PAL_DBG(LOG_TAG, "PDK module");
|
||||
module_type = ST_MODULE_TYPE_PDK;
|
||||
}
|
||||
|
||||
auto module_config = vui_1st_stage_cfg_list_.find(module_type);
|
||||
if (module_config != vui_1st_stage_cfg_list_.end())
|
||||
return module_config->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VUIStreamConfig::GetDetectionPropertyList(
|
||||
std::vector<uint32_t> &list) {
|
||||
|
||||
for (int i = 0; i < ext_det_prop_list_.size(); i++)
|
||||
list.push_back(ext_det_prop_list_[i]);
|
||||
}
|
||||
|
||||
void VUIStreamConfig::ReadDetectionPropertyList(const char *prop_string)
|
||||
{
|
||||
int ret = 0;
|
||||
char *token = nullptr;
|
||||
char *delims = ",";
|
||||
char *save = nullptr;
|
||||
|
||||
PAL_VERBOSE(LOG_TAG, "Detection property list %s", prop_string);
|
||||
|
||||
token = strtok_r(const_cast<char *>(prop_string), delims, &save);
|
||||
while (token) {
|
||||
ext_det_prop_list_.push_back(std::strtoul(token, nullptr, 16));
|
||||
token = strtok_r(NULL, delims, &save);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ext_det_prop_list_.size(); i++) {
|
||||
PAL_INFO(LOG_TAG, "Found extension detection property 0x%x",
|
||||
ext_det_prop_list_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool VUIStreamConfig::IsDetPropSupported(uint32_t prop) const {
|
||||
|
||||
auto iter =
|
||||
std::find(ext_det_prop_list_.begin(), ext_det_prop_list_.end(), prop);
|
||||
|
||||
return iter != ext_det_prop_list_.end();
|
||||
}
|
||||
|
||||
void VUIStreamConfig::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "first_stage_module_params")) {
|
||||
auto st_module_info_ = std::make_shared<VUIFirstStageConfig>();
|
||||
vui_uuid_1st_stage_cfg_list_.insert(std::make_pair(vendor_uuid_, st_module_info_));
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(st_module_info_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "arm_ss_module_params")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<VUISecondStageConfig>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "operating_modes") || !strcmp(tag, "sound_model_info")
|
||||
|| !strcmp(tag, "name")) {
|
||||
PAL_DBG(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SoundTriggerPlatformInfo> st_info = SoundTriggerPlatformInfo::GetInstance();
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!strcmp(attribs[i], "vendor_uuid")) {
|
||||
UUID::StringToUUID(attribs[++i], vendor_uuid_);
|
||||
if (vendor_uuid_.CompareUUID(qcva_uuid))
|
||||
is_qcva_uuid_ = true;
|
||||
} else if (!strcmp(attribs[i], "interface_plugin_lib")) {
|
||||
vui_intf_plugin_lib_name_ = attribs[++i];
|
||||
} else if (!strcmp(attribs[i], "get_module_version")) {
|
||||
get_module_version_supported_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "merge_first_stage_sound_models")) {
|
||||
merge_first_stage_sound_models_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "pdk_first_stage_max_engine_count")) {
|
||||
supported_first_stage_engine_count_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "enable_concurrent_event_capture")) {
|
||||
enable_concurrent_event_capture_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "capture_keyword")) {
|
||||
capture_keyword_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "client_capture_read_delay")) {
|
||||
client_capture_read_delay_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "pre_roll_duration")) {
|
||||
pre_roll_duration_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "kw_start_tolerance")) {
|
||||
kw_start_tolerance_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "kw_end_tolerance")) {
|
||||
kw_end_tolerance_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "data_before_kw_start")) {
|
||||
data_before_kw_start_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "data_after_kw_end")) {
|
||||
data_after_kw_end_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "sample_rate")) {
|
||||
sample_rate_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "bit_width")) {
|
||||
bit_width_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "out_channels")) {
|
||||
if (std::stoi(attribs[++i]) <= MAX_MODULE_CHANNELS)
|
||||
out_channels_ = std::stoi(attribs[i]);
|
||||
} else if (!strcmp(attribs[i], "detection_property_list")) {
|
||||
ReadDetectionPropertyList(attribs[++i]);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else if (!strcmp(tag, "low_power")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_LOW_POWER, attribs, vui_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF, attribs, vui_op_modes_);
|
||||
} else if (!strcmp(tag, "high_performance_and_charging")) {
|
||||
st_info->ReadCapProfileNames(ST_OPERATING_MODE_HIGH_PERF_AND_CHARGING, attribs, vui_op_modes_);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", (char *)tag);
|
||||
}
|
||||
}
|
||||
|
||||
void VUIStreamConfig::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "first_stage_module_params")) {
|
||||
std::shared_ptr<VUIFirstStageConfig> st_module_info(
|
||||
std::static_pointer_cast<VUIFirstStageConfig>(curr_child_));
|
||||
const auto res = vui_1st_stage_cfg_list_.insert(
|
||||
std::make_pair(st_module_info->GetModuleType(), st_module_info));
|
||||
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Failed to insert to map");
|
||||
curr_child_ = nullptr;
|
||||
} else if (!strcmp(tag, "arm_ss_module_params")) {
|
||||
std::shared_ptr<VUISecondStageConfig> ss_cfg(
|
||||
std::static_pointer_cast<VUISecondStageConfig>(curr_child_));
|
||||
const auto res = vui_2nd_stage_cfg_list_.insert(
|
||||
std::make_pair(ss_cfg->GetSoundModelID(), ss_cfg));
|
||||
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Failed to insert to map");
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_)
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<VoiceUIPlatformInfo> VoiceUIPlatformInfo::me_ = nullptr;
|
||||
|
||||
VoiceUIPlatformInfo::VoiceUIPlatformInfo() :
|
||||
enable_failure_detection_(false),
|
||||
transit_to_non_lpi_on_charging_(false),
|
||||
notify_second_stage_failure_(false),
|
||||
mmap_enable_(false),
|
||||
mmap_buffer_duration_(0),
|
||||
mmap_frame_length_(0),
|
||||
sound_model_lib_("liblistensoundmodel2vendor.so"),
|
||||
curr_child_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<VUIStreamConfig> VoiceUIPlatformInfo::GetStreamConfig(const UUID& uuid) const
|
||||
{
|
||||
auto smCfg = stream_cfg_list_.find(uuid);
|
||||
|
||||
if (smCfg != stream_cfg_list_.end())
|
||||
return smCfg->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We can assume only Hotword sm config supports version api
|
||||
void VoiceUIPlatformInfo::GetStreamConfigForVersionQuery(
|
||||
std::vector<std::shared_ptr<VUIStreamConfig>> &sm_cfg_list) const
|
||||
{
|
||||
std::shared_ptr<VUIStreamConfig> sm_cfg = nullptr;
|
||||
|
||||
for (auto iter = stream_cfg_list_.begin();
|
||||
iter != stream_cfg_list_.end(); iter++) {
|
||||
sm_cfg = iter->second;
|
||||
if (sm_cfg && sm_cfg->GetModuleVersionSupported())
|
||||
sm_cfg_list.push_back(sm_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<VoiceUIPlatformInfo> VoiceUIPlatformInfo::GetInstance()
|
||||
{
|
||||
if (!me_)
|
||||
me_ = std::shared_ptr<VoiceUIPlatformInfo> (new VoiceUIPlatformInfo);
|
||||
|
||||
return me_;
|
||||
}
|
||||
|
||||
void VoiceUIPlatformInfo::HandleStartTag(const char* tag, const char** attribs)
|
||||
{
|
||||
/* Delegate to child element if currently active */
|
||||
if (curr_child_) {
|
||||
curr_child_->HandleStartTag(tag, attribs);
|
||||
return;
|
||||
}
|
||||
|
||||
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
|
||||
std::make_shared<VUIStreamConfig>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "config")) {
|
||||
PAL_DBG(LOG_TAG, "tag:%s appeared, nothing to do", tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "param")) {
|
||||
uint32_t i = 0;
|
||||
while (attribs[i]) {
|
||||
if (!attribs[i]) {
|
||||
PAL_ERR(LOG_TAG,"missing attrib value for tag %s", tag);
|
||||
} else if (!strcmp(attribs[i], "version")) {
|
||||
vui_version_ = std::strtoul(attribs[++i], nullptr, 16);
|
||||
} else if (!strcmp(attribs[i], "enable_failure_detection")) {
|
||||
enable_failure_detection_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "transit_to_non_lpi_on_charging")) {
|
||||
transit_to_non_lpi_on_charging_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "notify_second_stage_failure")) {
|
||||
notify_second_stage_failure_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "mmap_enable")) {
|
||||
mmap_enable_ =
|
||||
!strncasecmp(attribs[++i], "true", 4) ? true : false;
|
||||
} else if (!strcmp(attribs[i], "mmap_buffer_duration")) {
|
||||
mmap_buffer_duration_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "mmap_frame_length")) {
|
||||
mmap_frame_length_ = std::stoi(attribs[++i]);
|
||||
} else if (!strcmp(attribs[i], "sound_model_lib")) {
|
||||
sound_model_lib_ = std::string(attribs[++i]);
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
|
||||
}
|
||||
++i; /* move to next attribute */
|
||||
}
|
||||
} else {
|
||||
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
|
||||
}
|
||||
}
|
||||
|
||||
void VoiceUIPlatformInfo::HandleEndTag(struct xml_userdata *data, const char* tag)
|
||||
{
|
||||
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
|
||||
|
||||
if (!strcmp(tag, "stream_config")) {
|
||||
std::shared_ptr<VUIStreamConfig> sm_cfg(
|
||||
std::static_pointer_cast<VUIStreamConfig>(curr_child_));
|
||||
const auto res = stream_cfg_list_.insert(
|
||||
std::make_pair(sm_cfg->GetUUID(), sm_cfg));
|
||||
|
||||
if (!res.second)
|
||||
PAL_ERR(LOG_TAG, "Failed to insert to map");
|
||||
curr_child_ = nullptr;
|
||||
}
|
||||
|
||||
if (curr_child_)
|
||||
curr_child_->HandleEndTag(data, tag);
|
||||
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user