blob: 6c8c0f78619dfed08d99178a1aad15ea83c585c3 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
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// #define LOG_NDEBUG 0
18#define LOG_TAG "VirtualCameraDevice"
19#include "VirtualCameraDevice.h"
20
21#include <chrono>
22#include <cstdint>
23#include <string>
24
25#include "VirtualCameraSession.h"
26#include "aidl/android/hardware/camera/common/Status.h"
27#include "aidl/android/hardware/camera/device/CameraMetadata.h"
28#include "android/binder_auto_utils.h"
29#include "android/binder_status.h"
30#include "log/log.h"
31#include "system/camera_metadata.h"
32#include "util/MetadataBuilder.h"
33#include "util/Util.h"
34
35namespace android {
36namespace companion {
37namespace virtualcamera {
38
39using ::aidl::android::companion::virtualcamera::IVirtualCameraCallback;
40using ::aidl::android::hardware::camera::common::CameraResourceCost;
41using ::aidl::android::hardware::camera::common::Status;
42using ::aidl::android::hardware::camera::device::CameraMetadata;
43using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
44using ::aidl::android::hardware::camera::device::ICameraDeviceSession;
45using ::aidl::android::hardware::camera::device::ICameraInjectionSession;
46using ::aidl::android::hardware::camera::device::StreamConfiguration;
47using ::aidl::android::hardware::camera::device::StreamRotation;
48using ::aidl::android::hardware::camera::device::StreamType;
49using ::aidl::android::hardware::graphics::common::PixelFormat;
50
51namespace {
52
53using namespace std::chrono_literals;
54
55// Prefix of camera name - "device@1.1/virtual/{numerical_id}"
56const char* kDevicePathPrefix = "device@1.1/virtual/";
57
58constexpr int32_t kVgaWidth = 640;
59constexpr int32_t kVgaHeight = 480;
60constexpr std::chrono::nanoseconds kMinFrameDuration30Fps = 1s / 30;
61constexpr int32_t kMaxJpegSize = 3 * 1024 * 1024 /*3MiB*/;
62
63constexpr MetadataBuilder::ControlRegion kDefaultEmptyControlRegion{};
64
65// TODO(b/301023410) - Populate camera characteristics according to camera configuration.
66CameraMetadata initCameraCharacteristics() {
67 auto metadata =
68 MetadataBuilder()
69 .setSupportedHardwareLevel(
70 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL)
71 .setFlashAvailable(false)
72 .setLensFacing(ANDROID_LENS_FACING_EXTERNAL)
73 .setSensorOrientation(0)
74 .setAvailableFaceDetectModes({ANDROID_STATISTICS_FACE_DETECT_MODE_OFF})
75 .setControlAfAvailableModes({ANDROID_CONTROL_AF_MODE_OFF})
76 .setAvailableOutputStreamConfigurations(
77 {MetadataBuilder::StreamConfiguration{
78 .width = kVgaWidth,
79 .height = kVgaHeight,
80 .format =
81 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
82 .minFrameDuration = kMinFrameDuration30Fps,
83 .minStallDuration = 0s},
84 MetadataBuilder::StreamConfiguration{
85 .width = kVgaWidth,
86 .height = kVgaHeight,
87 .format = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
88 .minFrameDuration = kMinFrameDuration30Fps,
89 .minStallDuration = 0s},
90 {MetadataBuilder::StreamConfiguration{
91 .width = kVgaWidth,
92 .height = kVgaHeight,
93 .format = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
94 .minFrameDuration = kMinFrameDuration30Fps,
95 .minStallDuration = 0s}}})
96 .setControlAeAvailableFpsRange(10, 30)
97 .setControlMaxRegions(0, 0, 0)
98 .setSensorActiveArraySize(0, 0, kVgaWidth, kVgaHeight)
99 .setControlAfRegions({kDefaultEmptyControlRegion})
100 .setControlAeRegions({kDefaultEmptyControlRegion})
101 .setControlAwbRegions({kDefaultEmptyControlRegion})
102 .setControlAeCompensationRange(0, 1)
103 .setControlAeCompensationStep(camera_metadata_rational_t{0, 1})
104 .setMaxJpegSize(kMaxJpegSize)
105 .setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE})
106 .setAvailableResultKeys({ANDROID_CONTROL_AF_MODE})
107 .setAvailableCapabilities(
108 {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE})
109 .setAvailableCharacteristicKeys()
110 .build();
111
112 if (metadata == nullptr) {
113 ALOGE("Failed to build metadata!");
114 return CameraMetadata();
115 }
116
117 return std::move(*metadata);
118}
119
120} // namespace
121
122VirtualCameraDevice::VirtualCameraDevice(
123 const uint32_t cameraId,
124 std::shared_ptr<IVirtualCameraCallback> virtualCameraClientCallback)
125 : mCameraId(cameraId),
126 mVirtualCameraClientCallback(virtualCameraClientCallback) {
127 mCameraCharacteristics = initCameraCharacteristics();
128}
129
130ndk::ScopedAStatus VirtualCameraDevice::getCameraCharacteristics(
131 CameraMetadata* _aidl_return) {
132 ALOGV("%s", __func__);
133 if (_aidl_return == nullptr) {
134 return cameraStatus(Status::ILLEGAL_ARGUMENT);
135 }
136
137 *_aidl_return = mCameraCharacteristics;
138 return ndk::ScopedAStatus::ok();
139}
140
141ndk::ScopedAStatus VirtualCameraDevice::getPhysicalCameraCharacteristics(
142 const std::string& in_physicalCameraId, CameraMetadata* _aidl_return) {
143 ALOGV("%s: physicalCameraId %s", __func__, in_physicalCameraId.c_str());
144 (void)_aidl_return;
145
146 // VTS tests expect this call to fail with illegal argument status for
147 // all publicly advertised camera ids.
148 // Because we don't support physical camera ids, we just always
149 // fail with illegal argument (there's no valid argument to provide).
150 return cameraStatus(Status::ILLEGAL_ARGUMENT);
151}
152
153ndk::ScopedAStatus VirtualCameraDevice::getResourceCost(
154 CameraResourceCost* _aidl_return) {
155 ALOGV("%s", __func__);
156 if (_aidl_return == nullptr) {
157 return cameraStatus(Status::ILLEGAL_ARGUMENT);
158 }
159 _aidl_return->resourceCost = 100; // ¯\_(ツ)_/¯
160 return ndk::ScopedAStatus::ok();
161}
162
163ndk::ScopedAStatus VirtualCameraDevice::isStreamCombinationSupported(
164 const StreamConfiguration& in_streams, bool* _aidl_return) {
165 ALOGV("%s", __func__);
166
167 if (_aidl_return == nullptr) {
168 return cameraStatus(Status::ILLEGAL_ARGUMENT);
169 }
170
171 for (const auto& stream : in_streams.streams) {
172 ALOGV("%s: Configuration queried: %s", __func__, stream.toString().c_str());
173
174 if (stream.streamType == StreamType::INPUT) {
175 ALOGW("%s: Input stream type is not supported", __func__);
176 *_aidl_return = false;
177 return ndk::ScopedAStatus::ok();
178 }
179
180 // TODO(b/301023410) remove hardcoded format checks, verify against configuration.
181 if (stream.width != 640 || stream.height != 480 ||
182 stream.rotation != StreamRotation::ROTATION_0 ||
183 (stream.format != PixelFormat::IMPLEMENTATION_DEFINED &&
184 stream.format != PixelFormat::YCBCR_420_888 &&
185 stream.format != PixelFormat::BLOB)) {
186 *_aidl_return = false;
187 return ndk::ScopedAStatus::ok();
188 }
189 }
190
191 *_aidl_return = true;
192 return ndk::ScopedAStatus::ok();
193};
194
195ndk::ScopedAStatus VirtualCameraDevice::open(
196 const std::shared_ptr<ICameraDeviceCallback>& in_callback,
197 std::shared_ptr<ICameraDeviceSession>* _aidl_return) {
198 ALOGV("%s", __func__);
199
200 *_aidl_return = ndk::SharedRefBase::make<VirtualCameraSession>(
201 std::to_string(mCameraId), in_callback, mVirtualCameraClientCallback);
202
203 return ndk::ScopedAStatus::ok();
204};
205
206ndk::ScopedAStatus VirtualCameraDevice::openInjectionSession(
207 const std::shared_ptr<ICameraDeviceCallback>& in_callback,
208 std::shared_ptr<ICameraInjectionSession>* _aidl_return) {
209 ALOGV("%s", __func__);
210
211 (void)in_callback;
212 (void)_aidl_return;
213 return cameraStatus(Status::OPERATION_NOT_SUPPORTED);
214}
215
216ndk::ScopedAStatus VirtualCameraDevice::setTorchMode(bool in_on) {
217 ALOGV("%s: on = %s", __func__, in_on ? "on" : "off");
218 return cameraStatus(Status::OPERATION_NOT_SUPPORTED);
219}
220
221ndk::ScopedAStatus VirtualCameraDevice::turnOnTorchWithStrengthLevel(
222 int32_t in_torchStrength) {
223 ALOGV("%s: torchStrength = %d", __func__, in_torchStrength);
224 return cameraStatus(Status::OPERATION_NOT_SUPPORTED);
225}
226
227ndk::ScopedAStatus VirtualCameraDevice::getTorchStrengthLevel(
228 int32_t* _aidl_return) {
229 (void)_aidl_return;
230 return cameraStatus(Status::OPERATION_NOT_SUPPORTED);
231}
232
233binder_status_t VirtualCameraDevice::dump(int fd, const char** args,
234 uint32_t numArgs) {
235 // TODO(b/301023410) Implement.
236 (void)fd;
237 (void)args;
238 (void)numArgs;
239 return STATUS_OK;
240}
241
242std::string VirtualCameraDevice::getCameraName() const {
243 return std::string(kDevicePathPrefix) + std::to_string(mCameraId);
244}
245
246} // namespace virtualcamera
247} // namespace companion
248} // namespace android