1 /*
2  * Copyright (C) 2018 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 <android/frameworks/cameraservice/service/2.0/ICameraService.h>
18 #include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
19 #include <android/frameworks/cameraservice/device/2.0/types.h>
20 #include <camera/NdkCameraDevice.h>
21 #include <CameraMetadata.h>
22 #include <hardware/camera3.h>
23 
24 #ifndef CAMERA_NDK_VENDOR_H
25 #define CAMERA_NDK_VENDOR_H
26 
27 using android::hardware::hidl_vec;
28 using android::hardware::hidl_handle;
29 
30 namespace android {
31 namespace acam {
32 namespace utils {
33 
34 using CameraMetadata = hardware::camera::common::V1_0::helper::CameraMetadata;
35 using HCameraMetadata  = frameworks::cameraservice::service::V2_0::CameraMetadata;
36 using Status = frameworks::cameraservice::common::V2_0::Status;
37 using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
38 using PhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
39 using HRotation = frameworks::cameraservice::device::V2_0::OutputConfiguration::Rotation;
40 using OutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
41 
42 // Utility class so that CaptureRequest can be stored by sp<>
43 struct CaptureRequest : public RefBase {
44   frameworks::cameraservice::device::V2_0::CaptureRequest mCaptureRequest;
45   std::vector<native_handle_t *> mSurfaceList;
46   //Physical camera settings metadata is stored here, since the capture request
47   //might not contain it. That's since, fmq might have consumed it.
48   hidl_vec<PhysicalCameraSettings> mPhysicalCameraSettings;
49 };
50 
51 bool areWindowNativeHandlesEqual(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2);
52 
53 bool areWindowNativeHandlesLessThan(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2);
54 
55 bool isWindowNativeHandleEqual(const native_handle_t *nh1, const native_handle_t *nh2);
56 
57 bool isWindowNativeHandleLessThan(const native_handle_t *nh1, const native_handle_t *nh2);
58 
59 // Convenience wrapper over isWindowNativeHandleLessThan and isWindowNativeHandleEqual
60 bool isWindowNativeHandleGreaterThan(const native_handle_t *nh1, const native_handle_t *nh2);
61 
62 // Utility class so the native_handle_t can be compared with  its contents instead
63 // of just raw pointer comparisons.
64 struct native_handle_ptr_wrapper {
65     native_handle_t *mWindow = nullptr;
66 
native_handle_ptr_wrappernative_handle_ptr_wrapper67     native_handle_ptr_wrapper(native_handle_t *nh) : mWindow(nh) { }
68 
69     native_handle_ptr_wrapper() = default;
70 
71     operator native_handle_t *() const { return mWindow; }
72 
73     bool operator ==(const native_handle_ptr_wrapper other) const {
74         return isWindowNativeHandleEqual(mWindow, other.mWindow);
75     }
76 
77     bool operator != (const native_handle_ptr_wrapper& other) const {
78         return !isWindowNativeHandleEqual(mWindow, other.mWindow);
79     }
80 
81     bool operator < (const native_handle_ptr_wrapper& other) const {
82         return isWindowNativeHandleLessThan(mWindow, other.mWindow);
83     }
84 
85     bool operator > (const native_handle_ptr_wrapper& other) const {
86         return !isWindowNativeHandleGreaterThan(mWindow, other.mWindow);
87     }
88 
89 };
90 
91 // Wrapper around OutputConfiguration. This is needed since HIDL
92 // OutputConfiguration is auto-generated and marked final. Therefore, operator
93 // overloads outside the class, will not get picked by clang while trying to
94 // store OutputConfiguration in maps/sets.
95 struct OutputConfigurationWrapper {
96     OutputConfiguration mOutputConfiguration;
97 
98     operator const OutputConfiguration &() const {
99         return mOutputConfiguration;
100     }
101 
OutputConfigurationWrapperOutputConfigurationWrapper102     OutputConfigurationWrapper() {
103         mOutputConfiguration.rotation = OutputConfiguration::Rotation::R0;
104         // The ndk currently doesn't support deferred surfaces
105         mOutputConfiguration.isDeferred = false;
106         mOutputConfiguration.width = 0;
107         mOutputConfiguration.height = 0;
108         // ndk doesn't support inter OutputConfiguration buffer sharing.
109         mOutputConfiguration.windowGroupId = -1;
110     };
111 
OutputConfigurationWrapperOutputConfigurationWrapper112     OutputConfigurationWrapper(OutputConfiguration &outputConfiguration)
113             : mOutputConfiguration((outputConfiguration)) { }
114 
115     bool operator ==(const OutputConfiguration &other) const {
116         const OutputConfiguration &self = mOutputConfiguration;
117         return self.rotation == other.rotation && self.windowGroupId == other.windowGroupId &&
118                 self.physicalCameraId == other.physicalCameraId && self.width == other.width &&
119                 self.height == other.height && self.isDeferred == other.isDeferred &&
120                 areWindowNativeHandlesEqual(self.windowHandles, other.windowHandles);
121     }
122 
123     bool operator < (const OutputConfiguration &other) const {
124         if (*this == other) {
125             return false;
126         }
127         const OutputConfiguration &self = mOutputConfiguration;
128         if (self.windowGroupId != other.windowGroupId) {
129             return self.windowGroupId < other.windowGroupId;
130         }
131 
132         if (self.width != other.width) {
133             return self.width < other.width;
134         }
135 
136         if (self.height != other.height) {
137             return self.height < other.height;
138         }
139 
140         if (self.rotation != other.rotation) {
141             return static_cast<uint32_t>(self.rotation) < static_cast<uint32_t>(other.rotation);
142         }
143 
144         if (self.isDeferred != other.isDeferred) {
145             return self.isDeferred < other.isDeferred;
146         }
147 
148         if (self.physicalCameraId != other.physicalCameraId) {
149             return self.physicalCameraId < other.physicalCameraId;
150         }
151         return areWindowNativeHandlesLessThan(self.windowHandles, other.windowHandles);
152     }
153 
154     bool operator != (const OutputConfiguration &other) const {
155         return !(*this == other);
156     }
157 
158     bool operator > (const OutputConfiguration &other) const {
159         return (*this != other) && !(*this < other);
160     }
161 };
162 
163 // Convert CaptureRequest wrappable by sp<> to hidl CaptureRequest.
164 frameworks::cameraservice::device::V2_0::CaptureRequest convertToHidl(
165     const CaptureRequest *captureRequest);
166 
167 HRotation convertToHidl(int rotation);
168 
169 bool convertFromHidlCloned(const HCameraMetadata &metadata, CameraMetadata *rawMetadata);
170 
171 // Note: existing data in dst will be gone.
172 void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn = false);
173 
174 TemplateId convertToHidl(ACameraDevice_request_template templateId);
175 
176 camera_status_t convertFromHidl(Status status);
177 
178 } // namespace utils
179 } // namespace acam
180 } // namespace android
181 
182 #endif // CAMERA_NDK_VENDOR_H
183