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 "IVhalClient.h"
18 
19 #include "AidlVhalClient.h"
20 #include "HidlVhalClient.h"
21 
22 #include <android-base/stringprintf.h>
23 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
24 
25 #include <condition_variable>  // NOLINT
26 #include <mutex>               // NOLINT
27 
28 namespace android {
29 namespace frameworks {
30 namespace automotive {
31 namespace vhal {
32 
33 using ::android::base::StringPrintf;
34 
create()35 std::shared_ptr<IVhalClient> IVhalClient::create() {
36     auto client = AidlVhalClient::create();
37     if (client != nullptr) {
38         return client;
39     }
40 
41     return HidlVhalClient::create();
42 }
43 
tryCreate()44 std::shared_ptr<IVhalClient> IVhalClient::tryCreate() {
45     auto client = AidlVhalClient::tryCreate();
46     if (client != nullptr) {
47         return client;
48     }
49 
50     return HidlVhalClient::tryCreate();
51 }
52 
tryCreateAidlClient(const char * descriptor)53 std::shared_ptr<IVhalClient> IVhalClient::tryCreateAidlClient(const char* descriptor) {
54     return AidlVhalClient::tryCreate(descriptor);
55 }
56 
tryCreateHidlClient(const char * descriptor)57 std::shared_ptr<IVhalClient> IVhalClient::tryCreateHidlClient(const char* descriptor) {
58     return HidlVhalClient::tryCreate(descriptor);
59 }
60 
getValueSync(const IHalPropValue & requestValue)61 VhalClientResult<std::unique_ptr<IHalPropValue>> IVhalClient::getValueSync(
62         const IHalPropValue& requestValue) {
63     struct {
64         std::mutex lock;
65         std::condition_variable cv;
66         VhalClientResult<std::unique_ptr<IHalPropValue>> result;
67         bool gotResult = false;
68     } s;
69 
70     auto callback = std::make_shared<IVhalClient::GetValueCallbackFunc>(
71             [&s](VhalClientResult<std::unique_ptr<IHalPropValue>> r) {
72                 {
73                     std::lock_guard<std::mutex> lockGuard(s.lock);
74                     s.result = std::move(r);
75                     s.gotResult = true;
76                     s.cv.notify_one();
77                 }
78             });
79 
80     getValue(requestValue, callback);
81 
82     std::unique_lock<std::mutex> lk(s.lock);
83     s.cv.wait(lk, [&s] { return s.gotResult; });
84 
85     return std::move(s.result);
86 }
87 
setValueSync(const IHalPropValue & requestValue)88 VhalClientResult<void> IVhalClient::setValueSync(const IHalPropValue& requestValue) {
89     struct {
90         std::mutex lock;
91         std::condition_variable cv;
92         VhalClientResult<void> result;
93         bool gotResult = false;
94     } s;
95 
96     auto callback =
97             std::make_shared<IVhalClient::SetValueCallbackFunc>([&s](VhalClientResult<void> r) {
98                 {
99                     std::lock_guard<std::mutex> lockGuard(s.lock);
100                     s.result = std::move(r);
101                     s.gotResult = true;
102                     s.cv.notify_one();
103                 }
104             });
105 
106     setValue(requestValue, callback);
107 
108     std::unique_lock<std::mutex> lk(s.lock);
109     s.cv.wait(lk, [&s] { return s.gotResult; });
110 
111     return std::move(s.result);
112 }
113 
value() const114 ErrorCode VhalClientError::value() const {
115     return mCode;
116 }
117 
toString(ErrorCode code)118 std::string VhalClientError::toString(ErrorCode code) {
119     switch (code) {
120         case ErrorCode::OK:
121             return "OK";
122         case ErrorCode::INVALID_ARG:
123             return "INVALID_ARG";
124         case ErrorCode::TIMEOUT:
125             return "TIMEOUT";
126         case ErrorCode::TRANSACTION_ERROR:
127             return "TRANSACTION_ERROR";
128         case ErrorCode::TRY_AGAIN_FROM_VHAL:
129             return "TRY_AGAIN_FROM_VHAL";
130         case ErrorCode::NOT_AVAILABLE_FROM_VHAL:
131             return "NOT_AVAILABLE_FROM_VHAL";
132         case ErrorCode::ACCESS_DENIED_FROM_VHAL:
133             return "ACCESS_DENIED_FROM_VHAL";
134         case ErrorCode::INTERNAL_ERROR_FROM_VHAL:
135             return "INTERNAL_ERROR_FROM_VHAL";
136         default:
137             return StringPrintf("Unknown error. Code: %d", static_cast<int>(code));
138     }
139 }
140 
print() const141 std::string VhalClientError::print() const {
142     return VhalClientError::toString(mCode);
143 }
144 
145 }  // namespace vhal
146 }  // namespace automotive
147 }  // namespace frameworks
148 }  // namespace android
149