Support DFX for audio subsystem

Signed-off-by: Sulav Mulmi <sulav.mulmi@huawei.com>
This commit is contained in:
Sulav Mulmi 2022-05-23 12:15:37 +05:30
parent 3289ca681c
commit e3692b686e
30 changed files with 469 additions and 6 deletions

View File

@ -17,6 +17,7 @@
"adapted_system_type": [ "standard" ],
"rom": "",
"ram": "",
"hisysevent_config": [ "//foundation/multimedia/audio_standard/hisysevent.yaml" ],
"deps": {
"components": [
"ability_manager",

View File

@ -39,7 +39,10 @@ ohos_shared_library("pulse_audio_service_adapter") {
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
external_deps = [
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
]
part_name = "multimedia_audio_standard"
subsystem_name = "multimedia"
}

View File

@ -19,6 +19,7 @@
#include <memory>
#include <string>
#include <unistd.h>
#include <vector>
#include "audio_info.h"
@ -140,6 +141,20 @@ public:
*/
virtual bool IsStreamActive(AudioStreamType streamType);
/**
* @brief returns the list of all sink inputs
*
* @return Returns : List of all sink inputs
*/
virtual std::vector<SinkInput> GetAllSinkInputs() = 0;
/**
* @brief returns the list of all source outputs
*
* @return Returns : List of all source outputs
*/
virtual std::vector<SourceOutput> GetAllSourceOutputs() = 0;
/**
* @brief Disconnects the connected audio server
*

View File

@ -19,6 +19,7 @@
#include <mutex>
#include <pulse/pulseaudio.h>
#include <vector>
#include "audio_service_adapter.h"
@ -39,6 +40,8 @@ public:
int32_t SuspendAudioDevice(std::string &audioPortName, bool isSuspend) override;
bool IsMute(AudioStreamType streamType) override;
bool IsStreamActive(AudioStreamType streamType) override;
std::vector<SinkInput> GetAllSinkInputs() override;
std::vector<SourceOutput> GetAllSourceOutputs() override;
void Disconnect() override;
// Static Member functions
@ -49,6 +52,8 @@ public:
static void PaGetSinkInputInfoMuteCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
static void PaGetSinkInputInfoMuteStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
static void PaGetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
static void PaGetAllSinkInputsCb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
static void PaGetAllSourceOutputsCb(pa_context *c, const pa_source_output_info *i, int eol, void *userdata);
private:
struct UserData {
PulseAudioServiceAdapterImpl *thiz;
@ -57,6 +62,8 @@ private:
bool mute;
bool isCorked;
uint32_t idx;
std::vector<SinkInput> sinkInputList;
std::vector<SourceOutput> sourceOutputList;
};
bool ConnectToPulseAudio();

View File

@ -23,6 +23,7 @@
#include "audio_errors.h"
#include "audio_log.h"
#include "hisysevent.h"
using namespace std;
@ -362,6 +363,70 @@ bool PulseAudioServiceAdapterImpl::IsStreamActive(AudioStreamType streamType)
return (userData->isCorked) ? false : true;
}
vector<SinkInput> PulseAudioServiceAdapterImpl::GetAllSinkInputs()
{
lock_guard<mutex> lock(mMutex);
unique_ptr<UserData> userData = make_unique<UserData>();
userData->thiz = this;
if (mContext == nullptr) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] GetAllSinkInputs mContext is nullptr");
return userData->sinkInputList;
}
pa_threaded_mainloop_lock(mMainLoop);
pa_operation *operation = pa_context_get_sink_input_info_list(mContext,
PulseAudioServiceAdapterImpl::PaGetAllSinkInputsCb, reinterpret_cast<void*>(userData.get()));
if (operation == nullptr) {
AUDIO_ERR_LOG("[GetAllSinkInputs] pa_context_get_sink_input_info_list returned nullptr");
pa_threaded_mainloop_unlock(mMainLoop);
return userData->sinkInputList;
}
while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
pa_threaded_mainloop_wait(mMainLoop);
}
pa_operation_unref(operation);
pa_threaded_mainloop_unlock(mMainLoop);
return userData->sinkInputList;
}
vector<SourceOutput> PulseAudioServiceAdapterImpl::GetAllSourceOutputs()
{
lock_guard<mutex> lock(mMutex);
unique_ptr<UserData> userData = make_unique<UserData>();
userData->thiz = this;
if (mContext == nullptr) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] GetAllSourceOutputs mContext is nullptr");
return userData->sourceOutputList;
}
pa_threaded_mainloop_lock(mMainLoop);
pa_operation *operation = pa_context_get_source_output_info_list(mContext,
PulseAudioServiceAdapterImpl::PaGetAllSourceOutputsCb, reinterpret_cast<void*>(userData.get()));
if (operation == nullptr) {
AUDIO_ERR_LOG("[GetAllSourceOutputs] pa_context_get_source_output_info_list returned nullptr");
pa_threaded_mainloop_unlock(mMainLoop);
return userData->sourceOutputList;
}
while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
pa_threaded_mainloop_wait(mMainLoop);
}
pa_operation_unref(operation);
pa_threaded_mainloop_unlock(mMainLoop);
return userData->sourceOutputList;
}
void PulseAudioServiceAdapterImpl::Disconnect()
{
if (mContext != nullptr) {
@ -613,6 +678,8 @@ void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoVolumeCb(pa_context *c, con
}
AUDIO_INFO_LOG("[PulseAudioServiceAdapterImpl]volume : %{public}f for stream : %{public}s, volumeInt%{public}d",
vol, i->name, volume);
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_VOLUME_CHANGE", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISOUTPUT", 1, "STREAMID", sessionID, "STREAMTYPE", streamID, "VOLUME", vol);
}
void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoCorkStatusCb(pa_context *c, const pa_sink_input_info *i, int eol,
@ -651,6 +718,86 @@ void PulseAudioServiceAdapterImpl::PaGetSinkInputInfoCorkStatusCb(pa_context *c,
}
}
void PulseAudioServiceAdapterImpl::PaGetAllSinkInputsCb(pa_context *c, const pa_sink_input_info *i, int eol,
void *userdata)
{
UserData *userData = reinterpret_cast<UserData *>(userdata);
PulseAudioServiceAdapterImpl *thiz = userData->thiz;
if (eol < 0) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get sink input information: %{public}s",
pa_strerror(pa_context_errno(c)));
return;
}
if (eol) {
pa_threaded_mainloop_signal(thiz->mMainLoop, 0);
return;
}
if (i->proplist == nullptr) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for sink input (%{public}d).", i->index);
return;
}
uint32_t sessionID = 0;
const char *sessionCStr = pa_proplist_gets(i->proplist, "stream.sessionID");
if (sessionCStr != nullptr) {
std::stringstream sessionStr;
sessionStr << sessionCStr;
sessionStr >> sessionID;
}
AudioStreamType audioStreamType = STREAM_DEFAULT;
const char *streamType = pa_proplist_gets(i->proplist, "stream.type");
if (streamType != nullptr) {
audioStreamType = thiz->GetIdByStreamType(streamType);
}
SinkInput sinkInput = {sessionID, audioStreamType};
userData->sinkInputList.push_back(sinkInput);
}
void PulseAudioServiceAdapterImpl::PaGetAllSourceOutputsCb(pa_context *c, const pa_source_output_info *i, int eol,
void *userdata)
{
UserData *userData = reinterpret_cast<UserData *>(userdata);
PulseAudioServiceAdapterImpl *thiz = userData->thiz;
if (eol < 0) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] Failed to get source output information: %{public}s",
pa_strerror(pa_context_errno(c)));
return;
}
if (eol) {
pa_threaded_mainloop_signal(thiz->mMainLoop, 0);
return;
}
if (i->proplist == nullptr) {
AUDIO_ERR_LOG("[PulseAudioServiceAdapterImpl] Invalid Proplist for source output (%{public}d).", i->index);
return;
}
uint32_t sessionID = 0;
const char *sessionCStr = pa_proplist_gets(i->proplist, "stream.sessionID");
if (sessionCStr != nullptr) {
std::stringstream sessionStr;
sessionStr << sessionCStr;
sessionStr >> sessionID;
}
AudioStreamType audioStreamType = STREAM_DEFAULT;
const char *streamType = pa_proplist_gets(i->proplist, "stream.type");
if (streamType != nullptr) {
audioStreamType = thiz->GetIdByStreamType(streamType);
}
SourceOutput sourceOutput = {sessionID, audioStreamType};
userData->sourceOutputList.push_back(sourceOutput);
}
void PulseAudioServiceAdapterImpl::PaSubscribeCb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx,
void *userdata)
{

View File

@ -66,6 +66,7 @@ public:
int32_t GetMute(bool &isMute);
int32_t SetAudioScene(AudioScene audioScene);
int32_t OpenInput(DeviceType deviceType);
uint64_t GetTransactionId();
static AudioCapturerSource *GetInstance(void);
bool capturerInited_;

View File

@ -459,6 +459,12 @@ int32_t AudioCapturerSource::SetAudioScene(AudioScene audioScene)
return SUCCESS;
}
uint64_t AudioCapturerSource::GetTransactionId()
{
AUDIO_INFO_LOG("AudioCapturerSource::GetTransactionId in");
return reinterpret_cast<uint64_t>(audioCapture_);
}
int32_t AudioCapturerSource::Stop(void)
{
int32_t ret;

View File

@ -51,6 +51,7 @@ public:
int32_t GetLatency(uint32_t *latency);
int32_t SetAudioScene(AudioScene audioScene);
int32_t OpenOutput(DeviceType deviceType);
uint64_t GetTransactionId();
static AudioRendererSink *GetInstance(void);
bool rendererInited_;
private:

View File

@ -46,6 +46,7 @@ public:
int32_t SetVolume(float left, float right);
int32_t GetVolume(float &left, float &right);
int32_t GetLatency(uint32_t *latency);
uint64_t GetTransactionId();
static BluetoothRendererSink *GetInstance(void);
bool rendererInited_;
private:

View File

@ -474,6 +474,12 @@ int32_t AudioRendererSink::SetAudioScene(AudioScene audioScene)
return SUCCESS;
}
uint64_t AudioRendererSink::GetTransactionId()
{
AUDIO_INFO_LOG("AudioRendererSink::GetTransactionId in");
return reinterpret_cast<uint64_t>(audioRender_);
}
int32_t AudioRendererSink::Stop(void)
{
int32_t ret;

View File

@ -392,6 +392,12 @@ int32_t BluetoothRendererSink::GetLatency(uint32_t *latency)
}
}
uint64_t BluetoothRendererSink::GetTransactionId()
{
AUDIO_INFO_LOG("BluetoothRendererSink::GetTransactionId in");
return reinterpret_cast<uint64_t>(audioRender_);
}
int32_t BluetoothRendererSink::Stop(void)
{
AUDIO_INFO_LOG("BluetoothRendererSink::Stop in");

45
hisysevent.yaml Normal file
View File

@ -0,0 +1,45 @@
# Copyright (c) 2022 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.
domain: AUDIO
AUDIO_DEVICE_CHANGE:
__BASE: {type: BEHAVIOR, level: MINOR, desc: audio output device}
ISOUTPUT: {type: INT32, desc: is output device}
STREAMID: {type: INT32, desc: stream id}
STREAMTYPE: {type: INT32, desc: stream type}
DEVICETYPE: {type: INT32, desc: device type}
AUDIO_VOLUME_CHANGE:
__BASE: {type: BEHAVIOR, level: MINOR, desc: audio input device}
ISOUTPUT: {type: INT32, desc: output device}
STREAMID: {type: INT32, desc: stream id}
STREAMTYPE: {type: INT32, desc: stream type}
VOLUME: {type: FLOAT, desc: audio volume}
AUDIO_STREAM_CHANGE:
__BASE: {type: BEHAVIOR, level: MINOR, desc: capturer state change}
ISOUTPUT: {type: INT32, desc: output device}
STREAMID: {type: INT32, desc: stream id}
UID: {type: INT32, desc: user id}
PID: {type: INT32, desc: process id}
TRANSACTIONID: {type: UINT64, desc: transaction id}
STREAMTYPE: {type: INT32, desc: stream type}
STATE: {type: INT32, desc: audio state}
DEVICETYPE: {type: INT32, desc: device type}
AUDIO_HEADSET_CHANGE:
__BASE: {type: BEHAVIOR, level: MINOR, desc: headset connection state}
ISCONNECT: {type: INT32, desc: is plugged in}
HASMIC: {type: INT32, desc: mic available}
DEVICETYPE: {type: INT32, desc: device type}

View File

@ -560,6 +560,16 @@ enum AudioCaptureMode {
CAPTURE_MODE_CALLBACK
};
struct SinkInput {
int32_t streamId;
AudioStreamType streamType;
};
struct SourceOutput {
int32_t streamId;
AudioStreamType streamType;
};
typedef uint32_t AudioIOHandle;
static inline bool FLOAT_COMPARE_EQ(const float& x, const float& y)

View File

@ -82,6 +82,7 @@ ohos_shared_library("audio_client") {
]
external_deps = [
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",

View File

@ -201,6 +201,7 @@ public:
const std::string GetAudioParameter(const std::string key);
void SetAudioParameter(const std::string &key, const std::string &value);
const char *RetrieveCookie(int32_t &size);
uint64_t GetTransactionId(DeviceType deviceType, DeviceRole deviceRole);
int32_t SetDeviceActive(ActiveDeviceType deviceType, bool flag) const;
bool IsDeviceActive(ActiveDeviceType deviceType) const;
bool IsStreamActive(AudioSystemManager::AudioVolumeType volumeType) const;

View File

@ -202,6 +202,7 @@ ohos_shared_library("audio_policy_service") {
external_deps = [
"access_token:libaccesstoken_sdk",
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"input:libmmi-client",
"ipc:ipc_core",

View File

@ -102,6 +102,16 @@ public:
*/
virtual const char *RetrieveCookie(int32_t &size) = 0;
/**
* Get the transaction Id
*
* @return Returns transaction id.
*/
virtual uint64_t GetTransactionId(DeviceType deviceType, DeviceRole deviceRole)
{
return 0;
}
enum {
GET_MAX_VOLUME = 0,
GET_MIN_VOLUME = 1,
@ -112,7 +122,8 @@ public:
IS_MICROPHONE_MUTE = 6,
SET_AUDIO_SCENE = 7,
UPDATE_ROUTE_REQ = 8,
RETRIEVE_COOKIE = 9
RETRIEVE_COOKIE = 9,
GET_TRANSACTION_ID = 10
};
public:

View File

@ -131,6 +131,8 @@ private:
void TriggerDeviceChangedCallback(const std::vector<sptr<AudioDeviceDescriptor>> &devChangeDesc, bool connection);
void WriteDeviceChangedSysEvents(const std::vector<sptr<AudioDeviceDescriptor>> &desc, bool isConnected);
bool GetActiveDeviceStreamInfo(DeviceType deviceType, AudioStreamInfo &streamInfo);
bool IsConfigurationUpdated(DeviceType deviceType, const AudioStreamInfo &streamInfo);

View File

@ -47,6 +47,10 @@ public:
virtual bool IsStreamActive(AudioStreamType streamType) = 0;
virtual std::vector<SinkInput> GetAllSinkInputs() = 0;
virtual std::vector<SourceOutput> GetAllSourceOutputs() = 0;
virtual AudioIOHandle OpenAudioPort(const AudioModuleInfo &audioPortInfo) = 0;
virtual int32_t CloseAudioPort(AudioIOHandle ioHandle) = 0;

View File

@ -63,6 +63,10 @@ public:
bool IsStreamActive(AudioStreamType streamType);
std::vector<SinkInput> GetAllSinkInputs();
std::vector<SourceOutput> GetAllSourceOutputs();
AudioIOHandle OpenAudioPort(const AudioModuleInfo &audioModuleInfo);
int32_t CloseAudioPort(AudioIOHandle ioHandle);

View File

@ -36,6 +36,7 @@ public:
void SetAudioParameter(const std::string &key, const std::string &value) override;
int32_t UpdateActiveDeviceRoute(DeviceType type, DeviceFlag flag) override;
const char *RetrieveCookie(int32_t &size) override;
uint64_t GetTransactionId(DeviceType deviceType, DeviceRole deviceRole) override;
private:
static inline BrokerDelegator<AudioManagerProxy> delegator_;
};

View File

@ -534,6 +534,7 @@ private:
pa_cvolume cvolume;
uint32_t streamIndex;
uint32_t sessionID;
uint32_t volumeChannels;
bool streamInfoUpdated;
@ -591,6 +592,8 @@ private:
void HandleRenderPositionCallbacks(size_t bytesWritten);
void HandleCapturePositionCallbacks(size_t bytesRead);
void WriteStateChangedSysEvents();
// Error code used
static const int32_t AUDIO_CLIENT_SUCCESS = 0;
static const int32_t AUDIO_CLIENT_ERR = -1;

View File

@ -47,6 +47,7 @@ public:
void SetAudioParameter(const std::string &key, const std::string &value) override;
const std::string GetAudioParameter(const std::string &key) override;
const char *RetrieveCookie(int32_t &size) override;
uint64_t GetTransactionId(DeviceType deviceType, DeviceRole deviceRole) override;
int32_t UpdateActiveDeviceRoute(DeviceType type, DeviceFlag flag) override;
private:

View File

@ -18,6 +18,7 @@
#include "audio_manager_base.h"
#include "iservice_registry.h"
#include "audio_log.h"
#include "hisysevent.h"
#include "system_ability_definition.h"
#include "audio_policy_service.h"
@ -793,12 +794,55 @@ InternalDeviceType AudioPolicyService::GetDeviceType(const std::string &deviceNa
return devType;
}
void AudioPolicyService::WriteDeviceChangedSysEvents(const vector<sptr<AudioDeviceDescriptor>> &desc, bool isConnected)
{
for (auto deviceDescriptor : desc) {
if (deviceDescriptor != nullptr) {
if (deviceDescriptor->deviceType_ == DEVICE_TYPE_WIRED_HEADSET) {
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_HEADSET_CHANGE",
HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISCONNECT", isConnected ? 1 : 0,
"HASMIC", 1,
"DEVICETYPE", DEVICE_TYPE_WIRED_HEADSET);
}
if (!isConnected) {
continue;
}
if (deviceDescriptor->deviceRole_ == OUTPUT_DEVICE) {
vector<SinkInput> sinkInputs = mAudioPolicyManager.GetAllSinkInputs();
for (SinkInput sinkInput : sinkInputs) {
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_DEVICE_CHANGE",
HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISOUTPUT", 1,
"STREAMID", sinkInput.streamId,
"STREAMTYPE", sinkInput.streamType,
"DEVICETYPE", deviceDescriptor->deviceType_);
}
} else if (deviceDescriptor->deviceRole_ == INPUT_DEVICE) {
vector<SourceOutput> sourceOutputs = mAudioPolicyManager.GetAllSourceOutputs();
for (SourceOutput sourceOutput : sourceOutputs) {
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_DEVICE_CHANGE",
HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISOUTPUT", 0,
"STREAMID", sourceOutput.streamId,
"STREAMTYPE", sourceOutput.streamType,
"DEVICETYPE", deviceDescriptor->deviceType_);
}
}
}
}
}
void AudioPolicyService::TriggerDeviceChangedCallback(const vector<sptr<AudioDeviceDescriptor>> &desc, bool isConnected)
{
DeviceChangeAction deviceChangeAction;
deviceChangeAction.deviceDescriptors = desc;
deviceChangeAction.type = isConnected ? DeviceChangeType::CONNECT : DeviceChangeType::DISCONNECT;
WriteDeviceChangedSysEvents(desc, isConnected);
for (auto it = deviceChangeCallbackMap_.begin(); it != deviceChangeCallbackMap_.end(); ++it) {
if (it->second) {
it->second->OnDeviceChange(deviceChangeAction);

View File

@ -21,6 +21,8 @@
#include "audio_adapter_manager.h"
using namespace std;
namespace OHOS {
namespace AudioStandard {
bool AudioAdapterManager::Init()
@ -134,6 +136,28 @@ bool AudioAdapterManager::IsStreamActive(AudioStreamType streamType)
return mAudioServiceAdapter->IsStreamActive(streamType);
}
vector<SinkInput> AudioAdapterManager::GetAllSinkInputs()
{
if (!mAudioServiceAdapter) {
AUDIO_ERR_LOG("[AudioAdapterManager] audio adapter null");
vector<SinkInput> sinkInputList;
return sinkInputList;
}
return mAudioServiceAdapter->GetAllSinkInputs();
}
vector<SourceOutput> AudioAdapterManager::GetAllSourceOutputs()
{
if (!mAudioServiceAdapter) {
AUDIO_ERR_LOG("[AudioAdapterManager] audio adapter null");
vector<SourceOutput> sourceOutputList;
return sourceOutputList;
}
return mAudioServiceAdapter->GetAllSourceOutputs();
}
int32_t AudioAdapterManager::SuspendAudioDevice(std::string &portName, bool isSuspend)
{
if (!mAudioServiceAdapter) {

View File

@ -205,6 +205,32 @@ const char *AudioManagerProxy::RetrieveCookie(int32_t &size)
return cookieInfo;
}
uint64_t AudioManagerProxy::GetTransactionId(DeviceType deviceType, DeviceRole deviceRole)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
uint32_t transactionId = 0;
if (!data.WriteInterfaceToken(GetDescriptor())) {
AUDIO_ERR_LOG("AudioManagerProxy: WriteInterfaceToken failed");
return transactionId;
}
data.WriteInt32(static_cast<int32_t>(deviceType));
data.WriteInt32(static_cast<int32_t>(deviceRole));
int32_t error = Remote()->SendRequest(GET_TRANSACTION_ID, data, reply, option);
if (error != ERR_NONE) {
AUDIO_ERR_LOG("get transaction id failed, error: %d", error);
return transactionId;
}
transactionId = reply.ReadUint64();
return transactionId;
}
int32_t AudioManagerProxy::UpdateActiveDeviceRoute(DeviceType type, DeviceFlag flag)
{
return ERR_NONE;

View File

@ -19,6 +19,7 @@
#include "iservice_registry.h"
#include "audio_log.h"
#include "hisysevent.h"
#include "securec.h"
#include "system_ability_definition.h"
#include "unistd.h"
@ -147,6 +148,7 @@ void AudioServiceClient::PAStreamStartSuccessCb(pa_stream *stream, int32_t succe
pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
asClient->state_ = RUNNING;
asClient->WriteStateChangedSysEvents();
std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
if (streamCb != nullptr) {
streamCb->OnStateChange(asClient->state_);
@ -166,6 +168,7 @@ void AudioServiceClient::PAStreamStopSuccessCb(pa_stream *stream, int32_t succes
pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
asClient->state_ = STOPPED;
asClient->WriteStateChangedSysEvents();
std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
if (streamCb != nullptr) {
streamCb->OnStateChange(asClient->state_);
@ -185,6 +188,7 @@ void AudioServiceClient::PAStreamPauseSuccessCb(pa_stream *stream, int32_t succe
pa_threaded_mainloop *mainLoop = static_cast<pa_threaded_mainloop *>(asClient->mainLoop);
asClient->state_ = PAUSED;
asClient->WriteStateChangedSysEvents();
std::shared_ptr<AudioStreamCallback> streamCb = asClient->streamCallback_.lock();
if (streamCb != nullptr) {
streamCb->OnStateChange(asClient->state_);
@ -450,6 +454,7 @@ AudioServiceClient::AudioServiceClient()
mAudioSystemMgr = nullptr;
streamIndex = 0;
sessionID = 0;
volumeChannels = STEREO;
streamInfoUpdated = false;
@ -946,6 +951,7 @@ int32_t AudioServiceClient::CreateStream(AudioStreamParams audioParams, AudioStr
}
state_ = PREPARED;
WriteStateChangedSysEvents();
std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
if (streamCb != nullptr) {
streamCb->OnStateChange(state_);
@ -1547,8 +1553,9 @@ int32_t AudioServiceClient::ReadStream(StreamBuffer &stream, bool isBlocking)
int32_t AudioServiceClient::ReleaseStream()
{
ResetPAAudioClient();
state_ = RELEASED;
WriteStateChangedSysEvents();
ResetPAAudioClient();
std::shared_ptr<AudioStreamCallback> streamCb = streamCallback_.lock();
if (streamCb != nullptr) {
@ -1964,8 +1971,17 @@ void AudioServiceClient::GetSinkInputInfoCb(pa_context *context, const pa_sink_i
return;
}
uint32_t sessionID = 0;
const char *sessionCStr = pa_proplist_gets(info->proplist, "stream.sessionID");
if (sessionCStr != nullptr) {
std::stringstream sessionStr;
sessionStr << sessionCStr;
sessionStr >> sessionID;
}
thiz->cvolume = info->volume;
thiz->streamIndex = info->index;
thiz->sessionID = sessionID;
thiz->volumeChannels = info->channel_map.channels;
thiz->streamInfoUpdated = true;
@ -1992,6 +2008,11 @@ void AudioServiceClient::SetPaVolume(const AudioServiceClient &client)
pa_operation_unref(pa_context_set_sink_input_volume(client.context, client.streamIndex, &cv, nullptr, nullptr));
AUDIO_INFO_LOG("Applied volume : %{public}f, pa volume: %{public}d", vol, volume);
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_VOLUME_CHANGE", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISOUTPUT", 1,
"STREAMID", client.sessionID,
"STREAMTYPE", client.mStreamType,
"VOLUME", vol);
}
int32_t AudioServiceClient::SetStreamRenderRate(AudioRendererRate audioRendererRate)
@ -2042,5 +2063,34 @@ void AudioServiceClient::SaveStreamCallback(const std::weak_ptr<AudioStreamCallb
streamCb->OnStateChange(state_);
}
}
void AudioServiceClient::WriteStateChangedSysEvents()
{
uint32_t sessionID = 0;
uint64_t transactionId = 0;
int32_t callingPid = getpid();
int32_t callingUid = getuid();
bool isOutput = true;
if (eAudioClientType == AUDIO_SERVICE_CLIENT_PLAYBACK) {
transactionId = mAudioSystemMgr->GetTransactionId(DEVICE_TYPE_SPEAKER, OUTPUT_DEVICE);
} else {
transactionId = mAudioSystemMgr->GetTransactionId(DEVICE_TYPE_MIC, INPUT_DEVICE);
isOutput = false;
}
GetSessionID(sessionID);
HiviewDFX::HiSysEvent::Write("AUDIO", "AUDIO_STREAM_CHANGE",
HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
"ISOUTPUT", isOutput ? 1 : 0,
"STREAMID", sessionID,
"UID", callingUid,
"PID", callingPid,
"TRANSACTIONID", transactionId,
"STREAMTYPE", mStreamType,
"STATE", state_,
"DEVICETYPE", DEVICE_TYPE_INVALID);
}
} // namespace AudioStandard
} // namespace OHOS

View File

@ -239,6 +239,14 @@ const char *AudioSystemManager::RetrieveCookie(int32_t &size)
return g_sProxy->RetrieveCookie(size);
}
uint64_t AudioSystemManager::GetTransactionId(DeviceType deviceType, DeviceRole deviceRole)
{
if (!IsAlived()) {
CHECK_AND_RETURN_RET_LOG(g_sProxy != nullptr, 0, "GetTransactionId::Audio service unavailable");
}
return g_sProxy->GetTransactionId(deviceType, deviceRole);
}
int32_t AudioSystemManager::SetVolume(AudioSystemManager::AudioVolumeType volumeType, int32_t volume) const
{
AUDIO_DEBUG_LOG("AudioSystemManager SetVolume volumeType=%{public}d ", volumeType);

View File

@ -84,6 +84,16 @@ int AudioManagerStub::OnRemoteRequest(
return AUDIO_OK;
}
case GET_TRANSACTION_ID: {
AUDIO_DEBUG_LOG("GET_TRANSACTION_ID AudioManagerStub");
DeviceType deviceType = (static_cast<DeviceType>(data.ReadInt32()));
DeviceRole deviceRole = (static_cast<DeviceRole>(data.ReadInt32()));
uint64_t transactionId = GetTransactionId(deviceType, deviceRole);
reply.WriteUint64(transactionId);
return AUDIO_OK;
}
case SET_MICROPHONE_MUTE: {
AUDIO_DEBUG_LOG("SET_MICROPHONE_MUTE AudioManagerStub");
bool isMute = data.ReadBool();

View File

@ -13,16 +13,18 @@
* limitations under the License.
*/
#include <cinttypes>
#include <fstream>
#include <sstream>
#include "audio_capturer_source.h"
#include "audio_errors.h"
#include "audio_renderer_sink.h"
#include "iservice_registry.h"
#include "audio_log.h"
#include "system_ability_definition.h"
#include "audio_server.h"
#include <fstream>
#include <sstream>
#include "audio_server.h"
#define PA
#ifdef PA
@ -135,6 +137,27 @@ const char *AudioServer::RetrieveCookie(int32_t &size)
return cookieInfo;
}
uint64_t AudioServer::GetTransactionId(DeviceType deviceType, DeviceRole deviceRole)
{
uint64_t transactionId = 0;
AUDIO_INFO_LOG("GetTransactionId in: device type: %{public}d, device role: %{public}d", deviceType, deviceRole);
if (deviceRole == OUTPUT_DEVICE) {
AudioRendererSink *audioRendererSinkInstance = AudioRendererSink::GetInstance();
if (audioRendererSinkInstance) {
transactionId = audioRendererSinkInstance->GetTransactionId();
}
} else if (deviceRole == INPUT_DEVICE) {
AudioCapturerSource *audioCapturerSourceInstance = AudioCapturerSource::GetInstance();
if (audioCapturerSourceInstance) {
transactionId = audioCapturerSourceInstance->GetTransactionId();
}
}
AUDIO_INFO_LOG("Transaction Id: %{public}" PRIu64, transactionId);
return transactionId;
}
int32_t AudioServer::GetMaxVolume(AudioSystemManager::AudioVolumeType volumeType)
{
AUDIO_DEBUG_LOG("GetMaxVolume server");