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