1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "AidlCameraStream.h"
18
19 #include "utils/include/Utils.h"
20
21 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
22 #include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
23 #include <aidl/android/hardware/automotive/evs/EvsEventType.h>
24 #include <android-base/logging.h>
25
26 namespace aidl::android::automotive::evs::implementation {
27
28 namespace hidlevs = ::android::hardware::automotive::evs;
29
30 using ::aidl::android::hardware::automotive::evs::BufferDesc;
31 using ::aidl::android::hardware::automotive::evs::EvsEventDesc;
32 using ::aidl::android::hardware::automotive::evs::EvsEventType;
33 using ::aidl::android::hardware::automotive::evs::EvsResult;
34 using ::ndk::ScopedAStatus;
35
AidlCameraStream(const::android::sp<hidlevs::V1_0::IEvsCameraStream> & hidlStream)36 AidlCameraStream::AidlCameraStream(
37 const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& hidlStream) {
38 auto hidlStreamV1 = hidlevs::V1_1::IEvsCameraStream::castFrom(hidlStream).withDefault(nullptr);
39 if (!hidlStreamV1) {
40 mImpl = std::make_shared<ImplV0>(hidlStream);
41 } else {
42 mImpl = std::make_shared<ImplV1>(hidlStreamV1);
43 }
44 }
45
deliverFrame(const std::vector<BufferDesc> & buffers)46 ScopedAStatus AidlCameraStream::deliverFrame(const std::vector<BufferDesc>& buffers) {
47 return mImpl->deliverFrame(buffers);
48 }
49
notify(const EvsEventDesc & event)50 ScopedAStatus AidlCameraStream::notify(const EvsEventDesc& event) {
51 return mImpl->notify(event);
52 }
53
getBuffer(int id,BufferDesc * _return)54 bool AidlCameraStream::getBuffer(int id, BufferDesc* _return) {
55 return mImpl->getBuffer(id, _return);
56 }
57
getBuffer(int id,BufferDesc * _return)58 bool AidlCameraStream::IHidlCameraStream::getBuffer(int id, BufferDesc* _return) {
59 auto it = std::find_if(mBuffers.begin(), mBuffers.end(),
60 [id](const BufferDesc& buffer) { return id == buffer.bufferId; });
61 if (it == mBuffers.end()) {
62 return false;
63 }
64
65 *_return = std::move(*it);
66 mBuffers.erase(it);
67 return true;
68 }
69
ImplV0(const::android::sp<hidlevs::V1_0::IEvsCameraStream> & stream)70 AidlCameraStream::ImplV0::ImplV0(const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& stream) :
71 IHidlCameraStream(stream) {}
72
deliverFrame(const std::vector<BufferDesc> & buffers)73 ScopedAStatus AidlCameraStream::ImplV0::deliverFrame(const std::vector<BufferDesc>& buffers) {
74 if (!mStream) {
75 return ScopedAStatus::fromServiceSpecificError(
76 static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
77 }
78
79 auto hidlBuffer = Utils::makeToHidlV1_0(buffers[0], /* doDup= */ false);
80 mBuffers.push_back(std::move(Utils::dupBufferDesc(buffers[0], /* doDup= */ true)));
81 if (auto status = mStream->deliverFrame(std::move(hidlBuffer)); !status.isOk()) {
82 LOG(ERROR) << "Failed to forward a frame to HIDL v1.0 client";
83 return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
84 }
85
86 return ScopedAStatus::ok();
87 }
88
notify(const EvsEventDesc & event)89 ScopedAStatus AidlCameraStream::ImplV0::notify(const EvsEventDesc& event) {
90 if (!mStream) {
91 return ScopedAStatus::fromServiceSpecificError(
92 static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
93 }
94
95 switch (event.aType) {
96 case EvsEventType::STREAM_STOPPED:
97 if (auto status = mStream->deliverFrame({}); !status.isOk()) {
98 LOG(ERROR) << "Error delivering the end of stream marker";
99 return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
100 }
101 break;
102
103 default:
104 // HIDL v1.0 interface does not support events
105 LOG(INFO) << "Event " << toString(event.aType)
106 << " is received but ignored for HIDL v1.0 client";
107 break;
108 }
109
110 return ScopedAStatus::ok();
111 }
112
ImplV1(const::android::sp<hidlevs::V1_1::IEvsCameraStream> & stream)113 AidlCameraStream::ImplV1::ImplV1(const ::android::sp<hidlevs::V1_1::IEvsCameraStream>& stream) :
114 IHidlCameraStream(stream), mStream(stream) {}
115
deliverFrame(const std::vector<BufferDesc> & buffers)116 ScopedAStatus AidlCameraStream::ImplV1::deliverFrame(const std::vector<BufferDesc>& buffers) {
117 const auto n = buffers.size();
118 ::android::hardware::hidl_vec<hidlevs::V1_1::BufferDesc> hidlBuffers(n);
119 for (auto i = 0; i < n; ++i) {
120 BufferDesc buffer = std::move(Utils::dupBufferDesc(buffers[i], /* doDup= */ true));
121 hidlBuffers[i] = std::move(Utils::makeToHidlV1_1(buffer, /* doDup= */ false));
122 mBuffers.push_back(std::move(buffer));
123 }
124
125 if (auto status = mStream->deliverFrame_1_1(hidlBuffers); !status.isOk()) {
126 LOG(ERROR) << "Failed to forward a frame to HIDL v1.1 client";
127 return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
128 }
129
130 return ScopedAStatus::ok();
131 }
132
notify(const EvsEventDesc & event)133 ScopedAStatus AidlCameraStream::ImplV1::notify(const EvsEventDesc& event) {
134 if (!mStream) {
135 return ScopedAStatus::fromServiceSpecificError(
136 static_cast<int>(EvsResult::RESOURCE_NOT_AVAILABLE));
137 }
138
139 hidlevs::V1_1::EvsEventDesc hidlEvent;
140 if (!Utils::makeToHidl(event, &hidlEvent)) {
141 return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
142 }
143
144 if (auto status = mStream->notify(hidlEvent); !status.isOk()) {
145 LOG(ERROR) << "Failed to forward an event, " << toString(event.aType);
146 return ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
147 }
148
149 return ScopedAStatus::ok();
150 }
151
152 } // namespace aidl::android::automotive::evs::implementation
153