• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (!mImpl) {
46         LOG(ERROR) << "Failed to initialize AidlCameraStream instance";
47     }
48 }
49 
deliverFrame(const std::vector<BufferDesc> & buffers)50 ScopedAStatus AidlCameraStream::deliverFrame(const std::vector<BufferDesc>& buffers) {
51     return mImpl->deliverFrame(buffers);
52 }
53 
notify(const EvsEventDesc & event)54 ScopedAStatus AidlCameraStream::notify(const EvsEventDesc& event) {
55     return mImpl->notify(event);
56 }
57 
getBuffer(int id,BufferDesc * _return)58 bool AidlCameraStream::getBuffer(int id, BufferDesc* _return) {
59     return mImpl->getBuffer(id, _return);
60 }
61 
getBuffer(int id,BufferDesc * _return)62 bool AidlCameraStream::IHidlCameraStream::getBuffer(int id, BufferDesc* _return) {
63     auto it = std::find_if(mBuffers.begin(), mBuffers.end(),
64                            [id](const BufferDesc& buffer) { return id == buffer.bufferId; });
65     if (it == mBuffers.end()) {
66         return false;
67     }
68 
69     *_return = std::move(*it);
70     mBuffers.erase(it);
71     return true;
72 }
73 
ImplV0(const::android::sp<hidlevs::V1_0::IEvsCameraStream> & stream)74 AidlCameraStream::ImplV0::ImplV0(const ::android::sp<hidlevs::V1_0::IEvsCameraStream>& stream) :
75       IHidlCameraStream(stream) {}
76 
deliverFrame(const std::vector<BufferDesc> & buffers)77 ScopedAStatus AidlCameraStream::ImplV0::deliverFrame(const std::vector<BufferDesc>& buffers) {
78     auto hidlBuffer = Utils::makeToHidlV1_0(buffers[0], /* doDup= */ false);
79     mBuffers.push_back(std::move(Utils::dupBufferDesc(buffers[0], /* doDup= */ true)));
80     if (auto status = mStream->deliverFrame(std::move(hidlBuffer)); !status.isOk()) {
81         LOG(ERROR) << "Failed to forward a frame to HIDL v1.0 client";
82         return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
83     }
84 
85     return ScopedAStatus::ok();
86 }
87 
notify(const EvsEventDesc & event)88 ScopedAStatus AidlCameraStream::ImplV0::notify(const EvsEventDesc& event) {
89     switch (event.aType) {
90         case EvsEventType::STREAM_STOPPED:
91             if (auto status = mStream->deliverFrame({}); !status.isOk()) {
92                 LOG(ERROR) << "Error delivering the end of stream marker";
93                 return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
94             }
95             break;
96 
97         default:
98             // HIDL v1.0 interface does not support events
99             LOG(INFO) << "Event " << Utils::toString(event.aType)
100                       << " is received but ignored for HIDL v1.0 client";
101             break;
102     }
103 
104     return ScopedAStatus::ok();
105 }
106 
ImplV1(const::android::sp<hidlevs::V1_1::IEvsCameraStream> & stream)107 AidlCameraStream::ImplV1::ImplV1(const ::android::sp<hidlevs::V1_1::IEvsCameraStream>& stream) :
108       IHidlCameraStream(stream), mStream(stream) {}
109 
deliverFrame(const std::vector<BufferDesc> & buffers)110 ScopedAStatus AidlCameraStream::ImplV1::deliverFrame(const std::vector<BufferDesc>& buffers) {
111     const auto n = buffers.size();
112     ::android::hardware::hidl_vec<hidlevs::V1_1::BufferDesc> hidlBuffers(n);
113     for (auto i = 0; i < n; ++i) {
114         BufferDesc buffer = std::move(Utils::dupBufferDesc(buffers[i], /* doDup= */ true));
115         hidlBuffers[i] = std::move(Utils::makeToHidlV1_1(buffer, /* doDup= */ false));
116         mBuffers.push_back(std::move(buffer));
117     }
118 
119     if (auto status = mStream->deliverFrame_1_1(hidlBuffers); !status.isOk()) {
120         LOG(ERROR) << "Failed to forward a frame to HIDL v1.1 client";
121         return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
122     }
123 
124     return ScopedAStatus::ok();
125 }
126 
notify(const EvsEventDesc & event)127 ScopedAStatus AidlCameraStream::ImplV1::notify(const EvsEventDesc& event) {
128     hidlevs::V1_1::EvsEventDesc hidlEvent;
129     if (!Utils::makeToHidl(event, &hidlEvent)) {
130         return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
131     }
132 
133     if (auto status = mStream->notify(hidlEvent); !status.isOk()) {
134         LOG(ERROR) << "Failed to forward an event, " << Utils::toString(event.aType);
135         return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
136     }
137 
138     return ScopedAStatus::ok();
139 }
140 
141 }  // namespace aidl::android::automotive::evs::implementation
142