1 /*
2 * Copyright (C) 2023 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 <log/log.h>
18 #include <multihal_sensors_transport.h>
19 #include <multihal_sensors.h>
20
21 #include "common/libs/transport/channel_sharedfd.h"
22
23 using ::android::hardware::sensors::V2_1::implementation::ISensorsSubHal;
24
25 namespace {
26
27 class VconsoleSensorsTransport : public goldfish::SensorsTransport {
28 public:
VconsoleSensorsTransport(const char * path)29 VconsoleSensorsTransport(const char* path)
30 : console_sensors_fd_(cuttlefish::SharedFD::Open(path, O_RDWR)),
31 pure_sensors_fd_(console_sensors_fd_->UNMANAGED_Dup()),
32 sensors_channel_(console_sensors_fd_, console_sensors_fd_) {}
33
~VconsoleSensorsTransport()34 ~VconsoleSensorsTransport() override { close(pure_sensors_fd_); }
35
Send(const void * msg,int size)36 int Send(const void* msg, int size) override {
37 auto message_result = cuttlefish::transport::CreateMessage(0, size);
38 if (!message_result.ok()) {
39 LOG(ERROR) << "Failed to allocate sensors message with size: " << size << " bytes. "
40 << "Error message: " << message_result.error().Message();
41 return -1;
42 }
43
44 auto message = std::move(message_result.value());
45 std::memcpy(message->payload, msg, size);
46
47 auto send_result = sensors_channel_.SendRequest(*message);
48 if (!send_result.ok()) {
49 LOG(ERROR) << "Failed to send sensors message with size: " << size << " bytes. "
50 << "Error message: " << send_result.error().Message();
51 return -1;
52 }
53
54 return size;
55 }
56
Receive(void * msg,int maxsize)57 int Receive(void* msg, int maxsize) override {
58 auto message_result = sensors_channel_.ReceiveMessage();
59 if (!message_result.ok()) {
60 LOG(ERROR) << "Failed to receive sensors message. "
61 << "Error message: " << message_result.error().Message();
62 return -1;
63 }
64
65 auto message = std::move(message_result.value());
66 if (message->payload_size > maxsize) {
67 LOG(ERROR) << "Received sensors message size is " << message->payload_size
68 << " maximum supported size is " << maxsize;
69 return -1;
70 }
71
72 std::memcpy(msg, message->payload, message->payload_size);
73
74 return message->payload_size;
75 }
76
Ok() const77 bool Ok() const override { return console_sensors_fd_->IsOpen(); }
78
Fd() const79 int Fd() const override { return pure_sensors_fd_; }
80
Name() const81 const char* Name() const override { return "vconsole_channel"; }
82
83 private:
84 cuttlefish::SharedFD console_sensors_fd_;
85 // Store pure dup of console_sensors_fd_ to return it from
86 // Fd() method which supposed to return pure fd used for
87 // receive/send sensors data.
88 int pure_sensors_fd_;
89 cuttlefish::transport::SharedFdChannel sensors_channel_;
90 };
91
92 } // namespace
93
sensorsHalGetSubHal_2_1(uint32_t * version)94 extern "C" ISensorsSubHal* sensorsHalGetSubHal_2_1(uint32_t* version) {
95 // Leaking the memory intentionally to make sure this object is available
96 // for other threads after main thread is terminated:
97 // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
98 // go/totw/110#destruction
99 static goldfish::MultihalSensors* impl = new goldfish::MultihalSensors([]() {
100 return std::make_unique<VconsoleSensorsTransport>("/dev/hvc13");
101 });
102
103 *version = SUB_HAL_2_1_VERSION;
104 return impl;
105 }
106