blob: 6b726e06eba4ab742bff5d0e292b397fec5a35d0 [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 Murashkin7efa5202013-02-13 15:53:56 -080023#include <camera/CameraMetadata.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070024#include <binder/Parcel.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
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080077const camera_metadata_t* CameraMetadata::getAndLock() {
78 mLocked = true;
79 return mBuffer;
80}
81
82status_t CameraMetadata::unlock(const camera_metadata_t *buffer) {
83 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) {
172 int tagType = get_camera_metadata_tag_type(tag);
173 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 ",
180 get_camera_metadata_tag_name(tag), tag,
181 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 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800276 return updateImpl(tag, (const void*)string.string(), string.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700277}
278
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800279status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700280 size_t data_count) {
281 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800282 if (mLocked) {
283 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
284 return INVALID_OPERATION;
285 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700286 int type = get_camera_metadata_tag_type(tag);
287 if (type == -1) {
288 ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
289 return BAD_VALUE;
290 }
291 size_t data_size = calculate_camera_metadata_entry_data_size(type,
292 data_count);
293
294 res = resizeIfNeeded(1, data_size);
295
296 if (res == OK) {
297 camera_metadata_entry_t entry;
298 res = find_camera_metadata_entry(mBuffer, tag, &entry);
299 if (res == NAME_NOT_FOUND) {
300 res = add_camera_metadata_entry(mBuffer,
301 tag, data, data_count);
302 } else if (res == OK) {
303 res = update_camera_metadata_entry(mBuffer,
304 entry.index, data, data_count, NULL);
305 }
306 }
307
308 if (res != OK) {
309 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
310 __FUNCTION__, get_camera_metadata_section_name(tag),
311 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
312 }
Igor Murashkine2d1e3d2013-04-30 18:18:06 -0700313
314 IF_ALOGV() {
315 ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
316 OK,
317
318 "%s: Failed to validate metadata structure after update %p",
319 __FUNCTION__, mBuffer);
320 }
321
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700322 return res;
323}
324
Igor Murashkinfc42642a2013-02-13 18:23:39 -0800325bool CameraMetadata::exists(uint32_t tag) const {
326 camera_metadata_ro_entry entry;
327 return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
328}
329
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700330camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
331 status_t res;
332 camera_metadata_entry entry;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800333 if (mLocked) {
334 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
335 entry.count = 0;
336 return entry;
337 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700338 res = find_camera_metadata_entry(mBuffer, tag, &entry);
339 if (CC_UNLIKELY( res != OK )) {
340 entry.count = 0;
341 entry.data.u8 = NULL;
342 }
343 return entry;
344}
345
346camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
347 status_t res;
348 camera_metadata_ro_entry entry;
349 res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
350 if (CC_UNLIKELY( res != OK )) {
351 entry.count = 0;
352 entry.data.u8 = NULL;
353 }
354 return entry;
355}
356
357status_t CameraMetadata::erase(uint32_t tag) {
358 camera_metadata_entry_t entry;
359 status_t res;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800360 if (mLocked) {
361 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
362 return INVALID_OPERATION;
363 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700364 res = find_camera_metadata_entry(mBuffer, tag, &entry);
365 if (res == NAME_NOT_FOUND) {
366 return OK;
367 } else if (res != OK) {
368 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
369 __FUNCTION__,
370 get_camera_metadata_section_name(tag),
371 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
372 return res;
373 }
374 res = delete_camera_metadata_entry(mBuffer, entry.index);
375 if (res != OK) {
376 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
377 __FUNCTION__,
378 get_camera_metadata_section_name(tag),
379 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
380 }
381 return res;
382}
383
384void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
385 dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
386}
387
388status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
389 if (mBuffer == NULL) {
390 mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
391 if (mBuffer == NULL) {
392 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
393 return NO_MEMORY;
394 }
395 } else {
396 size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
397 size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
398 size_t newEntryCount = currentEntryCount +
399 extraEntries;
400 newEntryCount = (newEntryCount > currentEntryCap) ?
401 newEntryCount * 2 : currentEntryCap;
402
403 size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
404 size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
405 size_t newDataCount = currentDataCount +
406 extraData;
407 newDataCount = (newDataCount > currentDataCap) ?
408 newDataCount * 2 : currentDataCap;
409
410 if (newEntryCount > currentEntryCap ||
411 newDataCount > currentDataCap) {
412 camera_metadata_t *oldBuffer = mBuffer;
413 mBuffer = allocate_camera_metadata(newEntryCount,
414 newDataCount);
415 if (mBuffer == NULL) {
416 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
417 return NO_MEMORY;
418 }
419 append_camera_metadata(mBuffer, oldBuffer);
420 free_camera_metadata(oldBuffer);
421 }
422 }
423 return OK;
424}
425
Igor Murashkine7ee7632013-06-11 18:10:18 -0700426status_t CameraMetadata::readFromParcel(const Parcel& data,
427 camera_metadata_t** out) {
428
429 status_t err = OK;
430
431 camera_metadata_t* metadata = NULL;
432
433 if (out) {
434 *out = NULL;
435 }
436
Zhijun He146aed12013-12-05 07:46:51 -0800437 // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation.
438 // arg0 = blobSize (int32)
439 int32_t blobSizeTmp = -1;
440 if ((err = data.readInt32(&blobSizeTmp)) != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700441 ALOGE("%s: Failed to read metadata size (error %d %s)",
442 __FUNCTION__, err, strerror(-err));
443 return err;
444 }
Zhijun He146aed12013-12-05 07:46:51 -0800445 const size_t blobSize = static_cast<size_t>(blobSizeTmp);
446 const size_t alignment = get_camera_metadata_alignment();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700447
Zhijun He146aed12013-12-05 07:46:51 -0800448 // Special case: zero blob size means zero sized (NULL) metadata.
449 if (blobSize == 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700450 ALOGV("%s: Read 0-sized metadata", __FUNCTION__);
451 return OK;
452 }
453
Zhijun He146aed12013-12-05 07:46:51 -0800454 if (blobSize <= alignment) {
455 ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)",
456 __FUNCTION__, blobSize, alignment);
457 return BAD_VALUE;
458 }
459
460 const size_t metadataSize = blobSize - alignment;
461
462 // NOTE: this doesn't make sense to me. shouldn't the blob
Igor Murashkine7ee7632013-06-11 18:10:18 -0700463 // know how big it is? why do we have to specify the size
464 // to Parcel::readBlob ?
Igor Murashkine7ee7632013-06-11 18:10:18 -0700465 ReadableBlob blob;
466 // arg1 = metadata (blob)
467 do {
Zhijun He146aed12013-12-05 07:46:51 -0800468 if ((err = data.readBlob(blobSize, &blob)) != OK) {
469 ALOGE("%s: Failed to read metadata blob (sized %zu). Possible "
Igor Murashkine7ee7632013-06-11 18:10:18 -0700470 " serialization bug. Error %d %s",
Zhijun He146aed12013-12-05 07:46:51 -0800471 __FUNCTION__, blobSize, err, strerror(-err));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700472 break;
473 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700474
Zhijun He146aed12013-12-05 07:46:51 -0800475 // arg2 = offset (blob)
476 // Must be after blob since we don't know offset until after writeBlob.
477 int32_t offsetTmp;
478 if ((err = data.readInt32(&offsetTmp)) != OK) {
479 ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)",
480 __FUNCTION__, err, strerror(-err));
481 break;
482 }
483 const size_t offset = static_cast<size_t>(offsetTmp);
484 if (offset >= alignment) {
485 ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)",
486 __FUNCTION__, blobSize, alignment);
487 err = BAD_VALUE;
488 break;
489 }
490
491 const uintptr_t metadataStart = reinterpret_cast<uintptr_t>(blob.data()) + offset;
492 const camera_metadata_t* tmp =
493 reinterpret_cast<const camera_metadata_t*>(metadataStart);
494 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
495 __FUNCTION__, alignment, tmp, offset);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700496 metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
497 if (metadata == NULL) {
498 // We consider that allocation only fails if the validation
499 // also failed, therefore the readFromParcel was a failure.
Zhijun He146aed12013-12-05 07:46:51 -0800500 ALOGE("%s: metadata allocation and copy failed", __FUNCTION__);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700501 err = BAD_VALUE;
502 }
503 } while(0);
504 blob.release();
505
506 if (out) {
507 ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata);
508 *out = metadata;
509 } else if (metadata != NULL) {
510 ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata);
511 free_camera_metadata(metadata);
512 }
513
514 return err;
515}
516
517status_t CameraMetadata::writeToParcel(Parcel& data,
518 const camera_metadata_t* metadata) {
519 status_t res = OK;
520
Zhijun He146aed12013-12-05 07:46:51 -0800521 /**
522 * Below is the camera metadata parcel layout:
523 *
524 * |--------------------------------------------|
525 * | arg0: blobSize |
526 * | (length = 4) |
527 * |--------------------------------------------|<--Skip the rest if blobSize == 0.
528 * | |
529 * | |
530 * | arg1: blob |
531 * | (length = variable, see arg1 layout below) |
532 * | |
533 * | |
534 * |--------------------------------------------|
535 * | arg2: offset |
536 * | (length = 4) |
537 * |--------------------------------------------|
538 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700539
Zhijun He146aed12013-12-05 07:46:51 -0800540 // arg0 = blobSize (int32)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700541 if (metadata == NULL) {
Zhijun He146aed12013-12-05 07:46:51 -0800542 // Write zero blobSize for null metadata.
Igor Murashkine7ee7632013-06-11 18:10:18 -0700543 return data.writeInt32(0);
544 }
545
Zhijun He146aed12013-12-05 07:46:51 -0800546 /**
547 * Always make the blob size sufficiently larger, as we need put alignment
548 * padding and metadata into the blob. Since we don't know the alignment
549 * offset before writeBlob. Then write the metadata to aligned offset.
550 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700551 const size_t metadataSize = get_camera_metadata_compact_size(metadata);
Zhijun He146aed12013-12-05 07:46:51 -0800552 const size_t alignment = get_camera_metadata_alignment();
553 const size_t blobSize = metadataSize + alignment;
554 res = data.writeInt32(static_cast<int32_t>(blobSize));
Igor Murashkine7ee7632013-06-11 18:10:18 -0700555 if (res != OK) {
556 return res;
557 }
558
Zhijun He146aed12013-12-05 07:46:51 -0800559 size_t offset = 0;
560 /**
561 * arg1 = metadata (blob).
562 *
563 * The blob size is the sum of front padding size, metadata size and back padding
564 * size, which is equal to metadataSize + alignment.
565 *
566 * The blob layout is:
567 * |------------------------------------|<----Start address of the blob (unaligned).
568 * | front padding |
569 * | (size = offset) |
570 * |------------------------------------|<----Aligned start address of metadata.
571 * | |
572 * | |
573 * | metadata |
574 * | (size = metadataSize) |
575 * | |
576 * | |
577 * |------------------------------------|
578 * | back padding |
579 * | (size = alignment - offset) |
580 * |------------------------------------|<----End address of blob.
581 * (Blob start address + blob size).
582 */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700583 WritableBlob blob;
584 do {
Zhijun He146aed12013-12-05 07:46:51 -0800585 res = data.writeBlob(blobSize, &blob);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700586 if (res != OK) {
587 break;
588 }
Zhijun He146aed12013-12-05 07:46:51 -0800589 const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
590 offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
591 ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
592 __FUNCTION__, alignment, metadataStart, offset);
593 copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700594
595 // Not too big of a problem since receiving side does hard validation
596 // Don't check the size since the compact size could be larger
597 if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) {
598 ALOGW("%s: Failed to validate metadata %p before writing blob",
599 __FUNCTION__, metadata);
600 }
601
602 } while(false);
603 blob.release();
604
Zhijun He146aed12013-12-05 07:46:51 -0800605 // arg2 = offset (int32)
606 res = data.writeInt32(static_cast<int32_t>(offset));
607
Igor Murashkine7ee7632013-06-11 18:10:18 -0700608 return res;
609}
610
611status_t CameraMetadata::readFromParcel(Parcel *parcel) {
612
613 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
614
615 status_t res = OK;
616
617 if (parcel == NULL) {
618 ALOGE("%s: parcel is null", __FUNCTION__);
619 return BAD_VALUE;
620 }
621
622 if (mLocked) {
623 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
624 return INVALID_OPERATION;
625 }
626
627 camera_metadata *buffer = NULL;
628 // TODO: reading should return a status code, in case validation fails
629 res = CameraMetadata::readFromParcel(*parcel, &buffer);
630
631 if (res != NO_ERROR) {
632 ALOGE("%s: Failed to read from parcel. Metadata is unchanged.",
633 __FUNCTION__);
634 return res;
635 }
636
637 clear();
638 mBuffer = buffer;
639
640 return OK;
641}
642
643status_t CameraMetadata::writeToParcel(Parcel *parcel) const {
644
645 ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
646
647 if (parcel == NULL) {
648 ALOGE("%s: parcel is null", __FUNCTION__);
649 return BAD_VALUE;
650 }
651
652 return CameraMetadata::writeToParcel(*parcel, mBuffer);
653}
654
655void CameraMetadata::swap(CameraMetadata& other) {
656 if (mLocked) {
657 ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
658 return;
659 } else if (other.mLocked) {
660 ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
661 return;
662 }
663
664 camera_metadata* thisBuf = mBuffer;
665 camera_metadata* otherBuf = other.mBuffer;
666
667 other.mBuffer = thisBuf;
668 mBuffer = otherBuf;
669}
670
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700671}; // namespace android