* Copyright (c) 2021-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_TAG
#define LOG_TAG "AudioServer"
#endif
#include "audio_server.h"
#include <unistd.h>
#include <cinttypes>
#include <codecvt>
#include <csignal>
#include <fstream>
#include <sstream>
#include <thread>
#include <unordered_map>
#include <vector>
#include <format>
#include <optional>
#include <sys/ioctl.h>
#include <fcntl.h>
#include "bundle_mgr_interface.h"
#include "bundle_mgr_proxy.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "hisysevent.h"
#include "parameters.h"
#include "media_monitor_manager.h"
#include "app_bundle_manager.h"
#include "audio_errors.h"
#include "audio_common_log.h"
#include "audio_info.h"
#include "audio_schedule.h"
#include "audio_utils.h"
#include "stream_dfx_manager.h"
#include "async_action_handler.h"
#include "audio_asr.h"
#include "audio_stream_enum.h"
#include "audio_service.h"
#include "core_service_handler.h"
#include "iv_a_device_controller.h"
#include "icore_service_provider_ipc.h"
#include "manager/hdi_adapter_manager.h"
#include "sink/i_audio_render_sink.h"
#include "source/i_audio_capture_source.h"
#include "util/id_handler.h"
#include "manager/hdi_monitor.h"
#include "audio_bundle_manager.h"
#include "va_device_controller_registry.h"
#ifdef HAS_FEATURE_INNERCAPTURER
#include "playback_capturer_manager.h"
#endif
#include "config/audio_param_parser.h"
#include "offline_stream_in_server.h"
#include "audio_dump_pcm.h"
#include "i_hpae_manager.h"
#include "audio_server_hpae_dump.h"
#include "audio_resource_service.h"
#include "audio_manager_listener.h"
#include "audio_injector_service.h"
#include "audio_sink_latency_fetcher.h"
#include "audio_system_load_listener.h"
#include "cJSON.h"
#ifdef FEATURE_CALL_MANAGER
#include "call_manager_client.h"
#include "securec.h"
#endif
#ifdef SUPPORT_OLD_ENGINE
#define PA
#ifdef PA
extern "C" {
extern int ohos_pa_main(int argc, char *argv[]);
}
#endif
#endif
using namespace std;
#define IOCTL_AUDIO_WAKEUP_TRACK_REPORT_CMD _IO('A', 0x02)
namespace OHOS {
namespace AudioStandard {
constexpr int32_t UID_MSDP_SA = 6699;
constexpr int32_t INTELL_VOICE_SERVICR_UID = 1042;
constexpr uint32_t DEFAULT_SINK_LATENCY_MS = 40;
constexpr uint32_t PRIMARY_SINK_LATENCY_MS = 100;
uint32_t AudioServer::paDaemonTid_;
std::map<std::string, std::string> AudioServer::audioParameters;
std::unordered_map<std::string, std::unordered_map<std::string, std::set<std::string>>> AudioServer::audioParameterKeys;
const string DEFAULT_COOKIE_PATH = "/data/data/.pulse_dir/state/cookie";
const std::string CHECK_FAST_BLOCK_PREFIX = "Is_Fast_Blocked_For_AppName#";
constexpr const char *TEL_SATELLITE_SUPPORT = "const.telephony.satellite.supported";
const std::string SATEMODEM_PARAMETER = "usedmodem=satemodem";
const std::string PCM_DUMP_KEY = "PCM_DUMP";
const std::string EFFECT_LIVE_KEY = "hpae_effect";
const std::string HOME_MUSIC_KEY = "HomeMusic";
const std::string COCKPIT_DIRECT_KEY = "cockpit_direct";
const std::string AUDIO_EFFECT_KEY = "audio_effect";
const std::string NETWORK_ID_KEY = "NETWORK_ID";
const std::string ZONE_ID_CHANGE = "zone_id_change";
const std::string MAIN_KEY_DFX = "dfx";
const std::string ACCESSORY_EXTRA_KEY = "accessory_extra";
const std::string SUB_KEY_UPDATE_WAKEUP_TRACE_RESULT = "update_wakeup_trace_result";
constexpr int32_t UID_CALL_MANAGER_SA = 1001;
const unsigned int TIME_OUT_SECONDS = 10;
const char* DUMP_AUDIO_PERMISSION = "ohos.permission.DUMP_AUDIO";
const char* MANAGE_INTELLIGENT_VOICE_PERMISSION = "ohos.permission.MANAGE_INTELLIGENT_VOICE";
const char* CAST_AUDIO_OUTPUT_PERMISSION = "ohos.permission.CAST_AUDIO_OUTPUT";
const char* CAPTURE_PLAYBACK_PERMISSION = "ohos.permission.CAPTURE_PLAYBACK";
const char* MANAGE_AUDIO_CONFIG_PERMISSION = "ohos.permission.MANAGE_AUDIO_CONFIG";
const char* CAPTURE_PLAYBACK_DOWNLINK_PERMISSION = "ohos.permission.CAPTURE_PLAYBACK_DOWNLINK";
const char* MANAGE_AUDIO_ACCESSORY = "ohos.permission.MANAGE_AUDIO_ACCESSORY";
static constexpr char WAKEUP_TRACK_FILE_PATCH[] = "/dev/audio_wakeup_track";
static const std::vector<StreamUsage> STREAMS_NEED_VERIFY_SYSTEM_PERMISSION = {
STREAM_USAGE_SYSTEM,
STREAM_USAGE_DTMF,
STREAM_USAGE_ENFORCED_TONE,
STREAM_USAGE_ULTRASONIC,
STREAM_USAGE_VOICE_MODEM_COMMUNICATION
};
std::shared_ptr<Media::MediaMonitor::EventBean> CreateStreamOccupancyEventBean(
const AudioRendererDataTransferStateChangeInfo &info)
{
std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
Media::MediaMonitor::ModuleId::AUDIO, Media::MediaMonitor::EventId::STREAM_OCCUPANCY,
Media::MediaMonitor::EventType::DURATION_AGGREGATION_EVENT);
CHECK_AND_RETURN_RET_LOG(bean != nullptr, nullptr, "bean is nullptr");
bean->Add("IS_PLAYBACK", info.audioMode == AUDIO_MODE_PLAYBACK ? 1 : 0);
bean->Add("SESSIONID", static_cast<int32_t>(info.sessionId));
bean->Add("UID", info.clientUID);
bean->Add("STREAM_OR_SOURCE_TYPE", info.streamUsage);
bean->Add("START_TIME", static_cast<uint64_t>(0));
bean->Add("UPLOAD_TIME", static_cast<uint64_t>(0));
return bean;
}
const int32_t KVPAIRS_LEN = 2;
static const int32_t MODERN_INNER_API_VERSION = 12;
const int32_t API_VERSION_REMAINDER = 1000;
static constexpr int32_t VM_MANAGER_UID = 7700;
static const int32_t FAST_DUMPINFO_LEN = 2;
static const int32_t BUNDLENAME_LENGTH_LIMIT = 1024;
static const size_t PARAMETER_SET_LIMIT = 1024;
constexpr int32_t UID_CAMERA = 1047;
constexpr int32_t MAX_RENDERER_STREAM_CNT_PER_UID = 128;
const int32_t DEFAULT_MAX_RENDERER_INSTANCES = 128;
const int32_t DEFAULT_MAX_LOOPBACK_INSTANCES = 1;
const int32_t MCU_UID = 7500;
const int32_t TV_SERVICE_UID = 7501;
const int32_t AAM_CONN_SVC_UID = 7878;
constexpr int32_t CHECK_ALL_RENDER_UID = -1;
constexpr int64_t RENDER_DETECTION_CYCLE_NS = 10000000000;
constexpr int32_t RENDER_BAD_FRAMES_RATIO = 100;
static const int32_t INVALID_APP_UID = -1;
static const int32_t INVALID_APP_CREATED_AUDIO_STREAM_NUM = 0;
constexpr uint32_t PLAYBACK_CAPTURE_MODE_ONLY_VOIP = 0x4000;
static bool IsOnlyVoipPlaybackCaptureUsages(const std::vector<StreamUsage> &usages)
{
for (const auto &usage : usages) {
if (usage == STREAM_USAGE_VOICE_COMMUNICATION) {
continue;
}
if (usage == STREAM_USAGE_VIDEO_COMMUNICATION) {
continue;
}
return false;
}
return true;
}
static const std::set<int32_t> RECORD_CHECK_FORWARD_LIST = {
VM_MANAGER_UID,
UID_CAMERA
};
static const std::set<int32_t> GENERATE_SESSIONID_UID_SET = {
MCU_UID,
TV_SERVICE_UID,
AAM_CONN_SVC_UID
};
const int32_t RSS_THRESHOLD = 2;
constexpr int32_t UID_MEDIA_SA = 1013;
enum PermissionStatus {
PERMISSION_GRANTED = 0,
PERMISSION_DENIED = 1,
PERMISSION_UNKNOWN = 2,
};
const std::set<int32_t> RECORD_PASS_APPINFO_LIST = {
UID_MEDIA_SA
};
const std::set<SourceType> VALID_SOURCE_TYPE = {
SOURCE_TYPE_MIC,
SOURCE_TYPE_VOICE_RECOGNITION,
SOURCE_TYPE_PLAYBACK_CAPTURE,
SOURCE_TYPE_WAKEUP,
SOURCE_TYPE_VOICE_CALL,
SOURCE_TYPE_VOICE_DOWNLINK,
SOURCE_TYPE_VOICE_COMMUNICATION,
SOURCE_TYPE_ULTRASONIC,
SOURCE_TYPE_VIRTUAL_CAPTURE,
SOURCE_TYPE_VOICE_MESSAGE,
SOURCE_TYPE_REMOTE_CAST,
SOURCE_TYPE_VOICE_TRANSCRIPTION,
SOURCE_TYPE_CAMCORDER,
SOURCE_TYPE_UNPROCESSED,
SOURCE_TYPE_LIVE,
SOURCE_TYPE_UNPROCESSED_VOICE_ASSISTANT,
SOURCE_TYPE_INTERPHONE,
};
const std::set<std::string> ASR_FORBIDDEN_KEYS = {
"asr_aec_mode",
"ASR_AEC",
"asr_ns_mode",
"asr_wd_mode",
"TTS_2_DEVICE",
"TTS_2_MODEM",
"MIC_2_MODEM",
"MODEM_2_DEVICE",
"audio2voicetx",
"audiomix2voicetx",
"audio2voicetxex",
"audiomix2voicetxex",
"output_mute=true",
"output_mute=false",
"input_mute=true",
"input_mute=false",
"mute_tts=true",
"mute_tts=false",
"mute_call=true",
"mute_call=false",
"ouput_mute_ex=true",
"ouput_mute_ex=false"
};
static constexpr unsigned int GET_BUNDLE_TIME_OUT_SECONDS = 10;
static constexpr unsigned int WAIT_AUDIO_POLICY_READY_TIMEOUT_SECONDS = 5;
static constexpr unsigned int WAIT_AUDIO_PARAMETER_PARSED_TIMEOUT_SECONDS = 5;
static constexpr int32_t MAX_WAIT_IN_SERVER_COUNT = 5;
static constexpr int32_t RESTORE_SESSION_TRY_COUNT = 10;
static constexpr uint32_t RESTORE_SESSION_RETRY_WAIT_TIME_IN_MS = 50000;
static constexpr unsigned int CREATE_TIMEOUT_IN_SECOND = 9;
static constexpr uint32_t DEFAULT_PIPE_ID = 0;
static const std::vector<SourceType> AUDIO_SUPPORTED_SOURCE_TYPES = {
SOURCE_TYPE_INVALID,
SOURCE_TYPE_MIC,
SOURCE_TYPE_VOICE_RECOGNITION,
SOURCE_TYPE_PLAYBACK_CAPTURE,
SOURCE_TYPE_WAKEUP,
SOURCE_TYPE_VOICE_CALL,
SOURCE_TYPE_VOICE_DOWNLINK,
SOURCE_TYPE_VOICE_COMMUNICATION,
SOURCE_TYPE_ULTRASONIC,
SOURCE_TYPE_VIRTUAL_CAPTURE,
SOURCE_TYPE_VOICE_MESSAGE,
SOURCE_TYPE_REMOTE_CAST,
SOURCE_TYPE_VOICE_TRANSCRIPTION,
SOURCE_TYPE_CAMCORDER,
SOURCE_TYPE_UNPROCESSED,
SOURCE_TYPE_LIVE,
SOURCE_TYPE_UNPROCESSED_VOICE_ASSISTANT,
SOURCE_TYPE_INTERPHONE,
};
static const std::vector<SourceType> AUDIO_FAST_STREAM_SUPPORTED_SOURCE_TYPES = {
SOURCE_TYPE_MIC,
SOURCE_TYPE_VOICE_RECOGNITION,
SOURCE_TYPE_VOICE_CALL,
SOURCE_TYPE_VOICE_DOWNLINK,
SOURCE_TYPE_VOICE_COMMUNICATION,
SOURCE_TYPE_VIRTUAL_CAPTURE,
SOURCE_TYPE_VOICE_MESSAGE,
SOURCE_TYPE_VOICE_TRANSCRIPTION,
SOURCE_TYPE_CAMCORDER,
SOURCE_TYPE_UNPROCESSED,
SOURCE_TYPE_LIVE,
};
static bool IsCockpitDirectCallerAllowed()
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
return callingUid == UID_COCKPIT_SA || callingUid == ROOT_UID;
}
static std::string BuildExtraParameterValue(const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
std::string value;
for (const auto &item : kvpairs) {
value += item.first + "=" + item.second + ";";
}
return value;
}
static bool IsVoiceModemCommunication(StreamUsage streamUsage, int32_t callingUid)
{
return streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION && callingUid == UID_CALL_MANAGER_SA;
}
static inline std::shared_ptr<IAudioRenderSink> GetSinkByProp(HdiIdType type, const std::string &info =
HDI_ID_INFO_DEFAULT, bool tryCreate = false, bool tryCreateId = true)
{
uint32_t id = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_RENDER, type, info, false, tryCreateId);
return HdiAdapterManager::GetInstance().GetRenderSink(id, tryCreate);
}
static inline std::shared_ptr<IAudioCaptureSource> GetSourceByProp(HdiIdType type, const std::string &info =
HDI_ID_INFO_DEFAULT, bool tryCreate = false)
{
uint32_t id = HdiAdapterManager::GetInstance().GetId(HDI_ID_BASE_CAPTURE, type, info);
return HdiAdapterManager::GetInstance().GetCaptureSource(id, tryCreate);
}
static void UpdateArmInstance(std::shared_ptr<IAudioRenderSink> &sink,
std::shared_ptr<IAudioCaptureSource> &source)
{
sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB, true);
source = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB, true);
std::shared_ptr<IAudioRenderSink> primarySink = GetSinkByProp(HDI_ID_TYPE_PRIMARY);
CHECK_AND_RETURN_LOG(primarySink, "primarySink is nullptr");
primarySink->ResetActiveDeviceForDisconnect(DEVICE_TYPE_NONE);
}
static void SetAudioSceneForAllSource(AudioScene audioScene, bool scoExcludeFlag,
int32_t phoneCallSceneType = SCENE_TYPE_INVALID)
{
std::vector<std::pair<HdiIdType, std::string>> sourceConfigs = {
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB},
{HDI_ID_TYPE_ACCESSORY, HDI_ID_INFO_ACCESSORY},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT},
{HDI_ID_TYPE_AI, HDI_ID_INFO_DEFAULT},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_UNPROCESS},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_ULTRASONIC},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_LIVE},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_INTERPHONE},
{HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_VOICE_RECOGNITION},
{HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_DEFAULT}
};
for (const auto& config : sourceConfigs) {
std::shared_ptr<IAudioCaptureSource> source = GetSourceByProp(config.first, config.second);
if (source != nullptr && source->IsInited()) {
source->SetAudioScene(audioScene, scoExcludeFlag, phoneCallSceneType);
}
}
#ifdef SUPPORT_LOW_LATENCY
std::shared_ptr<IAudioCaptureSource> fastSource = GetSourceByProp(HDI_ID_TYPE_FAST, HDI_ID_INFO_DEFAULT, true);
if (fastSource != nullptr && fastSource->IsInited()) {
fastSource->SetAudioScene(audioScene, scoExcludeFlag, phoneCallSceneType);
}
std::shared_ptr<IAudioCaptureSource> fastVoipSource = GetSourceByProp(HDI_ID_TYPE_FAST, HDI_ID_INFO_VOIP, true);
if (fastVoipSource != nullptr && fastVoipSource->IsInited()) {
fastVoipSource->SetAudioScene(audioScene, scoExcludeFlag, phoneCallSceneType);
}
#endif
}
static void SetAudioSceneForAllSink(AudioScene audioScene, bool scoExcludeFlag,
int32_t phoneCallSceneType = SCENE_TYPE_INVALID)
{
std::shared_ptr<IAudioRenderSink> usbSink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB);
if (usbSink != nullptr && usbSink->IsInited()) {
usbSink->SetAudioScene(audioScene, scoExcludeFlag, phoneCallSceneType);
}
std::shared_ptr<IAudioRenderSink> primarySink = GetSinkByProp(HDI_ID_TYPE_PRIMARY);
if (primarySink != nullptr && primarySink->IsInited()) {
primarySink->SetAudioScene(audioScene, scoExcludeFlag, phoneCallSceneType);
}
}
static void UpdateDeviceForAllSource(std::shared_ptr<IAudioCaptureSource> &source, DeviceType type)
{
if (source == nullptr || !source->IsInited()) {
StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
RECORD_DEVICE_SWITCH_ILLEGAL_STATE, "Capturer is not initialized", false);
AUDIO_WARNING_LOG("Capturer is not initialized.");
} else {
source->UpdateActiveDevice(type);
}
#ifdef SUPPORT_LOW_LATENCY
std::shared_ptr<IAudioCaptureSource> fastSource = GetSourceByProp(HDI_ID_TYPE_FAST, HDI_ID_INFO_DEFAULT, true);
if (fastSource != nullptr && fastSource->IsInited()) {
fastSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> fastVoipSource = GetSourceByProp(HDI_ID_TYPE_FAST, HDI_ID_INFO_VOIP, true);
if (fastVoipSource != nullptr && fastVoipSource->IsInited()) {
fastVoipSource->UpdateActiveDevice(type);
}
#endif
std::shared_ptr<IAudioCaptureSource> aiSource = GetSourceByProp(HDI_ID_TYPE_AI, HDI_ID_INFO_DEFAULT);
if (aiSource != nullptr && aiSource->IsInited()) {
aiSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> unprocessSource = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_UNPROCESS);
if (unprocessSource != nullptr && unprocessSource->IsInited()) {
unprocessSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> liveSource = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_LIVE);
if (liveSource != nullptr && liveSource->IsInited()) {
liveSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> ultrasonicSource =
GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_ULTRASONIC);
if (ultrasonicSource != nullptr && ultrasonicSource->IsInited()) {
ultrasonicSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> interphoneSource =
GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_INTERPHONE);
if (interphoneSource != nullptr && interphoneSource->IsInited()) {
interphoneSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> voiceRecognitionSource =
GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_VOICE_RECOGNITION);
if (voiceRecognitionSource != nullptr && voiceRecognitionSource->IsInited()) {
voiceRecognitionSource->UpdateActiveDevice(type);
}
std::shared_ptr<IAudioCaptureSource> rawAiSource =
GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_RAW_AI);
if (rawAiSource != nullptr && rawAiSource->IsInited()) {
rawAiSource->UpdateActiveDevice(type);
}
}
static void UpdateDeviceForOtherSinks(std::vector<DeviceType> &deviceTypes)
{
auto limitFunc = [](uint32_t renderId) -> bool {
uint32_t type = IdHandler::GetInstance().ParseType(renderId);
std::string info = IdHandler::GetInstance().ParseInfo(renderId);
if (type == HDI_ID_TYPE_OFFLOAD) {
return info == HDI_ID_INFO_DEFAULT;
}
if (type == HDI_ID_TYPE_MULTICHANNEL) {
return info == HDI_ID_INFO_DEFAULT;
}
return false;
};
auto processFunc = [&deviceTypes, limitFunc](uint32_t renderId, std::shared_ptr<IAudioRenderSink> sink) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(renderId), SUCCESS);
CHECK_AND_RETURN_RET(sink != nullptr && sink->IsInited(), SUCCESS);
sink->UpdateActiveDevice(deviceTypes);
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSink(processFunc);
}
static std::vector<std::pair<std::string, std::string>> ConvertStringPair(const std::vector<StringPair> &stringPair)
{
std::vector<std::pair<std::string, std::string>> result;
for (const auto &it : stringPair) {
result.emplace_back(it.firstParam, it.secondParam);
}
return result;
}
static std::vector<StringPair> ConvertStringPair(const std::vector<std::pair<std::string, std::string>> &result)
{
std::vector<StringPair> stringPair;
for (auto it = result.begin(); it != result.end(); it++) {
stringPair.push_back({it->first, it->second});
}
return stringPair;
}
void ProxyDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
{
CHECK_AND_RETURN_LOG(audioServer_ != nullptr, "audioServer is null");
audioServer_->RemoveRendererDataTransferCallback(pid_);
AudioStreamMonitor::GetInstance().OnCallbackAppDied(pid_);
}
PipeInfoGuard::PipeInfoGuard(uint32_t sessionId)
{
sessionId_ = sessionId;
}
PipeInfoGuard::~PipeInfoGuard()
{
if (releaseFlag_) {
CoreServiceHandler::GetInstance().UpdateSessionOperation(sessionId_, SESSION_OPERATION_RELEASE,
SESSION_OP_MSG_REMOVE_PIPE);
}
}
void PipeInfoGuard::SetReleaseFlag(bool flag)
{
releaseFlag_ = flag;
}
class CapturerStateOb final : public IAudioSourceCallback {
public:
explicit CapturerStateOb(uint32_t captureId, std::function<void(bool, size_t, size_t)> callback)
: captureId_(captureId), callback_(callback)
{
}
~CapturerStateOb() override final
{
}
void OnCaptureState(bool isActive) override final
{
std::lock_guard<std::mutex> lock(captureIdMtx_);
auto preNum = captureIds_.size();
if (isActive) {
captureIds_.insert(captureId_);
} else {
captureIds_.erase(captureId_);
}
auto curNum = captureIds_.size();
AUDIO_INFO_LOG("captureId: %{public}u, preNum: %{public}zu, curNum: %{public}zu, isActive: %{public}d",
captureId_, preNum, curNum, isActive);
callback_(isActive, preNum, curNum);
}
private:
static inline std::unordered_set<uint32_t> captureIds_;
static inline std::mutex captureIdMtx_;
uint32_t captureId_;
std::function<void(bool, size_t, size_t)> callback_;
};
class CamcorderMetadataOb final : public IAudioSourceCallback {
public:
explicit CamcorderMetadataOb(uint32_t captureId)
: captureId_(captureId)
{
}
~CamcorderMetadataOb() final
{
}
void OnHdiCaptureCallback(CaptureCallbackType type, const std::vector<uint8_t> &data) final
{
CHECK_AND_RETURN_LOG(type == CB_CAMCORDER_METADATA, "unsupported callback type: %{public}d", type);
CHECK_AND_RETURN_LOG(!data.empty(), "metadata is null.");
AUDIO_INFO_LOG("captureId: %{public}u, metadata size: %{public}zu", captureId_, data.size());
auto captureSource = HdiAdapterManager::GetInstance().GetCaptureSource(captureId_, false);
CHECK_AND_RETURN_LOG(captureSource != nullptr, "capture source is null for captureId: %{public}u", captureId_);
auto pipeInfo = captureSource->GetInputPipeInfo();
CHECK_AND_RETURN_LOG(pipeInfo != nullptr, "pipe info is null for captureId: %{public}u", captureId_);
auto streams = pipeInfo->GetStreams();
for (const auto &stream : streams) {
uint32_t streamId = stream.first;
auto capturerInServer = AudioService::GetInstance()->GetCapturerBySessionID(streamId);
if (capturerInServer == nullptr) {
AUDIO_WARNING_LOG("failed to find capturer for streamId: %{public}u", streamId);
continue;
}
int32_t ret = capturerInServer->OnMetaData(data);
if (ret != SUCCESS) {
AUDIO_WARNING_LOG("failed for streamId: %{public}u, ret: %{public}d", streamId, ret);
}
}
}
private:
uint32_t captureId_;
};
static void RegisterCamcorderMetadataCallback()
{
std::function<bool(uint32_t)> limitFunc = [](uint32_t id) -> bool {
IdHandler &idHandler = IdHandler::GetInstance();
uint32_t type = idHandler.ParseType(id);
std::string info = idHandler.ParseInfo(id);
return type == HDI_ID_TYPE_PRIMARY && info == HDI_ID_INFO_CAMCORDER;
};
std::function<std::shared_ptr<IAudioSourceCallback>(uint32_t)> callbackGenerator =
[](uint32_t captureId) -> std::shared_ptr<IAudioSourceCallback> {
return std::make_shared<CamcorderMetadataOb>(captureId);
};
HdiAdapterManager::GetInstance().RegistSourceCallbackGenerator(HDI_CB_CAPTURE_CAMCORDER_METADATA,
callbackGenerator, limitFunc);
}
REGISTER_SYSTEM_ABILITY_BY_ID(AudioServer, AUDIO_DISTRIBUTED_SERVICE_ID, true)
#ifdef SUPPORT_OLD_ENGINE
#ifdef PA
constexpr int PA_ARG_COUNT = 1;
void *AudioServer::paDaemonThread(void *arg)
{
char *argv[] = {
(char*)"pulseaudio",
};
ScheduleThreadInServer(getpid(), gettid());
paDaemonTid_ = static_cast<uint32_t>(gettid());
AUDIO_INFO_LOG("Calling ohos_pa_main\n");
ohos_pa_main(PA_ARG_COUNT, argv);
AUDIO_INFO_LOG("Exiting ohos_pa_main\n");
UnscheduleThreadInServer(getpid(), gettid());
_exit(-1);
}
#endif
#endif
AudioServer::AudioServer(int32_t systemAbilityId, bool runOnCreate)
: SystemAbility(systemAbilityId, runOnCreate),
audioEffectServer_(std::make_unique<AudioEffectServer>()),
hpaeDumpObj_(std::make_shared<AudioServerHpaeDump>())
{
AudioStreamMonitor::GetInstance().SetAudioServerPtr(this);
}
void AudioServer::OnDump() {}
int32_t AudioServer::Dump(int32_t fd, const std::vector<std::u16string> &args)
{
AUDIO_INFO_LOG("Dump Process Invoked");
if (args.size() == FAST_DUMPINFO_LEN && args[0] == u"-fb") {
std::string bundleName = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(args[1]);
std::string result;
GetAudioParameter(CHECK_FAST_BLOCK_PREFIX + bundleName, result);
std::string dumpString = "check fast list :bundle name is" + bundleName + " result is " + result + "\n";
return write(fd, dumpString.c_str(), dumpString.size());
}
if (args.size() == 1 && args[0] == u"-dfl") {
std::string dumpString;
AudioService::GetInstance()->DumpForegroundList(dumpString);
return write(fd, dumpString.c_str(), dumpString.size());
}
std::queue<std::u16string> argQue;
for (decltype(args.size()) index = 0; index < args.size(); ++index) {
argQue.push(args[index]);
}
std::lock_guard<std::mutex> lock(hpaeDumpMutex_);
std::string dumpString;
int32_t res = 0;
#ifdef SUPPORT_OLD_ENGINE
int32_t engineFlag = GetEngineFlag();
if (engineFlag == 1) {
res = hpaeDumpObj_->Initialize();
CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR,
"Audio Service Hpae Dump Not Initialed");
hpaeDumpObj_->AudioDataDump(dumpString, argQue);
} else {
AudioServerDump dumpObj;
res = dumpObj.Initialize();
CHECK_AND_RETURN_RET_LOG(res == AUDIO_DUMP_SUCCESS, AUDIO_DUMP_INIT_ERR,
"Audio Service Dump Not initialised\n");
dumpObj.AudioDataDump(dumpString, argQue);
}
#else
res = hpaeDumpObj_->Initialize();
CHECK_AND_RETURN_RET_LOG(res == SUCCESS, ERROR,
"Audio Service Hpae Dump Not Initialed");
hpaeDumpObj_->AudioDataDump(dumpString, argQue);
#endif
return write(fd, dumpString.c_str(), dumpString.size());
}
void AudioServer::RemoveRendererDataTransferCallback(const int32_t &pid)
{
std::lock_guard<std::mutex> lock(audioDataTransferMutex_);
if (audioDataTransferCbMap_.count(pid) > 0) {
audioDataTransferCbMap_.erase(pid);
}
}
int32_t AudioServer::RegisterDataTransferCallback(const sptr<IRemoteObject> &object)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "No system permission");
CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "AudioServer:set listener object is nullptr");
std::lock_guard<std::mutex> lock(audioDataTransferMutex_);
sptr<IStandardAudioServerManagerListener> listener = iface_cast<IStandardAudioServerManagerListener>(object);
CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "AudioServer: listener obj cast failed");
std::shared_ptr<DataTransferStateChangeCallbackInner> callback =
std::make_shared<AudioManagerListenerCallback>(listener);
CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "AudioPolicyServer: failed to create cb obj");
int32_t pid = IPCSkeleton::GetCallingPid();
sptr<ProxyDeathRecipient> recipient = new ProxyDeathRecipient(pid, this);
object->AddDeathRecipient(recipient);
audioDataTransferCbMap_[pid] = callback;
AUDIO_INFO_LOG("Pid: %{public}d registerDataTransferCallback done", pid);
return SUCCESS;
}
int32_t AudioServer::RegisterDataTransferMonitorParam(int32_t callbackId,
const DataTransferMonitorParam ¶m)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "No system permission");
int32_t pid = IPCSkeleton::GetCallingPid();
AudioStreamMonitor::GetInstance().RegisterAudioRendererDataTransferStateListener(
param, pid, callbackId);
AUDIO_INFO_LOG("Register end, pid = %{public}d, callbackId = %{public}d",
pid, callbackId);
return SUCCESS;
}
int32_t AudioServer::UnregisterDataTransferMonitorParam(int32_t callbackId)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "No system permission");
int32_t pid = IPCSkeleton::GetCallingPid();
AudioStreamMonitor::GetInstance().UnregisterAudioRendererDataTransferStateListener(
pid, callbackId);
AUDIO_INFO_LOG("Unregister end, pid = %{public}d, callbackId = %{public}d",
pid, callbackId);
return SUCCESS;
}
void AudioServer::OnDataTransferStateChange(const int32_t &pid, const int32_t &callbackId,
const AudioRendererDataTransferStateChangeInfo &info)
{
std::shared_ptr<DataTransferStateChangeCallbackInner> callback = nullptr;
{
std::lock_guard<std::mutex> lock(audioDataTransferMutex_);
if (audioDataTransferCbMap_.count(pid) > 0) {
callback = audioDataTransferCbMap_[pid];
} else {
AUDIO_ERR_LOG("callback is null");
return;
}
}
callback->OnDataTransferStateChange(callbackId, info);
}
void AudioServer::OnMuteStateChange(const int32_t &pid, const int32_t &callbackId,
const int32_t &uid, const uint32_t &sessionId, const bool &isMuted)
{
std::shared_ptr<DataTransferStateChangeCallbackInner> callback = nullptr;
{
std::lock_guard<std::mutex> lock(audioDataTransferMutex_);
CHECK_AND_RETURN_LOG(audioDataTransferCbMap_.find(pid) != audioDataTransferCbMap_.end(),
"pid:%{public}d no callback in CbMap", pid);
callback = audioDataTransferCbMap_[pid];
}
CHECK_AND_RETURN_LOG(callback != nullptr, "callback is null");
callback->OnMuteStateChange(callbackId, uid, sessionId, isMuted);
}
void AudioServer::RegisterDataTransferStateChangeCallback()
{
DataTransferMonitorParam param;
param.clientUID = CHECK_ALL_RENDER_UID;
param.badDataTransferTypeBitMap = (1 << NO_DATA_TRANS);
param.timeInterval = RENDER_DETECTION_CYCLE_NS;
param.badFramesRatio = RENDER_BAD_FRAMES_RATIO;
std::lock_guard<std::mutex> lock(audioDataTransferMutex_);
std::shared_ptr<DataTransferStateChangeCallbackInnerImpl> callback =
std::make_shared<DataTransferStateChangeCallbackInnerImpl>();
CHECK_AND_RETURN_LOG(callback != nullptr, "AudioPolicyServer: failed to create cb obj");
callback->SetDataTransferMonitorParam(param);
audioDataTransferCbMap_[SYSTEM_PID] = callback;
int32_t ret = AudioStreamMonitor::GetInstance().RegisterAudioRendererDataTransferStateListener(
param, SYSTEM_PID, -1);
CHECK_AND_RETURN_LOG(ret == SUCCESS, "register fail");
AUDIO_INFO_LOG("pid: %{public}d RegisterDataTransferStateChangeCallback done", SYSTEM_PID);
}
void DataTransferStateChangeCallbackInnerImpl::SetDataTransferMonitorParam(
const DataTransferMonitorParam ¶m)
{
param_.clientUID = param.clientUID;
param_.badDataTransferTypeBitMap = param.badDataTransferTypeBitMap;
param_.timeInterval = param.timeInterval;
param_.badFramesRatio = param.badFramesRatio;
}
void DataTransferStateChangeCallbackInnerImpl::OnDataTransferStateChange(
const int32_t &callbackId, const AudioRendererDataTransferStateChangeInfo &info)
{
if (info.stateChangeType == DATA_TRANS_STOP) {
ReportEvent(info);
NotifyStreamStandbyState(info, true);
CHECK_AND_RETURN(info.audioMode == AUDIO_MODE_PLAYBACK);
std::string bundleName = AppBundleManager::GetBundleNameFromUid(info.clientUID);
CHECK_AND_RETURN_LOG(AudioService::GetInstance()->InRenderWhitelist(bundleName),
"%{public}s not in whitelist", bundleName.c_str());
if (((info.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION) ||
(info.streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION) ||
(info.streamUsage == STREAM_USAGE_INTERPHONE) ||
(info.streamUsage == STREAM_USAGE_NOTIFICATION_RINGTONE) ||
(info.streamUsage == STREAM_USAGE_RINGTONE) ||
(info.streamUsage == STREAM_USAGE_NOTIFICATION)) && info.isBackground) {
int32_t ret = PolicyHandler::GetInstance().ClearAudioFocusBySessionID(info.sessionId);
CHECK_AND_RETURN_LOG(ret == SUCCESS, "focus clear fail");
}
} else if (info.stateChangeType == DATA_TRANS_RESUME) {
NotifyStreamStandbyState(info, false);
}
}
void DataTransferStateChangeCallbackInnerImpl::ReportEvent(
const AudioRendererDataTransferStateChangeInfo &info)
{
std::shared_ptr<Media::MediaMonitor::EventBean> bean = CreateStreamOccupancyEventBean(info);
CHECK_AND_RETURN_LOG(bean != nullptr, "bean is nullptr");
bean->Add("STANDBY_DURATION_S", static_cast<uint64_t>(0));
Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
}
void DataTransferStateChangeCallbackInnerImpl::ReportStandbyEvent(
const AudioRendererDataTransferStateChangeInfo &info, int32_t standbyDurationS)
{
std::shared_ptr<Media::MediaMonitor::EventBean> bean = CreateStreamOccupancyEventBean(info);
CHECK_AND_RETURN_LOG(bean != nullptr, "bean is nullptr");
bean->Add("STANDBY_DURATION_S", standbyDurationS);
Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
}
bool DataTransferStateChangeCallbackInnerImpl::IsNeedNotifyStandbyState(
const AudioRendererDataTransferStateChangeInfo &info, bool isStandby)
{
CHECK_AND_RETURN_RET(info.audioMode == AUDIO_MODE_PLAYBACK, false);
if (isStandby && !info.isBackground) {
return false;
}
return info.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION ||
info.streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION ||
info.streamUsage == STREAM_USAGE_INTERPHONE ||
info.streamUsage == STREAM_USAGE_NOTIFICATION_RINGTONE ||
info.streamUsage == STREAM_USAGE_RINGTONE ||
info.streamUsage == STREAM_USAGE_VOICE_RINGTONE ||
info.streamUsage == STREAM_USAGE_NOTIFICATION;
}
void DataTransferStateChangeCallbackInnerImpl::NotifyStreamStandbyState(
const AudioRendererDataTransferStateChangeInfo &info, bool isStandby)
{
CHECK_AND_RETURN_LOG(IsNeedNotifyStandbyState(info, isStandby), "stream no need notify standby state");
uint32_t sessionId = static_cast<uint32_t>(info.sessionId);
if (isStandby) {
int64_t startTime = ClockTime::GetCurNano();
{
std::lock_guard<std::mutex> lock(standbyMutex_);
standbyStartTimeMap_[sessionId] = startTime;
}
int32_t ret = CoreServiceHandler::GetInstance().NotifyStreamStandby(info.clientPid, info.sessionId);
if (ret != SUCCESS) {
std::lock_guard<std::mutex> lock(standbyMutex_);
standbyStartTimeMap_.erase(sessionId);
AUDIO_ERR_LOG("notify stream standby fail, ret %{public}d", ret);
}
return;
}
int64_t uploadTime = ClockTime::GetCurNano();
int64_t startTime = 0;
{
std::lock_guard<std::mutex> lock(standbyMutex_);
auto iter = standbyStartTimeMap_.find(sessionId);
CHECK_AND_RETURN_LOG(iter != standbyStartTimeMap_.end(), "standby start time not found");
startTime = iter->second;
standbyStartTimeMap_.erase(iter);
}
int32_t standbyDurationS = static_cast<int32_t>((uploadTime - startTime) / AUDIO_NS_PER_SECOND);
ReportStandbyEvent(info, standbyDurationS);
int32_t ret = CoreServiceHandler::GetInstance().NotifyStreamStandbyResume(info.clientPid, info.sessionId);
CHECK_AND_RETURN_LOG(ret == SUCCESS, "notify stream standby resume fail, ret %{public}d", ret);
}
void AudioServer::InitMaxRendererStreamCntPerUid()
{
bool result = GetSysPara("const.multimedia.audio.stream_cnt_uid", maxRendererStreamCntPerUid_);
if (!result || maxRendererStreamCntPerUid_ <= 0) {
maxRendererStreamCntPerUid_ = MAX_RENDERER_STREAM_CNT_PER_UID;
}
}
void AudioServer::OnStartExpansion()
{
RegisterAudioCapturerSourceCallback();
RegisterAudioRendererSinkCallback();
ParseAudioParameter();
InitHdiEventCallback();
}
void AudioServer::RecordBootStateTime(AudioServerBootState state, int64_t curTime)
{
CHECK_AND_RETURN(hpaeDumpObj_, "hpaeDumpObj_ is nullptr");
hpaeDumpObj_->RecordBootStateTime(state, curTime);
}
void AudioServer::InitAudioEngine()
{
#ifdef SUPPORT_OLD_ENGINE
int32_t engineFlag = GetEngineFlag();
if (engineFlag == 1) {
HPAE::IHpaeManager::GetHpaeManager().Init();
HPAE::IHpaeManager::GetHpaeManager().SetPersonalizedSpatializationStateResultCallback(
[](int32_t ret) {
PolicyHandler::GetInstance().NotifyUpdatePersonalizedSpatializationStateResult(ret);
});
AUDIO_INFO_LOG("IHpaeManager Init\n");
} else {
#ifdef PA
int32_t ret = pthread_create(&m_paDaemonThread, nullptr, AudioServer::paDaemonThread, nullptr);
pthread_setname_np(m_paDaemonThread, "OS_PaDaemon");
if (ret != 0) {
AUDIO_ERR_LOG("pthread_create failed %d", ret);
WriteServiceStartupError();
}
AUDIO_DEBUG_LOG("Created paDaemonThread\n");
#endif
}
#else
HPAE::IHpaeManager::GetHpaeManager().Init();
HPAE::IHpaeManager::GetHpaeManager().SetPersonalizedSpatializationStateResultCallback(
[](int32_t ret) {
PolicyHandler::GetInstance().NotifyUpdatePersonalizedSpatializationStateResult(ret);
});
AUDIO_INFO_LOG("IHpaeManager Init\n");
#endif
RecordBootStateTime(AudioServerBootState::INIT_PREEAUDIO, ClockTime::GetCurMilli());
}
void AudioServer::OnStart()
{
RecordBootStateTime(AudioServerBootState::BEGIN, ClockTime::GetCurMilli());
AUDIO_INFO_LOG("OnStart uid:%{public}d", getuid());
RecordBootStateTime(AudioServerBootState::LOAD_LIBXML2, ClockTime::GetCurMilli());
DlopenUtils::Init();
auto info = AudioDeviceEnhanceManager::GetInstance().GetSoundCardInfo();
if (!info.IsEmpty()) {
cacheSoundCardInfo_ = std::make_shared<SoundCardInfo>(info);
AUDIO_INFO_LOG("Cached sound card info: name=%{public}s", info.name.c_str());
}
InitMaxRendererStreamCntPerUid();
AudioInnerCall::GetInstance()->RegisterAudioServer(this);
asyncHandler_ = std::make_shared<AsyncActionHandler>("OS_ASAsyncHandler");
bool res = Publish(this);
RecordBootStateTime(AudioServerBootState::PUBLISH_AVAILABLE, ClockTime::GetCurMilli());
if (!res) {
AUDIO_ERR_LOG("start err");
WriteServiceStartupError();
}
int32_t audioCacheState = 0;
GetSysPara("persist.multimedia.audio.audioCacheState", audioCacheState);
if (audioCacheState != 0) {
AudioCacheMgr::GetInstance().Init();
}
* NOTICE:
* If the listening SA has already started, it immediately runs a callback on the main thread.
* Don't randomly change the current listening order.
* Otherwise, OnStart() might take too long.
*/
AddSystemAbilityListener(AUDIO_POLICY_SERVICE_ID);
AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID);
AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
InitAudioEngine();
OnStartExpansion();
DlopenUtils::DeInit();
RegisterDataTransferStateChangeCallback();
RecordBootStateTime(AudioServerBootState::END, ClockTime::GetCurMilli());
}
void AudioServer::ParseAudioParameter()
{
std::unique_ptr<AudioParamParser> audioParamParser = make_unique<AudioParamParser>();
if (audioParamParser == nullptr) {
WriteServiceStartupError();
}
CHECK_AND_RETURN_LOG(audioParamParser != nullptr, "Failed to create audio extra parameters parser");
if (audioParamParser->LoadConfiguration(audioParameterKeys)) {
AUDIO_INFO_LOG("Audio extra parameters load configuration successfully.");
}
NotifyAudioParameterParsed();
RecordBootStateTime(AudioServerBootState::LOAD_AUDIO_PARAM_CONFIG_XML, ClockTime::GetCurMilli());
PermissionUtil::UpdateBGSet();
}
void AudioServer::NotifyAudioParameterParsed()
{
std::lock_guard<std::mutex> lock(audioParameterCacheMutex_);
isAudioParameterParsed_.store(true);
isAudioParameterParsedCv_.notify_all();
}
bool AudioServer::WaitAudioParameterParsed()
{
if (isAudioParameterParsed_.load()) {
return true;
}
std::unique_lock<std::mutex> lock(audioParameterCacheMutex_);
return isAudioParameterParsedCv_.wait_for(lock, std::chrono::seconds(WAIT_AUDIO_PARAMETER_PARSED_TIMEOUT_SECONDS),
[this]() { return isAudioParameterParsed_.load(); });
}
void AudioServer::WriteServiceStartupError()
{
Trace trace("SYSEVENT FAULT EVENT AUDIO_SERVICE_STARTUP_ERROR, SERVICE_ID: "
+ std::to_string(Media::MediaMonitor::AUDIO_SERVER_ID) + ", ERROR_CODE: "
+ std::to_string(Media::MediaMonitor::AUDIO_SERVER));
std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_SERVICE_STARTUP_ERROR,
Media::MediaMonitor::FAULT_EVENT);
bean->Add("SERVICE_ID", static_cast<int32_t>(Media::MediaMonitor::AUDIO_SERVER_ID));
bean->Add("ERROR_CODE", static_cast<int32_t>(Media::MediaMonitor::AUDIO_SERVER));
Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
}
void AudioServer::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
{
AUDIO_DEBUG_LOG("systemAbilityId:%{public}d", systemAbilityId);
switch (systemAbilityId) {
case AUDIO_POLICY_SERVICE_ID:
AUDIO_INFO_LOG("input service start");
RegisterPolicyServerDeathRecipient();
break;
case RES_SCHED_SYS_ABILITY_ID:
AUDIO_INFO_LOG("ressched service start");
OnAddResSchedService(getpid());
RegisterResSchedSys();
break;
case MEMORY_MANAGER_SA_ID:
AUDIO_INFO_LOG("memory manager service start");
NotifyProcessStatus();
break;
default:
AUDIO_ERR_LOG("unhandled sysabilityId:%{public}d", systemAbilityId);
break;
}
}
void AudioServer::RegisterResSchedSys()
{
AudioSystemloadListener listener;
listener.RegisterResSchedSys();
}
void AudioServer::OnStop()
{
AUDIO_DEBUG_LOG("OnStop");
}
bool AudioServer::SetPcmDumpParameter(const std::vector<std::pair<std::string, std::string>> ¶ms)
{
bool ret = VerifyClientPermission(DUMP_AUDIO_PERMISSION);
CHECK_AND_RETURN_RET_LOG(ret, false, "set audiodump parameters failed: no permission.");
CHECK_AND_RETURN_RET_LOG(params.size() > 0, false, "params is empty!");
return AudioCacheMgr::GetInstance().SetDumpParameter(params);
}
bool AudioServer::SetEffectLiveParameter(const std::vector<std::pair<std::string, std::string>> ¶ms)
{
CHECK_AND_RETURN_RET_LOG(params.size() > 0, false, "params is empty!");
int32_t engineFlag = GetEngineFlag();
if (engineFlag == 1) {
return HPAE::IHpaeManager::GetHpaeManager().SetEffectLiveParameter(params);
}
AUDIO_INFO_LOG("SetEffectLiveParameter not support");
return false;
}
void AudioServer::HapReportWakeupEvent(const std::string &key,
const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
CHECK_AND_RETURN(key == MAIN_KEY_DFX);
for (const auto &kvPair : kvpairs) {
CHECK_AND_CONTINUE(kvPair.first == SUB_KEY_UPDATE_WAKEUP_TRACE_RESULT);
cJSON *root = cJSON_Parse(kvPair.second.c_str());
CHECK_AND_RETURN_LOG(root != nullptr, "parse json failed");
cJSON *stageObj = cJSON_GetObjectItem(root, "stage");
cJSON *resultObj = cJSON_GetObjectItem(root, "result");
cJSON *errCodeObj = cJSON_GetObjectItem(root, "errCode");
CHECK_AND_CALL_FUNC_RETURN_LOG(stageObj != nullptr && resultObj != nullptr && errCodeObj != nullptr &&
cJSON_IsString(stageObj) && cJSON_IsString(resultObj) && cJSON_IsString(errCodeObj),
cJSON_Delete(root), "invalid json fields");
std::string stageStr = stageObj->valuestring;
std::string resultStr = resultObj->valuestring;
std::string errCodeStr = errCodeObj->valuestring;
cJSON_Delete(root);
int32_t stage = 0;
int32_t result = 0;
int32_t errCode = 0;
CHECK_AND_BREAK_LOG(sscanf_s(stageStr.c_str(), "%i", &stage) == 1, "parse stage failed");
CHECK_AND_BREAK_LOG(sscanf_s(resultStr.c_str(), "%i", &result) == 1, "parse result failed");
CHECK_AND_BREAK_LOG(sscanf_s(errCodeStr.c_str(), "%i", &errCode) == 1, "parse errCode failed");
AudioWakeupTrackInfo audioWakeupTrackInfo;
audioWakeupTrackInfo.stage = static_cast<AudioWakeupStageCode>(stage);
audioWakeupTrackInfo.result = static_cast<AudioWakeupResult>(result);
audioWakeupTrackInfo.errCode = static_cast<AudioWakeupErrorCode>(errCode);
AUDIO_INFO_LOG("stage=%{public}d, result=%{public}d, errCode=%{public}d",
audioWakeupTrackInfo.stage, audioWakeupTrackInfo.result, audioWakeupTrackInfo.errCode);
ReportWakeupEvent(audioWakeupTrackInfo);
break;
}
}
int32_t AudioServer::TrySetAudioEffectParameterToRemote(std::vector<std::pair<std::string, std::string>> &newPair)
{
std::string networkId = LOCAL_NETWORK_ID;
std::string value = "";
for (auto it = newPair.begin(); it != newPair.end();) {
if (it->first == NETWORK_ID_KEY) {
networkId = it->second;
it = newPair.erase(it);
} else {
std::string itemValue = (value == "" ? "" : ";") + it->first + "=" + it->second;
value += itemValue;
++it;
}
}
CHECK_AND_RETURN_RET(networkId != LOCAL_NETWORK_ID &&
PolicyHandler::GetInstance().IsValidNetworkIdForSendEffectParam(networkId), ERR_NOT_SUPPORTED);
AUDIO_INFO_LOG("found match device, networkId: %{public}s", GetEncryptStr(networkId).c_str());
auto mainKeyIt = audioParameterKeys.find(AUDIO_EFFECT_KEY);
CHECK_AND_RETURN_RET_LOG(mainKeyIt != audioParameterKeys.end(), ERR_INVALID_PARAM, "invalid mainkey");
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> remoteDeviceManager =
manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
CHECK_AND_RETURN_RET_LOG(remoteDeviceManager != nullptr, ERROR, "remote device manager is nullptr");
remoteDeviceManager->SetAudioParameter(networkId, AudioParamKey::NONE, "", value);
return SUCCESS;
}
int32_t AudioServer::SetExtraParameters(const std::string &key,
const std::vector<StringPair> &kvpairs)
{
Trace trace("AudioServer::SetExtraParameters" + key);
CHECK_AND_RETURN_RET_LOG(kvpairs.size() >= 0 && kvpairs.size() <= AUDIO_EXTRA_PARAMETERS_COUNT_UPPER_LIMIT,
AUDIO_ERR, "Set extra audio parameters failed");
bool ret = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(ret, ERR_SYSTEM_PERMISSION_DENIED, "set extra parameters failed: not system app.");
ret = VerifyClientPermission(MODIFY_AUDIO_SETTINGS_PERMISSION);
CHECK_AND_RETURN_RET_LOG(ret, ERR_PERMISSION_DENIED, "set extra parameters failed: no permission.");
std::vector<std::pair<std::string, std::string>> newPair = ConvertStringPair(kvpairs);
CHECK_AND_RETURN_RET_LOG(WaitAudioParameterParsed(), ERROR,
"set extra parameters failed: audio parameters not ready");
if (key == EFFECT_LIVE_KEY) {
return SetEffectLiveExtraParameters(newPair);
}
if (key == PCM_DUMP_KEY) {
return SetPcmDumpExtraParameters(newPair);
}
if (key == HOME_MUSIC_KEY) {
return SetHomeMusicExtraParameters(newPair);
}
if (key == COCKPIT_DIRECT_KEY) {
return SetCockpitDirectExtraParameters(newPair);
}
if (key == AUDIO_EFFECT_KEY) {
int32_t ret = TrySetAudioEffectParameterToRemote(newPair);
CHECK_AND_RETURN_RET(ret == ERR_NOT_SUPPORTED, SUCCESS);
}
return SetCommonExtraParameters(key, newPair);
}
int32_t AudioServer::SetHomeMusicExtraParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
CHECK_AND_RETURN_RET_LOG(kvpairs.size() == KVPAIRS_LEN, AUDIO_ERR, "set extra audio parameters failed: size");
std::string homeMusicNetworkId = kvpairs[0].second;
std::string homeMusicZoneValue = kvpairs[1].second;
return HdiAdapterManager::GetInstance().SetExtraParameters(HDI_DEVICE_MANAGER_TYPE_REMOTE,
homeMusicNetworkId, ZONE_ID_CHANGE, homeMusicZoneValue);
}
int32_t AudioServer::SetEffectLiveExtraParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
bool ret = SetEffectLiveParameter(kvpairs);
CHECK_AND_RETURN_RET_LOG(ret, ERROR, "set effect live parameters failed.");
return SUCCESS;
}
int32_t AudioServer::SetPcmDumpExtraParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
bool ret = SetPcmDumpParameter(kvpairs);
CHECK_AND_RETURN_RET_LOG(ret, ERROR, "set audiodump parameters failed");
return SUCCESS;
}
int32_t AudioServer::SetCockpitDirectExtraParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
CHECK_AND_RETURN_RET_LOG(IsCockpitDirectCallerAllowed(), ERR_PERMISSION_DENIED,
"set cockpit direct extra parameters failed: invalid caller uid");
return HdiAdapterManager::GetInstance().SetExtraParameters(HDI_DEVICE_MANAGER_TYPE_LOCAL, "primary", "",
BuildExtraParameterValue(kvpairs));
}
int32_t AudioServer::SetCommonExtraParameters(const std::string &key,
const std::vector<std::pair<std::string, std::string>> &kvpairs)
{
HapReportWakeupEvent(key, kvpairs);
if (audioParameterKeys.empty()) {
AUDIO_ERR_LOG("audio extra parameters mainKey and subKey is empty");
return ERROR;
}
auto mainKeyIt = audioParameterKeys.find(key);
if (mainKeyIt == audioParameterKeys.end()) {
return ERR_INVALID_PARAM;
}
std::string value;
bool isParamValid = ProcessKeyValuePairs(key, kvpairs, mainKeyIt->second, value);
CHECK_AND_RETURN_RET(isParamValid, ERR_INVALID_PARAM);
if (key == ACCESSORY_EXTRA_KEY) {
return HdiAdapterManager::GetInstance().SetExtraParameters(HDI_DEVICE_MANAGER_TYPE_LOCAL,
"accessory", "", value);
} else {
return HdiAdapterManager::GetInstance().SetExtraParameters(HDI_DEVICE_MANAGER_TYPE_LOCAL,
"primary", "", value);
}
}
bool AudioServer::ProcessKeyValuePairs(const std::string &key,
const std::vector<std::pair<std::string, std::string>> &kvpairs,
const std::unordered_map<std::string, std::set<std::string>> &subKeyMap, std::string &value)
{
for (auto it = kvpairs.begin(); it != kvpairs.end(); it++) {
auto subKeyIt = subKeyMap.find(it->first);
if (subKeyIt != subKeyMap.end()) {
value += it->first + "=" + it->second + ";";
if (it->first == "unprocess_audio_effect") {
int appUid = IPCSkeleton::GetCallingUid();
AUDIO_INFO_LOG("add unprocess UID [%{public}d]", appUid);
IStreamManager::GetRecorderManager().AddUnprocessStream(appUid);
continue;
}
auto valueIter = subKeyIt->second.find("effect");
if (valueIter != subKeyIt->second.end()) {
RecognizeAudioEffectType(key, it->first, it->second);
}
} else {
return false;
}
}
return true;
}
bool AudioServer::CheckAndPreStoreA2dpParam(std::shared_ptr<IAudioRenderSink> btSink,
AudioParamKey parmKey, const std::string &renderValue)
{
if (btSink == nullptr || !btSink->IsInited()) {
AUDIO_WARNING_LOG("has no valid sink, need preStore %{public}s.", renderValue.c_str());
HdiAdapterManager::GetInstance().
UpdateSinkPrestoreInfo<std::pair<AudioParamKey, std::pair<std::string, std::string>>>(
PRESTORE_INFO_AUDIO_BT_PARAM, {parmKey, {"", renderValue}});
return false;
}
return true;
}
void AudioServer::SetA2dpAudioParameter(const std::string &renderValue)
{
std::lock_guard<std::mutex> lock(setA2dpParamMutex_);
auto parmKey = AudioParamKey::A2DP_SUSPEND_STATE;
std::shared_ptr<IAudioRenderSink> btSink = GetSinkByProp(HDI_ID_TYPE_BLUETOOTH);
CHECK_AND_RETURN(CheckAndPreStoreA2dpParam(btSink, parmKey, renderValue));
btSink->SetAudioParameter(parmKey, "", renderValue);
if (AudioService::GetInstance()->HasBluetoothEndpoint()) {
std::shared_ptr<IAudioRenderSink> btFastSink = GetSinkByProp(HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_MMAP);
CHECK_AND_RETURN_LOG(btFastSink != nullptr, "has no valid fast sink");
btFastSink->SetAudioParameter(parmKey, "", renderValue);
AUDIO_INFO_LOG("HasBlueToothEndpoint");
}
}
int32_t AudioServer::SetAudioParameter(const std::string &key, const std::string &value)
{
std::lock_guard<std::mutex> lockSet(audioParameterMutex_);
AudioXCollie audioXCollie("AudioServer::SetAudioParameter", TIME_OUT_SECONDS,
nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
CHECK_AND_RETURN_RET_LOG(AudioParameterValueCheck(key, value), ERR_INVALID_PARAM,
"AudioParameterValueCheck fail! key: %{public}s, value: %{public}s", key.c_str(), value.c_str());
if (key == "record_denoise_mode") {
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "no audio permission");
} else if (key != "AUDIO_EXT_PARAM_KEY_A2DP_OFFLOAD_CONFIG") {
bool ret = VerifyClientPermission(MODIFY_AUDIO_SETTINGS_PERMISSION);
CHECK_AND_RETURN_RET_LOG(ret, ERR_PERMISSION_DENIED, "MODIFY_AUDIO_SETTINGS permission denied");
} else {
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "modify permission denied");
}
if (key == "record_denoise_mode") {
AudioServer::audioParameters[key] = value;
std::string halName = "primary";
HdiAdapterManager::GetInstance().SetAudioParameter(HDI_DEVICE_MANAGER_TYPE_LOCAL, halName,
AudioParamKey::NONE, "", "record_denoise_mode=" + value);
return SUCCESS;
}
if (key == "VOICE_PHONE_STATUS") {
AudioServer::audioParameters[key] = value;
return SUCCESS;
}
if (key == "A2dpSuspended") {
AudioServer::audioParameters[key] = value;
SetA2dpAudioParameter(key + "=" + value + ";");
return SUCCESS;
}
AudioParamKey parmKey = AudioParamKey::NONE;
std::string valueNew = value;
std::string halName = "primary";
CHECK_AND_RETURN_RET(UpdateAudioParameterInfo(key, value, parmKey, valueNew, halName), SUCCESS);
CHECK_AND_RETURN_RET_LOG(audioParameters.size() < PARAMETER_SET_LIMIT, ERR_INVALID_PARAM, "too large!");
AudioServer::audioParameters[key] = value;
std::shared_ptr<IAudioCaptureSource> source = GetSourceByProp(HDI_ID_TYPE_VA, HDI_ID_INFO_VA, true);
if (source != nullptr) {
source->SetAudioParameter(parmKey, "", valueNew);
}
HdiAdapterManager::GetInstance().SetAudioParameter(HDI_DEVICE_MANAGER_TYPE_LOCAL, halName, parmKey, "", valueNew);
return SUCCESS;
}
bool AudioServer::UpdateAudioParameterInfo(const std::string &key, const std::string &value,
AudioParamKey &parmKey, std::string &valueNew, std::string &halName)
{
if (key == "AUDIO_EXT_PARAM_KEY_LOWPOWER") {
parmKey = AudioParamKey::PARAM_KEY_LOWPOWER;
HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO, "SMARTPA_LOWPOWER",
HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "STATE", valueNew == "SmartPA_lowpower=on" ? 1 : 0);
} else if (key == "bt_headset_nrec") {
parmKey = AudioParamKey::BT_HEADSET_NREC;
} else if (key == "bt_wbs") {
parmKey = AudioParamKey::BT_WBS;
} else if (key == "AUDIO_EXT_PARAM_KEY_A2DP_OFFLOAD_CONFIG") {
parmKey = AudioParamKey::A2DP_OFFLOAD_STATE;
valueNew = "a2dpOffloadConfig=" + value;
} else if (key == "mmi") {
parmKey = AudioParamKey::MMI;
} else if (key == "perf_info") {
parmKey = AudioParamKey::PERF_INFO;
} else if (key == "mute_call" || key == "game_record_recognition" || key == "nearLink_collaborative_state") {
valueNew = key + "=" + value;
} else if (key == "LOUD_VOLUMN_MODE") {
parmKey = AudioParamKey::NONE;
char param[128] = {0};
errno_t ret = memcpy_s(param, sizeof(param), value.c_str(), value.length());
if (ret != 0) {
AUDIO_ERR_LOG("LOUD_VOLUMN_MODE key and value is error");
return false;
}
char *subkey = std::strtok(param, "=");
char *strvalue = std::strtok(NULL, "=");
CHECK_AND_RETURN_RET_LOG(!(subkey == nullptr || strvalue == nullptr), false, "subkey and strvalue is nullptr");
RecognizeAudioEffectType(key, (std::string)subkey, (std::string)strvalue);
AUDIO_INFO_LOG("LOUD_VOLUMN_MODE mainkey = %{public}s, key = %{public}s, value = %{public}s",
key.c_str(), subkey, strvalue);
} else if ((key == "pm_kara") || (key == "pm_kara_code")) {
parmKey = AudioParamKey::USB_DEVICE;
halName = "usb";
valueNew = key + "=" +value;
} else if (key == "outdoor_mode") {
parmKey = AudioParamKey::NONE;
valueNew = key + "=" + value;
std::string newmainkey = "audio_effect";
AUDIO_INFO_LOG("outdoor_mode key = %{public}s, value = %{public}s", key.c_str(), value.c_str());
RecognizeAudioEffectType(newmainkey, key, value);
} else {
return false;
}
return true;
}
int32_t AudioServer::SetAuxiliarySinkEnable(bool isEnabled)
{
uid_t callingUid = static_cast<uid_t>(IPCSkeleton::GetCallingUid());
#ifdef AUDIO_BUILD_VARIANT_ROOT
if (callingUid == ROOT_UID) {
return HPAE::IHpaeManager::GetHpaeManager().SetAuxiliarySinkEnable(isEnabled);
}
#endif
CHECK_AND_RETURN_RET_LOG(callingUid == UID_MSDP_SA, ERROR,
"set fail! caller:[%{public}d] is not MSDP", callingUid);
return HPAE::IHpaeManager::GetHpaeManager().SetAuxiliarySinkEnable(isEnabled);
}
int32_t AudioServer::SuspendRenderSink(const std::string &sinkName)
{
if (!PermissionUtil::VerifyIsAudio()) {
AUDIO_ERR_LOG("not audio calling!");
return ERR_OPERATION_FAILED;
}
uint32_t id = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(sinkName.c_str());
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(id);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERROR, "get sink fail, sinkName: %{public}s", sinkName.c_str());
return sink->SuspendRenderSink();
}
int32_t AudioServer::RestoreRenderSink(const std::string &sinkName)
{
if (!PermissionUtil::VerifyIsAudio()) {
AUDIO_ERR_LOG("not audio calling!");
return ERR_OPERATION_FAILED;
}
uint32_t id = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(sinkName.c_str());
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(id);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERROR, "get sink fail, sinkName: %{public}s", sinkName.c_str());
return sink->RestoreRenderSink();
}
int32_t AudioServer::SetAudioParameter(const std::string& networkId, int32_t key, const std::string& condition,
const std::string& value)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
bool ret = VerifyClientPermission(ACCESS_NOTIFICATION_POLICY_PERMISSION);
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio() || ret, ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
return HdiAdapterManager::GetInstance().SetAudioParameter(HDI_DEVICE_MANAGER_TYPE_REMOTE,
networkId, static_cast<AudioParamKey>(key), condition, value);
}
bool AudioServer::GetPcmDumpParameter(const std::vector<std::string> &subKeys,
std::vector<std::pair<std::string, std::string>> &result)
{
bool ret = VerifyClientPermission(DUMP_AUDIO_PERMISSION);
CHECK_AND_RETURN_RET_LOG(ret, false, "get audiodump parameters no permission");
CHECK_AND_RETURN_RET_LOG(subKeys.size() > 0, false, "subKeys is empty!");
return AudioCacheMgr::GetInstance().GetDumpParameter(subKeys, result);
}
int32_t AudioServer::GetTaskIdParameter(const std::vector<std::string> &subKeys,
std::vector<std::pair<std::string, std::string>> &result)
{
for (const std::string &key : subKeys) {
result.push_back(std::make_pair(key, playTaskId_));
}
AUDIO_INFO_LOG("GetTaskIdParameter %{public}s", playTaskId_.c_str());
return SUCCESS;
}
bool AudioServer::GetEffectLiveParameter(const std::vector<std::string> &subKeys,
std::vector<std::pair<std::string, std::string>> &result)
{
int32_t engineFlag = GetEngineFlag();
if (engineFlag == 1) {
return HPAE::IHpaeManager::GetHpaeManager().GetEffectLiveParameter(subKeys, result);
}
AUDIO_INFO_LOG("GetEffectLiveParameter not support");
return false;
}
int32_t AudioServer::GetExtraParameters(const std::string &mainKey,
const std::vector<std::string> &subKeys, std::vector<StringPair> ¶meters)
{
CHECK_AND_RETURN_RET_LOG(subKeys.size() >= 0 && subKeys.size() <= AUDIO_EXTRA_PARAMETERS_COUNT_UPPER_LIMIT,
AUDIO_ERR, "Get extra audio parameters failed");
std::vector<std::pair<std::string, std::string>> result;
int32_t res = GetExtraParametersInner(mainKey, subKeys, result);
if (res == SUCCESS) {
parameters = ConvertStringPair(result);
}
return res;
}
int32_t AudioServer::GetExtraParametersInner(const std::string &mainKey,
const std::vector<std::string> &subKeys, std::vector<std::pair<std::string, std::string>> &result)
{
CHECK_AND_RETURN_RET_LOG(WaitAudioParameterParsed(), ERROR,
"get extra parameters failed: audio parameters not ready");
if (mainKey == EFFECT_LIVE_KEY) {
bool ret = GetEffectLiveParameter(subKeys, result);
CHECK_AND_RETURN_RET_LOG(ret, ERROR, "get effect live parameters failed.");
return SUCCESS;
} else if (mainKey == PCM_DUMP_KEY) {
bool ret = GetPcmDumpParameter(subKeys, result);
CHECK_AND_RETURN_RET_LOG(ret, ERROR, "get audiodump parameters failed");
return SUCCESS;
} else if (mainKey == HOME_MUSIC_KEY) {
return GetTaskIdParameter(subKeys, result);
} else if (mainKey == COCKPIT_DIRECT_KEY) {
CHECK_AND_RETURN_RET_LOG(IsCockpitDirectCallerAllowed(), ERR_PERMISSION_DENIED,
"get cockpit direct extra parameters failed: invalid caller uid");
return HdiAdapterManager::GetInstance().GetExtraParameters("primary", subKeys, result);
}
if (audioParameterKeys.empty()) {
AUDIO_ERR_LOG("audio extra parameters mainKey and subKey is empty");
return ERROR;
}
auto mainKeyIt = audioParameterKeys.find(mainKey);
if (mainKeyIt == audioParameterKeys.end()) {
return ERR_INVALID_PARAM;
}
std::vector<std::string> validSubKeys;
if (subKeys.empty()) {
for (const auto &item : mainKeyIt->second) {
validSubKeys.emplace_back(item.first);
}
} else {
for (const auto &subKey : subKeys) {
auto subKeyIt = mainKeyIt->second.find(subKey);
if (subKeyIt == mainKeyIt->second.end()) {
result.clear();
return ERR_INVALID_PARAM;
}
validSubKeys.emplace_back(subKey);
}
}
if (mainKey == ACCESSORY_EXTRA_KEY) {
return HdiAdapterManager::GetInstance().GetExtraParameters("accessory", validSubKeys, result);
} else {
return HdiAdapterManager::GetInstance().GetExtraParameters("primary", validSubKeys, result);
}
}
int32_t AudioServer::GetAudioParameter(const std::string &key, std::string &value)
{
value = GetAudioParameterInner(key);
if (value == "") {
value = GetVAParameter(key);
}
return SUCCESS;
}
const std::string AudioServer::GetAudioParameterInner(const std::string &key)
{
if (IPCSkeleton::GetCallingUid() == MEDIA_SERVICE_UID) {
return "";
}
std::lock_guard<std::mutex> lockSet(audioParameterMutex_);
AudioXCollie audioXCollie("GetAudioParameter", TIME_OUT_SECONDS,
nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
if (key == "record_denoise_mode_support") {
auto result = HdiAdapterManager::GetInstance().GetAudioParameterByKey(
HDI_DEVICE_MANAGER_TYPE_LOCAL, "record_denoise_mode_support");
if (result.has_value() && !result.value().empty()) {
return result.value();
}
return "";
}
auto result = HdiAdapterManager::GetInstance().GetAudioParameterByKey(HDI_DEVICE_MANAGER_TYPE_LOCAL, key);
if (result.has_value()) {
return result.value();
}
if (AudioServer::audioParameters.count(key)) {
return AudioServer::audioParameters[key];
} else {
return "";
}
}
const std::string AudioServer::GetVAParameter(const std::string &key)
{
AudioParamKey parmKey = AudioParamKey::NONE;
std::shared_ptr<IAudioCaptureSource> source = GetSourceByProp(HDI_ID_TYPE_VA, HDI_ID_INFO_VA, true);
if (source != nullptr) {
if (key == "AUDIO_EXT_PARAM_KEY_LOWPOWER") {
parmKey = AudioParamKey::PARAM_KEY_LOWPOWER;
return source->GetAudioParameter(AudioParamKey(parmKey), "");
}
if (key.find("need_change_usb_device#C") == 0) {
parmKey = AudioParamKey::USB_DEVICE;
return source->GetAudioParameter(AudioParamKey(parmKey), key);
}
if (key == "getSmartPAPOWER" || key == "show_RealTime_ChipModel") {
return source->GetAudioParameter(AudioParamKey::NONE, key);
}
if (key == "perf_info") {
return source->GetAudioParameter(AudioParamKey::PERF_INFO, key);
}
if (key == "concurrent_capture_stream_info") {
return source->GetAudioParameter(AudioParamKey::NONE, key);
}
if (key.size() < BUNDLENAME_LENGTH_LIMIT && key.size() > CHECK_FAST_BLOCK_PREFIX.size() &&
key.substr(0, CHECK_FAST_BLOCK_PREFIX.size()) == CHECK_FAST_BLOCK_PREFIX) {
return source->GetAudioParameter(AudioParamKey::NONE, key);
}
const std::string mmiPre2 = "mmi_";
if (key.size() > mmiPre2.size() && key.substr(0, mmiPre2.size()) == mmiPre2) {
parmKey = AudioParamKey::MMI;
return source->GetAudioParameter(AudioParamKey(parmKey),
key.substr(mmiPre2.size(),
key.size() - mmiPre2.size()));
} else {
return "";
}
} else {
return "";
}
}
const std::string AudioServer::GetDPParameter(const std::string &condition)
{
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DP, true);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, "", "get dp sink fail");
return sink->GetAudioParameter(AudioParamKey::GET_DP_DEVICE_INFO, condition);
}
const std::string AudioServer::GetUsbParameter(const std::string &condition)
{
AUDIO_INFO_LOG("AudioServer::GetUsbParameter Entry. condition=%{public}s", condition.c_str());
string address = GetField(condition, "address", ' ');
int32_t deviceRoleNum = static_cast<int32_t>(DEVICE_ROLE_NONE);
std::string usbInfoStr;
CHECK_AND_RETURN_RET_LOG(StringConverter(GetField(condition, "role", ' '), deviceRoleNum), usbInfoStr,
"convert invalid value: %{public}s", GetField(condition, "role", ' ').c_str());
DeviceRole role = static_cast<DeviceRole>(deviceRoleNum);
lock_guard<mutex> lg(mtxGetUsbParameter_);
std::string infoCond = std::string("get_usb_info#C") + GetField(address, "card", ';') + "D0";
if (role == OUTPUT_DEVICE || role == INPUT_DEVICE) {
auto it = usbInfoMap_.find(address);
if (it == usbInfoMap_.end()) {
usbInfoStr = HdiAdapterManager::GetInstance().GetAudioParameter(HDI_DEVICE_MANAGER_TYPE_LOCAL,
"usb", USB_DEVICE, infoCond);
usbInfoMap_[address] = usbInfoStr;
} else {
usbInfoStr = it->second;
}
} else {
usbInfoMap_.erase(address);
}
AUDIO_INFO_LOG("infoCond=%{public}s, usbInfoStr=%{public}s", infoCond.c_str(), usbInfoStr.c_str());
return usbInfoStr;
}
int32_t AudioServer::GetAudioParameter(const std::string& networkId, int32_t key,
const std::string& condition, std::string& value)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio() ||
VerifyClientPermission(ACCESS_NOTIFICATION_POLICY_PERMISSION), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
value = GetAudioParameterInner(networkId, static_cast<AudioParamKey>(key), condition);
return SUCCESS;
}
const std::string AudioServer::GetAudioParameterInner(const std::string& networkId, const AudioParamKey key,
const std::string& condition)
{
if (networkId == LOCAL_NETWORK_ID) {
AudioXCollie audioXCollie("GetAudioParameter", TIME_OUT_SECONDS,
nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
if (key == AudioParamKey::USB_DEVICE) {
return GetUsbParameter(condition);
}
if (key == AudioParamKey::GET_DP_DEVICE_INFO) {
return GetDPParameter(condition);
}
} else {
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, "", "get remote sink fail");
return sink->GetAudioParameter(key, condition);
}
return "";
}
int32_t AudioServer::SetMicrophoneMute(bool isMute)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "refused for %{public}d",
callingUid);
auto limitFunc = [](uint32_t captureId) -> bool {
std::string info = IdHandler::GetInstance().ParseInfo(captureId);
#ifdef DAUDIO_ENABLE
if (IdHandler::GetInstance().ParseType(captureId) == HDI_ID_TYPE_REMOTE) {
return true;
}
#endif
if (IdHandler::GetInstance().ParseType(captureId) == HDI_ID_TYPE_PRIMARY) {
return info == HDI_ID_INFO_DEFAULT || info == HDI_ID_INFO_USB;
}
if (IdHandler::GetInstance().ParseType(captureId) == HDI_ID_TYPE_BLUETOOTH) {
return info == HDI_ID_INFO_DEFAULT;
}
return false;
};
auto processFunc = [isMute, limitFunc](uint32_t captureId, std::shared_ptr<IAudioCaptureSource> source) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(captureId), SUCCESS);
CHECK_AND_RETURN_RET(source != nullptr, SUCCESS);
source->SetMute(isMute);
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSource(processFunc);
std::shared_ptr<IDeviceManager> deviceManager = HdiAdapterManager::GetInstance().GetDeviceManager(
HDI_DEVICE_MANAGER_TYPE_LOCAL);
if (deviceManager != nullptr) {
deviceManager->AllAdapterSetMicMute(isMute);
}
int32_t ret = SetMicrophoneMuteForEnhanceChain(isMute);
if (ret != SUCCESS) {
AUDIO_WARNING_LOG("SetMicrophoneMuteForEnhanceChain failed.");
}
return SUCCESS;
}
int32_t AudioServer::SetVoiceVolume(float volume)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d",
callingUid);
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
std::string info = HDI_ID_INFO_INTERPHONE;
std::string deviceClass = "primary";
uint32_t id = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass.c_str(), info, true, false,
AUDIO_OUTPUT_FLAG_INTERPHONE);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(id, false);
if (sink != nullptr) {
sink->SetVolume(volume, volume);
audioD2DValue_ = volume;
}
if (deviceManager == nullptr) {
AUDIO_WARNING_LOG("device manager is null.");
} else {
return deviceManager->SetVoiceVolume("primary", volume);
}
return ERROR;
}
int32_t AudioServer::OffloadSetVolume(float volume, uint32_t renderId)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(renderId);
if (sink == nullptr) {
AUDIO_ERR_LOG("Renderer is null.");
return ERROR;
}
return sink->SetVolume(volume, volume);
}
int32_t AudioServer::SetAudioScene(int32_t audioScene, int32_t a2dpOffloadFlag, bool scoExcludeFlag,
int32_t phoneCallSceneType)
{
AudioScene audioSceneIn = static_cast<AudioScene>(audioScene);
CHECK_AND_RETURN_RET_LOG(audioSceneIn > AUDIO_SCENE_INVALID && audioSceneIn < AUDIO_SCENE_MAX,
ERR_INVALID_PARAM, "param is invalid");
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
return SetAudioSceneInner(audioSceneIn, static_cast<BluetoothOffloadState>(a2dpOffloadFlag),
scoExcludeFlag, phoneCallSceneType);
}
int32_t AudioServer::SetAudioSceneForPipe(uint32_t pipeId, int32_t audioScene, bool scoExcludeFlag)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"SetAudioSceneForPipe refused, only internal call allowed");
AUDIO_INFO_LOG("SetAudioSceneForPipe pipeId: %{public}u, audioScene: %{public}d, scoExcludeFlag: %{public}d",
pipeId, audioScene, scoExcludeFlag);
AudioScene audioSceneIn = static_cast<AudioScene>(audioScene);
CHECK_AND_RETURN_RET_LOG(audioSceneIn > AUDIO_SCENE_INVALID && audioSceneIn < AUDIO_SCENE_MAX,
ERR_INVALID_PARAM, "param is invalid");
std::shared_ptr<IAudioRenderSink> sink = nullptr;
std::shared_ptr<IAudioCaptureSource> source = nullptr;
if (pipeId == DEFAULT_PIPE_ID) {
sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true);
source = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, false);
} else {
sink = HdiAdapterManager::GetInstance().GetRenderSink(pipeId, true);
source = HdiAdapterManager::GetInstance().GetCaptureSource(pipeId, false);
}
int32_t ret = SUCCESS;
if (sink != nullptr) {
ret = sink->SetAudioScene(audioSceneIn, scoExcludeFlag);
if (ret != SUCCESS) {
AUDIO_ERR_LOG("SetAudioScene for sink %{public}u failed: %{public}d", pipeId, ret);
}
}
if (source != nullptr) {
ret = source->SetAudioScene(audioSceneIn, scoExcludeFlag);
if (ret != SUCCESS) {
AUDIO_ERR_LOG("SetAudioScene for source %{public}u failed: %{public}d", pipeId, ret);
}
}
AUDIO_INFO_LOG("SetAudioSceneForPipe %{public}u completed with ret %{public}d", pipeId, ret);
return ret;
}
int32_t AudioServer::SetAudioSceneInner(AudioScene audioScene, BluetoothOffloadState a2dpOffloadFlag,
bool scoExcludeFlag, int32_t phoneCallSceneType)
{
std::lock_guard<std::mutex> lock(audioSceneMutex_);
AudioXCollie audioXCollie("AudioServer::SetAudioScene", TIME_OUT_SECONDS,
nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
SetAudioSceneForAllSource(audioScene, scoExcludeFlag, phoneCallSceneType);
SetAudioSceneForAllSink(audioScene, scoExcludeFlag, phoneCallSceneType);
audioScene_ = audioScene;
SetAudioBalanceStatus();
return SUCCESS;
}
int32_t AudioServer::CreateCallTransferProxy()
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED,
"refused for uid %{public}d", callingUid);
auto primarySink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, false);
if (primarySink != nullptr) {
primarySink->CreateCallTransfer();
}
return SUCCESS;
}
int32_t AudioServer::SetIORoutes(std::vector<std::pair<DeviceType, DeviceFlag>> &activeDevices,
BluetoothOffloadState a2dpOffloadFlag, const uint32_t pipeId, const std::string &networkId)
{
CHECK_AND_RETURN_RET_LOG(!activeDevices.empty() && activeDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
ERR_INVALID_PARAM, "Invalid audio devices.");
DeviceType type = activeDevices.front().first;
DeviceFlag flag = activeDevices.front().second;
std::vector<DeviceType> deviceTypes;
for (auto activeDevice : activeDevices) {
deviceTypes.push_back(activeDevice.first);
}
HILOG_COMM_INFO("[SetIORoutes] 1st deviceType: %{public}d, deviceSize: %{public}zu, flag: %{public}d",
activeDevices.front().first, deviceTypes.size(), flag);
if (type == DEVICE_TYPE_BLUETOOTH_A2DP && a2dpOffloadFlag != A2DP_OFFLOAD) {
deviceTypes[0] = DEVICE_TYPE_NONE;
}
{
std::lock_guard<std::mutex> lock(audioSceneMutex_);
isEarpiece_ = (type == DEVICE_TYPE_EARPIECE);
SetAudioBalanceStatus();
}
if (Util::IsEnhancedRoutingSupported()) {
return SetIORoutesForSpecificPipe(type, flag, deviceTypes, pipeId, networkId);
} else {
int32_t ret = networkId == LOCAL_NETWORK_ID ? SetIORoutes(type, flag, deviceTypes) :
SetIORoutesForRemote(flag, deviceTypes, networkId);
return ret;
}
}
int32_t AudioServer::SetIORoutesForSpecificPipe(const DeviceType type, const DeviceFlag flag,
std::vector<DeviceType> &deviceTypes, const uint32_t pipeId, const std::string &networkId)
{
std::shared_ptr<IAudioRenderSink> sink = nullptr;
std::shared_ptr<IAudioCaptureSource> source = nullptr;
if (pipeId == DEFAULT_PIPE_ID) {
sink = networkId == LOCAL_NETWORK_ID ? GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true) :
GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId, true);
source = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, false);
} else {
sink = HdiAdapterManager::GetInstance().GetRenderSink(pipeId, true);
source = HdiAdapterManager::GetInstance().GetCaptureSource(pipeId, false);
}
if (flag == DeviceFlag::INPUT_DEVICES_FLAG) {
CHECK_AND_CALL_FUNC_RETURN_RET_LOG(source != nullptr, ERR_INVALID_PARAM,
StreamDfxManager::GetInstance().SendAudioErrorEvent(static_cast<int32_t>(getuid()),
RECORD_DEVICE_SWITCH_ILLEGAL_STATE, "Capturer is not initialized", false),
"Capturer is not initialized");
source->UpdateActiveDevice(type);
} else if (flag == DeviceFlag::OUTPUT_DEVICES_FLAG) {
PolicyHandler::GetInstance().SetActiveOutputDevice(type);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_INVALID_PARAM, "Renderer is not initialized");
sink->UpdateActiveDevice(deviceTypes);
} else if (flag == DeviceFlag::ALL_DEVICES_FLAG) {
PolicyHandler::GetInstance().SetActiveOutputDevice(type);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_INVALID_PARAM, "Renderer is not initialized");
sink->UpdateActiveDevice(deviceTypes);
CHECK_AND_RETURN_RET_LOG(source != nullptr, ERR_INVALID_PARAM, "Capturer is not initialized");
source->UpdateActiveDevice(type);
} else {
AUDIO_ERR_LOG("SetIORoutes invalid device flag");
return ERR_INVALID_PARAM;
}
return SUCCESS;
}
int32_t AudioServer::SetIORoutes(const DeviceType type, const DeviceFlag flag, std::vector<DeviceType> deviceTypes)
{
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true);
std::shared_ptr<IAudioCaptureSource> source = nullptr;
if (type == DEVICE_TYPE_USB_ARM_HEADSET) {
UpdateArmInstance(sink, source);
} else if (type == DEVICE_TYPE_ACCESSORY) {
source = GetSourceByProp(HDI_ID_TYPE_ACCESSORY, HDI_ID_INFO_ACCESSORY, true);
} else {
source = GetSourceByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true);
}
CHECK_AND_RETURN_RET_LOG(sink != nullptr || source != nullptr,
ERR_INVALID_PARAM, "SetIORoutes failed for null instance!");
if (flag == DeviceFlag::INPUT_DEVICES_FLAG) {
UpdateDeviceForAllSource(source, type);
} else if (flag == DeviceFlag::OUTPUT_DEVICES_FLAG) {
PolicyHandler::GetInstance().SetActiveOutputDevice(type);
sink->UpdateActiveDevice(deviceTypes);
UpdateDeviceForOtherSinks(deviceTypes);
} else if (flag == DeviceFlag::ALL_DEVICES_FLAG) {
UpdateDeviceForAllSource(source, type);
PolicyHandler::GetInstance().SetActiveOutputDevice(type);
sink->UpdateActiveDevice(deviceTypes);
UpdateDeviceForOtherSinks(deviceTypes);
} else {
AUDIO_ERR_LOG("SetIORoutes invalid device flag");
return ERR_INVALID_PARAM;
}
return SUCCESS;
}
int32_t AudioServer::SetIORoutesForRemote(const DeviceFlag flag, std::vector<DeviceType> &deviceTypes,
const std::string &networkId)
{
CHECK_AND_RETURN_RET(flag == DeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG, ERR_INVALID_PARAM);
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId, true);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_INVALID_PARAM, "sink is nullptr");
sink->UpdateActiveDevice(deviceTypes);
return SUCCESS;
}
int32_t AudioServer::UpdateActiveDevicesRoute(const std::vector<IntPair> &activeDevices,
int32_t a2dpOffloadFlag, const uint32_t pipeId, const std::string &networkId)
{
CHECK_AND_RETURN_RET_LOG(!activeDevices.empty() && activeDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
ERR_INVALID_PARAM, "Invalid audio devices.");
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
std::vector<std::pair<DeviceType, DeviceFlag>> activeOutputDevices;
for (auto activeDevice : activeDevices) {
DeviceType type = static_cast<DeviceType>(activeDevice.firstParam);
DeviceFlag flag = static_cast<DeviceFlag>(activeDevice.secondParam);
activeOutputDevices.push_back({type, flag});
}
return SetIORoutes(activeOutputDevices, static_cast<BluetoothOffloadState>(a2dpOffloadFlag), pipeId, networkId);
}
int32_t AudioServer::ReleaseActiveDeviceRoute(int32_t deviceType, int32_t deviceFlag, const std::string &networkId)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET(deviceFlag == DeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG, ERR_INVALID_PARAM);
std::lock_guard<std::mutex> lock(audioSceneMutex_);
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId, true);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERR_INVALID_PARAM, "sink is nullptr");
sink->ReleaseActiveDevice(static_cast<DeviceType>(deviceType));
return SUCCESS;
}
int32_t AudioServer::SetDmDeviceType(uint16_t dmDeviceType, int32_t deviceType)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
std::shared_ptr<IAudioCaptureSource> source;
if (static_cast<DeviceType>(deviceType) == DEVICE_TYPE_NEARLINK_IN) {
source = GetSourceByProp(HDI_ID_TYPE_PRIMARY);
} else {
source = GetSourceByProp(HDI_ID_TYPE_ACCESSORY, HDI_ID_INFO_ACCESSORY, true);
}
CHECK_AND_RETURN_RET_LOG(source != nullptr, ERROR, "has no valid source");
source->SetDmDeviceType(dmDeviceType, static_cast<DeviceType>(deviceType));
return SUCCESS;
}
int32_t AudioServer::SetAudioMonoState(bool audioMono)
{
AUDIO_INFO_LOG("AudioMonoState = [%{public}s]", audioMono ? "true": "false");
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
auto limitFunc = [](uint32_t renderId) -> bool {
uint32_t type = IdHandler::GetInstance().ParseType(renderId);
std::string info = IdHandler::GetInstance().ParseInfo(renderId);
if (type == HDI_ID_TYPE_PRIMARY) {
return info == HDI_ID_INFO_DEFAULT || info == HDI_ID_INFO_DIRECT ||
info == HDI_ID_INFO_VOIP || info == HDI_ID_INFO_USB;
}
if (type == HDI_ID_TYPE_BLUETOOTH) {
return info == HDI_ID_INFO_DEFAULT;
}
if (type == HDI_ID_TYPE_OFFLOAD) {
return info == HDI_ID_INFO_DEFAULT;
}
return false;
};
auto processFunc = [audioMono, limitFunc](uint32_t renderId, std::shared_ptr<IAudioRenderSink> sink) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(renderId), SUCCESS);
CHECK_AND_RETURN_RET(sink != nullptr, SUCCESS);
sink->SetAudioMonoState(audioMono);
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSink(processFunc);
HdiAdapterManager::GetInstance().UpdateSinkPrestoreInfo<bool>(PRESTORE_INFO_AUDIO_MONO, audioMono);
return SUCCESS;
}
int32_t AudioServer::SetAudioBalanceStatus()
{
bool inPhoneScene = (audioScene_ == AUDIO_SCENE_PHONE_CALL || audioScene_ == AUDIO_SCENE_PHONE_CHAT);
bool isAudioBalanceEnabled = (!inPhoneScene) && (!isEarpiece_);
return SetAudioBalanceValueInner(isAudioBalanceEnabled, audioBalanceValue_);
}
int32_t AudioServer::SetAudioBalanceValue(float audioBalance)
{
AUDIO_INFO_LOG("AudioBalanceValue = [%{public}f]", audioBalance);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET_LOG(audioBalance >= -1.0f && audioBalance <= 1.0f, ERR_INVALID_PARAM,
"audioBalance value %{public}f is out of range [-1.0, 1.0]", audioBalance);
std::lock_guard<std::mutex> lock(audioSceneMutex_);
bool inPhoneScene = (audioScene_ == AUDIO_SCENE_PHONE_CALL || audioScene_ == AUDIO_SCENE_PHONE_CHAT);
bool isAudioBalanceEnabled = (!inPhoneScene) && (!isEarpiece_);
AUDIO_INFO_LOG("isAudioBalanceEnabled: %{public}d", isAudioBalanceEnabled);
return SetAudioBalanceValueInner(isAudioBalanceEnabled, audioBalance);
}
int32_t AudioServer::SetAudioBalanceValueInner(bool isAudioBalanceEnable, float audioBalance)
{
auto limitFunc = [](uint32_t renderId) -> bool {
uint32_t type = IdHandler::GetInstance().ParseType(renderId);
std::string info = IdHandler::GetInstance().ParseInfo(renderId);
if (type == HDI_ID_TYPE_PRIMARY) {
return info == HDI_ID_INFO_DEFAULT || info == HDI_ID_INFO_DIRECT ||
info == HDI_ID_INFO_VOIP || info == HDI_ID_INFO_USB;
}
if (type == HDI_ID_TYPE_BLUETOOTH) {
return info == HDI_ID_INFO_DEFAULT;
}
if (type == HDI_ID_TYPE_OFFLOAD) {
return info == HDI_ID_INFO_DEFAULT;
}
return false;
};
auto processFunc = [isAudioBalanceEnable, audioBalance, limitFunc](
uint32_t renderId, std::shared_ptr<IAudioRenderSink> sink) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(renderId), SUCCESS);
CHECK_AND_RETURN_RET(sink != nullptr, SUCCESS);
sink->SetAudioBalanceValue(isAudioBalanceEnable ? audioBalance : 0.0f);
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSink(processFunc);
HdiAdapterManager::GetInstance().UpdateSinkPrestoreInfo<float>(PRESTORE_INFO_AUDIO_BALANCE, audioBalance);
audioBalanceValue_ = audioBalance;
return SUCCESS;
}
int32_t AudioServer::NotifyDeviceInfo(const std::string &networkId, bool connected)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
AUDIO_INFO_LOG("notify device info: networkId(%{public}s), connected(%{public}d)",
GetEncryptStr(networkId).c_str(), connected);
if (networkId.find("taskId") != std::string::npos) {
size_t colon_pos = networkId.find(":");
size_t brace_pos = networkId.find("}");
playTaskId_ = networkId.substr(colon_pos + 1, brace_pos - colon_pos - 1);
AUDIO_INFO_LOG("NotifyDeviceInfo taskId %{public}s", playTaskId_.c_str());
return SUCCESS;
}
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId.c_str());
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, ERR_INVALID_HANDLE, "deviceManager is nullptr");
if (sink != nullptr && connected) {
sink->RegistCallback(HDI_CB_RENDER_PARAM, this);
deviceManager->RegistCallback(HDI_CB_RENDER_PARAM, this);
}
std::shared_ptr<IAudioRenderSink> sinkOffload = GetSinkByProp(HDI_ID_TYPE_REMOTE_OFFLOAD, networkId.c_str(),
false, false);
CHECK_AND_RETURN_RET(sinkOffload != nullptr && connected, SUCCESS);
sinkOffload->RegistCallback(HDI_CB_RENDER_PARAM, this);
return SUCCESS;
}
int32_t AudioServer::NotifyTaskIdProxy(const std::string &taskId, bool connected)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
if (taskId.find("taskId") != std::string::npos) {
size_t colon_pos = taskId.find(":");
size_t brace_pos = taskId.find("}");
playTaskId_ = taskId.substr(colon_pos + 1, brace_pos - colon_pos - 1);
AUDIO_INFO_LOG("NotifyTaskIdProxy taskId %{public}s", playTaskId_.c_str());
}
return SUCCESS;
}
inline bool IsParamEnabled(std::string key, bool &isEnabled)
{
int32_t policyFlag = 0;
if (GetSysPara(key.c_str(), policyFlag) && policyFlag == 1) {
isEnabled = true;
return true;
}
isEnabled = false;
return false;
}
int32_t AudioServer::RegiestPolicyProvider(const sptr<IRemoteObject> &object)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
sptr<IPolicyProviderIpc> policyProvider = iface_cast<IPolicyProviderIpc>(object);
CHECK_AND_RETURN_RET_LOG(policyProvider != nullptr, ERR_INVALID_PARAM,
"policyProvider obj cast failed");
bool ret = PolicyHandler::GetInstance().ConfigPolicyProvider(policyProvider);
CHECK_AND_RETURN_RET_LOG(ret, ERR_OPERATION_FAILED, "ConfigPolicyProvider failed!");
return SUCCESS;
}
int32_t AudioServer::RegistCoreServiceProvider(const sptr<IRemoteObject> &object)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
sptr<ICoreServiceProviderIpc> coreServiceProvider = iface_cast<ICoreServiceProviderIpc>(object);
CHECK_AND_RETURN_RET_LOG(coreServiceProvider != nullptr, ERR_INVALID_PARAM,
"coreServiceProvider obj cast failed");
int32_t ret = CoreServiceHandler::GetInstance().ConfigCoreServiceProvider(coreServiceProvider);
CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "ConfigCoreServiceProvider failed!");
return SUCCESS;
}
int32_t AudioServer::GetHapBuildApiVersion(int32_t callerUid)
{
AudioXCollie audioXCollie("AudioPolicyServer::PerStateChangeCbCustomizeCallback::getUidByBundleName",
GET_BUNDLE_TIME_OUT_SECONDS, nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
std::string bundleName {""};
AppExecFwk::BundleInfo bundleInfo;
WatchTimeout guard("SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager():GetHapBuildApiVersion");
auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_RET_LOG(saManager != nullptr, 0, "failed: saManager is nullptr");
guard.CheckCurrTimeout();
sptr<IRemoteObject> remoteObject = saManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
CHECK_AND_RETURN_RET_LOG(remoteObject != nullptr, 0, "failed: remoteObject is nullptr");
sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
CHECK_AND_RETURN_RET_LOG(bundleMgrProxy != nullptr, 0, "failed: bundleMgrProxy is nullptr");
WatchTimeout reguard("bundleMgrProxy->GetBundleNameForUid:GetHapBuildApiVersion");
bundleMgrProxy->GetBundleNameForUid(callerUid, bundleName);
bundleMgrProxy->GetBundleInfoV9(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT |
AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES |
AppExecFwk::BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION |
AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO |
AppExecFwk::BundleFlag::GET_BUNDLE_WITH_HASH_VALUE,
bundleInfo,
AppExecFwk::Constants::ALL_USERID);
reguard.CheckCurrTimeout();
int32_t hapApiVersion = bundleInfo.applicationInfo.apiTargetVersion % API_VERSION_REMAINDER;
AUDIO_INFO_LOG("callerUid %{public}d, version %{public}d", callerUid, hapApiVersion);
return hapApiVersion;
}
void AudioServer::ResetRecordConfig(AudioProcessConfig &config,
const AudioPlaybackCaptureConfig &filterConfig)
{
if (config.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
config.isInnerCapturer = true;
config.innerCapMode = LEGACY_INNER_CAP;
if (PermissionUtil::VerifyPermission(CAPTURE_PLAYBACK_PERMISSION, IPCSkeleton::GetCallingTokenID())) {
AUDIO_INFO_LOG("CAPTURE_PLAYBACK permission granted");
config.innerCapMode = MODERN_INNER_CAP;
} else if (config.callerUid == MEDIA_SERVICE_UID || config.callerUid == VASSISTANT_UID ||
config.isModernInnerCapturer) {
config.innerCapMode = MODERN_INNER_CAP;
} else if (GetHapBuildApiVersion(config.callerUid) >= MODERN_INNER_API_VERSION) {
config.innerCapMode = LEGACY_MUTE_CAP;
}
AUDIO_INFO_LOG("callerUid %{public}d, innerCapMode %{public}d", config.callerUid, config.innerCapMode);
} else {
config.isInnerCapturer = false;
}
#ifdef AUDIO_BUILD_VARIANT_ROOT
if (config.callerUid == ROOT_UID) {
config.innerCapMode = MODERN_INNER_CAP;
}
#endif
if (config.capturerInfo.sourceType == SourceType::SOURCE_TYPE_WAKEUP) {
config.isWakeupCapturer = true;
} else {
config.isWakeupCapturer = false;
}
}
AudioProcessConfig AudioServer::ResetProcessConfig(const AudioProcessConfig &config,
const AudioPlaybackCaptureConfig &filterConfig)
{
AudioProcessConfig resetConfig(config);
int32_t callerUid = IPCSkeleton::GetCallingUid();
int32_t callerPid = IPCSkeleton::GetCallingPid();
resetConfig.callerUid = callerUid;
resetConfig.originalAppInfo = resetConfig.appInfo;
if (RECORD_PASS_APPINFO_LIST.count(callerUid)) {
AUDIO_INFO_LOG("Create process for %{public}d, clientUid:%{public}d.", callerUid, config.appInfo.appUid);
} else if (RECORD_CHECK_FORWARD_LIST.count(callerUid)) {
AUDIO_INFO_LOG("Check forward calling for uid:%{public}d", callerUid);
resetConfig.appInfo.appTokenId = IPCSkeleton::GetFirstTokenID();
resetConfig.appInfo.appFullTokenId = IPCSkeleton::GetFirstFullTokenID();
} else {
AUDIO_INFO_LOG("Use true client appInfo instead for pid:%{public}d uid:%{public}d", callerPid, callerUid);
resetConfig.appInfo.appPid = callerPid;
resetConfig.appInfo.appUid = callerUid;
resetConfig.appInfo.appTokenId = IPCSkeleton::GetCallingTokenID();
resetConfig.appInfo.appFullTokenId = IPCSkeleton::GetCallingFullTokenID();
}
int32_t clientAppUid = config.appInfo.appUid;
if (clientAppUid != callerUid && !PermissionUtil::VerifySystemPermission()) {
resetConfig.originalAppInfo = resetConfig.appInfo;
}
if (resetConfig.audioMode == AUDIO_MODE_RECORD) {
ResetRecordConfig(resetConfig, filterConfig);
}
return resetConfig;
}
bool AudioServer::CheckStreamInfoFormat(const AudioProcessConfig &config)
{
if (NotContain(AUDIO_SUPPORTED_SAMPLING_RATES, config.streamInfo.samplingRate)) {
AUDIO_ERR_LOG("Check format failed invalid samplingRate:%{public}d", config.streamInfo.samplingRate);
return false;
}
CHECK_AND_RETURN_RET_LOG(config.streamInfo.customSampleRate == 0 ||
Util::IsCustomSampleRateValid(config.streamInfo.customSampleRate), false,
"Check format failed invalid customSampleRate:%{public}u", config.streamInfo.customSampleRate);
if (NotContain(AUDIO_SUPPORTED_FORMATS, config.streamInfo.format)) {
AUDIO_ERR_LOG("Check format failed invalid format:%{public}d", config.streamInfo.format);
return false;
}
if (NotContain(AUDIO_SUPPORTED_ENCODING_TYPES, config.streamInfo.encoding)) {
AUDIO_ERR_LOG("Check format failed invalid encoding:%{public}d", config.streamInfo.encoding);
return false;
}
if (NotContain(RENDERER_SUPPORTED_CHANNELLAYOUTS, config.streamInfo.channelLayout)) {
AUDIO_ERR_LOG("Check format failed invalid channelLayout:%{public}" PRId64".", config.streamInfo.channelLayout);
return false;
}
if (config.audioMode == AUDIO_MODE_PLAYBACK && (config.rendererInfo.rendererFlags != AUDIO_FLAG_3DA_DIRECT) &&
NotContain(RENDERER_SUPPORTED_CHANNELS, config.streamInfo.channels)) {
AUDIO_ERR_LOG("Check format failed invalid renderer channels:%{public}d", config.streamInfo.channels);
return false;
}
if (config.audioMode == AUDIO_MODE_RECORD && NotContain(CAPTURER_SUPPORTED_CHANNELS, config.streamInfo.channels)) {
AUDIO_ERR_LOG("Check format failed invalid capturer channels:%{public}d", config.streamInfo.channels);
return false;
}
return true;
}
bool AudioServer::CheckRendererFormat(const AudioProcessConfig &config)
{
if (NotContain(AUDIO_SUPPORTED_STREAM_USAGES, config.rendererInfo.streamUsage)) {
AUDIO_ERR_LOG("Check format failed invalid streamUsage:%{public}d", config.rendererInfo.streamUsage);
SendCreateErrorInfo(config, ERR_INVALID_PARAM);
return false;
}
return true;
}
bool AudioServer::CheckRecorderFormat(const AudioProcessConfig &config)
{
if (NotContain(AUDIO_SUPPORTED_SOURCE_TYPES, config.capturerInfo.sourceType)) {
AUDIO_ERR_LOG("Check format failed invalid sourceType:%{public}d", config.capturerInfo.sourceType);
SendCreateErrorInfo(config, ERR_INVALID_PARAM);
return false;
}
if (config.capturerInfo.capturerFlags != AUDIO_FLAG_NORMAL && NotContain(AUDIO_FAST_STREAM_SUPPORTED_SOURCE_TYPES,
config.capturerInfo.sourceType)) {
AUDIO_ERR_LOG("Check format failed invalid fast sourceType:%{public}d", config.capturerInfo.sourceType);
SendCreateErrorInfo(config, ERR_INVALID_PARAM);
return false;
}
return true;
}
bool AudioServer::CheckConfigFormat(const AudioProcessConfig &config)
{
if (!CheckStreamInfoFormat(config)) {
SendCreateErrorInfo(config, ERR_INVALID_PARAM);
return false;
}
if (config.audioMode == AUDIO_MODE_PLAYBACK) {
return CheckRendererFormat(config);
}
if (config.audioMode == AUDIO_MODE_RECORD) {
return CheckRecorderFormat(config);
}
SendCreateErrorInfo(config, ERR_INVALID_PARAM);
AUDIO_ERR_LOG("Check format failed invalid mode.");
return false;
}
bool AudioServer::IsFastBlocked(int32_t uid, PlayerType playerType)
{
if (playerType == PLAYER_TYPE_SOUND_POOL) {
return false;
}
std::string bundleName = AppBundleManager::GetBundleNameFromUid(uid);
std::string result;
GetAudioParameter(CHECK_FAST_BLOCK_PREFIX + bundleName, result);
return result == "true";
}
void AudioServer::SendCreateErrorInfo(const AudioProcessConfig &config, int32_t errorCode)
{
std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_STREAM_CREATE_ERROR_STATS,
Media::MediaMonitor::FREQUENCY_AGGREGATION_EVENT);
bool isPlayBack = config.audioMode == AUDIO_MODE_PLAYBACK ? 1 : 0;
bean->Add("IS_PLAYBACK", (isPlayBack ? 1 : 0));
bean->Add("CLIENT_UID", config.appInfo.appUid);
bean->Add("STREAM_TYPE", isPlayBack ? static_cast<int32_t>(config.rendererInfo.streamUsage) :
static_cast<int32_t>(config.capturerInfo.sourceType));
bean->Add("ERROR_CODE", errorCode);
Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
}
int32_t AudioServer::CheckMaxRendererInstances()
{
int32_t maxRendererInstances = PolicyHandler::GetInstance().GetMaxRendererInstances();
if (maxRendererInstances <= 0) {
maxRendererInstances = DEFAULT_MAX_RENDERER_INSTANCES;
}
if (AudioService::GetInstance()->GetCurrentRendererStreamCnt() >= maxRendererInstances) {
AUDIO_ERR_LOG("Current audio renderer stream num is greater than the maximum num of configured instances");
int32_t mostAppUid = INVALID_APP_UID;
int32_t mostAppNum = INVALID_APP_CREATED_AUDIO_STREAM_NUM;
AudioService::GetInstance()->GetCreatedAudioStreamMostUid(mostAppUid, mostAppNum);
std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
Media::MediaMonitor::ModuleId::AUDIO, Media::MediaMonitor::EventId::AUDIO_STREAM_EXHAUSTED_STATS,
Media::MediaMonitor::EventType::FAULT_EVENT);
bean->Add("CLIENT_UID", mostAppUid);
bean->Add("TIMES", mostAppNum);
bean->Add("EXCEEDED_SCENE", "System");
Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
return ERR_EXCEED_MAX_STREAM_CNT;
}
return SUCCESS;
}
int32_t AudioServer::CheckMaxLoopbackInstances(AudioMode audioMode)
{
if (AudioService::GetInstance()->GetCurrentLoopbackStreamCnt(audioMode) >= DEFAULT_MAX_LOOPBACK_INSTANCES) {
HILOG_COMM_ERROR("[CheckMaxLoopbackInstances]Current Loopback stream num is greater than "
"the maximum num of configured instances");
return ERR_EXCEED_MAX_STREAM_CNT;
}
return SUCCESS;
}
sptr<IRemoteObject> AudioServer::CreateAudioStream(const AudioProcessConfig &config, int32_t callingUid,
std::shared_ptr<PipeInfoGuard> &pipeInfoGuard)
{
CHECK_AND_RETURN_RET_LOG(pipeInfoGuard != nullptr, nullptr, "PipeInfoGuard is nullptr");
AudioXCollie audioXCollie(
"AudioServer::CreateAudioStream", CREATE_TIMEOUT_IN_SECOND, nullptr, nullptr,
AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
int32_t appUid = config.appInfo.appUid;
if (callingUid != MEDIA_SERVICE_UID) {
appUid = callingUid;
}
if (IsNormalIpcStream(config)) {
AUDIO_INFO_LOG("Create normal ipc stream, isFastControlled: %{public}d", GetFastControlParam());
int32_t ret = 0;
sptr<IpcStreamInServer> ipcStream = AudioService::GetInstance()->GetIpcStream(config, ret);
if (ipcStream == nullptr) {
if (config.audioMode == AUDIO_MODE_PLAYBACK) {
AudioService::GetInstance()->CleanAppUseNumMap(appUid);
}
HILOG_COMM_ERROR("[CreateAudioStream]GetIpcStream failed.");
return nullptr;
}
AudioService::GetInstance()->SetIncMaxRendererStreamCnt(config.audioMode);
if (config.capturerInfo.isLoopback || config.rendererInfo.isLoopback) {
AudioService::GetInstance()->SetIncMaxLoopbackStreamCnt(config.audioMode);
}
sptr<IRemoteObject> remoteObject= ipcStream->AsObject();
pipeInfoGuard->SetReleaseFlag(false);
return remoteObject;
}
HILOG_COMM_ERROR("[CreateAudioStream]GetAudioProcess failed.");
return nullptr;
}
int32_t AudioServer::CheckAndWaitAudioPolicyReady()
{
if (!isAudioPolicyReady_) {
std::unique_lock lock(isAudioPolicyReadyMutex_);
if (waitCreateStreamInServerCount_ > MAX_WAIT_IN_SERVER_COUNT) {
AUDIO_WARNING_LOG("let client retry");
return ERR_RETRY_IN_CLIENT;
}
waitCreateStreamInServerCount_++;
isAudioPolicyReadyCv_.wait_for(lock, std::chrono::seconds(WAIT_AUDIO_POLICY_READY_TIMEOUT_SECONDS), [this] () {
return isAudioPolicyReady_.load();
});
waitCreateStreamInServerCount_--;
}
return SUCCESS;
}
void AudioServer::NotifyProcessStatus()
{
void *libMemMgrClientHandle = dlopen("libmemmgrclient.z.so", RTLD_NOW);
if (!libMemMgrClientHandle) {
AUDIO_INFO_LOG("dlopen libmemmgrclient library failed");
return;
}
void *notifyProcessStatusFunc = dlsym(libMemMgrClientHandle, "notify_process_status");
if (!notifyProcessStatusFunc) {
AUDIO_INFO_LOG("dlsm notify_process_status failed");
#ifndef TEST_COVERAGE
dlclose(libMemMgrClientHandle);
#endif
return;
}
auto notifyProcessStatus = reinterpret_cast<int(*)(int, int, int, int)>(notifyProcessStatusFunc);
AUDIO_INFO_LOG("notify to memmgr when audio_server is started");
int pid = getpid();
notifyProcessStatus(pid, 1, RSS_THRESHOLD, 0);
RecordBootStateTime(AudioServerBootState::STAY_RESIDENT, ClockTime::GetCurMilli());
#ifndef TEST_COVERAGE
dlclose(libMemMgrClientHandle);
#endif
}
int32_t AudioServer::CreateAudioProcess(const AudioProcessConfig &config, int32_t &errorCode,
const AudioPlaybackCaptureConfig &filterConfig, sptr<IRemoteObject>& client)
{
client = CreateAudioProcessInner(config, errorCode, filterConfig);
if (client == nullptr) {
AUDIO_ERR_LOG("CreateAudioProcessInner failed");
if (errorCode == 0) {
errorCode = AUDIO_ERR;
}
}
return SUCCESS;
}
bool AudioServer::IsSatellite(const AudioProcessConfig &config, int32_t callingUid)
{
return config.rendererInfo.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION &&
callingUid == UID_CALL_MANAGER_SA && config.rendererInfo.isSatellite;
}
sptr<IRemoteObject> AudioServer::CreateAudioProcessInner(const AudioProcessConfig &config, int32_t &errorCode,
const AudioPlaybackCaptureConfig &filterConfig)
{
Trace trace("AudioServer::CreateAudioProcess");
std::shared_ptr<PipeInfoGuard> pipeinfoGuard = std::make_shared<PipeInfoGuard>(config.originalSessionId);
errorCode = CheckAndWaitAudioPolicyReady();
CHECK_AND_RETURN_RET(errorCode == SUCCESS, nullptr);
AudioProcessConfig resetConfig = ResetProcessConfig(config, filterConfig);
CHECK_AND_CALL_FUNC_RETURN_RET(CheckConfigFormat(resetConfig), nullptr,
HILOG_COMM_ERROR("[CreateAudioProcessInner]AudioProcessConfig format is wrong, please check"
":%{public}s", ProcessConfig::DumpProcessConfig(resetConfig).c_str()));
if (!PermissionChecker(resetConfig)) {
errorCode = ERR_PERMISSION_DENIED;
HILOG_COMM_ERROR("[CreateAudioProcessInner]Create audio process failed, no permission");
return nullptr;
}
std::lock_guard<std::mutex> lock(streamLifeCycleMutex_);
int32_t callingUid = IPCSkeleton::GetCallingUid();
if (resetConfig.audioMode == AUDIO_MODE_PLAYBACK &&
!IsVoiceModemCommunication(resetConfig.rendererInfo.streamUsage, callingUid)) {
errorCode = CheckMaxRendererInstances();
CHECK_AND_RETURN_RET(errorCode == SUCCESS, nullptr);
if (AudioService::GetInstance()->IsExceedingMaxStreamCntPerUid(callingUid, resetConfig.appInfo.appUid,
maxRendererStreamCntPerUid_)) {
errorCode = ERR_EXCEED_MAX_STREAM_CNT_PER_UID;
HILOG_COMM_ERROR("[CreateAudioProcessInner]Current audio renderer stream num exceeds "
"maxRendererStreamCntPerUid");
return nullptr;
}
}
if (resetConfig.rendererInfo.isLoopback || resetConfig.capturerInfo.isLoopback) {
errorCode = CheckMaxLoopbackInstances(resetConfig.audioMode);
CHECK_AND_RETURN_RET(errorCode == SUCCESS, nullptr);
}
if (IsSatellite(resetConfig, callingUid)) {
bool isSupportSate = OHOS::system::GetBoolParameter(TEL_SATELLITE_SUPPORT, false);
CHECK_AND_CALL_FUNC_RETURN_RET(isSupportSate, nullptr,
HILOG_COMM_ERROR("[CreateAudioProcessInner]Do not support satellite"));
(void)HdiAdapterManager::GetInstance().SetAudioParameter(HDI_DEVICE_MANAGER_TYPE_LOCAL,
"primary", AudioParamKey::NONE, "", SATEMODEM_PARAMETER);
}
#ifdef FEATURE_APPGALLERY
PolicyHandler::GetInstance().GetAndSaveClientType(resetConfig.appInfo.appUid,
AppBundleManager::GetBundleNameFromUid(resetConfig.appInfo.appUid));
#endif
#ifdef HAS_FEATURE_INNERCAPTURER
if (!HandleCheckCaptureLimit(resetConfig, filterConfig)) {
return nullptr;
}
#endif
return CreateAudioStream(resetConfig, callingUid, pipeinfoGuard);
}
#ifdef HAS_FEATURE_INNERCAPTURER
bool AudioServer::HandleCheckCaptureLimit(AudioProcessConfig &resetConfig,
const AudioPlaybackCaptureConfig &filterConfig)
{
if (resetConfig.capturerInfo.sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE) {
if (resetConfig.playbackCaptureMode == PLAYBACK_CAPTURE_MODE_ONLY_VOIP) {
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission(), false,
"Check permission failed, no system permission");
CHECK_AND_RETURN_RET_LOG(IsOnlyVoipPlaybackCaptureUsages(filterConfig.filterOptions.usages), false,
"Check playback capture usages failed");
}
int32_t innerCapId = 0;
if (InnerCheckCaptureLimit(filterConfig, innerCapId) == SUCCESS) {
resetConfig.innerCapId = innerCapId;
} else {
AUDIO_ERR_LOG("CheckCaptureLimit fail!");
return false;
}
}
return true;
}
int32_t AudioServer::InnerCheckCaptureLimit(const AudioPlaybackCaptureConfig &config, int32_t &innerCapId)
{
PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
int32_t ret = playbackCapturerMgr->CheckCaptureLimit(config, innerCapId);
if (ret == SUCCESS) {
PolicyHandler::GetInstance().LoadModernInnerCapSink(innerCapId);
bool isSupportInnerCaptureOffload = PolicyHandler::GetInstance().IsSupportInnerCaptureOffload();
AUDIO_INFO_LOG("LoadModernOffloadCapSource %{public}d", isSupportInnerCaptureOffload);
if (isSupportInnerCaptureOffload) {
PolicyHandler::GetInstance().LoadModernOffloadCapSource();
}
}
return ret;
}
#endif
bool AudioServer::IsNormalIpcStream(const AudioProcessConfig &config) const
{
return true;
}
int32_t AudioServer::CheckRemoteDeviceState(const std::string &networkId, int32_t deviceRole, bool isStartDevice)
{
AUDIO_INFO_LOG("CheckRemoteDeviceState: device[%{public}s] deviceRole[%{public}d] isStartDevice[%{public}s]",
GetEncryptStr(networkId).c_str(), static_cast<int32_t>(deviceRole), (isStartDevice ? "true" : "false"));
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET(isStartDevice, SUCCESS);
int32_t ret = SUCCESS;
switch (deviceRole) {
case OUTPUT_DEVICE:
{
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_REMOTE, networkId.c_str());
if (sink == nullptr || !sink->IsInited()) {
AUDIO_ERR_LOG("Remote renderer[%{public}s] is uninit.", networkId.c_str());
return ERR_ILLEGAL_STATE;
}
ret = sink->Start();
break;
}
case INPUT_DEVICE:
{
std::shared_ptr<IAudioCaptureSource> source = GetSourceByProp(HDI_ID_TYPE_REMOTE, networkId.c_str());
if (source == nullptr || !source->IsInited()) {
AUDIO_ERR_LOG("Remote capturer[%{public}s] is uninit.", networkId.c_str());
return ERR_ILLEGAL_STATE;
}
ret = source->Start();
break;
}
default:
AUDIO_ERR_LOG("Remote device role %{public}d is not supported.", deviceRole);
return ERR_NOT_SUPPORTED;
}
if (ret != SUCCESS) {
AUDIO_ERR_LOG("Check remote device[%{public}s] fail, ret %{public}d.", networkId.c_str(), ret);
}
return ret;
}
void AudioServer::OnRenderSinkParamChange(const std::string &networkId, const AudioParamKey key,
const std::string &condition, const std::string &value)
{
std::shared_ptr<AudioParameterCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lockSet(audioParamCbMtx_);
AUDIO_INFO_LOG("OnRenderSinkParamChange Callback from networkId: %s", networkId.c_str());
CHECK_AND_RETURN_LOG(audioParamCb_ != nullptr, "OnRenderSinkParamChange: audio param allback is null.");
callback = audioParamCb_;
}
callback->OnAudioParameterChange(networkId, key, condition, value);
}
void AudioServer::OnCaptureSourceParamChange(const std::string &networkId, const AudioParamKey key,
const std::string &condition, const std::string &value)
{
std::shared_ptr<AudioParameterCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lockSet(audioParamCbMtx_);
AUDIO_INFO_LOG("OnCaptureSourceParamChange Callback from networkId: %s", networkId.c_str());
CHECK_AND_RETURN_LOG(audioParamCb_ != nullptr, "OnCaptureSourceParamChange: audio param allback is null.");
callback = audioParamCb_;
}
callback->OnAudioParameterChange(networkId, key, condition, value);
}
void AudioServer::OnHdiRouteStateChange(const std::string &networkId, bool enable)
{
std::shared_ptr<AudioParameterCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lockSet(audioParamCbMtx_);
AUDIO_INFO_LOG("OnHdiRouteStateChange Callback from networkId: %s", networkId.c_str());
CHECK_AND_RETURN_LOG(audioParamCb_ != nullptr, "OnHdiRouteStateChange: audio param callback is null.");
callback = audioParamCb_;
}
callback->OnHdiRouteStateChange(networkId, enable);
}
void AudioServer::OnWakeupClose()
{
AUDIO_INFO_LOG("OnWakeupClose Callback start");
std::shared_ptr<WakeUpSourceCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lockSet(setWakeupCloseCallbackMutex_);
CHECK_AND_RETURN_LOG(wakeupCallback_ != nullptr, "OnWakeupClose callback is nullptr.");
callback = wakeupCallback_;
}
callback->OnWakeupClose();
}
void AudioServer::OnCapturerState(bool isActive, size_t preNum, size_t curNum)
{
AUDIO_DEBUG_LOG("OnCapturerState Callback start");
std::shared_ptr<WakeUpSourceCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lockSet(setWakeupCloseCallbackMutex_);
callback = wakeupCallback_;
}
std::lock_guard<std::mutex> lockCb(onCapturerStateCbMutex_);
bool previousState = preNum;
bool currentState = curNum;
if (previousState == currentState) {
return;
}
CHECK_AND_RETURN_LOG(callback != nullptr, "OnCapturerState callback is nullptr.");
Trace traceCb("callbackToIntelligentVoice");
int64_t stamp = ClockTime::GetCurNano();
callback->OnCapturerState(isActive);
stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
AUDIO_INFO_LOG("isActive:%{public}d cb cost[%{public}" PRId64 "]", isActive, stamp);
}
int32_t AudioServer::SetParameterCallback(const sptr<IRemoteObject>& object)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
std::lock_guard<std::mutex> lock(audioParamCbMtx_);
CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "AudioServer:set listener object is nullptr");
sptr<IStandardAudioServerManagerListener> listener = iface_cast<IStandardAudioServerManagerListener>(object);
CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "AudioServer: listener obj cast failed");
std::shared_ptr<AudioParameterCallback> callback = std::make_shared<AudioManagerListenerCallback>(listener);
CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "AudioPolicyServer: failed to create cb obj");
audioParamCb_ = callback;
AUDIO_INFO_LOG("AudioServer:: SetParameterCallback done");
return SUCCESS;
}
int32_t AudioServer::SetWakeupSourceCallback(const sptr<IRemoteObject>& object)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(callingUid == INTELL_VOICE_SERVICR_UID, false,
"SetWakeupSourceCallback refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM,
"SetWakeupCloseCallback set listener object is nullptr");
sptr<IStandardAudioServerManagerListener> listener = iface_cast<IStandardAudioServerManagerListener>(object);
CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM,
"SetWakeupCloseCallback listener obj cast failed");
std::shared_ptr<AudioManagerListenerCallback> wakeupCallback
= std::make_shared<AudioManagerListenerCallback>(listener);
CHECK_AND_RETURN_RET_LOG(wakeupCallback != nullptr, ERR_INVALID_PARAM,
"SetWakeupCloseCallback failed to create cb obj");
{
std::lock_guard<std::mutex> lockSet(setWakeupCloseCallbackMutex_);
wakeupCallback_ = wakeupCallback;
}
std::thread([this, wakeupCallback] {
std::lock_guard<std::mutex> lockCb(onCapturerStateCbMutex_);
wakeupCallback->TrigerFirstOnCapturerStateCallback(capturerStateFlag_);
}).detach();
AUDIO_INFO_LOG("SetWakeupCloseCallback done");
return SUCCESS;
}
bool AudioServer::VerifyClientPermission(const std::string &permissionName,
Security::AccessToken::AccessTokenID tokenId)
{
auto callerUid = IPCSkeleton::GetCallingUid();
#ifdef AUDIO_BUILD_VARIANT_ROOT
if (callerUid == ROOT_UID) {
AUDIO_INFO_LOG("Root user. Permission GRANTED!!!");
return true;
}
#endif
Security::AccessToken::AccessTokenID clientTokenId = tokenId;
if (clientTokenId == Security::AccessToken::INVALID_TOKENID) {
clientTokenId = IPCSkeleton::GetCallingTokenID();
}
int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(clientTokenId, permissionName);
CHECK_AND_RETURN_RET_LOG(res == Security::AccessToken::PermissionState::PERMISSION_GRANTED,
false, "Permission denied [tid:%{public}d], [%{public}s] for uid:%{public}d tokenId:%{public}u",
clientTokenId, permissionName.c_str(), callerUid, tokenId);
return true;
}
bool AudioServer::PermissionChecker(const AudioProcessConfig &config)
{
if (config.audioMode == AUDIO_MODE_PLAYBACK) {
return CheckPlaybackPermission(config);
}
if (config.audioMode == AUDIO_MODE_RECORD) {
return CheckRecorderPermission(config);
}
AUDIO_ERR_LOG("Check failed invalid mode.");
return false;
}
bool AudioServer::CheckPlaybackPermission(const AudioProcessConfig &config)
{
StreamUsage streamUsage = config.rendererInfo.streamUsage;
if (config.rendererInfo.playerType == PLAYER_TYPE_SYSTEM_SOUND_PLAYER &&
streamUsage == STREAM_USAGE_ENFORCED_TONE) {
AUDIO_INFO_LOG("rendererInfo playerType = %{public}d, streamUsage = %{public}d",
config.rendererInfo.playerType, streamUsage);
return true;
}
bool needVerifyPermission = false;
for (const auto& item : STREAMS_NEED_VERIFY_SYSTEM_PERMISSION) {
if (streamUsage == item) {
needVerifyPermission = true;
break;
}
}
if (needVerifyPermission == false) {
return true;
}
if (streamUsage == STREAM_USAGE_ULTRASONIC && config.callerUid != UID_MSDP_SA) {
AUDIO_ERR_LOG("not msdp using ultrasonic uid:%{public}d", config.callerUid);
return false;
}
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission(), false,
"Check playback permission failed, no system permission");
return true;
}
int32_t AudioServer::CheckInnerRecorderPermission(const AudioProcessConfig &config)
{
SourceType sourceType = config.capturerInfo.sourceType;
if (sourceType != SOURCE_TYPE_REMOTE_CAST && sourceType != SOURCE_TYPE_PLAYBACK_CAPTURE) {
return PERMISSION_UNKNOWN;
}
#ifdef HAS_FEATURE_INNERCAPTURER
Security::AccessToken::AccessTokenID tokenId = config.appInfo.appTokenId;
if (sourceType == SOURCE_TYPE_REMOTE_CAST) {
bool hasSystemPermission = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(hasSystemPermission, PERMISSION_DENIED,
"Create source remote cast failed: no system permission.");
bool hasCastAudioOutputPermission = VerifyClientPermission(CAST_AUDIO_OUTPUT_PERMISSION, tokenId);
CHECK_AND_RETURN_RET_LOG(hasCastAudioOutputPermission, PERMISSION_DENIED, "No cast audio output permission");
return PERMISSION_GRANTED;
}
if (sourceType == SOURCE_TYPE_PLAYBACK_CAPTURE && config.innerCapMode == MODERN_INNER_CAP) {
AUDIO_INFO_LOG("modern inner-cap source, no need to check.");
return PERMISSION_GRANTED;
}
return PERMISSION_UNKNOWN;
#else
return PERMISSION_DENIED;
#endif
}
bool AudioServer::CheckRecorderPermission(const AudioProcessConfig &config)
{
Security::AccessToken::AccessTokenID tokenId = config.appInfo.appTokenId;
SourceType sourceType = config.capturerInfo.sourceType;
CHECK_AND_RETURN_RET_LOG(VALID_SOURCE_TYPE.count(sourceType), false, "invalid source type:%{public}d", sourceType);
AUDIO_INFO_LOG("check for uid:%{public}d source type:%{public}d", config.callerUid, sourceType);
if (sourceType == SOURCE_TYPE_VOICE_TRANSCRIPTION) {
CHECK_AND_CALL_FUNC_RETURN_RET(PermissionUtil::VerifySystemPermission(), false,
HILOG_COMM_ERROR("[CheckRecorderPermission]VOICE_TRANSCRIPTION failed: no system permission."));
}
if (sourceType == SOURCE_TYPE_VOICE_CALL) {
bool hasSystemPermission = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(hasSystemPermission, false, "VOICE_CALL failed: no system permission.");
return CheckVoiceCallRecorderPermission(tokenId);
}
CHECK_AND_CALL_FUNC_RETURN_RET(CheckVoiceDownlinkPermission(config), false,
HILOG_COMM_ERROR("[CheckVoiceDownlinkPermission]Voice downlink permission check failed"));
int32_t permission = CheckInnerRecorderPermission(config);
AUDIO_INFO_LOG("CheckInnerRecorderPermission return %{public}d", permission);
if (permission == PERMISSION_GRANTED) {
return true;
} else if (permission == PERMISSION_DENIED) {
return false;
}
if (sourceType == SOURCE_TYPE_MIC && config.capturerInfo.capturerFlags == STREAM_FLAG_FAST &&
config.capturerInfo.isLoopback) {
AUDIO_INFO_LOG("mic data is by passed,no need check permission");
return true;
}
bool res = VerifyClientPermission(MICROPHONE_PERMISSION, tokenId);
if (!res) {
HILOG_COMM_INFO("[CheckRecorderPermission]Check record permission failed: No permission.");
return false;
}
if (sourceType == SOURCE_TYPE_ULTRASONIC && config.callerUid != UID_MSDP_SA) {
return false;
}
if (sourceType == SOURCE_TYPE_WAKEUP || sourceType == SOURCE_TYPE_UNPROCESSED_VOICE_ASSISTANT) {
bool hasSystemPermission = PermissionUtil::VerifySystemPermission();
bool hasIntelVoicePermission = VerifyClientPermission(MANAGE_INTELLIGENT_VOICE_PERMISSION, tokenId);
CHECK_AND_RETURN_RET_LOG(hasSystemPermission && hasIntelVoicePermission, false,
"Create wakeup record stream failed: no permission.");
return true;
}
if (!HandleCheckRecorderBackgroundCapture(config)) {
HILOG_COMM_INFO("[CheckRecorderPermission]VerifyBackgroundCapture failed for callerUid:%{public}d",
config.callerUid);
return false;
}
return true;
}
bool AudioServer::HandleCheckRecorderBackgroundCapture(const AudioProcessConfig &config)
{
if (!PermissionUtil::NeedVerifyBackgroundCapture(config.callerUid, config.capturerInfo.sourceType)) {
return true;
}
AppInfo appInfo = config.appInfo;
if (PermissionUtil::VerifyBackgroundCapture(appInfo.appTokenId, appInfo.appFullTokenId)) {
return true;
}
std::string bundleName = AppBundleManager::GetBundleNameFromUid(config.appInfo.appUid);
if (AudioService::GetInstance()->MatchForegroundList(bundleName, config.appInfo.appUid) &&
Util::IsBackgroundSourceType(config.capturerInfo.sourceType)) {
AudioService::GetInstance()->UpdateForegroundState(config.appInfo.appTokenId, true);
bool res = PermissionUtil::VerifyBackgroundCapture(appInfo.appTokenId, appInfo.appFullTokenId);
AUDIO_INFO_LOG("Retry for %{public}s, result:%{public}s", bundleName.c_str(), (res ? "success" : "fail"));
AudioService::GetInstance()->UpdateForegroundState(config.appInfo.appTokenId, false);
return res;
}
AUDIO_WARNING_LOG("failed for %{public}s", bundleName.c_str());
return false;
}
int32_t AudioServer::SetForegroundList(const std::vector<std::string> &list)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d",
IPCSkeleton::GetCallingUid());
AudioService::GetInstance()->SaveForegroundList(list);
return SUCCESS;
}
int32_t AudioServer::SetRenderWhitelist(const std::vector<std::string> &list)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d",
IPCSkeleton::GetCallingUid());
AudioService::GetInstance()->SaveRenderWhitelist(list);
return SUCCESS;
}
int32_t AudioServer::GetVolumeBySessionId(uint32_t sessionId, float &volume)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "No system permission");
return AudioStreamMonitor::GetInstance().GetVolumeBySessionId(sessionId, volume);
}
bool AudioServer::CheckVoiceCallRecorderPermission(Security::AccessToken::AccessTokenID tokenId)
{
bool hasRecordVoiceCallPermission = VerifyClientPermission(RECORD_VOICE_CALL_PERMISSION, tokenId);
CHECK_AND_RETURN_RET_LOG(hasRecordVoiceCallPermission, false, "No permission");
return true;
}
void AudioServer::AudioServerDied(pid_t pid, pid_t uid)
{
AUDIO_INFO_LOG("Policy server died: restart pulse audio");
_Exit(0);
}
void AudioServer::RegisterPolicyServerDeathRecipient()
{
AUDIO_INFO_LOG("Register policy server death recipient");
pid_t pid = IPCSkeleton::GetCallingPid();
pid_t uid = IPCSkeleton::GetCallingUid();
sptr<AudioServerDeathRecipient> deathRecipient_ = new(std::nothrow) AudioServerDeathRecipient(pid, uid);
if (deathRecipient_ != nullptr) {
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG(samgr != nullptr, "Failed to obtain system ability manager");
sptr<IRemoteObject> object = samgr->GetSystemAbility(OHOS::AUDIO_POLICY_SERVICE_ID);
CHECK_AND_RETURN_LOG(object != nullptr, "Policy service unavailable");
deathRecipient_->SetNotifyCb([this] (pid_t pid, pid_t uid) { this->AudioServerDied(pid, uid); });
bool result = object->AddDeathRecipient(deathRecipient_);
if (!result) {
AUDIO_ERR_LOG("Failed to add deathRecipient");
}
}
}
int32_t AudioServer::CreatePlaybackCapturerManager(bool &isSuccess)
{
#ifdef HAS_FEATURE_INNERCAPTURER
if (!PermissionUtil::VerifyIsAudio()) {
AUDIO_ERR_LOG("not audio calling!");
isSuccess = false;
return ERR_PERMISSION_DENIED;
}
std::vector<int32_t> usage;
PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
playbackCapturerMgr->SetSupportStreamUsage(usage);
isSuccess = true;
return SUCCESS;
#else
isSuccess = false;
return ERR_NOT_SUPPORTED;
#endif
}
void AudioServer::RegisterAudioCapturerSourceCallback()
{
IdHandler &idHandler = IdHandler::GetInstance();
std::function<bool(uint32_t)> limitFunc = [&idHandler] (uint32_t id) -> bool {
return idHandler.ParseType(id) == HDI_ID_TYPE_WAKEUP && idHandler.ParseInfo(id) == "Built_in_wakeup";
};
HdiAdapterManager::GetInstance().RegistSourceCallback(HDI_CB_CAPTURE_WAKEUP, this, limitFunc);
limitFunc = [&idHandler] (uint32_t id) -> bool {
return idHandler.ParseType(id) != HDI_ID_TYPE_WAKEUP;
};
HdiAdapterManager::GetInstance().RegistSourceCallback(HDI_CB_CAPTURE_STATE_ALL, this, limitFunc);
limitFunc = [&idHandler] (uint32_t id) -> bool {
uint32_t type = idHandler.ParseType(id);
std::string info = idHandler.ParseInfo(id);
if (type == HDI_ID_TYPE_PRIMARY) {
return info == HDI_ID_INFO_DEFAULT || info == HDI_ID_INFO_USB ||
info == HDI_ID_INFO_UNPROCESS || info == HDI_ID_INFO_ULTRASONIC ||
info == HDI_ID_INFO_VOICE_RECOGNITION || info == HDI_ID_INFO_RAW_AI ||
info == HDI_ID_INFO_INTERPHONE || info == HDI_ID_INFO_LIVE;
}
#ifdef SUPPORT_LOW_LATENCY
if (type == HDI_ID_TYPE_FAST) {
return info == HDI_ID_INFO_DEFAULT || info == HDI_ID_INFO_VOIP;
}
#endif
if (type == HDI_ID_TYPE_BLUETOOTH) {
return info == HDI_ID_INFO_DEFAULT;
}
if (type == HDI_ID_TYPE_AI) {
return info == HDI_ID_INFO_DEFAULT;
}
return false;
};
std::function<std::shared_ptr<IAudioSourceCallback>(uint32_t)> callbackGenerator = [this](uint32_t captureId) ->
std::shared_ptr<IAudioSourceCallback> {
return std::make_shared<CapturerStateOb>(captureId,
[this] (bool isActive, size_t preNum, size_t curNum) {
this->OnCapturerState(isActive, preNum, curNum);
}
);
};
HdiAdapterManager::GetInstance().RegistSourceCallbackGenerator(HDI_CB_CAPTURE_STATE, callbackGenerator, limitFunc);
RegisterCamcorderMetadataCallback();
}
void AudioServer::RegisterAudioRendererSinkCallback()
{
std::function<bool(uint32_t)> limitFunc = [] (uint32_t id) -> bool {
return true;
};
HdiAdapterManager::GetInstance().RegistSinkCallback(HDI_CB_RENDER_STATE, this, limitFunc);
}
int32_t AudioServer::NotifyStreamVolumeChanged(int32_t streamType, float volume)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
if (!PermissionUtil::VerifyIsAudio()) {
AUDIO_ERR_LOG("NotifyStreamVolumeChanged refused for %{public}d", callingUid);
return ERR_NOT_SUPPORTED;
}
AudioStreamType streamTypeTmp = static_cast<AudioStreamType>(streamType);
int32_t ret = AudioService::GetInstance()->NotifyStreamVolumeChanged(streamTypeTmp, volume);
if (ret != SUCCESS) {
AUDIO_WARNING_LOG("NotifyStreamVolumeChanged failed");
}
ret = SetVolumeInfoForEnhanceChain(streamTypeTmp);
if (ret != SUCCESS) {
AUDIO_WARNING_LOG("SetVolumeInfoForEnhanceChain failed");
}
return SUCCESS;
}
int32_t AudioServer::ResetRouteForDisconnect(int32_t type)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY);
if (sink == nullptr) {
AUDIO_ERR_LOG("audioRendererSinkInstance is null!");
return ERROR;
}
sink->ResetActiveDeviceForDisconnect(static_cast<DeviceType>(type));
return SUCCESS;
}
int32_t AudioServer::GetMaxAmplitude(bool isOutputDevice, const std::string &deviceClass, int32_t sourceType,
float &maxAmplitude)
{
maxAmplitude = 0;
int32_t callingUid = IPCSkeleton::GetCallingUid();
AUDIO_DEBUG_LOG("GetMaxAmplitude in audio server deviceClass %{public}s", deviceClass.c_str());
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"GetMaxAmplitude refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET_LOG(isOutputDevice, ERR_NOT_SUPPORTED, "Input device use GetInputMaxAmplitude");
float fastMaxAmplitude = AudioService::GetInstance()->GetMaxAmplitude(isOutputDevice);
std::shared_ptr<IAudioRenderSink> sink = nullptr;
uint32_t renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass);
sink = HdiAdapterManager::GetInstance().GetRenderSink(renderId, false);
if (sink != nullptr) {
float normalMaxAmplitude = sink->GetMaxAmplitude();
maxAmplitude = (normalMaxAmplitude > fastMaxAmplitude) ? normalMaxAmplitude : fastMaxAmplitude;
}
return SUCCESS;
}
int32_t AudioServer::GetInputMaxAmplitude(const std::string &sourceName, float &maxAmplitude)
{
maxAmplitude = 0;
int32_t callingUid = IPCSkeleton::GetCallingUid();
AUDIO_DEBUG_LOG("GetInputMaxAmplitude in audio server sourceName %{public}s", sourceName.c_str());
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"GetInputMaxAmplitude refused for %{public}d", callingUid);
maxAmplitude = HdiAdapterManager::GetInstance().GetCaptureSourceMaxAmplitude(sourceName);
return SUCCESS;
}
int32_t AudioServer::GetVolumeDataCount(const std::string &sinkName, int64_t &volumeData)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "refused for %{public}d",
IPCSkeleton::GetCallingUid());
uint32_t renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(sinkName);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(renderId, false);
if (sink == nullptr) {
AUDIO_WARNING_LOG("can not find: %{public}s", sinkName.c_str());
return ERR_OPERATION_FAILED;
}
return sink->GetVolumeDataCount(volumeData);
}
int32_t AudioServer::UpdateLatencyTimestamp(const std::string ×tamp, bool isRenderer)
{
static bool isEnabled = AudioLatencyMeasurement::CheckIfEnabled();
CHECK_AND_RETURN_RET(isEnabled, SUCCESS);
std::string stringTimestamp = timestamp;
if (isRenderer) {
LatencyMonitor::GetInstance().UpdateClientTime(true, stringTimestamp);
} else {
LatencyMonitor::GetInstance().UpdateClientTime(false, stringTimestamp);
LatencyMonitor::GetInstance().ShowTimestamp(false);
}
return SUCCESS;
}
int32_t AudioServer::UpdateDualToneState(bool enable, int32_t sessionId, const std::string &dupSinkName)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
if (enable) {
return AudioService::GetInstance()->EnableDualStream(static_cast<uint32_t>(sessionId), dupSinkName);
} else {
return AudioService::GetInstance()->DisableDualStream(static_cast<uint32_t>(sessionId));
}
}
int32_t AudioServer::SetSinkRenderEmpty(const std::string &deviceClass, int32_t durationUs)
{
if (durationUs <= 0) {
return SUCCESS;
}
std::shared_ptr<IAudioRenderSink> sink = GetSinkByProp(HDI_ID_TYPE_PRIMARY);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERROR, "has no valid sink");
return sink->SetRenderEmpty(durationUs);
}
int32_t AudioServer::SetSinkMuteForSwitchDevice(const std::string &deviceClass, int32_t durationUs, bool mute,
const std::string &networkId)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED, "refused for %{public}d",
callingUid);
if (durationUs <= 0) {
return SUCCESS;
}
bool isMmap = deviceClass == A2DP_FAST_CLASS || deviceClass == MMAP_CLASS;
if (isMmap) {
AudioService::GetInstance()->SetEndpointMuteForSwitchDevice(deviceClass, mute);
}
std::string info;
if (deviceClass == PRIMARY_EXTRA_CLASS) {
info = networkId;
} else {
info = networkId == LOCAL_NETWORK_ID ? HDI_ID_INFO_DEFAULT : networkId;
}
uint32_t id = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, info);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(id);
CHECK_AND_RETURN_RET_LOG(sink != nullptr, ERROR, "has no valid sink");
return sink->SetSinkMuteForSwitchDevice(mute);
}
int32_t AudioServer::UpdateSessionConnectionState(int32_t sessionId, int32_t state)
{
AUDIO_INFO_LOG("Server get sessionID: %{public}d, state: %{public}d", sessionId, state);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"Update session connection state refused for %{public}d", callingUid);
std::shared_ptr<RendererInServer> renderer =
AudioService::GetInstance()->GetRendererBySessionID(static_cast<uint32_t>(sessionId));
if (renderer == nullptr) {
AUDIO_ERR_LOG("No render in server has sessionID");
return ERROR;
}
renderer->OnDataLinkConnectionUpdate(static_cast<IOperation>(state));
return SUCCESS;
}
int32_t AudioServer::SetLatestMuteState(uint32_t sessionId, bool muteFlag)
{
AUDIO_INFO_LOG("sessionId_: %{public}u, muteFlag: %{public}d", sessionId, muteFlag);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"Refused for %{public}d", callingUid);
AudioService::GetInstance()->SetLatestMuteState(sessionId, muteFlag);
return SUCCESS;
}
int32_t AudioServer::SetNonInterruptMute(uint32_t sessionId, bool muteFlag)
{
AUDIO_INFO_LOG("sessionId_: %{public}u, muteFlag: %{public}d", sessionId, muteFlag);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"Refused for %{public}d", callingUid);
AudioService::GetInstance()->SetNonInterruptMute(sessionId, muteFlag);
return SUCCESS;
}
int32_t AudioServer::RestoreSession(uint32_t sessionID, const RestoreInfoIpc &restoreInfoIpc)
{
const RestoreInfo &restoreInfo = restoreInfoIpc.restoreInfo;
AUDIO_INFO_LOG("restore session: %{public}u, reason: %{public}d, device change reason %{public}d, "
"target flag %{public}d", sessionID, restoreInfo.restoreReason, restoreInfo.deviceChangeReason,
restoreInfo.targetStreamFlag);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"Update session connection state refused for %{public}d", callingUid);
int32_t tryCount = RESTORE_SESSION_TRY_COUNT;
RestoreStatus restoreStatus;
while (tryCount > 0) {
restoreStatus = AudioService::GetInstance()->RestoreSession(sessionID, restoreInfo);
if (restoreStatus == NEED_RESTORE) {
return SUCCESS;
}
if (restoreStatus == RESTORING) {
AUDIO_WARNING_LOG("Session %{public}u is restoring, wait 50ms, tryCount %{public}d", sessionID, tryCount);
usleep(RESTORE_SESSION_RETRY_WAIT_TIME_IN_MS);
}
tryCount--;
}
if (restoreStatus != NEED_RESTORE) {
AUDIO_WARNING_LOG("Restore session in server failed, restore status %{public}d", restoreStatus);
}
return SUCCESS;
}
int32_t AudioServer::SetOffloadMode(uint32_t sessionId, int32_t state, bool isAppBack)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d",
callingUid);
return AudioService::GetInstance()->SetOffloadMode(sessionId, state, isAppBack);
}
int32_t AudioServer::UnsetOffloadMode(uint32_t sessionId)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d",
callingUid);
return AudioService::GetInstance()->UnsetOffloadMode(sessionId);
}
void AudioServer::OnRenderSinkStateChange(uint32_t sinkId, bool started)
{
AudioService::GetInstance()->UpdateAudioSinkState(sinkId, started);
return;
}
int32_t AudioServer::CheckHibernateState(bool hibernate)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
AudioService::GetInstance()->CheckHibernateState(hibernate);
return SUCCESS;
}
int32_t AudioServer::CreateIpcOfflineStream(int32_t &errorCode, sptr<IRemoteObject>& client)
{
client = nullptr;
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
sptr<OfflineStreamInServer> stream = OfflineStreamInServer::GetOfflineStream(errorCode);
CHECK_AND_RETURN_RET_LOG(stream, ERROR, "Create IIpcOfflineStream failed.");
client = stream->AsObject();
return SUCCESS;
}
int32_t AudioServer::GetOfflineAudioEffectChains(std::vector<std::string> &effectChains)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
#ifdef FEATURE_OFFLINE_EFFECT
return OfflineStreamInServer::GetOfflineAudioEffectChains(effectChains);
#endif
return ERR_NOT_SUPPORTED;
}
int32_t AudioServer::GetStandbyStatus(uint32_t sessionId, bool &isStandby, int64_t &enterStandbyTime)
{
Trace trace("AudioServer::GetStandbyStatus:" + std::to_string(sessionId));
auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID());
bool isAllowed = type == Security::AccessToken::TOKEN_NATIVE;
#ifdef AUDIO_BUILD_VARIANT_ROOT
isAllowed = isAllowed || type == Security::AccessToken::TOKEN_SHELL;
#endif
CHECK_AND_RETURN_RET_LOG(isAllowed, ERR_INVALID_OPERATION, "not allowed");
return AudioService::GetInstance()->GetStandbyStatus(sessionId, isStandby, enterStandbyTime);
}
int32_t AudioServer::GenerateSessionId(uint32_t &sessionId)
{
int32_t uid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(GENERATE_SESSIONID_UID_SET.count(uid) == 1, ERROR, "uid is %{public}d, not mcu uid", uid);
sessionId = CoreServiceHandler::GetInstance().GenerateSessionId();
return SUCCESS;
}
int32_t AudioServer::GetAllSinkInputs(std::vector<SinkInput> &sinkInputs)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"Refused for %{public}d", callingUid);
AudioService::GetInstance()->GetAllSinkInputs(sinkInputs);
return SUCCESS;
}
int32_t AudioServer::NotifyAudioPolicyReady()
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
std::lock_guard lock(isAudioPolicyReadyMutex_);
isAudioPolicyReady_ = true;
isAudioPolicyReadyCv_.notify_all();
AUDIO_INFO_LOG("out");
return SUCCESS;
}
int32_t AudioServer::CheckCaptureLimit(const AudioPlaybackCaptureConfig &config, int32_t &innerCapId)
{
#if defined(AUDIO_BUILD_VARIANT_ROOT) && defined(HAS_FEATURE_INNERCAPTURER)
uid_t callingUid = static_cast<uid_t>(IPCSkeleton::GetCallingUid());
if (callingUid == ROOT_UID) {
return InnerCheckCaptureLimit(config, innerCapId);
}
#endif
return ERR_NOT_SUPPORTED;
}
int32_t AudioServer::SetInnerCapLimit(uint32_t innerCapLimit)
{
#ifdef HAS_FEATURE_INNERCAPTURER
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED,
"refused for %{public}d", callingUid);
PlaybackCapturerManager *playbackCapturerMgr = PlaybackCapturerManager::GetInstance();
int32_t ret = playbackCapturerMgr->SetInnerCapLimit(innerCapLimit);
if (ret != SUCCESS) {
AUDIO_ERR_LOG("SetInnerCapLimit error");
}
return ret;
#endif
return ERR_NOT_SUPPORTED;
}
int32_t AudioServer::ReleaseCaptureLimit(int32_t innerCapId)
{
#if defined(AUDIO_BUILD_VARIANT_ROOT) && defined(HAS_FEATURE_INNERCAPTURER)
uid_t callingUid = static_cast<uid_t>(IPCSkeleton::GetCallingUid());
if (callingUid == ROOT_UID) {
PlaybackCapturerManager::GetInstance()->CheckReleaseUnloadModernInnerCapSink(innerCapId);
PlaybackCapturerManager::GetInstance()->CheckReleaseUnloadModernOffloadCapSource();
return SUCCESS;
}
#endif
return ERR_NOT_SUPPORTED;
}
int32_t AudioServer::LoadHdiAdapter(uint32_t devMgrType, const std::string &adapterName)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_NOT_SUPPORTED, "refused for %{public}d", callingUid);
return HdiAdapterManager::GetInstance().LoadAdapter(static_cast<HdiDeviceManagerType>(devMgrType), adapterName);
}
int32_t AudioServer::UnloadHdiAdapter(uint32_t devMgrType, const std::string &adapterName, bool force)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
HdiAdapterManager::GetInstance().UnloadAdapter(static_cast<HdiDeviceManagerType>(devMgrType), adapterName, force);
return SUCCESS;
}
int32_t AudioServer::CreateHdiSinkPort(const std::string &deviceClass, const std::string &idInfo,
const IAudioSinkAttr &attr, uint32_t &renderId)
{
renderId = HDI_INVALID_ID;
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), SUCCESS,
"refused for %{public}d", callingUid);
renderId = HdiAdapterManager::GetInstance().GetRenderIdByDeviceClass(deviceClass, idInfo, true, true,
attr.routeFlag);
CHECK_AND_RETURN_RET(renderId != HDI_INVALID_ID, SUCCESS);
CHECK_AND_RETURN_RET(deviceClass != "Virtual_Injector", SUCCESS);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(renderId, true);
if (sink == nullptr) {
HdiAdapterManager::GetInstance().ReleaseId(renderId);
renderId = HDI_INVALID_ID;
return SUCCESS;
}
if (!sink->IsInited()) {
std::lock_guard<std::mutex> lock(setA2dpParamMutex_);
sink->Init(attr);
if (attr.routeFlag == AUDIO_OUTPUT_FLAG_INTERPHONE) {
DeviceType deviceType = PolicyHandler::GetInstance().GetActiveOutPutDevice();
Volume vol = {false, 0.0f, 0};
PolicyHandler::GetInstance().GetSharedVolume(STREAM_VOICE_CALL, deviceType, vol);
float systemVol = vol.isMute ? 0.0f : vol.volumeFloat;
sink->SetVolume(systemVol, systemVol);
AUDIO_INFO_LOG("interphone CreateHdiSinkPort sink->SetVolume volume=%{public}f", systemVol);
}
}
(deviceClass == "primary" && idInfo == HDI_ID_INFO_DEFAULT) ?
RegisterSinkLatencyFetcher(renderId, PRIMARY_SINK_LATENCY_MS) : RegisterSinkLatencyFetcher(renderId);
return SUCCESS;
}
bool AudioServer::NeedDelayCreateSink(const uint32_t idBase, const uint32_t idType, const std::string &idInfo)
{
CHECK_AND_RETURN_RET(idBase == HDI_ID_BASE_RENDER, false);
if (HDI_ID_TYPE_FAST == idType || HDI_ID_INFO_MMAP == idInfo || HDI_ID_INFO_USB == idInfo) {
AUDIO_INFO_LOG("delay create");
return true;
}
return false;
}
int32_t AudioServer::CreateSinkPort(uint32_t idBase, uint32_t idType, const std::string &idInfo,
const IAudioSinkAttr &attr, uint32_t &renderId)
{
renderId = HDI_INVALID_ID;
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), SUCCESS,
"refused for %{public}d", callingUid);
HILOG_COMM_INFO("[CreateSinkPort]In, idBase: %{public}u, idType: %{public}u, info: %{public}s",
idBase, idType, idInfo.c_str());
renderId = HdiAdapterManager::GetInstance().GetId(static_cast<HdiIdBase>(idBase),
static_cast<HdiIdType>(idType), idInfo, true);
CHECK_AND_RETURN_RET(renderId != HDI_INVALID_ID, SUCCESS);
if (idInfo.find("InnerCapturerSink") != string::npos) {
AUDIO_INFO_LOG("Inner-cap stream return");
return SUCCESS;
}
CHECK_AND_RETURN_RET(!NeedDelayCreateSink(idBase, idType, idInfo), SUCCESS);
std::shared_ptr<IAudioRenderSink> sink = HdiAdapterManager::GetInstance().GetRenderSink(renderId, true);
if (sink == nullptr) {
AUDIO_WARNING_LOG("Sink is nullptr");
HdiAdapterManager::GetInstance().ReleaseId(renderId);
renderId = HDI_INVALID_ID;
return SUCCESS;
}
if (!sink->IsInited()) {
sink->Init(attr);
}
RegisterSinkLatencyFetcher(renderId);
return SUCCESS;
}
bool AudioServer::NeedDelayCreateSource(const uint32_t idBase, const uint32_t idType, const std::string &idInfo)
{
CHECK_AND_RETURN_RET(idBase == HDI_ID_BASE_CAPTURE, false);
if (HDI_ID_TYPE_FAST == idType || HDI_ID_INFO_MMAP == idInfo || HDI_ID_INFO_USB == idInfo) {
AUDIO_INFO_LOG("delay create");
return true;
}
return false;
}
int32_t AudioServer::CreateSourcePort(uint32_t idBase, uint32_t idType, const std::string &idInfo,
const IAudioSourceAttr &attr, uint32_t &captureId)
{
captureId = HDI_INVALID_ID;
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), SUCCESS,
"refused for %{public}d", callingUid);
HILOG_COMM_INFO("[CreateSourcePort]In, idBase: %{public}u, idType: %{public}u, sourceType: %{public}d, "
"info: %{public}s", idBase, idType, attr.sourceType, idInfo.c_str());
captureId = HdiAdapterManager::GetInstance().GetId(static_cast<HdiIdBase>(idBase),
static_cast<HdiIdType>(idType), idInfo, true);
CHECK_AND_RETURN_RET(captureId != HDI_INVALID_ID, SUCCESS);
CHECK_AND_RETURN_RET(!NeedDelayCreateSource(idBase, idType, idInfo), SUCCESS);
std::shared_ptr<IAudioCaptureSource> source = HdiAdapterManager::GetInstance().GetCaptureSource(captureId, true);
if (source == nullptr) {
AUDIO_WARNING_LOG("Source is nullptr");
HdiAdapterManager::GetInstance().ReleaseId(captureId);
captureId = HDI_INVALID_ID;
return SUCCESS;
}
if (!source->IsInited()) {
source->Init(attr);
}
return SUCCESS;
}
int32_t AudioServer::CreateHdiSourcePort(const std::string &deviceClass, const std::string &idInfo,
const IAudioSourceAttr &attr, uint32_t &captureId)
{
captureId = HDI_INVALID_ID;
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), SUCCESS,
"refused for %{public}d", callingUid);
captureId = HdiAdapterManager::GetInstance().GetCaptureIdByDeviceClass(deviceClass,
static_cast<SourceType>(attr.sourceType), idInfo, true, attr.routeFlag);
CHECK_AND_RETURN_RET(captureId != HDI_INVALID_ID, SUCCESS);
std::shared_ptr<IAudioCaptureSource> source = HdiAdapterManager::GetInstance().GetCaptureSource(captureId, true);
if (source == nullptr) {
AUDIO_WARNING_LOG("Source is nullptr");
HdiAdapterManager::GetInstance().ReleaseId(captureId);
captureId = HDI_INVALID_ID;
return SUCCESS;
}
if (!source->IsInited()) {
source->Init(attr);
}
return SUCCESS;
}
int32_t AudioServer::RegisterVADeviceController(const std::string &macAddress, const sptr<IRemoteObject> &controller)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission() ||
PermissionUtil::VerifyPermission(MANAGE_AUDIO_ACCESSORY, IPCSkeleton::GetCallingTokenID()),
ERR_PERMISSION_DENIED, "refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET_LOG(!macAddress.empty() && controller != nullptr, ERR_INVALID_PARAM,
"invalid va device controller");
sptr<IVADeviceController> vaController = iface_cast<IVADeviceController>(controller);
CHECK_AND_RETURN_RET_LOG(vaController != nullptr, ERR_INVALID_PARAM, "va controller is null");
VADeviceControllerRegistry::GetInstance().RegisterController(macAddress, vaController);
return SUCCESS;
}
int32_t AudioServer::UnregisterVADeviceController(const std::string &macAddress)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySystemPermission() ||
PermissionUtil::VerifyPermission(MANAGE_AUDIO_ACCESSORY, IPCSkeleton::GetCallingTokenID()),
ERR_PERMISSION_DENIED, "refused for %{public}d", callingUid);
CHECK_AND_RETURN_RET_LOG(!macAddress.empty(), ERR_INVALID_PARAM, "macAddress is empty");
VADeviceControllerRegistry::GetInstance().UnregisterController(macAddress);
return SUCCESS;
}
int32_t AudioServer::DestroyHdiPort(uint32_t id)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
SinkLatencyFetcherManager::GetInstance().RemoveFetcherById(id);
HdiAdapterManager::GetInstance().ReleaseId(id);
return SUCCESS;
}
void AudioServer::RegisterSinkLatencyFetcher(uint32_t renderId, uint32_t sinkLatency)
{
SinkLatencyFetcherManager::GetInstance().RegisterProvider(renderId,
[sinkLatency] (uint32_t renderId, uint32_t &latency) -> int32_t {
latency = sinkLatency;
return SUCCESS;
});
return;
}
void AudioServer::RegisterSinkLatencyFetcher(uint32_t renderId)
{
SinkLatencyFetcherManager::GetInstance().RegisterProvider(renderId,
[] (uint32_t renderId, uint32_t &latency) -> int32_t {
latency = DEFAULT_SINK_LATENCY_MS;
std::shared_ptr<IAudioRenderSink> audioRendererSink =
HdiAdapterManager::GetInstance().GetRenderSink(renderId, false);
CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_OPERATION,
"audioRendererSink is null, renderId %{public}u", renderId);
int32_t ret = audioRendererSink->GetLatency(latency);
CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_LATENCY_DEFAULT_VALUE,
"GetLatency failed, renderId %{public}u ret %{public}d, use default", renderId, ret);
return SUCCESS;
});
auto fetcher = SinkLatencyFetcherManager::GetInstance().EnsureFetcher(renderId);
CHECK_AND_RETURN_LOG(fetcher, "sinkLatencyFetcher is null, renderId %{public}u", renderId);
uint32_t dummyLatency = 0;
int32_t ret = fetcher(dummyLatency);
CHECK_AND_RETURN_LOG(ret == SUCCESS,
"Preload sink latency failed, renderId %{public}u, ret %{public}d", renderId, ret);
}
int32_t AudioServer::SetDeviceConnectedFlag(bool flag)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
std::shared_ptr<IAudioRenderSink> primarySink = GetSinkByProp(HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT, true);
CHECK_AND_RETURN_RET_LOG(primarySink, ERROR, "primarySink is nullptr");
primarySink->SetDeviceConnectedFlag(flag);
return SUCCESS;
}
int32_t AudioServer::CreateAudioWorkgroup(const sptr<IRemoteObject> &object, int32_t &workgroupId)
{
int32_t pid = IPCSkeleton::GetCallingPid();
CHECK_AND_RETURN_RET_LOG(AudioResourceService::GetInstance() != nullptr, ERROR, "AudioResourceService is nullptr");
workgroupId = AudioResourceService::GetInstance()->CreateAudioWorkgroup(pid, object);
return SUCCESS;
}
int32_t AudioServer::ReleaseAudioWorkgroup(int32_t workgroupId)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->ReleaseAudioWorkgroup(pid, workgroupId);
}
int32_t AudioServer::AddThreadToGroup(int32_t workgroupId, int32_t tokenId)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->AddThreadToGroup(pid, workgroupId, tokenId);
}
int32_t AudioServer::RemoveThreadFromGroup(int32_t workgroupId, int32_t tokenId)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->RemoveThreadFromGroup(pid, workgroupId, tokenId);
}
int32_t AudioServer::StartGroup(int32_t workgroupId, uint64_t startTime, uint64_t deadlineTime)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->StartGroup(pid, workgroupId, startTime, deadlineTime);
}
int32_t AudioServer::StopGroup(int32_t workgroupId)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->StopGroup(pid, workgroupId);
}
int32_t AudioServer::SetBtHdiInvalidState()
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
auto limitFunc = [](uint32_t id) -> bool {
std::string info = IdHandler::GetInstance().ParseInfo(id);
if (IdHandler::GetInstance().ParseType(id) == HDI_ID_TYPE_BLUETOOTH &&
IdHandler::GetInstance().ParseInfo(id) != HDI_ID_INFO_HEARING_AID) {
return true;
}
return false;
};
auto sinkProcessFunc = [limitFunc](uint32_t renderId, std::shared_ptr<IAudioRenderSink> sink) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(renderId), SUCCESS);
CHECK_AND_RETURN_RET(sink != nullptr, SUCCESS);
sink->SetInvalidState();
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSink(sinkProcessFunc);
auto sourceProcessFunc = [limitFunc](uint32_t captureId, std::shared_ptr<IAudioCaptureSource> source) -> int32_t {
CHECK_AND_RETURN_RET(limitFunc(captureId), SUCCESS);
CHECK_AND_RETURN_RET(source != nullptr, SUCCESS);
source->SetInvalidState();
return SUCCESS;
};
(void)HdiAdapterManager::GetInstance().ProcessSource(sourceProcessFunc);
return SUCCESS;
}
int32_t AudioServer::SetActiveOutputDevice(int32_t deviceType)
{
CHECK_AND_RETURN_RET_LOG(deviceType >= DEVICE_TYPE_NONE && deviceType <= DEVICE_TYPE_MAX, AUDIO_ERR,
"Set active output device failed, please check log");
Trace trace("AudioServer::SetActiveOutputDevice:" + std::to_string(deviceType));
if (!PermissionUtil::VerifyIsAudio()) {
AUDIO_ERR_LOG("not audio calling!");
return ERR_PERMISSION_DENIED;
}
PolicyHandler::GetInstance().SetActiveOutputDevice(static_cast<DeviceType>(deviceType));
return SUCCESS;
}
int32_t AudioServer::ForceStopAudioStream(int32_t audioType)
{
CHECK_AND_RETURN_RET_LOG(audioType >= STOP_ALL && audioType <= STOP_RECORD,
ERR_INVALID_PARAM, "Invalid audioType");
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_SYSTEM_PERMISSION_DENIED, "not audio calling!");
CHECK_AND_RETURN_RET_LOG(AudioService::GetInstance() != nullptr, ERR_INVALID_OPERATION, "AudioService is nullptr");
return AudioService::GetInstance()->ForceStopAudioStream(static_cast<StopAudioType>(audioType));
}
int32_t AudioServer::ImproveAudioWorkgroupPrio(const std::unordered_map<int32_t, bool> &threads)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->ImproveAudioWorkgroupPrio(pid, threads);
}
int32_t AudioServer::RestoreAudioWorkgroupPrio(const std::unordered_map<int32_t, int32_t> &threads)
{
int32_t pid = IPCSkeleton::GetCallingPid();
return AudioResourceService::GetInstance()->RestoreAudioWorkgroupPrio(pid, threads);
}
int32_t AudioServer::GetPrivacyTypeAudioServer(uint32_t sessionId, int32_t &privacyType, int32_t &ret)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_SYSTEM_PERMISSION_DENIED, "not audio calling!");
AudioPrivacyType type = PRIVACY_TYPE_PUBLIC;
ret = AudioService::GetInstance()->GetPrivacyType(sessionId, type);
CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, SUCCESS, "%{public}u err", sessionId);
privacyType = static_cast<int32_t>(type);
return SUCCESS;
}
int32_t AudioServer::AddCaptureInjector(uint32_t sinkPortidx, std::string &rate, std::string &format,
std::string &channels, std::string &bufferSize)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_SYSTEM_PERMISSION_DENIED, "not audio calling!");
int32_t ret = ERROR;
return ret;
}
int32_t AudioServer::RemoveCaptureInjector(uint32_t sinkPortidx)
{
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_SYSTEM_PERMISSION_DENIED, "not audio calling!");
int32_t ret = ERROR;
return ret;
}
int32_t AudioServer::RegistAdapterManagerCallback(const sptr<IRemoteObject>& object, const std::string& networkId)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "no system permission");
std::lock_guard<std::mutex> lock(audioAdapterCbMutex_);
CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "listener object is nullptr");
sptr<IStandardAudioServerManagerListener> listener = iface_cast<IStandardAudioServerManagerListener>(object);
CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "AudioServer: listener obj cast failed");
std::shared_ptr<AudioParameterCallback> callback =
std::make_shared<AudioManagerListenerCallback>(listener);
CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "AudioPolicyServer: failed to create cb obj");
audioAdapterCb_ = callback;
audioAdapterNetworkIdSet_.insert(networkId);
AUDIO_INFO_LOG("set audioadpater callback success");
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, ERROR, "device manager is nullptr");
deviceManager->RegistAdapterManagerCallback(networkId.c_str(), this);
return SUCCESS;
}
void AudioServer::InitHdiEventCallback()
{
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
CHECK_AND_RETURN_LOG(deviceManager != nullptr, "device manager is nullptr");
deviceManager->RegistHdiEventCallback(
std::shared_ptr<IDeviceManagerCallback>(this, [](IDeviceManagerCallback*) {}));
}
int32_t AudioServer::UnRegistAdapterManagerCallback(const std::string& networkId)
{
bool result = PermissionUtil::VerifySystemPermission();
CHECK_AND_RETURN_RET_LOG(result, ERR_SYSTEM_PERMISSION_DENIED, "no system permission");
std::lock_guard<std::mutex> lock(audioAdapterCbMutex_);
audioAdapterNetworkIdSet_.erase(networkId);
audioAdapterCb_ = audioAdapterNetworkIdSet_.empty() ? nullptr : audioAdapterCb_;
HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, ERROR, "device manager is nullptr");
deviceManager->UnRegistAdapterManagerCallback(networkId.c_str());
return SUCCESS;
}
void AudioServer::OnAdapterParamChange(std::string networkId, const AudioParamKey key,
std::string condition, std::string value)
{
std::shared_ptr<AudioParameterCallback> callback = nullptr;
{
std::lock_guard<std::mutex> lock(audioAdapterCbMutex_);
callback = audioAdapterCb_;
}
CHECK_AND_RETURN_LOG(callback != nullptr, "audioAdapterCb_ is nullptr");
callback->OnAudioParameterChange(networkId, key, condition, value);
}
void AudioServer::OnDeviceStateChange(const std::string &networkId, DeviceRole role, bool isAvailable)
{
AUDIO_INFO_LOG("networkId: %{public}s, role: %{public}d, isAvailable: %{public}d", GetEncryptStr(networkId).c_str(),
static_cast<int32_t>(role), isAvailable);
CHECK_AND_RETURN_LOG(asyncHandler_ != nullptr, "async handler not inited");
auto action = std::make_shared<DeviceStateChangeCallbackAction>(networkId, role, isAvailable);
AsyncActionHandler::AsyncActionDesc desc;
desc.action = std::static_pointer_cast<AsyncActionHandler::AsyncAction>(action);
desc.priority = AsyncActionHandler::ActionPriority::IMMEDIATE;
asyncHandler_->PostAsyncAction(desc);
}
int32_t AudioServer::GetRemoteAudioParameter(const std::string& networkId, int32_t key,
const std::string& condition, std::string& value)
{
int32_t callingUid = IPCSkeleton::GetCallingUid();
bool ret = VerifyClientPermission(ACCESS_NOTIFICATION_POLICY_PERMISSION);
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio() || ret, ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
value = HdiAdapterManager::GetInstance().GetAudioParameter(HDI_DEVICE_MANAGER_TYPE_REMOTE,
networkId, static_cast<AudioParamKey>(key), condition);
AUDIO_INFO_LOG("Get valume %{public}s by key:%{public}d, condition:%{public}s",
value.c_str(), key, condition.c_str());
return SUCCESS;
}
int32_t AudioServer::RequestUserPrivacyAuthority(uint32_t sessionId)
{
CHECK_AND_RETURN_RET_LOG(AudioService::GetInstance() != nullptr, ERR_INVALID_OPERATION, "AudioService is nullptr");
return AudioService::GetInstance()->RequestUserPrivacyAuthority(sessionId);
}
bool AudioServer::AudioParameterValueCheck(const std::string &key, const std::string &value)
{
for (const auto &keyWord : ASR_FORBIDDEN_KEYS) {
if (value.find(keyWord) != std::string::npos) {
std::string bundleName = AudioBundleManager::GetBundleNameByToken(IPCSkeleton::GetCallingFullTokenID());
HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CHECK_HDI_FAILED, -1,
(bundleName + " ASR parameter not allowed in SetAudioParameter! key: " + key + ", value: " + value));
return false;
}
}
return true;
}
int32_t AudioServer::ReportPlaybackCaptureUserChoice(uint32_t sessionId, bool choice)
{
bool ret = VerifyClientPermission(MANAGE_AUDIO_CONFIG_PERMISSION);
CHECK_AND_RETURN_RET_LOG(ret, false, "ReportPlaybackCaptureUserChoice failed: no permission.");
CHECK_AND_RETURN_RET_LOG(AudioService::GetInstance() != nullptr, ERR_INVALID_OPERATION, "AudioService is nullptr");
return AudioService::GetInstance()->ReportPlaybackCaptureUserChoice(sessionId, choice);
}
int32_t AudioServer::ReportWakeupEvent(const AudioWakeupTrackInfo &audioWakeupTrackInfo)
{
int32_t fd = open(WAKEUP_TRACK_FILE_PATCH, O_RDWR | O_NONBLOCK, 0);
CHECK_AND_RETURN_RET_LOG(fd >= 0, ERR_OPERATION_FAILED,
"Open audio_wakeup_track err, errno: %{public}d (%{public}s)", errno, strerror(errno));
WakeupTrackInfo wakeupTrackInfo;
wakeupTrackInfo.stage = static_cast<WakeupStageCode>(audioWakeupTrackInfo.stage);
wakeupTrackInfo.result = static_cast<WakeupResult>(audioWakeupTrackInfo.result);
wakeupTrackInfo.errCode = static_cast<WakeupErrorCode>(audioWakeupTrackInfo.errCode);
int32_t ret = ioctl(fd, IOCTL_AUDIO_WAKEUP_TRACK_REPORT_CMD, &wakeupTrackInfo);
CHECK_AND_CALL_FUNC_RETURN_RET(ret >= 0, ERR_OPERATION_FAILED, (void)close(fd));
(void)close(fd);
return SUCCESS;
}
int32_t AudioServer::SetAncoRecordingConfigChanged(const std::vector<std::string> &bundleNameList)
{
CHECK_AND_RETURN_RET_LOG(AudioService::GetInstance() != nullptr, ERR_INVALID_OPERATION, "AudioService is nullptr");
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudioBroker(), ERR_OPERATION_FAILED, "Not audio broker calling");
AudioService::GetInstance()->SetAncoRecordingConfigChanged(bundleNameList);
return SUCCESS;
}
bool AudioServer::CheckVoiceDownlinkPermission(const AudioProcessConfig &config)
{
if (config.capturerInfo.sourceType != SOURCE_TYPE_VOICE_DOWNLINK) {
return true;
}
bool hasAclPermission = PermissionUtil::VerifyPermission(
CAPTURE_PLAYBACK_DOWNLINK_PERMISSION, IPCSkeleton::GetCallingTokenID());
CHECK_AND_RETURN_RET_LOG(hasAclPermission, false,
"CheckVoiceDownlinkPermission failed: no ACL permission");
CHECK_AND_RETURN_RET_LOG(!config.capturerInfo.cellularRecordPhoneNum.empty() &&
!config.capturerInfo.cellularRecordToken.empty(), false,
"CheckCallRecordingPermission failed: phoneNum or token is empty");
#ifdef FEATURE_CALL_MANAGER
std::shared_ptr<Telephony::CallManagerClient> callManager =
DelayedSingleton<Telephony::CallManagerClient>::GetInstance();
CHECK_AND_RETURN_RET_LOG(callManager != nullptr, false, "Get CallManagerClient failed");
callManager->Init(TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
bool isValid = callManager->CheckCallRecordingPermission(
config.capturerInfo.cellularRecordPhoneNum,
config.capturerInfo.cellularRecordToken);
CHECK_AND_RETURN_RET_LOG(isValid, false, "");
return true;
#else
AUDIO_INFO_LOG("CheckVoiceDownlinkPermission success!");
return true;
#endif
}
int32_t AudioServer::NotifySensitiveRecordPermit(uint32_t sessionId, bool isPermitted)
{
AUDIO_INFO_LOG("sessionId: %{public}u, isPermitted: %{public}d", sessionId, isPermitted);
int32_t callingUid = IPCSkeleton::GetCallingUid();
CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifyIsAudio(), ERR_PERMISSION_DENIED,
"refused for %{public}d", callingUid);
AudioService::GetInstance()->NotifySensitiveRecordPermit(sessionId, isPermitted);
return SUCCESS;
}
}
}