blob: 92fe84b6d37e70b03b6603594cc31bf2901298c4 [file] [log] [blame]
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001/*
2 * Copyright (C) 2012 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
Igor Murashkine2d1e3d2013-04-30 18:18:06 -070017// #define LOG_NDEBUG 0
18
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070019#define LOG_TAG "Camera2-Metadata"
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070020#include <utils/Log.h>
21#include <utils/Errors.h>
22
Igor Murashkine7ee7632013-06-11 18:10:18 -070023#include <binder/Parcel.h>
Eino-Ville Talvala4d453832016-07-15 11:56:53 -070024#include <camera/CameraMetadata.h>
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070025
26namespace android {
27
Zhijun He146aed12013-12-05 07:46:51 -080028#define ALIGN_TO(val, alignment) \
29 (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
30
Igor Murashkine7ee7632013-06-11 18:10:18 -070031typedef Parcel::WritableBlob WritableBlob;
32typedef Parcel::ReadableBlob ReadableBlob;
33
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070034CameraMetadata::CameraMetadata() :
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080035 mBuffer(NULL), mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070036}
37
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080038CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
39 mLocked(false)
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070040{
41 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
42}
43
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080044CameraMetadata::CameraMetadata(const CameraMetadata &other) :
45 mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070046 mBuffer = clone_camera_metadata(other.mBuffer);
47}
48
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080049CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
50 mBuffer(NULL), mLocked(false) {
Igor Murashkin7efa5202013-02-13 15:53:56 -080051 acquire(buffer);
52}
53
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070054CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
55 return operator=(other.mBuffer);
56}
57
58CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080059 if (mLocked) {
60 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
61 return *this;
62 }
63
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070064 if (CC_LIKELY(buffer != mBuffer)) {
65 camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
66 clear();
67 mBuffer = newBuffer;
68 }
69 return *this;
70}
71
72CameraMetadata::~CameraMetadata() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080073 mLocked = false;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070074 clear();
75}
76
Yin-Chia Yeh54298b32015-03-24 16:51:41 -070077const camera_metadata_t* CameraMetadata::getAndLock() const {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080078 mLocked = true;
79 return mBuffer;
80}
81
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080082status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080083 if (!mLocked) {
84 ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
85 return INVALID_OPERATION;
86 }
87 if (buffer != mBuffer) {
88 ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
89 __FUNCTION__);
90 return BAD_VALUE;
91 }
92 mLocked = false;
93 return OK;
94}
95
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070096camera_metadata_t* CameraMetadata::release() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080097 if (mLocked) {
98 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
99 return NULL;
100 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700101 camera_metadata_t *released = mBuffer;
102 mBuffer = NULL;
103 return released;
104}
105
106void CameraMetadata::clear() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800107 if (mLocked) {
108 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
109 return;
110 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700111 if (mBuffer) {
112 free_camera_metadata(mBuffer);
113 mBuffer = NULL;
114 }
115}
116
117void CameraMetadata::acquire(camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800118 if (mLocked) {
119 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
120 return;
121 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700122 clear();
123 mBuffer = buffer;
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700124
125 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
126 "%s: Failed to validate metadata structure %p",
127 __FUNCTION__, buffer);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700128}
129
130void CameraMetadata::acquire(CameraMetadata &other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800131 if (mLocked) {
132 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
133 return;
134 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700135 acquire(other.release());
136}
137
138status_t CameraMetadata::append(const CameraMetadata &other) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700139 return append(other.mBuffer);
140}
141
142status_t CameraMetadata::append(const camera_metadata_t* other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800143 if (mLocked) {
144 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
145 return INVALID_OPERATION;
146 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700147 size_t extraEntries = get_camera_metadata_entry_count(other);
148 size_t extraData = get_camera_metadata_data_count(other);
149 resizeIfNeeded(extraEntries, extraData);
150
151 return append_camera_metadata(mBuffer, other);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700152}
153
154size_t CameraMetadata::entryCount() const {
155 return (mBuffer == NULL) ? 0 :
156 get_camera_metadata_entry_count(mBuffer);
157}
158
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700159bool CameraMetadata::isEmpty() const {
160 return entryCount() == 0;
161}
162
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700163status_t CameraMetadata::sort() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800164 if (mLocked) {
165 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
166 return INVALID_OPERATION;
167 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700168 return sort_camera_metadata(mBuffer);
169}
170
171status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000172 int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700173 if ( CC_UNLIKELY(tagType == -1)) {
174 ALOGE("Update metadata entry: Unknown tag %d", tag);
175 return INVALID_OPERATION;
176 }
177 if ( CC_UNLIKELY(tagType != expectedType) ) {
178 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
179 "got type %s data instead ",
Emilian Peev71c73a22017-03-21 16:35:51 +0000180 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700181 camera_metadata_type_names[tagType],
182 camera_metadata_type_names[expectedType]);
183 return INVALID_OPERATION;
184 }
185 return OK;
186}
187
188status_t CameraMetadata::update(uint32_t tag,
189 const int32_t *data, size_t data_count) {
190 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800191 if (mLocked) {
192 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
193 return INVALID_OPERATION;
194 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700195 if ( (res = checkType(tag, TYPE_INT32)) != OK) {
196 return res;
197 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800198 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700199}
200
201status_t CameraMetadata::update(uint32_t tag,
202 const uint8_t *data, size_t data_count) {
203 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800204 if (mLocked) {
205 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
206 return INVALID_OPERATION;
207 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700208 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
209 return res;
210 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800211 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700212}
213
214status_t CameraMetadata::update(uint32_t tag,
215 const float *data, size_t data_count) {
216 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800217 if (mLocked) {
218 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
219 return INVALID_OPERATION;
220 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700221 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
222 return res;
223 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800224 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700225}
226
227status_t CameraMetadata::update(uint32_t tag,
228 const int64_t *data, size_t data_count) {
229 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800230 if (mLocked) {
231 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
232 return INVALID_OPERATION;
233 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700234 if ( (res = checkType(tag, TYPE_INT64)) != OK) {
235 return res;
236 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800237 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700238}
239
240status_t CameraMetadata::update(uint32_t tag,
241 const double *data, size_t data_count) {
242 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800243 if (mLocked) {
244 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
245 return INVALID_OPERATION;
246 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700247 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
248 return res;
249 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800250 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700251}
252
253status_t CameraMetadata::update(uint32_t tag,
254 const camera_metadata_rational_t *data, size_t data_count) {
255 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800256 if (mLocked) {
257 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
258 return INVALID_OPERATION;
259 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700260 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
261 return res;
262 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800263 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700264}
265
266status_t CameraMetadata::update(uint32_t tag,
267 const String8 &string) {
268 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800269 if (mLocked) {
270 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
271 return INVALID_OPERATION;
272 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700273 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
274 return res;
275 }
Zhijun He7595c472014-03-27 16:46:15 -0700276 // string.size() doesn't count the null termination character.
277 return updateImpl(tag, (const void*)string.string(), string.size() + 1);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700278}
279
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700280status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
281 status_t res;
282 if (mLocked) {
283 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
284 return INVALID_OPERATION;
285 }
286 if ( (res = checkType(entry.tag, entry.type)) != OK) {
287 return res;
288 }
289 return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
290}
291
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800292status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700293 size_t data_count) {
294 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800295 if (mLocked) {
296 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
297 return INVALID_OPERATION;
298 }
Emilian Peev71c73a22017-03-21 16:35:51 +0000299 int type = get_local_camera_metadata_tag_type(tag, mBuffer);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700300 if (type == -1) {
301 ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
302 return BAD_VALUE;
303 }
Eino-Ville Talvalae2b60c82015-07-17 16:21:44 -0700304 // Safety check - ensure that data isn't pointing to this metadata, since
305 // that would get invalidated if a resize is needed
306 size_t bufferSize = get_camera_metadata_size(mBuffer);
307 uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
308 uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
309 if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
310 ALOGE("%s: Update attempted with data from the same metadata buffer!",
311 __FUNCTION__);
312 return INVALID_OPERATION;
313 }
314
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700315 size_t data_size = calculate_camera_metadata_entry_data_size(type,
316 data_count);
317
318 res = resizeIfNeeded(1, data_size);
319
320 if (res == OK) {
321 camera_metadata_entry_t entry;
322 res = find_camera_metadata_entry(mBuffer, tag, &entry);
323 if (res == NAME_NOT_FOUND) {
324 res = add_camera_metadata_entry(mBuffer,
325 tag, data, data_count);
326 } else if (res == OK) {
327 res = update_camera_metadata_entry(mBuffer,
328 entry.index, data, data_count, NULL);
329 }
330 }
331
332 if (res != OK) {
333 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
Emilian Peev71c73a22017-03-21 16:35:51 +0000334 __FUNCTION__, get_local_camera_metadata_section_name(tag, mBuffer),
335 get_local_camera_metadata_tag_name(tag, mBuffer), tag,
336 strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700337 }
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700338
339 IF_ALOGV() {
340 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
341 OK,
342
343 "%s: Failed to validate metadata structure after update %p",
344 __FUNCTION__, mBuffer);
345 }
346
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700347 return res;
348}
349
Igor Murashkinfc42642a2013-02-13 18:23:39 -0800350bool CameraMetadata::exists(uint32_t tag) const {
351 camera_metadata_ro_entry entry;
352 return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
353}
354
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700355camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
356 status_t res;
357 camera_metadata_entry entry;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800358 if (mLocked) {
359 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
360 entry.count = 0;
361 return entry;
362 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700363 res = find_camera_metadata_entry(mBuffer, tag, &entry);
364 if (CC_UNLIKELY( res != OK )) {
365 entry.count = 0;
366 entry.data.u8 = NULL;
367 }
368 return entry;
369}
370
371camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
372 status_t res;
373 camera_metadata_ro_entry entry;
374 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
375 if (CC_UNLIKELY( res != OK )) {
376 entry.count = 0;
377 entry.data.u8 = NULL;
378 }
379 return entry;
380}
381
382status_t CameraMetadata::erase(uint32_t tag) {
383 camera_metadata_entry_t entry;
384 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800385 if (mLocked) {
386 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
387 return INVALID_OPERATION;
388 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700389 res = find_camera_metadata_entry(mBuffer, tag, &entry);
390 if (res == NAME_NOT_FOUND) {
391 return OK;
392 } else if (res != OK) {
393 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
394 __FUNCTION__,
Emilian Peev71c73a22017-03-21 16:35:51 +0000395 get_local_camera_metadata_section_name(tag, mBuffer),
396 get_local_camera_metadata_tag_name(tag, mBuffer),
397 tag, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700398 return res;
399 }
400 res = delete_camera_metadata_entry(mBuffer, entry.index);
401 if (res != OK) {
402 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
403 __FUNCTION__,
Emilian Peev71c73a22017-03-21 16:35:51 +0000404 get_local_camera_metadata_section_name(tag, mBuffer),
405 get_local_camera_metadata_tag_name(tag, mBuffer),
406 tag, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700407 }
408 return res;
409}
410
Emilian Peeve20c6372018-08-14 18:45:53 +0100411status_t CameraMetadata::removePermissionEntries(metadata_vendor_id_t vendorId,
412 std::vector<int32_t> *tagsRemoved) {
413 uint32_t tagCount = 0;
414 std::vector<uint32_t> tagsToRemove;
415
416 if (tagsRemoved == nullptr) {
417 return BAD_VALUE;
418 }
419
420 sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
421 if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) {
422 sp<VendorTagDescriptorCache> cache =
423 VendorTagDescriptorCache::getGlobalVendorTagCache();
424 if (cache.get()) {
425 cache->getVendorTagDescriptor(vendorId, &vTags);
426 }
427 }
428
429 if ((nullptr != vTags.get()) && (vTags->getTagCount() > 0)) {
430 tagCount = vTags->getTagCount();
431 uint32_t *vendorTags = new uint32_t[tagCount];
432 if (nullptr == vendorTags) {
433 return NO_MEMORY;
434 }
435 vTags->getTagArray(vendorTags);
436
437 tagsToRemove.reserve(tagCount);
438 tagsToRemove.insert(tagsToRemove.begin(), vendorTags, vendorTags + tagCount);
439
440 delete [] vendorTags;
441 tagCount = 0;
442 }
443
444 auto tagsNeedingPermission = get_camera_metadata_permission_needed(&tagCount);
445 if (tagCount > 0) {
446 tagsToRemove.reserve(tagsToRemove.capacity() + tagCount);
447 tagsToRemove.insert(tagsToRemove.end(), tagsNeedingPermission,
448 tagsNeedingPermission + tagCount);
449 }
450
451 tagsRemoved->reserve(tagsToRemove.size());
452 for (const auto &it : tagsToRemove) {
453 if (exists(it)) {
454 auto rc = erase(it);
455 if (NO_ERROR != rc) {
456 ALOGE("%s: Failed to erase tag: %x", __func__, it);
457 return rc;
458 }
459 tagsRemoved->push_back(it);
460 }
461 }
462
463 // Update the available characterstics accordingly
464 if (exists(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS)) {
465 std::vector<uint32_t> currentKeys;
466
467 std::sort(tagsRemoved->begin(), tagsRemoved->end());
468 auto keys = find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
469 currentKeys.reserve(keys.count);
470 currentKeys.insert(currentKeys.end(), keys.data.i32, keys.data.i32 + keys.count);
471 std::sort(currentKeys.begin(), currentKeys.end());
472
473 std::vector<int32_t> newKeys(keys.count);
474 auto end = std::set_difference(currentKeys.begin(), currentKeys.end(), tagsRemoved->begin(),
475 tagsRemoved->end(), newKeys.begin());
476 newKeys.resize(end - newKeys.begin());
477
478 update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, newKeys.data(), newKeys.size());
479 }
480
481 return NO_ERROR;
482}
483
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700484void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
485 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
486}
487
488status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
489 if (mBuffer == NULL) {
490 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
491 if (mBuffer == NULL) {
492 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
493 return NO_MEMORY;
494 }
495 } else {
496 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
497 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
498 size_t newEntryCount = currentEntryCount +
499 extraEntries;
500 newEntryCount = (newEntryCount > currentEntryCap) ?
501 newEntryCount * 2 : currentEntryCap;
502
503 size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
504 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
505 size_t newDataCount = currentDataCount +
506 extraData;
507 newDataCount = (newDataCount > currentDataCap) ?
508 newDataCount * 2 : currentDataCap;
509
510 if (newEntryCount > currentEntryCap ||
511 newDataCount > currentDataCap) {
512 camera_metadata_t *oldBuffer = mBuffer;
513 mBuffer = allocate_camera_metadata(newEntryCount,
514 newDataCount);
515 if (mBuffer == NULL) {
516 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
517 return NO_MEMORY;
518 }
519 append_camera_metadata(mBuffer, oldBuffer);
520 free_camera_metadata(oldBuffer);
521 }
522 }
523 return OK;
524}
525
Igor Murashkine7ee7632013-06-11 18:10:18 -0700526status_t CameraMetadata::readFromParcel(const Parcel& data,
527 camera_metadata_t** out) {
528
529 status_t err = OK;
530
531 camera_metadata_t* metadata = NULL;
532
533 if (out) {
534 *out = NULL;
535 }
536
Zhijun He146aed12013-12-05 07:46:51 -0800537 // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
538 // arg0 = blobSize (int32)
539 int32_t blobSizeTmp = -1;
540 if ((err = data.readInt32(&blobSizeTmp)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700541 ALOGE("%s: Failed to read metadata size (error %d %s)",
542 __FUNCTION__, err, strerror(-err));
543 return err;
544 }
Zhijun He146aed12013-12-05 07:46:51 -0800545 const size_t blobSize = static_cast<size_t>(blobSizeTmp);
546 const size_t alignment = get_camera_metadata_alignment();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700547
Zhijun He146aed12013-12-05 07:46:51 -0800548 // Special case: zero blob size means zero sized (NULL) metadata.
549 if (blobSize == 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700550 ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
551 return OK;
552 }
553
Zhijun He146aed12013-12-05 07:46:51 -0800554 if (blobSize <= alignment) {
555 ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
556 __FUNCTION__, blobSize, alignment);
557 return BAD_VALUE;
558 }
559
560 const size_t metadataSize = blobSize - alignment;
561
562 // NOTE: this doesn't make sense to me. shouldn't the blob
Igor Murashkine7ee7632013-06-11 18:10:18 -0700563 // know how big it is? why do we have to specify the size
564 // to Parcel::readBlob ?
Igor Murashkine7ee7632013-06-11 18:10:18 -0700565 ReadableBlob blob;
566 // arg1 = metadata (blob)
567 do {
Zhijun He146aed12013-12-05 07:46:51 -0800568 if ((err = data.readBlob(blobSize, &blob)) != OK) {
569 ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
Igor Murashkine7ee7632013-06-11 18:10:18 -0700570 " serialization bug. Error %d %s",
Zhijun He146aed12013-12-05 07:46:51 -0800571 __FUNCTION__, blobSize, err, strerror(-err));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700572 break;
573 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700574
Zhijun He146aed12013-12-05 07:46:51 -0800575 // arg2 = offset (blob)
576 // Must be after blob since we don't know offset until after writeBlob.
577 int32_t offsetTmp;
578 if ((err = data.readInt32(&offsetTmp)) != OK) {
579 ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
580 __FUNCTION__, err, strerror(-err));
581 break;
582 }
583 const size_t offset = static_cast<size_t>(offsetTmp);
584 if (offset >= alignment) {
585 ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
586 __FUNCTION__, blobSize, alignment);
587 err = BAD_VALUE;
588 break;
589 }
590
591 const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
592 const camera_metadata_t* tmp =
593 reinterpret_cast<const camera_metadata_t*>(metadataStart);
594 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
595 __FUNCTION__, alignment, tmp, offset);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700596 metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
597 if (metadata == NULL) {
598 // We consider that allocation only fails if the validation
599 // also failed, therefore the readFromParcel was a failure.
Zhijun He146aed12013-12-05 07:46:51 -0800600 ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700601 err = BAD_VALUE;
602 }
603 } while(0);
604 blob.release();
605
606 if (out) {
607 ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
608 *out = metadata;
609 } else if (metadata != NULL) {
610 ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
611 free_camera_metadata(metadata);
612 }
613
614 return err;
615}
616
617status_t CameraMetadata::writeToParcel(Parcel& data,
618 const camera_metadata_t* metadata) {
619 status_t res = OK;
620
Zhijun He146aed12013-12-05 07:46:51 -0800621 /**
622 * Below is the camera metadata parcel layout:
623 *
624 * |--------------------------------------------|
625 * | arg0: blobSize |
626 * | (length = 4) |
627 * |--------------------------------------------|<--Skip the rest if blobSize == 0.
628 * | |
629 * | |
630 * | arg1: blob |
631 * | (length = variable, see arg1 layout below) |
632 * | |
633 * | |
634 * |--------------------------------------------|
635 * | arg2: offset |
636 * | (length = 4) |
637 * |--------------------------------------------|
638 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700639
Zhijun He146aed12013-12-05 07:46:51 -0800640 // arg0 = blobSize (int32)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700641 if (metadata == NULL) {
Zhijun He146aed12013-12-05 07:46:51 -0800642 // Write zero blobSize for null metadata.
Igor Murashkine7ee7632013-06-11 18:10:18 -0700643 return data.writeInt32(0);
644 }
645
Zhijun He146aed12013-12-05 07:46:51 -0800646 /**
647 * Always make the blob size sufficiently larger, as we need put alignment
648 * padding and metadata into the blob. Since we don't know the alignment
649 * offset before writeBlob. Then write the metadata to aligned offset.
650 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700651 const size_t metadataSize = get_camera_metadata_compact_size(metadata);
Zhijun He146aed12013-12-05 07:46:51 -0800652 const size_t alignment = get_camera_metadata_alignment();
653 const size_t blobSize = metadataSize + alignment;
654 res = data.writeInt32(static_cast<int32_t>(blobSize));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700655 if (res != OK) {
656 return res;
657 }
658
Zhijun He146aed12013-12-05 07:46:51 -0800659 size_t offset = 0;
660 /**
661 * arg1 = metadata (blob).
662 *
663 * The blob size is the sum of front padding size, metadata size and back padding
664 * size, which is equal to metadataSize + alignment.
665 *
666 * The blob layout is:
667 * |------------------------------------|<----Start address of the blob (unaligned).
668 * | front padding |
669 * | (size = offset) |
670 * |------------------------------------|<----Aligned start address of metadata.
671 * | |
672 * | |
673 * | metadata |
674 * | (size = metadataSize) |
675 * | |
676 * | |
677 * |------------------------------------|
678 * | back padding |
679 * | (size = alignment - offset) |
680 * |------------------------------------|<----End address of blob.
681 * (Blob start address + blob size).
682 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700683 WritableBlob blob;
684 do {
Jeff Browne8df5392015-06-05 15:10:44 -0700685 res = data.writeBlob(blobSize, false, &blob);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700686 if (res != OK) {
687 break;
688 }
Zhijun He146aed12013-12-05 07:46:51 -0800689 const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
690 offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
691 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
Mark Salyzyn1a93f0c2014-06-09 16:34:58 -0700692 __FUNCTION__, alignment,
693 reinterpret_cast<const void *>(metadataStart), offset);
Zhijun He146aed12013-12-05 07:46:51 -0800694 copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700695
696 // Not too big of a problem since receiving side does hard validation
697 // Don't check the size since the compact size could be larger
698 if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
699 ALOGW("%s: Failed to validate metadata %p before writing blob",
700 __FUNCTION__, metadata);
701 }
702
703 } while(false);
704 blob.release();
705
Zhijun He146aed12013-12-05 07:46:51 -0800706 // arg2 = offset (int32)
707 res = data.writeInt32(static_cast<int32_t>(offset));
708
Igor Murashkine7ee7632013-06-11 18:10:18 -0700709 return res;
710}
711
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800712status_t CameraMetadata::readFromParcel(const Parcel *parcel) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700713
714 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
715
716 status_t res = OK;
717
718 if (parcel == NULL) {
719 ALOGE("%s: parcel is null", __FUNCTION__);
720 return BAD_VALUE;
721 }
722
723 if (mLocked) {
724 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
725 return INVALID_OPERATION;
726 }
727
728 camera_metadata *buffer = NULL;
729 // TODO: reading should return a status code, in case validation fails
730 res = CameraMetadata::readFromParcel(*parcel, &buffer);
731
732 if (res != NO_ERROR) {
733 ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
734 __FUNCTION__);
735 return res;
736 }
737
738 clear();
739 mBuffer = buffer;
740
741 return OK;
742}
743
744status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
745
746 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
747
748 if (parcel == NULL) {
749 ALOGE("%s: parcel is null", __FUNCTION__);
750 return BAD_VALUE;
751 }
752
753 return CameraMetadata::writeToParcel(*parcel, mBuffer);
754}
755
756void CameraMetadata::swap(CameraMetadata& other) {
757 if (mLocked) {
758 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
759 return;
760 } else if (other.mLocked) {
761 ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
762 return;
763 }
764
765 camera_metadata* thisBuf = mBuffer;
766 camera_metadata* otherBuf = other.mBuffer;
767
768 other.mBuffer = thisBuf;
769 mBuffer = otherBuf;
770}
771
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700772status_t CameraMetadata::getTagFromName(const char *name,
773 const VendorTagDescriptor* vTags, uint32_t *tag) {
774
775 if (name == nullptr || tag == nullptr) return BAD_VALUE;
776
777 size_t nameLength = strlen(name);
778
779 const SortedVector<String8> *vendorSections;
780 size_t vendorSectionCount = 0;
781
782 if (vTags != NULL) {
783 vendorSections = vTags->getAllSectionNames();
784 vendorSectionCount = vendorSections->size();
785 }
786
787 // First, find the section by the longest string match
788 const char *section = NULL;
789 size_t sectionIndex = 0;
790 size_t sectionLength = 0;
791 size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
792 for (size_t i = 0; i < totalSectionCount; ++i) {
793
794 const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
795 (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
796
797 ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
798
799 if (strstr(name, str) == name) { // name begins with the section name
800 size_t strLength = strlen(str);
801
802 ALOGV("%s: Name begins with section name", __FUNCTION__);
803
804 // section name is the longest we've found so far
805 if (section == NULL || sectionLength < strLength) {
806 section = str;
807 sectionIndex = i;
808 sectionLength = strLength;
809
810 ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
811 }
812 }
813 }
814
815 // TODO: Make above get_camera_metadata_section_from_name ?
816
817 if (section == NULL) {
818 return NAME_NOT_FOUND;
819 } else {
820 ALOGV("%s: Found matched section '%s' (%zu)",
821 __FUNCTION__, section, sectionIndex);
822 }
823
824 // Get the tag name component of the name
825 const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
826 if (sectionLength + 1 >= nameLength) {
827 return BAD_VALUE;
828 }
829
830 // Match rest of name against the tag names in that section only
831 uint32_t candidateTag = 0;
832 if (sectionIndex < ANDROID_SECTION_COUNT) {
833 // Match built-in tags (typically android.*)
834 uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
835 tagBegin = camera_metadata_section_bounds[sectionIndex][0];
836 tagEnd = camera_metadata_section_bounds[sectionIndex][1];
837
838 for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
839 const char *tagName = get_camera_metadata_tag_name(candidateTag);
840
841 if (strcmp(nameTagName, tagName) == 0) {
842 ALOGV("%s: Found matched tag '%s' (%d)",
843 __FUNCTION__, tagName, candidateTag);
844 break;
845 }
846 }
847
848 if (candidateTag == tagEnd) {
849 return NAME_NOT_FOUND;
850 }
851 } else if (vTags != NULL) {
852 // Match vendor tags (typically com.*)
853 const String8 sectionName(section);
854 const String8 tagName(nameTagName);
855
856 status_t res = OK;
857 if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
858 return NAME_NOT_FOUND;
859 }
860 }
861
862 *tag = candidateTag;
863 return OK;
864}
865
866
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700867}; // namespace android