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 #define LOG_TAG "ACameraVendorUtils"
18 
19 #include <utils/Log.h>
20 
21 #include "utils.h"
22 
23 namespace android {
24 namespace acam {
25 namespace utils {
26 
27 // Convert CaptureRequest wrappable by sp<> to hidl CaptureRequest.
28 frameworks::cameraservice::device::V2_0::CaptureRequest
convertToHidl(const CaptureRequest * captureRequest)29 convertToHidl(const CaptureRequest *captureRequest) {
30     frameworks::cameraservice::device::V2_0::CaptureRequest hCaptureRequest;
31     hCaptureRequest.physicalCameraSettings = captureRequest->mCaptureRequest.physicalCameraSettings;
32     hCaptureRequest.streamAndWindowIds = captureRequest->mCaptureRequest.streamAndWindowIds;
33     return hCaptureRequest;
34 }
35 
convertToHidl(int rotation)36 HRotation convertToHidl(int rotation) {
37     HRotation hRotation = HRotation::R0;
38     switch(rotation) {
39         case CAMERA3_STREAM_ROTATION_90:
40             hRotation = HRotation::R90;
41             break;
42         case CAMERA3_STREAM_ROTATION_180:
43             hRotation = HRotation::R180;
44             break;
45         case CAMERA3_STREAM_ROTATION_270:
46             hRotation = HRotation::R270;
47             break;
48         default:
49             break;
50     }
51     return hRotation;
52 }
53 
convertFromHidlCloned(const HCameraMetadata & metadata,CameraMetadata * rawMetadata)54 bool convertFromHidlCloned(const HCameraMetadata &metadata, CameraMetadata *rawMetadata) {
55     const camera_metadata *buffer = (camera_metadata_t*)(metadata.data());
56     size_t expectedSize = metadata.size();
57     int ret = validate_camera_metadata_structure(buffer, &expectedSize);
58     if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
59         *rawMetadata = buffer;
60     } else {
61         ALOGE("%s: Malformed camera metadata received from caller", __FUNCTION__);
62         return false;
63     }
64     return true;
65 }
66 
67 // Note: existing data in dst will be gone. dst owns memory if shouldOwn is set
68 //       to true.
convertToHidl(const camera_metadata_t * src,HCameraMetadata * dst,bool shouldOwn)69 void convertToHidl(const camera_metadata_t *src, HCameraMetadata* dst, bool shouldOwn) {
70     if (src == nullptr) {
71         return;
72     }
73     size_t size = get_camera_metadata_size(src);
74     dst->setToExternal((uint8_t *) src, size, shouldOwn);
75     return;
76 }
77 
convertToHidl(ACameraDevice_request_template templateId)78 TemplateId convertToHidl(ACameraDevice_request_template templateId) {
79     switch(templateId) {
80         case TEMPLATE_STILL_CAPTURE:
81             return TemplateId::STILL_CAPTURE;
82         case TEMPLATE_RECORD:
83             return TemplateId::RECORD;
84         case TEMPLATE_VIDEO_SNAPSHOT:
85             return TemplateId::VIDEO_SNAPSHOT;
86         case TEMPLATE_ZERO_SHUTTER_LAG:
87             return TemplateId::ZERO_SHUTTER_LAG;
88         case TEMPLATE_MANUAL:
89             return TemplateId::MANUAL;
90         default:
91             return TemplateId::PREVIEW;
92     }
93 }
94 
convertFromHidl(Status status)95 camera_status_t convertFromHidl(Status status) {
96     camera_status_t ret = ACAMERA_OK;
97     switch(status) {
98         case Status::NO_ERROR:
99             break;
100         case Status::DISCONNECTED:
101             ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
102             break;
103         case Status::CAMERA_IN_USE:
104             ret = ACAMERA_ERROR_CAMERA_IN_USE;
105             break;
106         case Status::MAX_CAMERAS_IN_USE:
107             ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
108             break;
109         case Status::ILLEGAL_ARGUMENT:
110             ret = ACAMERA_ERROR_INVALID_PARAMETER;
111             break;
112         case Status::DEPRECATED_HAL:
113             // Should not reach here since we filtered legacy HALs earlier
114             ret = ACAMERA_ERROR_INVALID_PARAMETER;
115             break;
116         case Status::DISABLED:
117             ret = ACAMERA_ERROR_CAMERA_DISABLED;
118             break;
119         case Status::PERMISSION_DENIED:
120             ret = ACAMERA_ERROR_PERMISSION_DENIED;
121             break;
122         case Status::INVALID_OPERATION:
123             ret = ACAMERA_ERROR_INVALID_OPERATION;
124             break;
125         default:
126             ret = ACAMERA_ERROR_UNKNOWN;
127             break;
128     }
129     return ret;
130 }
131 
isWindowNativeHandleEqual(const native_handle_t * nh1,const native_handle_t * nh2)132 bool isWindowNativeHandleEqual(const native_handle_t *nh1, const native_handle_t *nh2) {
133     if (nh1->numFds !=0 || nh2->numFds !=0) {
134         ALOGE("Invalid window native handles being compared");
135         return false;
136     }
137     if (nh1->version != nh2->version || nh1->numFds != nh2->numFds ||
138         nh1->numInts != nh2->numInts) {
139         return false;
140     }
141     for (int i = 0; i < nh1->numInts; i++) {
142         if(nh1->data[i] != nh2->data[i]) {
143             return false;
144         }
145     }
146     return true;
147 }
148 
isWindowNativeHandleLessThan(const native_handle_t * nh1,const native_handle_t * nh2)149 bool isWindowNativeHandleLessThan(const native_handle_t *nh1, const native_handle_t *nh2) {
150     if (isWindowNativeHandleEqual(nh1, nh2)) {
151         return false;
152     }
153     if (nh1->numInts != nh2->numInts) {
154         return nh1->numInts < nh2->numInts;
155     }
156 
157     for (int i = 0; i < nh1->numInts; i++) {
158         if (nh1->data[i] != nh2->data[i]) {
159             return nh1->data[i] < nh2->data[i];
160         }
161     }
162     return false;
163 }
164 
isWindowNativeHandleGreaterThan(const native_handle_t * nh1,const native_handle_t * nh2)165 bool isWindowNativeHandleGreaterThan(const native_handle_t *nh1, const native_handle_t *nh2) {
166     return !isWindowNativeHandleLessThan(nh1, nh2) && !isWindowNativeHandleEqual(nh1, nh2);
167 }
168 
areWindowNativeHandlesEqual(hidl_vec<hidl_handle> handles1,hidl_vec<hidl_handle> handles2)169 bool areWindowNativeHandlesEqual(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle> handles2) {
170     if (handles1.size() != handles2.size()) {
171         return false;
172     }
173     for (int i = 0; i < handles1.size(); i++) {
174         if (!isWindowNativeHandleEqual(handles1[i], handles2[i])) {
175             return false;
176         }
177     }
178     return true;
179 }
180 
areWindowNativeHandlesLessThan(hidl_vec<hidl_handle> handles1,hidl_vec<hidl_handle> handles2)181 bool areWindowNativeHandlesLessThan(hidl_vec<hidl_handle> handles1, hidl_vec<hidl_handle>handles2) {
182     if (handles1.size() != handles2.size()) {
183         return handles1.size() < handles2.size();
184     }
185     for (int i = 0; i < handles1.size(); i++) {
186         const native_handle_t *handle1 = handles1[i].getNativeHandle();
187         const native_handle_t *handle2 = handles2[i].getNativeHandle();
188         if (!isWindowNativeHandleEqual(handle1, handle2)) {
189             return isWindowNativeHandleLessThan(handle1, handle2);
190         }
191     }
192     return false;
193 }
194 
195 } // namespace utils
196 } // namespace acam
197 } // namespace android
198