Add tests for attribute resolution

- Adds unit tests for attribute resolution. These include
  some test data resource tables and compiled XML files.
- Convert touched files to Google style guide.

Test: make libandroidfw_tests
Change-Id: Ib3a36061dc874de5f6a266b4e82c0a12ef435f23
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 1fe1773..6837f25 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -40,7 +40,7 @@
     -Werror \
     -Wunused \
     -Wunreachable-code \
-    -Wno-missing-field-initializers \
+    -Wno-missing-field-initializers
 
 # gtest is broken.
 androidfw_test_cflags += -Wno-unnamed-type-template-args
@@ -52,9 +52,10 @@
 
 LOCAL_MODULE := libandroidfw_tests
 LOCAL_CFLAGS := $(androidfw_test_cflags)
-LOCAL_SRC_FILES := $(testFiles)
+LOCAL_SRC_FILES := $(testFiles) AttributeResolution_test.cpp
 LOCAL_STATIC_LIBRARIES := \
     libandroidfw \
+    libbase \
     libutils \
     libcutils \
     liblog \
@@ -76,6 +77,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libandroidfw \
+    libbase \
     libcutils \
     libutils \
     libui \
diff --git a/libs/androidfw/tests/AttributeFinder_test.cpp b/libs/androidfw/tests/AttributeFinder_test.cpp
index 5054624..d9ed48e 100644
--- a/libs/androidfw/tests/AttributeFinder_test.cpp
+++ b/libs/androidfw/tests/AttributeFinder_test.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,115 +14,105 @@
  * limitations under the License.
  */
 
-#include <androidfw/AttributeFinder.h>
+#include "../AttributeFinder.h"
 
+#include <android-base/macros.h>
 #include <gtest/gtest.h>
 
 using android::BackTrackingAttributeFinder;
 
 class MockAttributeFinder : public BackTrackingAttributeFinder<MockAttributeFinder, int> {
-public:
-    MockAttributeFinder(const uint32_t* attrs, int len)
-        : BackTrackingAttributeFinder(0, len) {
-        mAttrs = new uint32_t[len];
-        memcpy(mAttrs, attrs, sizeof(*attrs) * len);
-    }
+ public:
+  MockAttributeFinder(const uint32_t* attrs, int len) : BackTrackingAttributeFinder(0, len) {
+    attrs_ = new uint32_t[len];
+    memcpy(attrs_, attrs, sizeof(*attrs) * len);
+  }
 
-    ~MockAttributeFinder() {
-        delete mAttrs;
-    }
+  ~MockAttributeFinder() { delete attrs_; }
 
-    inline uint32_t getAttribute(const int index) const {
-        return mAttrs[index];
-    }
+  inline uint32_t GetAttribute(const int index) const { return attrs_[index]; }
 
-private:
-    uint32_t* mAttrs;
+ private:
+  uint32_t* attrs_;
 };
 
-static const uint32_t sortedAttributes[] = {
-        0x01010000, 0x01010001, 0x01010002, 0x01010004,
-        0x02010001, 0x02010010, 0x7f010001
-};
+static const uint32_t kSortedAttributes[] = {0x01010000, 0x01010001, 0x01010002, 0x01010004,
+                                             0x02010001, 0x02010010, 0x7f010001};
 
-static const uint32_t packageUnsortedAttributes[] = {
-        0x02010001, 0x02010010, 0x01010000, 0x01010001,
-        0x01010002, 0x01010004, 0x7f010001
-};
+static const uint32_t kPackageUnsortedAttributes[] = {
+    0x02010001, 0x02010010, 0x01010000, 0x01010001, 0x01010002, 0x01010004, 0x7f010001};
 
