diff --git a/frameworks/js/avrecorder/avrecorder_napi.cpp b/frameworks/js/avrecorder/avrecorder_napi.cpp index a02f12870a7297727b3b4897681590d459f7a426..0b54f3868acadaf95cae767f504491a11c4b19df 100644 --- a/frameworks/js/avrecorder/avrecorder_napi.cpp +++ b/frameworks/js/avrecorder/avrecorder_napi.cpp @@ -266,6 +266,12 @@ napi_value AVRecorderNapi::JsPrepare(napi_env env, napi_callback_info info) if (asyncCtx->napi->CheckStateMachine(opt) == MSERR_OK) { if (asyncCtx->napi->GetConfig(asyncCtx, env, args[0]) == MSERR_OK) { + QOS::QosLevel level; + GetThreadQos(level); + MEDIA_LOGI("GetThreadQos %{public}d", static_cast(level)); + if (level == QOS::QosLevel::QOS_USER_INTERACTIVE) { + asyncCtx->napi->taskQue_->SetQos(level); + } asyncCtx->task_ = AVRecorderNapi::GetPrepareTask(asyncCtx); (void)asyncCtx->napi->taskQue_->EnqueueTask(asyncCtx->task_); } @@ -285,6 +291,7 @@ napi_value AVRecorderNapi::JsPrepare(napi_env env, napi_callback_info info) asyncCtx->SignError(result.Value().first, result.Value().second); } } + asyncCtx->napi->taskQue_->ResetQos(); MEDIA_LOGI("The js thread of prepare finishes execution and returns"); }, MediaAsyncContext::CompleteCallback, static_cast(asyncCtx.get()), &asyncCtx->work)); NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCtx->work, napi_qos_user_initiated)); diff --git a/services/include/i_recorder_service.h b/services/include/i_recorder_service.h index 48282bd699497ee45260a6009e8a6d83132bdcbe..6d420bd3e2d9893f3a4b864a9ea938e51c0ee931 100644 --- a/services/include/i_recorder_service.h +++ b/services/include/i_recorder_service.h @@ -21,6 +21,7 @@ #include "refbase.h" #include "surface.h" #include "media_data_source.h" +#include "qos.h" namespace OHOS { namespace Media { @@ -630,6 +631,7 @@ public: virtual int32_t SetUserMeta(const std::shared_ptr &userMeta) = 0; virtual int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) = 0; + virtual int32_t TransmitQos(QOS::QosLevel level) = 0; }; } // namespace Media } // namespace OHOS diff --git a/services/services/recorder/client/recorder_client.cpp b/services/services/recorder/client/recorder_client.cpp index 486df47104aaf626d2c33d968728ffb543cfab48..4c94153700449320b25fdfdffc1e3dc12159d75b 100644 --- a/services/services/recorder/client/recorder_client.cpp +++ b/services/services/recorder/client/recorder_client.cpp @@ -40,6 +40,12 @@ RecorderClient::RecorderClient(const sptr &ipcProxy) : recorderProxy_(ipcProxy) { MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); + QOS::QosLevel level; + GetThreadQos(level); + MEDIA_LOGI("GetThreadQos %{public}d", static_cast(level)); + if (level == QOS::QosLevel::QOS_USER_INTERACTIVE) { + recorderProxy_->TransmitQos(level); + } } RecorderClient::~RecorderClient() @@ -564,5 +570,14 @@ int32_t RecorderClient::SetWillMuteWhenInterrupted(bool muteWhenInterrupted) MEDIA_LOGD("SetWillMuteWhenInterrupted"); return recorderProxy_->SetWillMuteWhenInterrupted(muteWhenInterrupted); } + +int32_t RecorderClient::TransmitQos(QOS::QosLevel level) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(recorderProxy_ != nullptr, MSERR_NO_MEMORY, "recorder service does not exist."); + + MEDIA_LOGD("TransmitQos"); + return recorderProxy_->TransmitQos(level); +} } // namespace Media } // namespace OHOS diff --git a/services/services/recorder/client/recorder_client.h b/services/services/recorder/client/recorder_client.h index 04af372972fb48144c479129eb62a985f3f05281..0f731dcc80a6073452ea1e0c9edf6cab8c617b14 100644 --- a/services/services/recorder/client/recorder_client.h +++ b/services/services/recorder/client/recorder_client.h @@ -82,6 +82,7 @@ public: int32_t SetWatermark(std::shared_ptr &waterMarkBuffer) override; int32_t SetUserMeta(const std::shared_ptr &userMeta) override; int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) override; + int32_t TransmitQos(QOS::QosLevel level) override; // RecorderClient void MediaServerDied(); diff --git a/services/services/recorder/ipc/i_standard_recorder_service.h b/services/services/recorder/ipc/i_standard_recorder_service.h index cc180ee6ff67b9b6d2b604972f7fb48b693d05b7..43e5e22bf39b65f09958b90a8a5b5529f4c46fb6 100644 --- a/services/services/recorder/ipc/i_standard_recorder_service.h +++ b/services/services/recorder/ipc/i_standard_recorder_service.h @@ -21,6 +21,7 @@ #include "iremote_proxy.h" #include "iremote_stub.h" #include "recorder.h" +#include "qos.h" namespace OHOS { namespace Media { @@ -98,6 +99,7 @@ public: virtual int32_t SetWatermark(std::shared_ptr &waterMarkBuffer) = 0; virtual int32_t SetUserMeta(const std::shared_ptr &userMeta) = 0; virtual int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) = 0; + virtual int32_t TransmitQos(QOS::QosLevel level) = 0; /** * IPC code ID */ @@ -154,6 +156,7 @@ public: SET_WATERMARK, SET_USERMETA, SET_INTERRUPT_STRATEGY, + TRANSMIT_QOS, }; DECLARE_INTERFACE_DESCRIPTOR(u"IStandardRecorderService"); diff --git a/services/services/recorder/ipc/recorder_service_proxy.cpp b/services/services/recorder/ipc/recorder_service_proxy.cpp index 242473fb74b6b4961e8ea6be40397a206bd996b0..8e58d32bcb466d282d71ca941b33da526c1df165 100644 --- a/services/services/recorder/ipc/recorder_service_proxy.cpp +++ b/services/services/recorder/ipc/recorder_service_proxy.cpp @@ -1024,5 +1024,24 @@ int32_t RecorderServiceProxy::SetWillMuteWhenInterrupted(bool muteWhenInterrupte return reply.ReadInt32(); } + +int32_t RecorderServiceProxy::TransmitQos(QOS::QosLevel level) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(RecorderServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + token = data.WriteInt32(static_cast(level)); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "write data failed"); + + int error = Remote()->SendRequest(TRANSMIT_QOS, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "TransmitQos failed, error: %{public}d", error); + + return reply.ReadInt32(); +} } // namespace Media } // namespace OHOS diff --git a/services/services/recorder/ipc/recorder_service_proxy.h b/services/services/recorder/ipc/recorder_service_proxy.h index c76069da5802f503cd6b329aa9c41648539961fd..efd16e9fe20b59262ee6fec68b6ca317943138a4 100644 --- a/services/services/recorder/ipc/recorder_service_proxy.h +++ b/services/services/recorder/ipc/recorder_service_proxy.h @@ -78,6 +78,7 @@ public: int32_t SetWatermark(std::shared_ptr &waterMarkBuffer) override; int32_t SetUserMeta(const std::shared_ptr &userMeta) override; int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) override; + int32_t TransmitQos(QOS::QosLevel level) override; private: static inline BrokerDelegator delegator_; }; diff --git a/services/services/recorder/ipc/recorder_service_stub.cpp b/services/services/recorder/ipc/recorder_service_stub.cpp index 6938c9045312b041f8730d6d8adaa9a4872874ba..7dd317b53f3faee074d2414bb67863b80f3174e9 100644 --- a/services/services/recorder/ipc/recorder_service_stub.cpp +++ b/services/services/recorder/ipc/recorder_service_stub.cpp @@ -170,6 +170,8 @@ void RecorderServiceStub::FillRecFuncPart3() [this](MessageParcel &data, MessageParcel &reply) { return SetWillMuteWhenInterrupted(data, reply); }; recFuncs_[SET_VIDEO_ENABLE_B_FRAME] = [this](MessageParcel &data, MessageParcel &reply) { return SetVideoEnableBFrame(data, reply); }; + recFuncs_[TRANSMIT_QOS] = + [this](MessageParcel &data, MessageParcel &reply) { return TransmitQos(data, reply); }; } int32_t RecorderServiceStub::DestroyStub() @@ -536,6 +538,12 @@ int32_t RecorderServiceStub::SetUserMeta(const std::shared_ptr &userMeta) return recorderServer_->SetUserMeta(userMeta); } +int32_t RecorderServiceStub::TransmitQos(QOS::QosLevel level) +{ + CHECK_AND_RETURN_RET_LOG(recorderServer_ != nullptr, MSERR_NO_MEMORY, "recorder server is nullptr"); + return recorderServer_->TransmitQos(level); +} + int32_t RecorderServiceStub::DoIpcAbnormality() { MEDIA_LOGI("Enter DoIpcAbnormality."); @@ -990,6 +998,7 @@ int32_t RecorderServiceStub::IsWatermarkSupported(MessageParcel &data, MessagePa CHECK_AND_RETURN_RET_LOG(reply.WriteInt32(ret), MSERR_INVALID_OPERATION, "reply write failed"); return MSERR_OK; } + int32_t RecorderServiceStub::SetWatermark(MessageParcel &data, MessageParcel &reply) { std::shared_ptr buffer = AVBuffer::CreateAVBuffer(); @@ -1015,5 +1024,12 @@ int32_t RecorderServiceStub::SetWillMuteWhenInterrupted(MessageParcel &data, Mes reply.WriteInt32(SetWillMuteWhenInterrupted(muteWhenInterrupted)); return MSERR_OK; } + +int32_t RecorderServiceStub::TransmitQos(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + QOS::QosLevel level = static_cast(data.ReadInt32()); + return TransmitQos(level); +} } // namespace Media } // namespace OHOS diff --git a/services/services/recorder/ipc/recorder_service_stub.h b/services/services/recorder/ipc/recorder_service_stub.h index e522a7cabce08853321f9bb7f91348e0ac0088fb..5fad6aa9f579b70ab8e6e0e68c7d567a94ff0752 100644 --- a/services/services/recorder/ipc/recorder_service_stub.h +++ b/services/services/recorder/ipc/recorder_service_stub.h @@ -84,6 +84,7 @@ public: int32_t SetWatermark(std::shared_ptr &waterMarkBuffer) override; int32_t SetUserMeta(const std::shared_ptr &userMeta) override; int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) override; + int32_t TransmitQos(QOS::QosLevel level) override; // MonitorServerObject override int32_t DoIpcAbnormality() override; int32_t DoIpcRecovery(bool fromMonitor) override; @@ -139,6 +140,7 @@ private: int32_t SetWatermark(MessageParcel &data, MessageParcel &reply); int32_t SetUserMeta(MessageParcel &data, MessageParcel &reply); int32_t SetWillMuteWhenInterrupted(MessageParcel &data, MessageParcel &reply); + int32_t TransmitQos(MessageParcel &data, MessageParcel &reply); int32_t CheckPermission(); void FillRecFuncPart1(); void FillRecFuncPart2(); diff --git a/services/services/recorder/server/recorder_server.cpp b/services/services/recorder/server/recorder_server.cpp index d2166426c0b0b3170a42bef05a59bf7d59e754c1..7dacfa70a0239459793385cb5d76d305071ef381 100644 --- a/services/services/recorder/server/recorder_server.cpp +++ b/services/services/recorder/server/recorder_server.cpp @@ -33,9 +33,15 @@ #ifdef SUPPORT_POWER_MANAGER #include "shutdown/shutdown_priority.h" #endif +#include "res_type.h" +#include "res_sched_client.h" namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_RECORDER, "RecorderServer"}; + constexpr uint32_t THREAD_PRIORITY_41 = 7; // evevate priority for avRecorder + constexpr uint32_t RES_TYPE = OHOS::ResourceSchedule::ResType::RES_TYPE_THREAD_QOS_CHANGE; + constexpr int64_t RES_VALUE = 0; + const std::string PAYLOAD_BUNDLE_NAME_VAL = "media_service"; const std::map RECORDER_STATE_MAP = { {OHOS::Media::RecorderServer::REC_INITIALIZED, "initialized"}, {OHOS::Media::RecorderServer::REC_CONFIGURED, "configured"}, @@ -1186,6 +1192,28 @@ int32_t RecorderServer::SetUserMeta(const std::shared_ptr &userMeta) return result.Value(); } +int32_t RecorderServer::TransmitQos(QOS::QosLevel level) +{ + MEDIA_LOGI("TransmitQos in %{public}d", static_cast(level)); + std::lock_guard lock(mutex_); + clientQos_ = level; + auto task = std::make_shared>([&, this] { + if (clientQos_ == QOS::QosLevel::QOS_USER_INTERACTIVE) { + std::unordered_map mapPayload; + mapPayload["bundleName"] = PAYLOAD_BUNDLE_NAME_VAL; + mapPayload["pid"] = std::to_string(getpid()); + mapPayload[std::to_string(gettid())] = std::to_string(THREAD_PRIORITY_41); + OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(RES_TYPE, RES_VALUE, mapPayload); + } + return MSERR_OK; + }); + int32_t ret = taskQue_.EnqueueTask(task); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed"); + + auto result = task->GetResult(); + return result.Value(); +} + int32_t RecorderServer::SetWillMuteWhenInterrupted(bool muteWhenInterrupted) { MEDIA_LOGI("SetWillMuteWhenInterrupted in"); diff --git a/services/services/recorder/server/recorder_server.h b/services/services/recorder/server/recorder_server.h index 82502fc1c3afc32b57f0559a365e2935008f45ac..9b954e8310d02b3517100f2f2bf1260e553061f5 100644 --- a/services/services/recorder/server/recorder_server.h +++ b/services/services/recorder/server/recorder_server.h @@ -122,6 +122,7 @@ public: int32_t SetWatermark(std::shared_ptr &waterMarkBuffer) override; int32_t SetUserMeta(const std::shared_ptr &userMeta) override; int32_t SetWillMuteWhenInterrupted(bool muteWhenInterrupted) override; + int32_t TransmitQos(QOS::QosLevel level) override; // IRecorderEngineObs override void OnError(ErrorType errorType, int32_t errorCode) override; @@ -197,6 +198,7 @@ private: int32_t startLatency = -1; } statisticalEventInfo_; int64_t startTime_ = 0; + QOS::QosLevel clientQos_ = QOS::QosLevel::QOS_BACKGROUND; #ifdef SUPPORT_POWER_MANAGER sptr syncCallback_ = nullptr; PowerMgr::ShutdownClient &shutdownClient_ = PowerMgr::ShutdownClient::GetInstance(); diff --git a/test/unittest/media_server_manager_unittest/mock/recorder_service_stub.h b/test/unittest/media_server_manager_unittest/mock/recorder_service_stub.h index a4df2eccf3d6d67e0077d26b5277a99b81e12078..42fd1c563dfbd7b3c4dea687db12f334e75bfcc6 100644 --- a/test/unittest/media_server_manager_unittest/mock/recorder_service_stub.h +++ b/test/unittest/media_server_manager_unittest/mock/recorder_service_stub.h @@ -90,6 +90,7 @@ public: MOCK_METHOD(int32_t, SetWatermark, (std::shared_ptr &waterMarkBuffer), (override)); MOCK_METHOD(int32_t, SetUserMeta, (const std::shared_ptr &userMeta), (override)); MOCK_METHOD(int32_t, SetWillMuteWhenInterrupted, (bool muteWhenInterrupted), (override)); + MOCK_METHOD(int32_t, TransmitQos, (QOS::QosLevel level), (override)); MOCK_METHOD(int32_t, DoIpcAbnormality, (), (override)); MOCK_METHOD(int32_t, DoIpcRecovery, (bool fromMonitor), (override)); MOCK_METHOD(int32_t, SetListenerObjectInner, (MessageParcel &data, MessageParcel &reply)); diff --git a/test/unittest/recorder_test/recorder_server_unittest/include/recorder_server_mock.h b/test/unittest/recorder_test/recorder_server_unittest/include/recorder_server_mock.h index e6dcb1411b10f7b719e697321a5a3e6d102978b2..1fe7b53d80730ecdab179234cb4c309170db6e61 100644 --- a/test/unittest/recorder_test/recorder_server_unittest/include/recorder_server_mock.h +++ b/test/unittest/recorder_test/recorder_server_unittest/include/recorder_server_mock.h @@ -147,6 +147,7 @@ public: int32_t Release(); int32_t SetFileSplitDuration(FileSplitType type, int64_t timestamp, uint32_t duration); int32_t SetParameter(int32_t sourceId, const Format &format); + int32_t TransmitQos(QOS::QosLevel level); int32_t RequesetBuffer(const std::string &recorderType, RecorderTestParam::VideoRecorderConfig &recorderConfig); void StopBuffer(const std::string &recorderType); void HDICreateESBuffer(); diff --git a/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_mock.cpp b/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_mock.cpp index 21ca3b829f8082d13886b9e870e9020cc95d0f1f..0ae31399b35996cc63a5fe091448f91109953ef9 100644 --- a/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_mock.cpp +++ b/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_mock.cpp @@ -314,6 +314,12 @@ int32_t RecorderServerMock::SetParameter(int32_t sourceId, const Format &format) return recorder_->SetParameter(sourceId, format); } +int32_t RecorderServerMock::TransmitQos(QOS::QosLevel level) +{ + UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, MSERR_INVALID_OPERATION, "recorder_ == nullptr"); + return recorder_->TransmitQos(level); +} + int32_t RecorderServerMock::RequesetBuffer(const std::string &recorderType, VideoRecorderConfig &recorderConfig) { UNITTEST_CHECK_AND_RETURN_RET_LOG(recorder_ != nullptr, MSERR_INVALID_OPERATION, "recorder_ == nullptr"); diff --git a/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_unit_test.cpp b/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_unit_test.cpp index 36313e1de982a1539d49aacd87f49cc8e363448d..54e7f334432e3297e88e59855dac91d4f920b9b0 100644 --- a/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_unit_test.cpp +++ b/test/unittest/recorder_test/recorder_server_unittest/src/recorder_server_unit_test.cpp @@ -861,6 +861,26 @@ HWTEST_F(RecorderServerUnitTest, recorder_configure_022, TestSize.Level2) EXPECT_EQ(MSERR_OK, recorderServer_->Release()); } + +/** + * @tc.name: recorder_configure_023 + * @tc.desc: evevate priority for avRecorder TransmitQos + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RecorderServerUnitTest, recorder_configure_023, TestSize.Level2) +{ + EXPECT_NE(MSERR_OK, recorderServer_->TransmitQos(QOS::QosLevel::QOS_USER_INTERACTIVE)); + EXPECT_NE(MSERR_OK, recorderServer_->Prepare()); + EXPECT_NE(MSERR_OK, recorderServer_->Start()); + sleep(RECORDER_TIME); + EXPECT_NE(MSERR_OK, recorderServer_->Pause()); + EXPECT_NE(MSERR_OK, recorderServer_->Resume()); + EXPECT_NE(MSERR_OK, recorderServer_->Stop(false)); + EXPECT_EQ(MSERR_OK, recorderServer_->Reset()); + EXPECT_EQ(MSERR_OK, recorderServer_->Release()); +} + /** * @tc.name: recorder_mp3_001 * @tc.desc: record mp3