Support lazy tuner server
*) Refine code to not use global instance. It makes us easier to debug
reference count.
*) The service will only be started if the tuner feature is declard by
the vendor. So we don't need to check tuner feature and whether tuner
HAL is presented anymore.
*) The service will register its resources to TRM every time when it's
started. The TRM will update its resource mapping accordingly.
*) Use tuner.server.enable to change tuner server to be a normal service
if the HAL is not a lazy HAL.
Bug: 236002754
Test: atest android.media.tv.tuner.cts on both lazy and normal HALs
Change-Id: I564490fd46154bb0a8bcf6b77e2b2d9478471434
diff --git a/services/tuner/hidl/TunerHidlDemux.cpp b/services/tuner/hidl/TunerHidlDemux.cpp
index a8151d2..bbb7782 100644
--- a/services/tuner/hidl/TunerHidlDemux.cpp
+++ b/services/tuner/hidl/TunerHidlDemux.cpp
@@ -20,6 +20,7 @@
#include "TunerHidlDvr.h"
#include "TunerHidlFilter.h"
+#include "TunerHidlService.h"
#include "TunerHidlTimeFilter.h"
using ::aidl::android::hardware::tv::tuner::DemuxFilterSubType;
@@ -42,23 +43,20 @@
namespace tv {
namespace tuner {
-TunerHidlDemux::TunerHidlDemux(sp<IDemux> demux, int id) {
+TunerHidlDemux::TunerHidlDemux(const sp<IDemux> demux, const int id,
+ const shared_ptr<TunerHidlService> tuner) {
mDemux = demux;
mDemuxId = id;
+ mTunerService = tuner;
}
TunerHidlDemux::~TunerHidlDemux() {
mDemux = nullptr;
+ mTunerService = nullptr;
}
::ndk::ScopedAStatus TunerHidlDemux::setFrontendDataSource(
const shared_ptr<ITunerFrontend>& in_frontend) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
int frontendId;
in_frontend->getFrontendId(&frontendId);
HidlResult res = mDemux->setFrontendDataSource(frontendId);
@@ -69,12 +67,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::setFrontendDataSourceById(int frontendId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->setFrontendDataSource(frontendId);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -86,12 +78,6 @@
int32_t in_bufferSize,
const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlDemuxFilterMainType mainType = static_cast<HidlDemuxFilterMainType>(in_type.mainType);
HidlDemuxFilterType filterType{
.mainType = mainType,
@@ -132,17 +118,12 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
- *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, filterCb, in_type);
+ *_aidl_return =
+ ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, filterCb, in_type, mTunerService);
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlDemux::openTimeFilter(shared_ptr<ITunerTimeFilter>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlITimeFilter> filterSp;
mDemux->openTimeFilter([&](HidlResult r, const sp<HidlITimeFilter>& filter) {
@@ -159,12 +140,6 @@
::ndk::ScopedAStatus TunerHidlDemux::getAvSyncHwId(const shared_ptr<ITunerFilter>& tunerFilter,
int32_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
uint32_t avSyncHwId;
HidlResult res;
sp<HidlIFilter> halFilter = static_cast<TunerHidlFilter*>(tunerFilter.get())->getHalFilter();
@@ -181,12 +156,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::getAvSyncTime(int32_t avSyncHwId, int64_t* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
uint64_t time;
HidlResult res;
mDemux->getAvSyncTime(static_cast<uint32_t>(avSyncHwId), [&](HidlResult r, uint64_t ts) {
@@ -204,12 +173,6 @@
::ndk::ScopedAStatus TunerHidlDemux::openDvr(DvrType in_dvbType, int32_t in_bufferSize,
const shared_ptr<ITunerDvrCallback>& in_cb,
shared_ptr<ITunerDvr>* _aidl_return) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res;
sp<HidlIDvrCallback> callback = new TunerHidlDvr::DvrCallback(in_cb);
sp<HidlIDvr> hidlDvr;
@@ -228,12 +191,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::connectCiCam(int32_t ciCamId) {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->connectCiCam(static_cast<uint32_t>(ciCamId));
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -242,12 +199,6 @@
}
::ndk::ScopedAStatus TunerHidlDemux::disconnectCiCam() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->disconnectCiCam();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -256,15 +207,7 @@
}
::ndk::ScopedAStatus TunerHidlDemux::close() {
- if (mDemux == nullptr) {
- ALOGE("IDemux is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(HidlResult::UNAVAILABLE));
- }
-
HidlResult res = mDemux->close();
- mDemux = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlDemux.h b/services/tuner/hidl/TunerHidlDemux.h
index d535da6..94a715e 100644
--- a/services/tuner/hidl/TunerHidlDemux.h
+++ b/services/tuner/hidl/TunerHidlDemux.h
@@ -37,9 +37,12 @@
namespace tv {
namespace tuner {
+class TunerHidlService;
+
class TunerHidlDemux : public BnTunerDemux {
public:
- TunerHidlDemux(sp<HidlIDemux> demux, int demuxId);
+ TunerHidlDemux(const sp<HidlIDemux> demux, const int demuxId,
+ const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlDemux();
::ndk::ScopedAStatus setFrontendDataSource(
@@ -64,6 +67,7 @@
private:
sp<HidlIDemux> mDemux;
int mDemuxId;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlDescrambler.cpp b/services/tuner/hidl/TunerHidlDescrambler.cpp
index dd8cd9c..51b7ede 100644
--- a/services/tuner/hidl/TunerHidlDescrambler.cpp
+++ b/services/tuner/hidl/TunerHidlDescrambler.cpp
@@ -45,12 +45,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::setDemuxSource(
const shared_ptr<ITunerDemux>& in_tunerDemux) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->setDemuxSource(
static_cast<TunerHidlDemux*>(in_tunerDemux.get())->getId());
if (res != HidlResult::SUCCESS) {
@@ -60,12 +54,6 @@
}
::ndk::ScopedAStatus TunerHidlDescrambler::setKeyToken(const vector<uint8_t>& in_keyToken) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->setKeyToken(in_keyToken);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -75,12 +63,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::addPid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
sp<HidlIFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -94,12 +76,6 @@
::ndk::ScopedAStatus TunerHidlDescrambler::removePid(
const DemuxPid& in_pid, const shared_ptr<ITunerFilter>& in_optionalSourceFilter) {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
sp<HidlIFilter> halFilter =
(in_optionalSourceFilter == nullptr)
? nullptr
@@ -112,15 +88,7 @@
}
::ndk::ScopedAStatus TunerHidlDescrambler::close() {
- if (mDescrambler == nullptr) {
- ALOGE("IDescrambler is not initialized.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDescrambler->close();
- mDescrambler = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlDvr.cpp b/services/tuner/hidl/TunerHidlDvr.cpp
index 1a619d5..50d92de 100644
--- a/services/tuner/hidl/TunerHidlDvr.cpp
+++ b/services/tuner/hidl/TunerHidlDvr.cpp
@@ -54,12 +54,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::getQueueDesc(AidlMQDesc* _aidl_return) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
MQDesc dvrMQDesc;
HidlResult res;
mDvr->getQueueDesc([&](HidlResult r, const MQDesc& desc) {
@@ -77,12 +71,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::configure(const DvrSettings& in_settings) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->configure(getHidlDvrSettings(in_settings));
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -91,12 +79,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::attachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -116,12 +98,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::detachFilter(const shared_ptr<ITunerFilter>& in_filter) {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (in_filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -141,12 +117,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::start() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->start();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -155,12 +125,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::stop() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->stop();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -169,12 +133,6 @@
}
::ndk::ScopedAStatus TunerHidlDvr::flush() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->flush();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -183,15 +141,7 @@
}
::ndk::ScopedAStatus TunerHidlDvr::close() {
- if (mDvr == nullptr) {
- ALOGE("IDvr is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mDvr->close();
- mDvr = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index fe74a5c..d4a3db5 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -92,31 +92,32 @@
namespace tv {
namespace tuner {
-TunerHidlFilter::TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb,
- DemuxFilterType type)
+TunerHidlFilter::TunerHidlFilter(const sp<HidlIFilter> filter, const sp<FilterCallback> cb,
+ const DemuxFilterType type,
+ const shared_ptr<TunerHidlService> tuner)
: mFilter(filter),
mType(type),
mStarted(false),
mShared(false),
mClientPid(-1),
- mFilterCallback(cb) {
+ mFilterCallback(cb),
+ mTunerService(tuner) {
mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
}
TunerHidlFilter::~TunerHidlFilter() {
- Mutex::Autolock _l(mLock);
- mFilter = nullptr;
- mFilter_1_1 = nullptr;
+ freeSharedFilterToken("");
+
+ {
+ Mutex::Autolock _l(mLock);
+ mFilter = nullptr;
+ mFilter_1_1 = nullptr;
+ mTunerService = nullptr;
+ }
}
::ndk::ScopedAStatus TunerHidlFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -146,12 +147,6 @@
::ndk::ScopedAStatus TunerHidlFilter::getId(int32_t* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -200,12 +195,6 @@
::ndk::ScopedAStatus TunerHidlFilter::configure(const DemuxFilterSettings& in_settings) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -318,12 +307,6 @@
::ndk::ScopedAStatus TunerHidlFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (filter == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -378,12 +361,6 @@
::ndk::ScopedAStatus TunerHidlFilter::releaseAvHandle(const NativeHandle& in_handle,
int64_t in_avDataId) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
ALOGD("%s is called on a shared filter", __FUNCTION__);
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -407,12 +384,6 @@
::ndk::ScopedAStatus TunerHidlFilter::start() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -434,12 +405,6 @@
::ndk::ScopedAStatus TunerHidlFilter::stop() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -461,12 +426,6 @@
::ndk::ScopedAStatus TunerHidlFilter::flush() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -487,12 +446,6 @@
::ndk::ScopedAStatus TunerHidlFilter::close() {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared) {
IPCThreadState* ipc = IPCThreadState::self();
int32_t callingPid = ipc->getCallingPid();
@@ -501,7 +454,7 @@
mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
mFilterCallback->detachSharedFilterCallback();
}
- TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerHidlFilter>());
} else {
// Calling from shared process, do not really close this filter.
if (mFilterCallback != nullptr) {
@@ -516,8 +469,6 @@
mFilterCallback->detachCallbacks();
}
HidlResult res = mFilter->close();
- mFilter = nullptr;
- mFilter_1_1 = nullptr;
mStarted = false;
mShared = false;
mClientPid = -1;
@@ -531,12 +482,6 @@
::ndk::ScopedAStatus TunerHidlFilter::acquireSharedFilterToken(string* _aidl_return) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (mShared || mStarted) {
ALOGD("create SharedFilter in wrong state");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -545,8 +490,7 @@
IPCThreadState* ipc = IPCThreadState::self();
mClientPid = ipc->getCallingPid();
- string token =
- TunerHidlService::getTunerService()->addFilterToShared(this->ref<TunerHidlFilter>());
+ string token = mTunerService->addFilterToShared(this->ref<TunerHidlFilter>());
_aidl_return->assign(token);
mShared = true;
@@ -555,12 +499,6 @@
::ndk::ScopedAStatus TunerHidlFilter::freeSharedFilterToken(const string& /* in_filterToken */) {
Mutex::Autolock _l(mLock);
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (!mShared) {
// The filter is not shared or the shared filter has been closed.
return ::ndk::ScopedAStatus::ok();
@@ -571,19 +509,13 @@
mFilterCallback->detachSharedFilterCallback();
}
- TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ mTunerService->removeSharedFilter(this->ref<TunerHidlFilter>());
mShared = false;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlFilter::getFilterType(DemuxFilterType* _aidl_return) {
- if (mFilter == nullptr) {
- ALOGE("IFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
*_aidl_return = mType;
return ::ndk::ScopedAStatus::ok();
}
diff --git a/services/tuner/hidl/TunerHidlFilter.h b/services/tuner/hidl/TunerHidlFilter.h
index 63c7a1b..a58eeca 100644
--- a/services/tuner/hidl/TunerHidlFilter.h
+++ b/services/tuner/hidl/TunerHidlFilter.h
@@ -114,6 +114,8 @@
const static int IP_V4_LENGTH = 4;
const static int IP_V6_LENGTH = 16;
+class TunerHidlService;
+
class TunerHidlFilter : public BnTunerFilter {
public:
class FilterCallback : public HidlIFilterCallback {
@@ -165,7 +167,8 @@
Mutex mCallbackLock;
};
- TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb, DemuxFilterType type);
+ TunerHidlFilter(const sp<HidlIFilter> filter, const sp<FilterCallback> cb,
+ const DemuxFilterType type, const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlFilter();
::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
@@ -230,6 +233,7 @@
int32_t mClientPid;
sp<FilterCallback> mFilterCallback;
Mutex mLock;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlFrontend.cpp b/services/tuner/hidl/TunerHidlFrontend.cpp
index 03957f3..7ffb2a4 100644
--- a/services/tuner/hidl/TunerHidlFrontend.cpp
+++ b/services/tuner/hidl/TunerHidlFrontend.cpp
@@ -176,26 +176,23 @@
namespace tv {
namespace tuner {
-TunerHidlFrontend::TunerHidlFrontend(sp<HidlIFrontend> frontend, int id) {
+TunerHidlFrontend::TunerHidlFrontend(const sp<HidlIFrontend> frontend, const int id,
+ const shared_ptr<TunerHidlService> tuner) {
mFrontend = frontend;
mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
mId = id;
+ mTunerService = tuner;
}
TunerHidlFrontend::~TunerHidlFrontend() {
mFrontend = nullptr;
mFrontend_1_1 = nullptr;
mId = -1;
+ mTunerService = nullptr;
}
::ndk::ScopedAStatus TunerHidlFrontend::setCallback(
const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (tunerFrontendCallback == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -211,12 +208,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::tune(const FrontendSettings& settings) {
- if (mFrontend == nullptr) {
- ALOGE("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
HidlFrontendSettings frontendSettings;
HidlFrontendSettingsExt1_1 frontendSettingsExt;
@@ -234,12 +225,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::stopTune() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mFrontend->stopTune();
if (status == HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::ok();
@@ -250,12 +235,6 @@
::ndk::ScopedAStatus TunerHidlFrontend::scan(const FrontendSettings& settings,
FrontendScanType frontendScanType) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
HidlFrontendSettings frontendSettings;
HidlFrontendSettingsExt1_1 frontendSettingsExt;
@@ -276,12 +255,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::stopScan() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mFrontend->stopScan();
if (status == HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::ok();
@@ -291,12 +264,6 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::setLnb(const shared_ptr<ITunerLnb>& lnb) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
if (lnb == nullptr) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
@@ -349,18 +316,8 @@
}
::ndk::ScopedAStatus TunerHidlFrontend::close() {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
- TunerHidlService::getTunerService()->removeFrontend(this->ref<TunerHidlFrontend>());
-
+ mTunerService->removeFrontend(this->ref<TunerHidlFrontend>());
HidlResult status = mFrontend->close();
- mFrontend = nullptr;
- mFrontend_1_1 = nullptr;
-
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
@@ -370,12 +327,6 @@
::ndk::ScopedAStatus TunerHidlFrontend::getStatus(const vector<FrontendStatusType>& in_statusTypes,
vector<FrontendStatus>* _aidl_return) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
vector<HidlFrontendStatus> status;
vector<HidlFrontendStatusExt1_1> statusExt;
@@ -442,11 +393,6 @@
}
void TunerHidlFrontend::setLna(bool bEnable) {
- if (mFrontend == nullptr) {
- ALOGD("IFrontend is not initialized");
- return;
- }
-
mFrontend->setLna(bEnable);
}
diff --git a/services/tuner/hidl/TunerHidlFrontend.h b/services/tuner/hidl/TunerHidlFrontend.h
index f698655..f54127b 100644
--- a/services/tuner/hidl/TunerHidlFrontend.h
+++ b/services/tuner/hidl/TunerHidlFrontend.h
@@ -64,9 +64,12 @@
namespace tv {
namespace tuner {
+class TunerHidlService;
+
class TunerHidlFrontend : public BnTunerFrontend {
public:
- TunerHidlFrontend(sp<HidlIFrontend> frontend, int id);
+ TunerHidlFrontend(const sp<HidlIFrontend> frontend, const int id,
+ const shared_ptr<TunerHidlService> tuner);
virtual ~TunerHidlFrontend();
::ndk::ScopedAStatus setCallback(
@@ -118,6 +121,7 @@
int mId;
sp<HidlIFrontend> mFrontend;
sp<::android::hardware::tv::tuner::V1_1::IFrontend> mFrontend_1_1;
+ shared_ptr<TunerHidlService> mTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index 6f55f1e..aa03316 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -24,6 +24,7 @@
#include <android/binder_manager.h>
#include <binder/IPCThreadState.h>
#include <binder/PermissionCache.h>
+#include <cutils/properties.h>
#include <utils/Log.h>
#include "TunerHelper.h"
@@ -46,7 +47,6 @@
using ::aidl::android::hardware::tv::tuner::FrontendIsdbtTimeInterleaveMode;
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::Result;
-using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
using ::android::IPCThreadState;
using ::android::PermissionCache;
using ::android::hardware::hidl_vec;
@@ -63,47 +63,9 @@
namespace tv {
namespace tuner {
-shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
-
TunerHidlService::TunerHidlService() {
- if (!TunerHelper::checkTunerFeature()) {
- ALOGD("Device doesn't have tuner hardware.");
- return;
- }
-
- updateTunerResources();
-}
-
-TunerHidlService::~TunerHidlService() {
- mOpenedFrontends.clear();
- mLnaStatus = -1;
-}
-
-binder_status_t TunerHidlService::instantiate() {
- if (HidlITuner::getService() == nullptr) {
- ALOGD("Failed to get ITuner HIDL HAL");
- return STATUS_NAME_NOT_FOUND;
- }
-
- sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
- return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
-}
-
-shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
- return sTunerService;
-}
-
-bool TunerHidlService::hasITuner() {
- ALOGV("hasITuner");
- if (mTuner != nullptr) {
- return true;
- }
-
mTuner = HidlITuner::getService();
- if (mTuner == nullptr) {
- ALOGE("Failed to get ITuner service");
- return false;
- }
+ ALOGE_IF(mTuner == nullptr, "Failed to get ITuner service");
mTunerVersion = TUNER_HAL_VERSION_1_0;
mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
@@ -113,23 +75,35 @@
ALOGD("Failed to get ITuner_1_1 service");
}
- return true;
+ // Register tuner resources to TRM.
+ updateTunerResources();
}
-bool TunerHidlService::hasITuner_1_1() {
- ALOGV("hasITuner_1_1");
- hasITuner();
- return (mTunerVersion == TUNER_HAL_VERSION_1_1);
+TunerHidlService::~TunerHidlService() {
+ mOpenedFrontends.clear();
+ mLnaStatus = -1;
+ mTuner = nullptr;
+ mTuner_1_1 = nullptr;
+}
+
+binder_status_t TunerHidlService::instantiate() {
+ if (HidlITuner::getService() == nullptr) {
+ ALOGD("Failed to get ITuner HIDL HAL");
+ return STATUS_NAME_NOT_FOUND;
+ }
+
+ shared_ptr<TunerHidlService> tunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
+ bool lazyHal = property_get_bool("ro.tuner.lazyhal", false);
+ if (lazyHal) {
+ return AServiceManager_registerLazyService(tunerService->asBinder().get(),
+ getServiceName());
+ }
+ return AServiceManager_addService(tunerService->asBinder().get(), getServiceName());
}
::ndk::ScopedAStatus TunerHidlService::openDemux(int32_t /* in_demuxHandle */,
shared_ptr<ITunerDemux>* _aidl_return) {
ALOGV("openDemux");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
uint32_t id;
sp<IDemux> demuxSp = nullptr;
@@ -140,7 +114,8 @@
ALOGD("open demux, id = %d", demuxId);
});
if (res == HidlResult::SUCCESS) {
- *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id);
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id,
+ this->ref<TunerHidlService>());
return ::ndk::ScopedAStatus::ok();
}
@@ -150,11 +125,6 @@
::ndk::ScopedAStatus TunerHidlService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
ALOGV("getDemuxCaps");
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res;
HidlDemuxCapabilities caps;
mTuner->getDemuxCaps([&](HidlResult r, const HidlDemuxCapabilities& demuxCaps) {
@@ -171,11 +141,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getFrontendIds(vector<int32_t>* ids) {
- if (!hasITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
hidl_vec<HidlFrontendId> feIds;
HidlResult res = getHidlFrontendIds(feIds);
if (res != HidlResult::SUCCESS) {
@@ -188,12 +153,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlFrontendInfo info;
HidlResult res = getHidlFrontendInfo(id, info);
if (res != HidlResult::SUCCESS) {
@@ -202,7 +161,7 @@
HidlFrontendDtmbCapabilities dtmbCaps;
if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
- if (!hasITuner_1_1()) {
+ if (mTuner_1_1 == nullptr) {
ALOGE("ITuner_1_1 service is not init.");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -224,12 +183,6 @@
::ndk::ScopedAStatus TunerHidlService::openFrontend(int32_t frontendHandle,
shared_ptr<ITunerFrontend>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlIFrontend> frontend;
int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
@@ -241,8 +194,8 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
- shared_ptr<TunerHidlFrontend> tunerFrontend =
- ::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
+ shared_ptr<TunerHidlFrontend> tunerFrontend = ::ndk::SharedRefBase::make<TunerHidlFrontend>(
+ frontend, id, this->ref<TunerHidlService>());
if (mLnaStatus != -1) {
tunerFrontend->setLna(mLnaStatus == 1);
}
@@ -255,12 +208,6 @@
}
::ndk::ScopedAStatus TunerHidlService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlILnb> lnb;
int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
@@ -278,12 +225,6 @@
::ndk::ScopedAStatus TunerHidlService::openLnbByName(const string& lnbName,
shared_ptr<ITunerLnb>* _aidl_return) {
- if (!hasITuner()) {
- ALOGE("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
int lnbId;
HidlResult status;
sp<HidlILnb> lnb;
@@ -302,12 +243,6 @@
::ndk::ScopedAStatus TunerHidlService::openDescrambler(
int32_t /*descramblerHandle*/, shared_ptr<ITunerDescrambler>* _aidl_return) {
- if (!hasITuner()) {
- ALOGD("get ITuner failed");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
sp<HidlIDescrambler> descrambler;
//int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
@@ -324,7 +259,6 @@
}
::ndk::ScopedAStatus TunerHidlService::getTunerHalVersion(int* _aidl_return) {
- hasITuner();
*_aidl_return = mTunerVersion;
return ::ndk::ScopedAStatus::ok();
}
@@ -332,7 +266,7 @@
::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
shared_ptr<ITunerFilter>* _aidl_return) {
- if (!hasITuner()) {
+ if (mTuner == nullptr) {
ALOGE("get ITuner failed");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -369,7 +303,7 @@
}
::ndk::ScopedAStatus TunerHidlService::setLna(bool bEnable) {
- if (!hasITuner()) {
+ if (mTuner == nullptr) {
ALOGE("get ITuner failed");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
@@ -428,11 +362,6 @@
}
void TunerHidlService::updateTunerResources() {
- if (!hasITuner()) {
- ALOGE("Failed to updateTunerResources");
- return;
- }
-
TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
}
diff --git a/services/tuner/hidl/TunerHidlService.h b/services/tuner/hidl/TunerHidlService.h
index 2252d35..6f43d43 100644
--- a/services/tuner/hidl/TunerHidlService.h
+++ b/services/tuner/hidl/TunerHidlService.h
@@ -99,11 +99,7 @@
void removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter);
void removeFrontend(const shared_ptr<TunerHidlFrontend>& frontend);
- static shared_ptr<TunerHidlService> getTunerService();
-
private:
- bool hasITuner();
- bool hasITuner_1_1();
void updateTunerResources();
vector<TunerFrontendInfo> getTRMFrontendInfos();
vector<int32_t> getTRMLnbHandles();
@@ -121,8 +117,6 @@
Mutex mOpenedFrontendsLock;
unordered_set<shared_ptr<TunerHidlFrontend>> mOpenedFrontends;
int mLnaStatus = -1;
-
- static shared_ptr<TunerHidlService> sTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlTimeFilter.cpp b/services/tuner/hidl/TunerHidlTimeFilter.cpp
index d0606d6..06a71d0 100644
--- a/services/tuner/hidl/TunerHidlTimeFilter.cpp
+++ b/services/tuner/hidl/TunerHidlTimeFilter.cpp
@@ -43,12 +43,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::setTimeStamp(int64_t timeStamp) {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mTimeFilter->setTimeStamp(static_cast<uint64_t>(timeStamp));
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
@@ -57,12 +51,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::clearTimeStamp() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status = mTimeFilter->clearTimeStamp();
if (status != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
@@ -71,13 +59,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::getSourceTime(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
mTimeFilter->getSourceTime([&](HidlResult r, uint64_t t) {
status = r;
@@ -91,13 +72,6 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::getTimeStamp(int64_t* _aidl_return) {
- if (mTimeFilter == nullptr) {
- *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult status;
mTimeFilter->getTimeStamp([&](HidlResult r, uint64_t t) {
status = r;
@@ -111,15 +85,7 @@
}
::ndk::ScopedAStatus TunerHidlTimeFilter::close() {
- if (mTimeFilter == nullptr) {
- ALOGE("ITimeFilter is not initialized");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
- }
-
HidlResult res = mTimeFilter->close();
- mTimeFilter = nullptr;
-
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}