-static const uint32_t singlePackageAttributes[] = {
-        0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000
-};
+static const uint32_t kSinglePackageAttributes[] = {0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000};
 
 TEST(AttributeFinderTest, IteratesSequentially) {
-    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
-    MockAttributeFinder finder(sortedAttributes, end);
+  const int end = arraysize(kSortedAttributes);
+  MockAttributeFinder finder(kSortedAttributes, end);
 
-    EXPECT_EQ(0, finder.find(0x01010000));
-    EXPECT_EQ(1, finder.find(0x01010001));
-    EXPECT_EQ(2, finder.find(0x01010002));
-    EXPECT_EQ(3, finder.find(0x01010004));
-    EXPECT_EQ(4, finder.find(0x02010001));
-    EXPECT_EQ(5, finder.find(0x02010010));
-    EXPECT_EQ(6, finder.find(0x7f010001));
-    EXPECT_EQ(end, finder.find(0x7f010002));
+  EXPECT_EQ(0, finder.Find(0x01010000));
+  EXPECT_EQ(1, finder.Find(0x01010001));
+  EXPECT_EQ(2, finder.Find(0x01010002));
+  EXPECT_EQ(3, finder.Find(0x01010004));
+  EXPECT_EQ(4, finder.Find(0x02010001));
+  EXPECT_EQ(5, finder.Find(0x02010010));
+  EXPECT_EQ(6, finder.Find(0x7f010001));
+  EXPECT_EQ(end, finder.Find(0x7f010002));
 }
 
 TEST(AttributeFinderTest, PackagesAreOutOfOrder) {
-    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
-    MockAttributeFinder finder(sortedAttributes, end);
+  const int end = arraysize(kSortedAttributes);
+  MockAttributeFinder finder(kSortedAttributes, end);
 
-    EXPECT_EQ(6, finder.find(0x7f010001));
-    EXPECT_EQ(end, finder.find(0x7f010002));
-    EXPECT_EQ(4, finder.find(0x02010001));
-    EXPECT_EQ(5, finder.find(0x02010010));
-    EXPECT_EQ(0, finder.find(0x01010000));
-    EXPECT_EQ(1, finder.find(0x01010001));
-    EXPECT_EQ(2, finder.find(0x01010002));
-    EXPECT_EQ(3, finder.find(0x01010004));
+  EXPECT_EQ(6, finder.Find(0x7f010001));
+  EXPECT_EQ(end, finder.Find(0x7f010002));
+  EXPECT_EQ(4, finder.Find(0x02010001));
+  EXPECT_EQ(5, finder.Find(0x02010010));
+  EXPECT_EQ(0, finder.Find(0x01010000));
+  EXPECT_EQ(1, finder.Find(0x01010001));
+  EXPECT_EQ(2, finder.Find(0x01010002));
+  EXPECT_EQ(3, finder.Find(0x01010004));
 }
 
 TEST(AttributeFinderTest, SomeAttributesAreNotFound) {
-    const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
-    MockAttributeFinder finder(sortedAttributes, end);
+  const int end = arraysize(kSortedAttributes);
+  MockAttributeFinder finder(kSortedAttributes, end);
 
-    EXPECT_EQ(0, finder.find(0x01010000));
-    EXPECT_EQ(1, finder.find(0x01010001));
-    EXPECT_EQ(2, finder.find(0x01010002));
-    EXPECT_EQ(end, finder.find(0x01010003));
-    EXPECT_EQ(3, finder.find(0x01010004));
-    EXPECT_EQ(end, finder.find(0x01010005));
-    EXPECT_EQ(end, finder.find(0x01010006));
-    EXPECT_EQ(4, finder.find(0x02010001));
-    EXPECT_EQ(end, finder.find(0x02010002));
+  EXPECT_EQ(0, finder.Find(0x01010000));
+  EXPECT_EQ(1, finder.Find(0x01010001));
+  EXPECT_EQ(2, finder.Find(0x01010002));
+  EXPECT_EQ(end, finder.Find(0x01010003));
+  EXPECT_EQ(3, finder.Find(0x01010004));
+  EXPECT_EQ(end, finder.Find(0x01010005));
+  EXPECT_EQ(end, finder.Find(0x01010006));
+  EXPECT_EQ(4, finder.Find(0x02010001));
+  EXPECT_EQ(end, finder.Find(0x02010002));
 }
 
 TEST(AttributeFinderTest, FindAttributesInPackageUnsortedAttributeList) {
-    const int end = sizeof(packageUnsortedAttributes) / sizeof(*packageUnsortedAttributes);
-    MockAttributeFinder finder(packageUnsortedAttributes, end);
+  const int end = arraysize(kPackageUnsortedAttributes);
+  MockAttributeFinder finder(kPackageUnsortedAttributes, end);
 
-    EXPECT_EQ(2, finder.find(0x01010000));
-    EXPECT_EQ(3, finder.find(0x01010001));
-    EXPECT_EQ(4, finder.find(0x01010002));
-    EXPECT_EQ(end, finder.find(0x01010003));
-    EXPECT_EQ(5, finder.find(0x01010004));
-    EXPECT_EQ(end, finder.find(0x01010005));
-    EXPECT_EQ(end, finder.find(0x01010006));
-    EXPECT_EQ(0, finder.find(0x02010001));
-    EXPECT_EQ(end, finder.find(0x02010002));
-    EXPECT_EQ(1, finder.find(0x02010010));
-    EXPECT_EQ(6, finder.find(0x7f010001));
+  EXPECT_EQ(2, finder.Find(0x01010000));
+  EXPECT_EQ(3, finder.Find(0x01010001));
+  EXPECT_EQ(4, finder.Find(0x01010002));
+  EXPECT_EQ(end, finder.Find(0x01010003));
+  EXPECT_EQ(5, finder.Find(0x01010004));
+  EXPECT_EQ(end, finder.Find(0x01010005));
+  EXPECT_EQ(end, finder.Find(0x01010006));
+  EXPECT_EQ(0, finder.Find(0x02010001));
+  EXPECT_EQ(end, finder.Find(0x02010002));
+  EXPECT_EQ(1, finder.Find(0x02010010));
+  EXPECT_EQ(6, finder.Find(0x7f010001));
 }
 
 TEST(AttributeFinderTest, FindAttributesInSinglePackageAttributeList) {
-    const int end = sizeof(singlePackageAttributes) / sizeof(*singlePackageAttributes);
-    MockAttributeFinder finder(singlePackageAttributes, end);
+  const int end = arraysize(kSinglePackageAttributes);
+  MockAttributeFinder finder(kSinglePackageAttributes, end);
 
-    EXPECT_EQ(end, finder.find(0x010100f4));
-    EXPECT_EQ(end, finder.find(0x010100f5));
-    EXPECT_EQ(end, finder.find(0x010100f6));
-    EXPECT_EQ(end, finder.find(0x010100f7));
-    EXPECT_EQ(end, finder.find(0x010100f8));
-    EXPECT_EQ(end, finder.find(0x010100fa));
-    EXPECT_EQ(0, finder.find(0x7f010007));
+  EXPECT_EQ(end, finder.Find(0x010100f4));
+  EXPECT_EQ(end, finder.Find(0x010100f5));
+  EXPECT_EQ(end, finder.Find(0x010100f6));
+  EXPECT_EQ(end, finder.Find(0x010100f7));
+  EXPECT_EQ(end, finder.Find(0x010100f8));
+  EXPECT_EQ(end, finder.Find(0x010100fa));
+  EXPECT_EQ(0, finder.Find(0x7f010007));
 }
