blob: 373b94e8cda4d924e68300576a244a8ee0917074 [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>
25#include <camera/VendorTagDescriptor.h>
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070026
27namespace android {
28
Zhijun He146aed12013-12-05 07:46:51 -080029#define ALIGN_TO(val, alignment) \
30 (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
31
Igor Murashkine7ee7632013-06-11 18:10:18 -070032typedef Parcel::WritableBlob WritableBlob;
33typedef Parcel::ReadableBlob ReadableBlob;
34
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070035CameraMetadata::CameraMetadata() :
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080036 mBuffer(NULL), mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070037}
38
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080039CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
40 mLocked(false)
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070041{
42 mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
43}
44
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080045CameraMetadata::CameraMetadata(const CameraMetadata &other) :
46 mLocked(false) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070047 mBuffer = clone_camera_metadata(other.mBuffer);
48}
49
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080050CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
51 mBuffer(NULL), mLocked(false) {
Igor Murashkin7efa5202013-02-13 15:53:56 -080052 acquire(buffer);
53}
54
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070055CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
56 return operator=(other.mBuffer);
57}
58
59CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080060 if (mLocked) {
61 ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
62 return *this;
63 }
64
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070065 if (CC_LIKELY(buffer != mBuffer)) {
66 camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
67 clear();
68 mBuffer = newBuffer;
69 }
70 return *this;
71}
72
73CameraMetadata::~CameraMetadata() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080074 mLocked = false;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070075 clear();
76}
77
Yin-Chia Yeh54298b32015-03-24 16:51:41 -070078const camera_metadata_t* CameraMetadata::getAndLock() const {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080079 mLocked = true;
80 return mBuffer;
81}
82
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -080083status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080084 if (!mLocked) {
85 ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
86 return INVALID_OPERATION;
87 }
88 if (buffer != mBuffer) {
89 ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
90 __FUNCTION__);
91 return BAD_VALUE;
92 }
93 mLocked = false;
94 return OK;
95}
96
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -070097camera_metadata_t* CameraMetadata::release() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080098 if (mLocked) {
99 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
100 return NULL;
101 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700102 camera_metadata_t *released = mBuffer;
103 mBuffer = NULL;
104 return released;
105}
106
107void CameraMetadata::clear() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800108 if (mLocked) {
109 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
110 return;
111 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700112 if (mBuffer) {
113 free_camera_metadata(mBuffer);
114 mBuffer = NULL;
115 }
116}
117
118void CameraMetadata::acquire(camera_metadata_t *buffer) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800119 if (mLocked) {
120 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
121 return;
122 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700123 clear();
124 mBuffer = buffer;
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700125
126 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
127 "%s: Failed to validate metadata structure %p",
128 __FUNCTION__, buffer);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700129}
130
131void CameraMetadata::acquire(CameraMetadata &other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800132 if (mLocked) {
133 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
134 return;
135 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700136 acquire(other.release());
137}
138
139status_t CameraMetadata::append(const CameraMetadata &other) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700140 return append(other.mBuffer);
141}
142
143status_t CameraMetadata::append(const camera_metadata_t* other) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800144 if (mLocked) {
145 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
146 return INVALID_OPERATION;
147 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700148 size_t extraEntries = get_camera_metadata_entry_count(other);
149 size_t extraData = get_camera_metadata_data_count(other);
150 resizeIfNeeded(extraEntries, extraData);
151
152 return append_camera_metadata(mBuffer, other);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700153}
154
155size_t CameraMetadata::entryCount() const {
156 return (mBuffer == NULL) ? 0 :
157 get_camera_metadata_entry_count(mBuffer);
158}
159
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700160bool CameraMetadata::isEmpty() const {
161 return entryCount() == 0;
162}
163
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700164status_t CameraMetadata::sort() {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800165 if (mLocked) {
166 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
167 return INVALID_OPERATION;
168 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700169 return sort_camera_metadata(mBuffer);
170}
171
172status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
173 int tagType = get_camera_metadata_tag_type(tag);
174 if ( CC_UNLIKELY(tagType == -1)) {
175 ALOGE("Update metadata entry: Unknown tag %d", tag);
176 return INVALID_OPERATION;
177 }
178 if ( CC_UNLIKELY(tagType != expectedType) ) {
179 ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
180 "got type %s data instead ",
181 get_camera_metadata_tag_name(tag), tag,
182 camera_metadata_type_names[tagType],
183 camera_metadata_type_names[expectedType]);
184 return INVALID_OPERATION;
185 }
186 return OK;
187}
188
189status_t CameraMetadata::update(uint32_t tag,
190 const int32_t *data, size_t data_count) {
191 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800192 if (mLocked) {
193 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
194 return INVALID_OPERATION;
195 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700196 if ( (res = checkType(tag, TYPE_INT32)) != OK) {
197 return res;
198 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800199 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700200}
201
202status_t CameraMetadata::update(uint32_t tag,
203 const uint8_t *data, size_t data_count) {
204 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800205 if (mLocked) {
206 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
207 return INVALID_OPERATION;
208 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700209 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
210 return res;
211 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800212 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700213}
214
215status_t CameraMetadata::update(uint32_t tag,
216 const float *data, size_t data_count) {
217 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800218 if (mLocked) {
219 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
220 return INVALID_OPERATION;
221 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700222 if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
223 return res;
224 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800225 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700226}
227
228status_t CameraMetadata::update(uint32_t tag,
229 const int64_t *data, size_t data_count) {
230 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800231 if (mLocked) {
232 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
233 return INVALID_OPERATION;
234 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700235 if ( (res = checkType(tag, TYPE_INT64)) != OK) {
236 return res;
237 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800238 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700239}
240
241status_t CameraMetadata::update(uint32_t tag,
242 const double *data, size_t data_count) {
243 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800244 if (mLocked) {
245 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
246 return INVALID_OPERATION;
247 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700248 if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
249 return res;
250 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800251 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700252}
253
254status_t CameraMetadata::update(uint32_t tag,
255 const camera_metadata_rational_t *data, size_t data_count) {
256 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800257 if (mLocked) {
258 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
259 return INVALID_OPERATION;
260 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700261 if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
262 return res;
263 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800264 return updateImpl(tag, (const void*)data, data_count);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700265}
266
267status_t CameraMetadata::update(uint32_t tag,
268 const String8 &string) {
269 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800270 if (mLocked) {
271 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
272 return INVALID_OPERATION;
273 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700274 if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
275 return res;
276 }
Zhijun He7595c472014-03-27 16:46:15 -0700277 // string.size() doesn't count the null termination character.
278 return updateImpl(tag, (const void*)string.string(), string.size() + 1);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700279}
280
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700281status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
282 status_t res;
283 if (mLocked) {
284 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
285 return INVALID_OPERATION;
286 }
287 if ( (res = checkType(entry.tag, entry.type)) != OK) {
288 return res;
289 }
290 return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
291}
292
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800293status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700294 size_t data_count) {
295 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800296 if (mLocked) {
297 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
298 return INVALID_OPERATION;
299 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700300 int type = get_camera_metadata_tag_type(tag);
301 if (type == -1) {
302 ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
303 return BAD_VALUE;
304 }
Eino-Ville Talvalae2b60c82015-07-17 16:21:44 -0700305 // Safety check - ensure that data isn't pointing to this metadata, since
306 // that would get invalidated if a resize is needed
307 size_t bufferSize = get_camera_metadata_size(mBuffer);
308 uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
309 uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
310 if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
311 ALOGE("%s: Update attempted with data from the same metadata buffer!",
312 __FUNCTION__);
313 return INVALID_OPERATION;
314 }
315
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700316 size_t data_size = calculate_camera_metadata_entry_data_size(type,
317 data_count);
318
319 res = resizeIfNeeded(1, data_size);
320
321 if (res == OK) {
322 camera_metadata_entry_t entry;
323 res = find_camera_metadata_entry(mBuffer, tag, &entry);
324 if (res == NAME_NOT_FOUND) {
325 res = add_camera_metadata_entry(mBuffer,
326 tag, data, data_count);
327 } else if (res == OK) {
328 res = update_camera_metadata_entry(mBuffer,
329 entry.index, data, data_count, NULL);
330 }
331 }
332
333 if (res != OK) {
334 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
335 __FUNCTION__, get_camera_metadata_section_name(tag),
336 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
337 }
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__,
395 get_camera_metadata_section_name(tag),
396 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
397 return res;
398 }
399 res = delete_camera_metadata_entry(mBuffer, entry.index);
400 if (res != OK) {
401 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
402 __FUNCTION__,
403 get_camera_metadata_section_name(tag),
404 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
405 }
406 return res;
407}
408
409void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
410 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
411}
412
413status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
414 if (mBuffer == NULL) {
415 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
416 if (mBuffer == NULL) {
417 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
418 return NO_MEMORY;
419 }
420 } else {
421 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
422 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
423 size_t newEntryCount = currentEntryCount +
424 extraEntries;
425 newEntryCount = (newEntryCount > currentEntryCap) ?
426 newEntryCount * 2 : currentEntryCap;
427
428 size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
429 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
430 size_t newDataCount = currentDataCount +
431 extraData;
432 newDataCount = (newDataCount > currentDataCap) ?
433 newDataCount * 2 : currentDataCap;
434
435 if (newEntryCount > currentEntryCap ||
436 newDataCount > currentDataCap) {
437 camera_metadata_t *oldBuffer = mBuffer;
438 mBuffer = allocate_camera_metadata(newEntryCount,
439 newDataCount);
440 if (mBuffer == NULL) {
441 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
442 return NO_MEMORY;
443 }
444 append_camera_metadata(mBuffer, oldBuffer);
445 free_camera_metadata(oldBuffer);
446 }
447 }
448 return OK;
449}
450
Igor Murashkine7ee7632013-06-11 18:10:18 -0700451status_t CameraMetadata::readFromParcel(const Parcel& data,
452 camera_metadata_t** out) {
453
454 status_t err = OK;
455
456 camera_metadata_t* metadata = NULL;
457
458 if (out) {
459 *out = NULL;
460 }
461
Zhijun He146aed12013-12-05 07:46:51 -0800462 // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
463 // arg0 = blobSize (int32)
464 int32_t blobSizeTmp = -1;
465 if ((err = data.readInt32(&blobSizeTmp)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700466 ALOGE("%s: Failed to read metadata size (error %d %s)",
467 __FUNCTION__, err, strerror(-err));
468 return err;
469 }
Zhijun He146aed12013-12-05 07:46:51 -0800470 const size_t blobSize = static_cast<size_t>(blobSizeTmp);
471 const size_t alignment = get_camera_metadata_alignment();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700472
Zhijun He146aed12013-12-05 07:46:51 -0800473 // Special case: zero blob size means zero sized (NULL) metadata.
474 if (blobSize == 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700475 ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
476 return OK;
477 }
478
Zhijun He146aed12013-12-05 07:46:51 -0800479 if (blobSize <= alignment) {
480 ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
481 __FUNCTION__, blobSize, alignment);
482 return BAD_VALUE;
483 }
484
485 const size_t metadataSize = blobSize - alignment;
486
487 // NOTE: this doesn't make sense to me. shouldn't the blob
Igor Murashkine7ee7632013-06-11 18:10:18 -0700488 // know how big it is? why do we have to specify the size
489 // to Parcel::readBlob ?
Igor Murashkine7ee7632013-06-11 18:10:18 -0700490 ReadableBlob blob;
491 // arg1 = metadata (blob)
492 do {
Zhijun He146aed12013-12-05 07:46:51 -0800493 if ((err = data.readBlob(blobSize, &blob)) != OK) {
494 ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
Igor Murashkine7ee7632013-06-11 18:10:18 -0700495 " serialization bug. Error %d %s",
Zhijun He146aed12013-12-05 07:46:51 -0800496 __FUNCTION__, blobSize, err, strerror(-err));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700497 break;
498 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700499
Zhijun He146aed12013-12-05 07:46:51 -0800500 // arg2 = offset (blob)
501 // Must be after blob since we don't know offset until after writeBlob.
502 int32_t offsetTmp;
503 if ((err = data.readInt32(&offsetTmp)) != OK) {
504 ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
505 __FUNCTION__, err, strerror(-err));
506 break;
507 }
508 const size_t offset = static_cast<size_t>(offsetTmp);
509 if (offset >= alignment) {
510 ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
511 __FUNCTION__, blobSize, alignment);
512 err = BAD_VALUE;
513 break;
514 }
515
516 const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
517 const camera_metadata_t* tmp =
518 reinterpret_cast<const camera_metadata_t*>(metadataStart);
519 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
520 __FUNCTION__, alignment, tmp, offset);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700521 metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
522 if (metadata == NULL) {
523 // We consider that allocation only fails if the validation
524 // also failed, therefore the readFromParcel was a failure.
Zhijun He146aed12013-12-05 07:46:51 -0800525 ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700526 err = BAD_VALUE;
527 }
528 } while(0);
529 blob.release();
530
531 if (out) {
532 ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
533 *out = metadata;
534 } else if (metadata != NULL) {
535 ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
536 free_camera_metadata(metadata);
537 }
538
539 return err;
540}
541
542status_t CameraMetadata::writeToParcel(Parcel& data,
543 const camera_metadata_t* metadata) {
544 status_t res = OK;
545
Zhijun He146aed12013-12-05 07:46:51 -0800546 /**
547 * Below is the camera metadata parcel layout:
548 *
549 * |--------------------------------------------|
550 * | arg0: blobSize |
551 * | (length = 4) |
552 * |--------------------------------------------|<--Skip the rest if blobSize == 0.
553 * | |
554 * | |
555 * | arg1: blob |
556 * | (length = variable, see arg1 layout below) |
557 * | |
558 * | |
559 * |--------------------------------------------|
560 * | arg2: offset |
561 * | (length = 4) |
562 * |--------------------------------------------|
563 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700564
Zhijun He146aed12013-12-05 07:46:51 -0800565 // arg0 = blobSize (int32)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700566 if (metadata == NULL) {
Zhijun He146aed12013-12-05 07:46:51 -0800567 // Write zero blobSize for null metadata.
Igor Murashkine7ee7632013-06-11 18:10:18 -0700568 return data.writeInt32(0);
569 }
570
Zhijun He146aed12013-12-05 07:46:51 -0800571 /**
572 * Always make the blob size sufficiently larger, as we need put alignment
573 * padding and metadata into the blob. Since we don't know the alignment
574 * offset before writeBlob. Then write the metadata to aligned offset.
575 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700576 const size_t metadataSize = get_camera_metadata_compact_size(metadata);
Zhijun He146aed12013-12-05 07:46:51 -0800577 const size_t alignment = get_camera_metadata_alignment();
578 const size_t blobSize = metadataSize + alignment;
579 res = data.writeInt32(static_cast<int32_t>(blobSize));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700580 if (res != OK) {
581 return res;
582 }
583
Zhijun He146aed12013-12-05 07:46:51 -0800584 size_t offset = 0;
585 /**
586 * arg1 = metadata (blob).
587 *
588 * The blob size is the sum of front padding size, metadata size and back padding
589 * size, which is equal to metadataSize + alignment.
590 *
591 * The blob layout is:
592 * |------------------------------------|<----Start address of the blob (unaligned).
593 * | front padding |
594 * | (size = offset) |
595 * |------------------------------------|<----Aligned start address of metadata.
596 * | |
597 * | |
598 * | metadata |
599 * | (size = metadataSize) |
600 * | |
601 * | |
602 * |------------------------------------|
603 * | back padding |
604 * | (size = alignment - offset) |
605 * |------------------------------------|<----End address of blob.
606 * (Blob start address + blob size).
607 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700608 WritableBlob blob;
609 do {
Jeff Browne8df5392015-06-05 15:10:44 -0700610 res = data.writeBlob(blobSize, false, &blob);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700611 if (res != OK) {
612 break;
613 }
Zhijun He146aed12013-12-05 07:46:51 -0800614 const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
615 offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
616 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
Mark Salyzyn1a93f0c2014-06-09 16:34:58 -0700617 __FUNCTION__, alignment,
618 reinterpret_cast<const void *>(metadataStart), offset);
Zhijun He146aed12013-12-05 07:46:51 -0800619 copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700620
621 // Not too big of a problem since receiving side does hard validation
622 // Don't check the size since the compact size could be larger
623 if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
624 ALOGW("%s: Failed to validate metadata %p before writing blob",
625 __FUNCTION__, metadata);
626 }
627
628 } while(false);
629 blob.release();
630
Zhijun He146aed12013-12-05 07:46:51 -0800631 // arg2 = offset (int32)
632 res = data.writeInt32(static_cast<int32_t>(offset));
633
Igor Murashkine7ee7632013-06-11 18:10:18 -0700634 return res;
635}
636
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800637status_t CameraMetadata::readFromParcel(const Parcel *parcel) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700638
639 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
640
641 status_t res = OK;
642
643 if (parcel == NULL) {
644 ALOGE("%s: parcel is null", __FUNCTION__);
645 return BAD_VALUE;
646 }
647
648 if (mLocked) {
649 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
650 return INVALID_OPERATION;
651 }
652
653 camera_metadata *buffer = NULL;
654 // TODO: reading should return a status code, in case validation fails
655 res = CameraMetadata::readFromParcel(*parcel, &buffer);
656
657 if (res != NO_ERROR) {
658 ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
659 __FUNCTION__);
660 return res;
661 }
662
663 clear();
664 mBuffer = buffer;
665
666 return OK;
667}
668
669status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
670
671 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
672
673 if (parcel == NULL) {
674 ALOGE("%s: parcel is null", __FUNCTION__);
675 return BAD_VALUE;
676 }
677
678 return CameraMetadata::writeToParcel(*parcel, mBuffer);
679}
680
681void CameraMetadata::swap(CameraMetadata& other) {
682 if (mLocked) {
683 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
684 return;
685 } else if (other.mLocked) {
686 ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
687 return;
688 }
689
690 camera_metadata* thisBuf = mBuffer;
691 camera_metadata* otherBuf = other.mBuffer;
692
693 other.mBuffer = thisBuf;
694 mBuffer = otherBuf;
695}
696
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700697status_t CameraMetadata::getTagFromName(const char *name,
698 const VendorTagDescriptor* vTags, uint32_t *tag) {
699
700 if (name == nullptr || tag == nullptr) return BAD_VALUE;
701
702 size_t nameLength = strlen(name);
703
704 const SortedVector<String8> *vendorSections;
705 size_t vendorSectionCount = 0;
706
707 if (vTags != NULL) {
708 vendorSections = vTags->getAllSectionNames();
709 vendorSectionCount = vendorSections->size();
710 }
711
712 // First, find the section by the longest string match
713 const char *section = NULL;
714 size_t sectionIndex = 0;
715 size_t sectionLength = 0;
716 size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
717 for (size_t i = 0; i < totalSectionCount; ++i) {
718
719 const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
720 (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
721
722 ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
723
724 if (strstr(name, str) == name) { // name begins with the section name
725 size_t strLength = strlen(str);
726
727 ALOGV("%s: Name begins with section name", __FUNCTION__);
728
729 // section name is the longest we've found so far
730 if (section == NULL || sectionLength < strLength) {
731 section = str;
732 sectionIndex = i;
733 sectionLength = strLength;
734
735 ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
736 }
737 }
738 }
739
740 // TODO: Make above get_camera_metadata_section_from_name ?
741
742 if (section == NULL) {
743 return NAME_NOT_FOUND;
744 } else {
745 ALOGV("%s: Found matched section '%s' (%zu)",
746 __FUNCTION__, section, sectionIndex);
747 }
748
749 // Get the tag name component of the name
750 const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
751 if (sectionLength + 1 >= nameLength) {
752 return BAD_VALUE;
753 }
754
755 // Match rest of name against the tag names in that section only
756 uint32_t candidateTag = 0;
757 if (sectionIndex < ANDROID_SECTION_COUNT) {
758 // Match built-in tags (typically android.*)
759 uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
760 tagBegin = camera_metadata_section_bounds[sectionIndex][0];
761 tagEnd = camera_metadata_section_bounds[sectionIndex][1];
762
763 for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
764 const char *tagName = get_camera_metadata_tag_name(candidateTag);
765
766 if (strcmp(nameTagName, tagName) == 0) {
767 ALOGV("%s: Found matched tag '%s' (%d)",
768 __FUNCTION__, tagName, candidateTag);
769 break;
770 }
771 }
772
773 if (candidateTag == tagEnd) {
774 return NAME_NOT_FOUND;
775 }
776 } else if (vTags != NULL) {
777 // Match vendor tags (typically com.*)
778 const String8 sectionName(section);
779 const String8 tagName(nameTagName);
780
781 status_t res = OK;
782 if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
783 return NAME_NOT_FOUND;
784 }
785 }
786
787 *tag = candidateTag;
788 return OK;
789}
790
791
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700792}; // namespace android