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