diff --git a/libs/androidfw/tests/AttributeResolution_test.cpp b/libs/androidfw/tests/AttributeResolution_test.cpp
new file mode 100644
index 0000000..7fbe6d3
--- /dev/null
+++ b/libs/androidfw/tests/AttributeResolution_test.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "androidfw/AttributeResolution.h"
+#include "TestHelpers.h"
+#include "data/styles/R.h"
+
+#include <android-base/file.h>
+#include <android-base/macros.h>
+
+using namespace android;
+using android::base::ReadFileToString;
+using com::android::app::R;
+
+class AttributeResolutionTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    std::string test_source_dir = TestSourceDir();
+    std::string contents;
+    LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/resources.arsc", &contents));
+    LOG_ALWAYS_FATAL_IF(
+        table_.add(contents.data(), contents.size(), 1 /*cookie*/, true /*copyData*/) != NO_ERROR);
+  }
+
+ protected:
+  ResTable table_;
+};
+
+class AttributeResolutionXmlTest : public AttributeResolutionTest {
+ public:
+  virtual void SetUp() override {
+    AttributeResolutionTest::SetUp();
+    std::string test_source_dir = TestSourceDir();
+    std::string contents;
+    LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/layout.xml", &contents));
+    LOG_ALWAYS_FATAL_IF(xml_parser_.setTo(contents.data(), contents.size(), true /*copyData*/) !=
+                        NO_ERROR);
+
+    // Skip to the first tag.
+    while (xml_parser_.next() != ResXMLParser::START_TAG) {
+    }
+  }
+
+ protected:
+  ResXMLTree xml_parser_;
+};
+
+TEST_F(AttributeResolutionTest, Theme) {
+  ResTable::Theme theme(table_);
+  ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
+
+  uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
+                      R::attr::attr_four};
+  std::vector<uint32_t> values;
+  values.resize(arraysize(attrs) * 6);
+
+  ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
+                           nullptr /*src_values*/, 0 /*src_values_length*/, attrs, arraysize(attrs),
+                           values.data(), nullptr /*out_indices*/));
+
+  const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
+
+  const uint32_t* values_cursor = values.data();
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+}
+
+TEST_F(AttributeResolutionXmlTest, XmlParser) {
+  uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
+                      R::attr::attr_four};
+  std::vector<uint32_t> values;
+  values.resize(arraysize(attrs) * 6);
+
+  ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs, arraysize(attrs), values.data(),
+                                 nullptr /*out_indices*/));
+
+  uint32_t* values_cursor = values.data();
+  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_ATTRIBUTE, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(R::attr::attr_indirect, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+}
+
+TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
+  ResTable::Theme theme(table_);
+  ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
+
+  uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, R::attr::attr_four,
+                      R::attr::attr_five};
+  std::vector<uint32_t> values;
+  values.resize(arraysize(attrs) * 6);
+
+  ASSERT_TRUE(ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs,
+                         arraysize(attrs), values.data(), nullptr /*out_indices*/));
+
+  const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
+
+  uint32_t* values_cursor = values.data();
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(10u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(3u, values_cursor[STYLE_DATA]);
+  EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+
+  values_cursor += STYLE_NUM_ENTRIES;
+  EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]);
+  EXPECT_EQ(R::string::string_one, values_cursor[STYLE_RESOURCE_ID]);
+  EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
+  EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
+  EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
+}
diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp
index 41a19a7..3d1d5f5 100644
--- a/libs/androidfw/tests/TestHelpers.cpp
+++ b/libs/androidfw/tests/TestHelpers.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -17,32 +17,46 @@
 #include "TestHelpers.h"
 
 #include <androidfw/ResourceTypes.h>
