| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_NDEBUG 0 |
| #define LOG_TAG "VendorTagDescriptorTests" |
| |
| #include <binder/Parcel.h> |
| #include <camera/VendorTagDescriptor.h> |
| #include <camera_metadata_tests_fake_vendor.h> |
| #include <camera_metadata_hidden.h> |
| #include <system/camera_vendor_tags.h> |
| #include <utils/Errors.h> |
| #include <utils/Log.h> |
| #include <utils/RefBase.h> |
| |
| #include <gtest/gtest.h> |
| #include <stdint.h> |
| |
| using namespace android; |
| |
| enum { |
| BAD_TAG_ARRAY = 0xDEADBEEFu, |
| BAD_TAG = 0x8DEADBADu, |
| }; |
| |
| #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
| |
| static bool ContainsTag(uint32_t* tagArray, size_t size, uint32_t tag) { |
| for (size_t i = 0; i < size; ++i) { |
| if (tag == tagArray[i]) return true; |
| } |
| return false; |
| } |
| |
| #define EXPECT_CONTAINS_TAG(t, a) \ |
| EXPECT_TRUE(ContainsTag(a, ARRAY_SIZE(a), t)) |
| |
| #define ASSERT_NOT_NULL(x) \ |
| ASSERT_TRUE((x) != NULL) |
| |
| extern "C" { |
| |
| static int zero_get_tag_count(const vendor_tag_ops_t*) { |
| return 0; |
| } |
| |
| static int default_get_tag_count(const vendor_tag_ops_t*) { |
| return VENDOR_TAG_COUNT_ERR; |
| } |
| |
| static void default_get_all_tags(const vendor_tag_ops_t*, uint32_t*) { |
| //Noop |
| } |
| |
| static const char* default_get_section_name(const vendor_tag_ops_t*, uint32_t) { |
| return VENDOR_SECTION_NAME_ERR; |
| } |
| |
| static const char* default_get_tag_name(const vendor_tag_ops_t*, uint32_t) { |
| return VENDOR_TAG_NAME_ERR; |
| } |
| |
| static int default_get_tag_type(const vendor_tag_ops_t*, uint32_t) { |
| return VENDOR_TAG_TYPE_ERR; |
| } |
| |
| } /*extern "C"*/ |
| |
| // Set default vendor operations for a vendor_tag_ops struct |
| static void FillWithDefaults(vendor_tag_ops_t* vOps) { |
| ASSERT_NOT_NULL(vOps); |
| vOps->get_tag_count = default_get_tag_count; |
| vOps->get_all_tags = default_get_all_tags; |
| vOps->get_section_name = default_get_section_name; |
| vOps->get_tag_name = default_get_tag_name; |
| vOps->get_tag_type = default_get_tag_type; |
| } |
| |
| /** |
| * Test if values from VendorTagDescriptor methods match corresponding values |
| * from vendor_tag_ops functions. |
| */ |
| TEST(VendorTagDescriptorTest, ConsistentWithVendorTags) { |
| sp<VendorTagDescriptor> vDesc; |
| const vendor_tag_ops_t *vOps = &fakevendor_ops; |
| EXPECT_EQ(OK, VendorTagDescriptor::createDescriptorFromOps(vOps, /*out*/vDesc)); |
| |
| ASSERT_NOT_NULL(vDesc); |
| |
| // Ensure reasonable tag count |
| int tagCount = vDesc->getTagCount(); |
| EXPECT_EQ(tagCount, vOps->get_tag_count(vOps)); |
| |
| uint32_t descTagArray[tagCount]; |
| uint32_t opsTagArray[tagCount]; |
| |
| // Get all tag ids |
| vDesc->getTagArray(descTagArray); |
| vOps->get_all_tags(vOps, opsTagArray); |
| |
| ASSERT_NOT_NULL(descTagArray); |
| ASSERT_NOT_NULL(opsTagArray); |
| |
| uint32_t tag; |
| for (int i = 0; i < tagCount; ++i) { |
| // For each tag id, check whether type, section name, tag name match |
| tag = descTagArray[i]; |
| EXPECT_CONTAINS_TAG(tag, opsTagArray); |
| EXPECT_EQ(vDesc->getTagType(tag), vOps->get_tag_type(vOps, tag)); |
| EXPECT_STREQ(vDesc->getSectionName(tag), vOps->get_section_name(vOps, tag)); |
| EXPECT_STREQ(vDesc->getTagName(tag), vOps->get_tag_name(vOps, tag)); |
| } |
| } |
| |
| /** |
| * Test if values from VendorTagDescriptor methods stay consistent after being |
| * parcelled/unparcelled. |
| */ |
| TEST(VendorTagDescriptorTest, ConsistentAcrossParcel) { |
| sp<VendorTagDescriptor> vDescOriginal, vDescParceled; |
| const vendor_tag_ops_t *vOps = &fakevendor_ops; |
| EXPECT_EQ(OK, VendorTagDescriptor::createDescriptorFromOps(vOps, /*out*/vDescOriginal)); |
| |
| ASSERT_TRUE(vDescOriginal != NULL); |
| |
| Parcel p; |
| |
| // Check whether parcel read/write succeed |
| EXPECT_EQ(OK, vDescOriginal->writeToParcel(&p)); |
| p.setDataPosition(0); |
| |
| ASSERT_EQ(OK, vDescParceled->readFromParcel(&p)); |
| |
| // Ensure consistent tag count |
| int tagCount = vDescOriginal->getTagCount(); |
| ASSERT_EQ(tagCount, vDescParceled->getTagCount()); |
| |
| uint32_t descTagArray[tagCount]; |
| uint32_t desc2TagArray[tagCount]; |
| |
| // Get all tag ids |
| vDescOriginal->getTagArray(descTagArray); |
| vDescParceled->getTagArray(desc2TagArray); |
| |
| ASSERT_NOT_NULL(descTagArray); |
| ASSERT_NOT_NULL(desc2TagArray); |
| |
| uint32_t tag; |
| for (int i = 0; i < tagCount; ++i) { |
| // For each tag id, check consistency between the two vendor tag |
| // descriptors for each type, section name, tag name |
| tag = descTagArray[i]; |
| EXPECT_CONTAINS_TAG(tag, desc2TagArray); |
| EXPECT_EQ(vDescOriginal->getTagType(tag), vDescParceled->getTagType(tag)); |
| EXPECT_STREQ(vDescOriginal->getSectionName(tag), vDescParceled->getSectionName(tag)); |
| EXPECT_STREQ(vDescOriginal->getTagName(tag), vDescParceled->getTagName(tag)); |
| } |
| } |
| |
| /** |
| * Test defaults and error conditions. |
| */ |
| TEST(VendorTagDescriptorTest, ErrorConditions) { |
| sp<VendorTagDescriptor> vDesc; |
| vendor_tag_ops_t vOps; |
| FillWithDefaults(&vOps); |
| |
| // Make empty tag count |
| vOps.get_tag_count = zero_get_tag_count; |
| |
| // Ensure create fails when using null vOps |
| EXPECT_EQ(BAD_VALUE, VendorTagDescriptor::createDescriptorFromOps(/*vOps*/NULL, vDesc)); |
| |
| // Ensure creat succeeds for empty vendor tag ops |
| ASSERT_EQ(OK, VendorTagDescriptor::createDescriptorFromOps(&vOps, vDesc)); |
| |
| // Ensure defaults are returned when no vtags are defined, or tag is unknown |
| EXPECT_EQ(VENDOR_TAG_COUNT_ERR, vDesc->getTagCount()); |
| uint32_t* tagArray = reinterpret_cast<uint32_t*>(BAD_TAG_ARRAY); |
| uint32_t* testArray = tagArray; |
| vDesc->getTagArray(tagArray); |
| EXPECT_EQ(testArray, tagArray); |
| EXPECT_EQ(VENDOR_SECTION_NAME_ERR, vDesc->getSectionName(BAD_TAG)); |
| EXPECT_EQ(VENDOR_TAG_NAME_ERR, vDesc->getTagName(BAD_TAG)); |
| EXPECT_EQ(VENDOR_TAG_TYPE_ERR, vDesc->getTagType(BAD_TAG)); |
| |
| // Make sure global can be set/cleared |
| sp<VendorTagDescriptor> prevGlobal = VendorTagDescriptor::getGlobalVendorTagDescriptor(); |
| VendorTagDescriptor::clearGlobalVendorTagDescriptor(); |
| |
| EXPECT_TRUE(VendorTagDescriptor::getGlobalVendorTagDescriptor() == NULL); |
| EXPECT_EQ(OK, VendorTagDescriptor::setAsGlobalVendorTagDescriptor(vDesc)); |
| EXPECT_TRUE(VendorTagDescriptor::getGlobalVendorTagDescriptor() != NULL); |
| EXPECT_EQ(VENDOR_SECTION_NAME_ERR, vDesc->getSectionName(BAD_TAG)); |
| EXPECT_EQ(OK, VendorTagDescriptor::setAsGlobalVendorTagDescriptor(prevGlobal)); |
| EXPECT_EQ(prevGlobal, VendorTagDescriptor::getGlobalVendorTagDescriptor()); |
| } |