1 /*
2  * Copyright 2021 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 #define LOG_TAG "VsockCameraProvider"
17 #include "vsock_camera_provider_2_7.h"
18 #include <cutils/properties.h>
19 #include <log/log.h>
20 #include "vsock_camera_server.h"
21 
22 namespace android::hardware::camera::provider::V2_7::implementation {
23 
24 namespace {
25 VsockCameraServer gCameraServer;
26 constexpr auto kDeviceName = "device@3.4/external/0";
27 }  // namespace
28 
29 using android::hardware::camera::provider::V2_7::ICameraProvider;
HIDL_FETCH_ICameraProvider(const char * name)30 extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
31   return (strcmp(name, "external/0") == 0)
32              ? new VsockCameraProvider(&gCameraServer)
33              : nullptr;
34 }
35 
VsockCameraProvider(VsockCameraServer * server)36 VsockCameraProvider::VsockCameraProvider(VsockCameraServer* server) {
37   server_ = server;
38   if (!server->isRunning()) {
39     constexpr static const auto camera_port_property =
40         "ro.boot.vsock_camera_port";
41     auto port = property_get_int32(camera_port_property, -1);
42     if (port > 0) {
43       server->start(port, VMADDR_CID_ANY);
44     }
45   }
46 }
47 
~VsockCameraProvider()48 VsockCameraProvider::~VsockCameraProvider() {
49   server_->setConnectedCallback(nullptr);
50 }
51 
setCallback(const sp<ICameraProviderCallback> & callback)52 Return<Status> VsockCameraProvider::setCallback(
53     const sp<ICameraProviderCallback>& callback) {
54   {
55     std::lock_guard<std::mutex> lock(mutex_);
56     callbacks_ = callback;
57   }
58   server_->setConnectedCallback(
59       [this](std::shared_ptr<cuttlefish::VsockConnection> connection,
60              VsockCameraDevice::Settings settings) {
61         connection_ = connection;
62         settings_ = settings;
63         deviceAdded(kDeviceName);
64         connection_->SetDisconnectCallback(
65             [this] { deviceRemoved(kDeviceName); });
66       });
67   return Status::OK;
68 }
69 
getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb)70 Return<void> VsockCameraProvider::getVendorTags(
71     ICameraProvider::getVendorTags_cb _hidl_cb) {
72   // No vendor tag support
73   hidl_vec<VendorTagSection> empty;
74   _hidl_cb(Status::OK, empty);
75   return Void();
76 }
77 
getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb)78 Return<void> VsockCameraProvider::getCameraIdList(
79     ICameraProvider::getCameraIdList_cb _hidl_cb) {
80   // External camera HAL always report 0 camera, and extra cameras
81   // are just reported via cameraDeviceStatusChange callbacks
82   hidl_vec<hidl_string> empty;
83   _hidl_cb(Status::OK, empty);
84   return Void();
85 }
86 
isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb)87 Return<void> VsockCameraProvider::isSetTorchModeSupported(
88     ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
89   // setTorchMode API is supported, though right now no external camera device
90   // has a flash unit.
91   _hidl_cb(Status::OK, true);
92   return Void();
93 }
94 
getCameraDeviceInterface_V1_x(const hidl_string &,ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)95 Return<void> VsockCameraProvider::getCameraDeviceInterface_V1_x(
96     const hidl_string&,
97     ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb) {
98   // External Camera HAL does not support HAL1
99   _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr);
100   return Void();
101 }
102 
getCameraDeviceInterface_V3_x(const hidl_string & name_hidl_str,ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)103 Return<void> VsockCameraProvider::getCameraDeviceInterface_V3_x(
104     const hidl_string& name_hidl_str,
105     ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
106   std::string name(name_hidl_str.c_str());
107   if (name != kDeviceName) {
108     _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
109     return Void();
110   }
111 
112   _hidl_cb(Status::OK, new VsockCameraDevice(name, settings_, connection_));
113   return Void();
114 }
115 
notifyDeviceStateChange(hardware::hidl_bitfield<DeviceState>)116 Return<void> VsockCameraProvider::notifyDeviceStateChange(
117     hardware::hidl_bitfield<DeviceState> /*newState*/) {
118   return Void();
119 }
120 
getConcurrentStreamingCameraIds(getConcurrentStreamingCameraIds_cb _hidl_cb)121 Return<void> VsockCameraProvider::getConcurrentStreamingCameraIds(
122     getConcurrentStreamingCameraIds_cb _hidl_cb) {
123   hidl_vec<hidl_vec<hidl_string>> hidl_camera_id_combinations;
124   _hidl_cb(Status::OK, hidl_camera_id_combinations);
125   return Void();
126 }
127 
isConcurrentStreamCombinationSupported(const hidl_vec<::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination> &,isConcurrentStreamCombinationSupported_cb _hidl_cb)128 Return<void> VsockCameraProvider::isConcurrentStreamCombinationSupported(
129     const hidl_vec<::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination>&,
130     isConcurrentStreamCombinationSupported_cb _hidl_cb) {
131   _hidl_cb(Status::OK, false);
132   return Void();
133 }
134 
isConcurrentStreamCombinationSupported_2_7(const hidl_vec<::android::hardware::camera::provider::V2_7::CameraIdAndStreamCombination> &,isConcurrentStreamCombinationSupported_2_7_cb _hidl_cb)135 Return<void> VsockCameraProvider::isConcurrentStreamCombinationSupported_2_7(
136     const hidl_vec<::android::hardware::camera::provider::V2_7::CameraIdAndStreamCombination>&,
137     isConcurrentStreamCombinationSupported_2_7_cb _hidl_cb) {
138   _hidl_cb(Status::OK, false);
139   return Void();
140 }
141 
deviceAdded(const char * name)142 void VsockCameraProvider::deviceAdded(const char* name) {
143   std::lock_guard<std::mutex> lock(mutex_);
144   if (callbacks_ != nullptr) {
145     callbacks_->cameraDeviceStatusChange(name, CameraDeviceStatus::PRESENT);
146   }
147 }
148 
deviceRemoved(const char * name)149 void VsockCameraProvider::deviceRemoved(const char* name) {
150   std::lock_guard<std::mutex> lock(mutex_);
151   if (callbacks_ != nullptr) {
152     callbacks_->cameraDeviceStatusChange(name, CameraDeviceStatus::NOT_PRESENT);
153   }
154 }
155 
156 }  // namespace android::hardware::camera::provider::V2_7::implementation
157