-#include <utils/String8.h>
 #include <gtest/gtest.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+std::string TestSourceDir() {
+  const char* dir = getenv("ANDROID_BUILD_TOP");
+  LOG_ALWAYS_FATAL_IF(dir == nullptr, "Environment variable ANDROID_BUILD_TOP must be set");
+  std::string testdir = std::string(dir) + "/frameworks/base/libs/androidfw/tests/data";
+
+  // Check that the directory exists.
+  struct stat filestat;
+  LOG_ALWAYS_FATAL_IF(stat(testdir.c_str(), &filestat) != 0, "test data path '%s' does not exist",
+                      testdir.c_str());
+  return testdir;
+}
 
 namespace android {
 
-::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr) {
-    Res_value val;
-    ssize_t block = table.getResource(resourceId, &val, MAY_NOT_BE_BAG);
-    if (block < 0) {
-        return ::testing::AssertionFailure() << "could not find resource";
-    }
+::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
+                                         const char* expected_str) {
+  Res_value val;
+  ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG);
+  if (block < 0) {
+    return ::testing::AssertionFailure() << "could not find resource";
+  }
 
-    if (val.dataType != Res_value::TYPE_STRING) {
-        return ::testing::AssertionFailure() << "resource is not a string";
-    }
+  if (val.dataType != Res_value::TYPE_STRING) {
+    return ::testing::AssertionFailure() << "resource is not a string";
+  }
 
-    const ResStringPool* pool = table.getTableStringBlock(block);
-    if (pool == NULL) {
-        return ::testing::AssertionFailure() << "table has no string pool for block " << block;
-    }
+  const ResStringPool* pool = table.getTableStringBlock(block);
+  if (pool == NULL) {
+    return ::testing::AssertionFailure() << "table has no string pool for block " << block;
+  }
 
-    const String8 actual = pool->string8ObjectAt(val.data);
-    if (String8(expectedStr) != actual) {
-        return ::testing::AssertionFailure() << actual.string();
-    }
-    return ::testing::AssertionSuccess() << actual.string();
+  const String8 actual_str = pool->string8ObjectAt(val.data);
+  if (String8(expected_str) != actual_str) {
+    return ::testing::AssertionFailure() << actual_str.string();
+  }
+  return ::testing::AssertionSuccess() << actual_str.string();
 }
 
-} // namespace android
+}  // namespace android
diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h
index ff9be16..5f0c4552 100644
--- a/libs/androidfw/tests/TestHelpers.h
+++ b/libs/androidfw/tests/TestHelpers.h
@@ -1,35 +1,56 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
 #ifndef __TEST_HELPERS_H
 #define __TEST_HELPERS_H
 
-#include <ostream>
-
 #include <androidfw/ResourceTypes.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
 #include <gtest/gtest.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#include <ostream>
+#include <string>
+
+std::string TestSourceDir();
 
 static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {
-    return out << str.string();
+  return out << str.string();
 }
 
 static inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {
-    return out << android::String8(str).string();
+  return out << android::String8(str).string();
 }
 
 namespace android {
 
 enum { MAY_NOT_BE_BAG = false };
 
-static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) {
-    return a.compare(b) == 0;
+static inline bool operator==(const android::ResTable_config& a,
+                              const android::ResTable_config& b) {
+  return a.compare(b) == 0;
 }
 
 static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {
-    return out << c.toString().string();
+  return out << c.toString().string();
 }
 
-::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr);
+::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
+                                         const char* expected_str);
 
