status_t CameraMetadata::writeToParcel(Parcel& data, const camera_metadata_t* metadata) { status_t res = OK; /** * Below is the camera metadata parcel layout: * * |--------------------------------------------| * | arg0: blobSize | * | (length = 4) | * |--------------------------------------------|<--Skip the rest if blobSize == 0. * | | * | | * | arg1: blob | * | (length = variable, see arg1 layout below) | * | | * | | * |--------------------------------------------| * | arg2: offset | * | (length = 4) | * |--------------------------------------------| */ // arg0 = blobSize (int32) if (metadata == NULL) { // Write zero blobSize for null metadata. return data.writeInt32(0); } /** * Always make the blob size sufficiently larger, as we need put alignment * padding and metadata into the blob. Since we don't know the alignment * offset before writeBlob. Then write the metadata to aligned offset. */ const size_t metadataSize = get_camera_metadata_compact_size(metadata); const size_t alignment = get_camera_metadata_alignment(); const size_t blobSize = metadataSize + alignment; res = data.writeInt32(static_cast<int32_t>(blobSize)); if (res != OK) { return res; } size_t offset = 0; /** * arg1 = metadata (blob). * * The blob size is the sum of front padding size, metadata size and back padding * size, which is equal to metadataSize + alignment. * * The blob layout is: * |------------------------------------|<----Start address of the blob (unaligned). * | front padding | * | (size = offset) | * |------------------------------------|<----Aligned start address of metadata. * | | * | | * | metadata | * | (size = metadataSize) | * | | * | | * |------------------------------------| * | back padding | * | (size = alignment - offset) | * |------------------------------------|<----End address of blob. * (Blob start address + blob size). */ WritableBlob blob; do { res = data.writeBlob(blobSize, &blob); if (res != OK) { break; } const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment); offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data()); ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu", __FUNCTION__, alignment, reinterpret_cast<const void *>(metadataStart), offset); copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata); // Not too big of a problem since receiving side does hard validation // Don't check the size since the compact size could be larger if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) { ALOGW("%s: Failed to validate metadata %p before writing blob", __FUNCTION__, metadata); } } while(false); blob.release(); // arg2 = offset (int32) res = data.writeInt32(static_cast<int32_t>(offset)); return res; }
void writeVector(Parcel &data, Vector<uint8_t> const &vector) const { data.writeInt32(vector.size()); data.write(vector.array(), vector.size()); }
static void sendSchedPolicy(Parcel& data) { SchedPolicy policy; get_sched_policy(gettid(), &policy); data.writeInt32(policy); }