blob: acc78004261799e3b49ac7574c87f1fb81f597d7 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
#include "HidlDisplay.h"
#include "utils/include/Utils.h"
#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
#include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
#include <aidl/android/hardware/automotive/evs/DisplayState.h>
#include <aidl/android/hardware/automotive/evs/EvsResult.h>
#include <android-base/logging.h>
#include <ui/DisplayMode.h>
#include <ui/DisplayState.h>
namespace aidl::android::automotive::evs::implementation {
namespace hidlevs = ::android::hardware::automotive::evs;
using ::aidl::android::hardware::automotive::evs::BufferDesc;
using ::aidl::android::hardware::automotive::evs::DisplayDesc;
using ::aidl::android::hardware::automotive::evs::DisplayState;
using ::aidl::android::hardware::automotive::evs::EvsResult;
using ::android::hardware::Return;
HidlDisplay::~HidlDisplay() {
// simply release a shared pointer to remote display object.
mAidlDisplay = nullptr;
}
Return<void> HidlDisplay::getDisplayInfo(getDisplayInfo_cb _hidl_cb) {
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
_hidl_cb({});
return {};
}
DisplayDesc aidlDesc;
if (auto status = mAidlDisplay->getDisplayInfo(&aidlDesc); !status.isOk()) {
LOG(ERROR) << "Failed to read a display information";
_hidl_cb({});
return {};
}
hidlevs::V1_0::DisplayDesc hidlDesc = {
.displayId = aidlDesc.id,
.vendorFlags = static_cast<uint32_t>(aidlDesc.vendorFlags),
};
_hidl_cb(std::move(hidlDesc));
return {};
}
Return<hidlevs::V1_0::EvsResult> HidlDisplay::setDisplayState(hidlevs::V1_0::DisplayState state) {
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
}
if (auto status = mAidlDisplay->setDisplayState(Utils::makeFromHidl(state)); !status.isOk()) {
return Utils::makeToHidl(static_cast<EvsResult>(status.getServiceSpecificError()));
}
return hidlevs::V1_0::EvsResult::OK;
}
Return<hidlevs::V1_0::DisplayState> HidlDisplay::getDisplayState() {
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
return Utils::makeToHidl(DisplayState::DEAD);
}
DisplayState aidlState;
if (auto status = mAidlDisplay->getDisplayState(&aidlState); !status.isOk()) {
return Utils::makeToHidl(DisplayState::DEAD);
}
return Utils::makeToHidl(aidlState);
}
Return<void> HidlDisplay::getTargetBuffer(getTargetBuffer_cb _hidl_cb) {
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
_hidl_cb({});
return {};
}
BufferDesc aidlBuffer;
auto status = mAidlDisplay->getTargetBuffer(&aidlBuffer);
if (!status.isOk()) {
LOG(ERROR) << "Failed to get a target buffer";
_hidl_cb({});
return {};
}
// We already own a copy of a buffer handle so do not need to duplicate it
// again.
hidlevs::V1_0::BufferDesc hidlBuffer = Utils::makeToHidlV1_0(aidlBuffer, /* doDup = */ false);
mHeldBuffer = std::move(aidlBuffer);
_hidl_cb(hidlBuffer);
return {};
}
Return<hidlevs::V1_0::EvsResult> HidlDisplay::returnTargetBufferForDisplay(
const hidlevs::V1_0::BufferDesc& buffer) {
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
return hidlevs::V1_0::EvsResult::UNDERLYING_SERVICE_ERROR;
}
if (buffer.bufferId != mHeldBuffer.bufferId) {
LOG(WARNING) << "Ignores a request to return a buffer " << buffer.bufferId << "; a buffer "
<< mHeldBuffer.bufferId << " is held.";
} else {
auto status = mAidlDisplay->returnTargetBufferForDisplay(std::move(mHeldBuffer));
if (!status.isOk()) {
LOG(WARNING) << "Failed to return a buffer " << mHeldBuffer.bufferId;
}
}
return hidlevs::V1_0::EvsResult::OK;
}
Return<void> HidlDisplay::getDisplayInfo_1_1(getDisplayInfo_1_1_cb _hidl_cb) {
::android::hardware::hidl_vec<uint8_t> hidlMode(sizeof(::android::ui::DisplayMode));
::android::hardware::hidl_vec<uint8_t> hidlState(sizeof(::android::ui::DisplayState));
if (!mAidlDisplay) {
LOG(ERROR) << "A reference to AIDL IEvsDisplay is invalid.";
_hidl_cb(hidlMode, hidlState);
return {};
}
DisplayDesc aidlDesc;
if (auto status = mAidlDisplay->getDisplayInfo(&aidlDesc); !status.isOk()) {
LOG(ERROR) << "Failed to read a display information";
_hidl_cb(hidlMode, hidlState);
return {};
}
::android::ui::DisplayMode* pMode =
reinterpret_cast<::android::ui::DisplayMode*>(hidlMode.data());
::android::ui::DisplayState* pState =
reinterpret_cast<::android::ui::DisplayState*>(hidlState.data());
pMode->resolution.width = aidlDesc.width;
pMode->resolution.height = aidlDesc.height;
pState->orientation = static_cast<::android::ui::Rotation>(aidlDesc.orientation);
_hidl_cb(hidlMode, hidlState);
return {};
}
} // namespace aidl::android::automotive::evs::implementation