-} // namespace android
+}  // namespace android
 
-#endif // __TEST_HELPERS_H
+#endif  // __TEST_HELPERS_H
diff --git a/libs/androidfw/tests/data/.gitignore b/libs/androidfw/tests/data/.gitignore
deleted file mode 100644
index c05cfb0..0000000
--- a/libs/androidfw/tests/data/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.apk
-*.arsc
diff --git a/libs/androidfw/tests/data/styles/AndroidManifest.xml b/libs/androidfw/tests/data/styles/AndroidManifest.xml
new file mode 100644
index 0000000..5211316
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.app">
+</manifest>
diff --git a/libs/androidfw/tests/data/styles/R.h b/libs/androidfw/tests/data/styles/R.h
new file mode 100644
index 0000000..6dc6ede
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/R.h
@@ -0,0 +1,35 @@
+#include <cstdint>
+
+namespace com {
+namespace android {
+namespace app {
+
+struct R {
+  struct attr {
+    enum : uint32_t {
+      attr_one = 0x7f010000u,
+      attr_two = 0x7f010001u,
+      attr_three = 0x7f010002u,
+      attr_four = 0x7f010003u,
+      attr_five = 0x7f010004u,
+      attr_indirect = 0x7f010005u,
+    };
+  };
+
+  struct string {
+      enum : uint32_t {
+          string_one = 0x7f030000u,
+      };
+  };
+
+  struct style {
+    enum : uint32_t {
+      StyleOne = 0x7f020000u,
+      StyleTwo = 0x7f020001u,
+    };
+  };
+};
+
+}  // namespace app
+}  // namespace android
+}  // namespace com
diff --git a/libs/androidfw/tests/data/styles/build.sh b/libs/androidfw/tests/data/styles/build.sh
new file mode 100755
index 0000000..e763421
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/build.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+
+aapt package -F package.apk -M AndroidManifest.xml -S res
+unzip -j package.apk resources.arsc res/layout/layout.xml
+rm package.apk
diff --git a/libs/androidfw/tests/data/styles/layout.xml b/libs/androidfw/tests/data/styles/layout.xml
new file mode 100644
index 0000000..4997e71
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/layout.xml
Binary files differ
diff --git a/libs/androidfw/tests/data/styles/res/layout/layout.xml b/libs/androidfw/tests/data/styles/res/layout/layout.xml
new file mode 100644
index 0000000..f3aa0f8
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/res/layout/layout.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<View xmlns:app="http://schemas.android.com/apk/res-auto"
+    app:attr_four="?attr/attr_indirect"
+    app:attr_three="10" />
+
diff --git a/libs/androidfw/tests/data/styles/res/values/styles.xml b/libs/androidfw/tests/data/styles/res/values/styles.xml
new file mode 100644
index 0000000..70c54f6
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/res/values/styles.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <public type="attr" name="attr_one" id="0x7f010000" />
+    <attr name="attr_one" />
+
+    <public type="attr" name="attr_two" id="0x7f010001" />
+    <attr name="attr_two" />
+
+    <public type="attr" name="attr_three" id="0x7f010002" />
+    <attr name="attr_three" />
+
+    <public type="attr" name="attr_four" id="0x7f010003" />
+    <attr name="attr_four" />
+
+    <public type="attr" name="attr_five" id="0x7f010004" />
+    <attr name="attr_five" />
+
+    <public type="attr" name="attr_indirect" id="0x7f010005" />
+    <attr name="attr_indirect" />
+
+    <public type="string" name="string_one" id="0x7f030000" />
+    <string name="string_one">Hi</string>
+
+    <public type="style" name="StyleOne" id="0x7f020000" />
+    <style name="StyleOne">
+        <item name="attr_one">1</item>
+    </style>
+
+    <public type="style" name="StyleTwo" id="0x7f020001" />
+    <style name="StyleTwo" parent="@style/StyleOne">
+        <item name="attr_indirect">3</item>
+        <item name="attr_two">"string"</item>
+        <item name="attr_three">?attr/attr_indirect</item>
+        <item name="attr_five">@string/string_one</item>
+    </style>
+
+</resources>
diff --git a/libs/androidfw/tests/data/styles/resources.arsc b/libs/androidfw/tests/data/styles/resources.arsc
new file mode 100644
index 0000000..8f65c9a
--- /dev/null
+++ b/libs/androidfw/tests/data/styles/resources.arsc
Binary files differ