/* * Copyright (c) 2021-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. */ /** * @addtogroup Audio * @{ * * @brief Defines audio-related APIs, including custom data types and functions for loading drivers, * accessing a driver adapter, and rendering audios. * * @since 1.0 * @version 1.0 */ /** * @file audio_hdi_common.h * * @brief Declares APIs for operations related to the audio render adapter. * * @since 1.0 * @version 1.0 */ #include "audio_hdi_common.h" #include "audio_hdirender_test.h" using namespace std; using namespace testing::ext; using namespace OHOS::Audio; namespace { class AudioHdiRenderTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); void TearDown(); static TestAudioManager *manager; }; using THREAD_FUNC = void *(*)(void *); TestAudioManager *AudioHdiRenderTest::manager = nullptr; void AudioHdiRenderTest::SetUpTestCase(void) { manager = GetAudioManagerFuncs(); ASSERT_NE(nullptr, manager); } void AudioHdiRenderTest::TearDownTestCase(void) {} void AudioHdiRenderTest::SetUp(void) {} void AudioHdiRenderTest::TearDown(void) {} /** * @tc.name AudioRenderGetLatency_001 * @tc.desc test RenderGetLatency interface, return 0 if GetLatency successful * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetLatency_001, TestSize.Level1) { int32_t ret = -1; uint32_t latencyTime = 0; uint32_t expectLatency = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetLatency(render, &latencyTime); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_LT(expectLatency, latencyTime); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetLatency_002 * @tc.desc test RenderGetLatency interface, return -1 if Setting parameters render is empty * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetLatency_002, TestSize.Level1) { int32_t ret = -1; uint32_t latencyTime = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetLatency(renderNull, &latencyTime); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetLatency_003 * @tc.desc test RenderGetLatency interface,return -1 if Setting parameters ms is empty * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetLatency_003, TestSize.Level1) { int32_t ret = -1; uint32_t *latencyTime = nullptr; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetLatency(render, latencyTime); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderSetRenderSpeed_001 * @tc.desc Test SetRenderSpeed interface,return -2 if setting RenderSpeed * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderSetRenderSpeed_001, TestSize.Level1) { int32_t ret = -1; float speed = 100; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->SetRenderSpeed(render, speed); EXPECT_EQ(AUDIO_HAL_ERR_NOT_SUPPORT, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderSetRenderSpeed_002 * @tc.desc Test SetRenderSpeed interface,return -2 if the incoming parameter handle is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderSetRenderSpeed_002, TestSize.Level1) { int32_t ret = -1; float speed = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->SetRenderSpeed(renderNull, speed); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderSpeed_001 * @tc.desc Test GetRenderSpeed interface,return -2 if getting RenderSpeed * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderSpeed_001, TestSize.Level1) { int32_t ret = -1; float speed = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderSpeed(render, &speed); EXPECT_EQ(AUDIO_HAL_ERR_NOT_SUPPORT, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderSpeed_002 * @tc.desc Test GetRenderSpeed interface,return -2 if the incoming parameter handle is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderSpeed_002, TestSize.Level1) { int32_t ret = -1; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; float speed = 0; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderSpeed(renderNull, &speed); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderSpeed_002 * @tc.desc Test GetRenderSpeed interface,return -2 if the incoming parameter speed is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderSpeed_003, TestSize.Level1) { int32_t ret = -1; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; float *speedNull = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderSpeed(render, speedNull); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderFrame_001 * @tc.desc test AudioRenderFrame interface,Returns 0 if the data is written successfully * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderFrame_001, TestSize.Level1) { int32_t ret = -1; uint64_t requestBytes = 0; uint64_t replyBytes = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; char *frame = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = RenderFramePrepare(AUDIO_FILE, frame, requestBytes); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->RenderFrame(render, frame, requestBytes, &replyBytes); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); if (frame != nullptr) { free(frame); frame = nullptr; } } /** * @tc.name AudioRenderFrame_002 * @tc.desc Test AudioRenderFrame interface,Returns -1 if the incoming parameter render is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderFrame_002, TestSize.Level1) { int32_t ret = -1; uint64_t requestBytes = 0; uint64_t replyBytes = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; char *frame = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = RenderFramePrepare(AUDIO_FILE, frame, requestBytes); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->RenderFrame(renderNull, frame, requestBytes, &replyBytes); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); if (frame != nullptr) { free(frame); frame = nullptr; } } /** * @tc.name AudioRenderFrame_003 * @tc.desc Test AudioRenderFrame interface,Returns -1 if the incoming parameter frame is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderFrame_003, TestSize.Level1) { int32_t ret = -1; uint64_t requestBytes = 0; uint64_t replyBytes = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; char *frame = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->RenderFrame(render, frame, requestBytes, &replyBytes); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderFrame_004 * @tc.desc Test AudioRenderFrame interface,Returns -1 if the incoming parameter replyBytes is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderFrame_004, TestSize.Level1) { int32_t ret = -1; uint64_t requestBytes = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; char *frame = nullptr; uint64_t *replyBytes = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = RenderFramePrepare(AUDIO_FILE, frame, requestBytes); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->RenderFrame(render, frame, requestBytes, replyBytes); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); ret = render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); if (frame != nullptr) { free(frame); frame = nullptr; } } /** * @tc.name AudioRenderFrame_005 * @tc.desc Test AudioRenderFrame interface,Returns -1 if without calling interface renderstart * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderFrame_005, TestSize.Level1) { int32_t ret = -1; uint64_t replyBytes = 0; uint64_t requestBytes = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; char *frame = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = RenderFramePrepare(AUDIO_FILE, frame, requestBytes); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->RenderFrame(render, frame, requestBytes, &replyBytes); EXPECT_EQ(AUDIO_HAL_ERR_INTERNAL, ret); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); if (frame != nullptr) { free(frame); frame = nullptr; } } /** * @tc.name AudioRenderGetRenderPosition_001 * @tc.desc Test GetRenderPosition interface,Returns 0 if get RenderPosition during playing. * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_001, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; int64_t timeExp = 0; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); ret = pthread_create(&audiopara.tids, NULL, (THREAD_FUNC)PlayAudioFile, &audiopara); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); sleep(1); if (audiopara.render != nullptr) { ret = audiopara.render->GetRenderPosition(audiopara.render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); EXPECT_GT(frames, INITIAL_VALUE); } ret = ThreadRelease(audiopara); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); } /** * @tc.name AudioRenderGetRenderPosition_002 * @tc.desc Test GetRenderPosition interface,Returns 0 if get RenderPosition after Pause and resume during playing * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_002, TestSize.Level1) { int32_t ret = -1; int64_t timeExp = 0; uint64_t frames = 0; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); ret = pthread_create(&audiopara.tids, NULL, (THREAD_FUNC)PlayAudioFile, &audiopara); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); sleep(1); if (audiopara.render != nullptr) { FrameStatus(0); usleep(1000); ret = audiopara.render->control.Pause((AudioHandle)(audiopara.render)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = audiopara.render->GetRenderPosition(audiopara.render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); EXPECT_GT(frames, INITIAL_VALUE); usleep(1000); ret = audiopara.render->control.Resume((AudioHandle)(audiopara.render)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); FrameStatus(1); ret = audiopara.render->GetRenderPosition(audiopara.render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); EXPECT_GT(frames, INITIAL_VALUE); } ret = ThreadRelease(audiopara); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); } /** * @tc.name AudioRenderGetRenderPosition_003 * @tc.desc Test GetRenderPosition interface,Returns 0 if get RenderPosition after stop * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_003, TestSize.Level1) { int32_t ret = -1; int64_t timeExp = 0; uint64_t frames = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Stop((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); EXPECT_GT(frames, INITIAL_VALUE); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderPosition_004 * @tc.desc Test AudioRenderGetRenderPosition interface, return -1 if setting the parameter render is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_004, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; int64_t timeExp = 0; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; ASSERT_NE(nullptr, manager); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_EQ((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderPosition_005 * @tc.desc Test AudioRenderGetRenderPosition interface, return -1 if setting the parameter render is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_005, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; struct AudioTimeStamp time = {}; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(renderNull, &frames, &time); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderPosition_006 * @tc.desc Test AudioRenderGetRenderPosition interface, return -1 if setting the parameter frames is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_006, TestSize.Level1) { int32_t ret = -1; uint64_t *framesNull = nullptr; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, framesNull, &time); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderPosition_007 * @tc.desc Test AudioRenderGetRenderPosition interface, return -1 if setting the parameter time is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_007, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioTimeStamp *timeNull = nullptr; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, &frames, timeNull); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetRenderPosition_008 * @tc.desc Test AudioRenderGetRenderPosition interface, return 0 if the GetRenderPosition was called twice * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetRenderPosition_008, TestSize.Level1) { int32_t ret = -1; int64_t timeExp = 0; uint64_t frames = 0; struct AudioAdapter *adapter = nullptr; struct AudioRender *render = nullptr; struct AudioTimeStamp time = {.tvSec = 0, .tvNSec = 0}; ASSERT_NE(nullptr, manager); ret = AudioCreateStartRender(manager, &render, &adapter, ADAPTER_NAME); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->GetRenderPosition(render, &frames, &time); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((time.tvSec) * SECTONSEC + (time.tvNSec), timeExp); EXPECT_GT(frames, INITIAL_VALUE); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_001 * @tc.desc Test ReqMmapBuffer interface,return 0 if call ReqMmapBuffer interface successfully * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_001, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; ASSERT_NE(nullptr, manager); struct AudioSampleAttributes attrs = {}; FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } InitAttrs(attrs); attrs.startThreshold = 0; ret = render->attr.SetSampleAttributes(render, &attrs); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); fclose(fp); if (ret == 0) { munmap(desc.memoryAddress, reqSize); } render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_002 * @tc.desc Test ReqMmapBuffer interface,return -3 if call ReqMmapBuffer interface unsuccessfully when setting the incoming parameter reqSize is bigger than the size of actual audio file * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_002, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; ASSERT_NE(nullptr, manager); FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); reqSize = reqSize + BUFFER_LENTH; ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); fclose(fp); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_003 * @tc.desc Test ReqMmapBuffer interface,return 0 if call ReqMmapBuffer interface successfully when setting the incoming parameter reqSize is smaller than the size of actual audio file * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_003, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; ASSERT_NE(nullptr, manager); FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); reqSize = reqSize / 2; ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); fclose(fp); if (ret == 0) { munmap(desc.memoryAddress, reqSize); } render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_003 * @tc.desc Test ReqMmapBuffer interface,return -1 if call ReqMmapBuffer interface unsuccessfully when setting the incoming parameter reqSize is zero * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_004, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; ASSERT_NE(nullptr, manager); struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); reqSize = 0; ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_ERR_INTERNAL, ret); fclose(fp); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_003 * @tc.desc Test ReqMmapBuffer interface,return -3 if call ReqMmapBuffer interface unsuccessfully when setting the incoming parameter memoryFd of desc is illegal * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_005, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); desc.memoryFd = -1; // -1 is invalid fd ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_ERR_INTERNAL, ret); fclose(fp); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_005 * @tc.desc Test ReqMmapBuffer interface,return -3 if call ReqMmapBuffer interface unsuccessfully when setting the incoming parameter handle is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_006, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioRender *render = nullptr; struct AudioRender *renderNull = nullptr; ASSERT_NE(nullptr, manager); struct AudioAdapter *adapter = nullptr; FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)renderNull, reqSize, &desc); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); fclose(fp); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderReqMmapBuffer_006 * @tc.desc Test ReqMmapBuffer interface,return -3 if call ReqMmapBuffer interface unsuccessfully when setting the incoming parameter desc is nullptr * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderReqMmapBuffer_007, TestSize.Level1) { int32_t ret = -1; bool isRender = true; int32_t reqSize = 0; struct AudioMmapBufferDescripter desc = {}; struct AudioMmapBufferDescripter *descNull = nullptr; struct AudioRender *render = nullptr; struct AudioAdapter *adapter = nullptr; ASSERT_NE(nullptr, manager); FILE *fp = fopen(LOW_LATENCY_AUDIO_FILE.c_str(), "rb+"); ASSERT_NE(fp, nullptr); ret = AudioCreateRender(manager, PIN_OUT_SPEAKER, ADAPTER_NAME, &adapter, &render); if (ret < 0 || render == nullptr) { fclose(fp); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, render); } ret = InitMmapDesc(fp, desc, reqSize, isRender); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->control.Start((AudioHandle)render); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = render->attr.ReqMmapBuffer((AudioHandle)render, reqSize, descNull); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); fclose(fp); render->control.Stop((AudioHandle)render); adapter->DestroyRender(adapter, render); manager->UnloadAdapter(manager, adapter); } /** * @tc.name AudioRenderGetMmapPosition_001 * @tc.desc Test GetMmapPosition interface,return 0 if Getting position successfully. * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetMmapPosition_001, TestSize.Level1) { uint64_t frames = 0; uint64_t framesRendering = 0; uint64_t framesexpRender = 0; int64_t timeExp = 0; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = LOW_LATENCY_AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); int32_t ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter, &audiopara.render); if (ret < 0 || audiopara.render == nullptr) { ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, audiopara.render); } InitAttrs(audiopara.attrs); audiopara.attrs.startThreshold = 0; ret = audiopara.render->attr.SetSampleAttributes(audiopara.render, &(audiopara.attrs)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); ret = audiopara.render->attr.GetMmapPosition(audiopara.render, &frames, &(audiopara.time)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_EQ((audiopara.time.tvSec) * SECTONSEC + (audiopara.time.tvNSec), timeExp); EXPECT_EQ(frames, INITIAL_VALUE); ret = pthread_create(&audiopara.tids, NULL, (THREAD_FUNC)PlayMapAudioFile, &audiopara); if (ret != 0) { audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render); audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter); ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); } sleep(1); ret = audiopara.render->attr.GetMmapPosition(audiopara.render, &framesRendering, &(audiopara.time)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GT((audiopara.time.tvSec) * SECTONSEC + (audiopara.time.tvNSec), timeExp); EXPECT_GT(framesRendering, INITIAL_VALUE); int64_t timeExprendering = (audiopara.time.tvSec) * SECTONSEC + (audiopara.time.tvNSec); void *result = nullptr; pthread_join(audiopara.tids, &result); EXPECT_EQ(AUDIO_HAL_SUCCESS, (intptr_t)result); ret = audiopara.render->attr.GetMmapPosition(audiopara.render, &framesexpRender, &(audiopara.time)); EXPECT_EQ(AUDIO_HAL_SUCCESS, ret); EXPECT_GE((audiopara.time.tvSec) * SECTONSEC + (audiopara.time.tvNSec), timeExprendering); EXPECT_GE(framesexpRender, framesRendering); audiopara.render->control.Stop((AudioHandle)audiopara.render); audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render); audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter); } /** * @tc.name AudioRenderGetMmapPosition_003 * @tc.desc Test GetMmapPosition interface,return -3 if Error in incoming parameter. * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetMmapPosition_003, TestSize.Level1) { int32_t ret = -1; uint64_t *frames = nullptr; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = LOW_LATENCY_AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter, &audiopara.render); if (ret < 0 || audiopara.render == nullptr) { ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, audiopara.render); } ret = audiopara.render->attr.GetMmapPosition(audiopara.render, frames, &(audiopara.time)); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render); audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter); } /** * @tc.name AudioRenderGetMmapPosition_004 * @tc.desc Test GetMmapPosition interface,return -3 if Error in incoming parameter. * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetMmapPosition_004, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; struct AudioTimeStamp *time = nullptr; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = LOW_LATENCY_AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter, &audiopara.render); if (ret < 0 || audiopara.render == nullptr) { ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, audiopara.render); } ret = audiopara.render->attr.GetMmapPosition(audiopara.render, &frames, time); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render); audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter); } /** * @tc.name AudioRenderGetMmapPosition_005 * @tc.desc Test GetMmapPosition interface,return -3 if Error in incoming parameter. * @tc.type: FUNC */ HWTEST_F(AudioHdiRenderTest, AudioRenderGetMmapPosition_005, TestSize.Level1) { int32_t ret = -1; uint64_t frames = 0; struct AudioRender *renderNull = nullptr; struct PrepareAudioPara audiopara = { .portType = PORT_OUT, .adapterName = ADAPTER_NAME.c_str(), .pins = PIN_OUT_SPEAKER, .path = LOW_LATENCY_AUDIO_FILE.c_str() }; audiopara.manager = manager; ASSERT_NE(audiopara.manager, nullptr); ret = AudioCreateRender(audiopara.manager, audiopara.pins, audiopara.adapterName, &audiopara.adapter, &audiopara.render); if (ret < 0 || audiopara.render == nullptr) { ASSERT_EQ(AUDIO_HAL_SUCCESS, ret); ASSERT_EQ(nullptr, audiopara.render); } ret = audiopara.render->attr.GetMmapPosition(renderNull, &frames, &(audiopara.time)); EXPECT_EQ(AUDIO_HAL_ERR_INVALID_PARAM, ret); audiopara.adapter->DestroyRender(audiopara.adapter, audiopara.render); audiopara.manager->UnloadAdapter(audiopara.manager, audiopara.adapter); } }