Fix shared library bug in bag attributes

A ResTable_map entry has a name attribute, which
could be a dynamic reference if it comes from
a shared library. It was not being patched with
the correct package id.

Bug:16795890
Change-Id: Ia8df6a943269b2fefb2132c3ed74eb1997d7701b
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 4147608..5faf03d 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1021,7 +1021,7 @@
         return JNI_FALSE;
     }
 
-    DEBUG_STYLES(LOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x",
+    DEBUG_STYLES(ALOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x",
         themeToken, defStyleAttr, defStyleRes));
 
     ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
@@ -1089,7 +1089,7 @@
     for (jsize ii=0; ii<NI; ii++) {
         const uint32_t curIdent = (uint32_t)src[ii];
 
-        DEBUG_STYLES(LOGI("RETRIEVING ATTR 0x%08x...", curIdent));
+        DEBUG_STYLES(ALOGI("RETRIEVING ATTR 0x%08x...", curIdent));
 
         // Try to find a value for this attribute...  we prioritize values
         // coming from, first XML attributes, then XML style, then default
@@ -1104,7 +1104,7 @@
             block = -1;
             value.dataType = Res_value::TYPE_ATTRIBUTE;
             value.data = srcValues[ii];
-            DEBUG_STYLES(LOGI("-> From values: type=0x%x, data=0x%08x",
+            DEBUG_STYLES(ALOGI("-> From values: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         }
 
@@ -1118,7 +1118,7 @@
                 block = defStyleEnt->stringBlock;
                 typeSetFlags = defStyleTypeSetFlags;
                 value = defStyleEnt->map.value;
-                DEBUG_STYLES(LOGI("-> From def style: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> From def style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
             defStyleEnt++;
@@ -1130,14 +1130,14 @@
             ssize_t newBlock = theme->resolveAttributeReference(&value, block,
                     &resid, &typeSetFlags, &config);
             if (newBlock >= 0) block = newBlock;
-            DEBUG_STYLES(LOGI("-> Resolved attr: type=0x%x, data=0x%08x",
+            DEBUG_STYLES(ALOGI("-> Resolved attr: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         } else {
             // If we still don't have a value for this attribute, try to find
             // it in the theme!
             ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
             if (newBlock >= 0) {
-                DEBUG_STYLES(LOGI("-> From theme: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> From theme: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
                 newBlock = res.resolveReference(&value, block, &resid,
                         &typeSetFlags, &config);
@@ -1148,19 +1148,19 @@
                 }
 #endif
                 if (newBlock >= 0) block = newBlock;
-                DEBUG_STYLES(LOGI("-> Resolved theme: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> Resolved theme: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
         }
 
         // Deal with the special @null value -- it turns back to TYPE_NULL.
         if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
-            DEBUG_STYLES(LOGI("-> Setting to @null!"));
+            DEBUG_STYLES(ALOGI("-> Setting to @null!"));
             value.dataType = Res_value::TYPE_NULL;
             block = -1;
         }
 
-        DEBUG_STYLES(LOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
+        DEBUG_STYLES(ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
                 curIdent, value.dataType, value.data));
 
         // Write the final value back to Java.
@@ -1215,7 +1215,7 @@
         return JNI_FALSE;
     }
 
-    DEBUG_STYLES(LOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x",
+    DEBUG_STYLES(ALOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x",
         themeToken, defStyleAttr, defStyleRes, xmlParserToken));
 
     ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
@@ -1313,7 +1313,7 @@
     for (jsize ii=0; ii<NI; ii++) {
         const uint32_t curIdent = (uint32_t)src[ii];
 
-        DEBUG_STYLES(LOGI("RETRIEVING ATTR 0x%08x...", curIdent));
+        DEBUG_STYLES(ALOGI("RETRIEVING ATTR 0x%08x...", curIdent));
 
         // Try to find a value for this attribute...  we prioritize values
         // coming from, first XML attributes, then XML style, then default
@@ -1334,7 +1334,7 @@
             xmlParser->getAttributeValue(ix, &value);
             ix++;
             curXmlAttr = xmlParser->getAttributeNameResID(ix);
-            DEBUG_STYLES(LOGI("-> From XML: type=0x%x, data=0x%08x",
+            DEBUG_STYLES(ALOGI("-> From XML: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         }
 
@@ -1348,7 +1348,7 @@
                 block = styleEnt->stringBlock;
                 typeSetFlags = styleTypeSetFlags;
                 value = styleEnt->map.value;
-                DEBUG_STYLES(LOGI("-> From style: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> From style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
             styleEnt++;
@@ -1364,7 +1364,7 @@
                 block = defStyleEnt->stringBlock;
                 typeSetFlags = defStyleTypeSetFlags;
                 value = defStyleEnt->map.value;
-                DEBUG_STYLES(LOGI("-> From def style: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> From def style: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
             defStyleEnt++;
@@ -1376,14 +1376,14 @@
             ssize_t newBlock = theme->resolveAttributeReference(&value, block,
                     &resid, &typeSetFlags, &config);
             if (newBlock >= 0) block = newBlock;
-            DEBUG_STYLES(LOGI("-> Resolved attr: type=0x%x, data=0x%08x",
+            DEBUG_STYLES(ALOGI("-> Resolved attr: type=0x%x, data=0x%08x",
                     value.dataType, value.data));
         } else {
             // If we still don't have a value for this attribute, try to find
             // it in the theme!
             ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
             if (newBlock >= 0) {
-                DEBUG_STYLES(LOGI("-> From theme: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> From theme: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
                 newBlock = res.resolveReference(&value, block, &resid,
                         &typeSetFlags, &config);
@@ -1394,19 +1394,19 @@
                 }
 #endif
                 if (newBlock >= 0) block = newBlock;
-                DEBUG_STYLES(LOGI("-> Resolved theme: type=0x%x, data=0x%08x",
+                DEBUG_STYLES(ALOGI("-> Resolved theme: type=0x%x, data=0x%08x",
                         value.dataType, value.data));
             }
         }
 
         // Deal with the special @null value -- it turns back to TYPE_NULL.
         if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
-            DEBUG_STYLES(LOGI("-> Setting to @null!"));
+            DEBUG_STYLES(ALOGI("-> Setting to @null!"));
             value.dataType = Res_value::TYPE_NULL;
             block = kXmlBlock;
         }
 
-        DEBUG_STYLES(LOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
+        DEBUG_STYLES(ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
                 curIdent, value.dataType, value.data));
 
         // Write the final value back to Java.
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index cc22564..7661d58 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -3907,7 +3907,17 @@
         map = (const ResTable_map*)(((const uint8_t*)entry.type) + curOff);
         N++;
 
-        const uint32_t newName = htodl(map->name.ident);
+        uint32_t newName = htodl(map->name.ident);
+        if (!Res_INTERNALID(newName)) {
+            // Attributes don't have a resource id as the name. They specify
+            // other data, which would be wrong to change via a lookup.
+            if (grp->dynamicRefTable.lookupResourceId(&newName) != NO_ERROR) {
+                ALOGE("Failed resolving ResTable_map name at %d with ident 0x%08x",
+                        (int) curOff, (int) newName);
+                return UNKNOWN_ERROR;
+            }
+        }
+
         bool isInside;
         uint32_t oldName = 0;
         while ((isInside=(curEntry < set->numAttrs))
@@ -5856,11 +5866,11 @@
     // Do a proper lookup.
     uint8_t translatedId = mLookupTable[packageId];
     if (translatedId == 0) {
-        ALOGV("DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.",
+        ALOGE("DynamicRefTable(0x%02x): No mapping for build-time package ID 0x%02x.",
                 (uint8_t)mAssignedPackageId, (uint8_t)packageId);
         for (size_t i = 0; i < 256; i++) {
             if (mLookupTable[i] != 0) {
-                ALOGV("e[0x%02x] -> 0x%02x", (uint8_t)i, mLookupTable[i]);
+                ALOGE("e[0x%02x] -> 0x%02x", (uint8_t)i, mLookupTable[i]);
             }
         }
         return UNKNOWN_ERROR;
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index 7a4d1ad..f50c178 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -19,7 +19,7 @@
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include "TestHelpers.h"
-#include "data/R.h"
+#include "data/basic/R.h"
 
 #include <gtest/gtest.h>
 
@@ -70,7 +70,7 @@
 
 TEST_F(IdmapTest, overlayOverridesResourceValue) {
     Res_value val;
-    ssize_t block = mTargetTable.getResource(R::string::test2, &val, false);
+    ssize_t block = mTargetTable.getResource(base::R::string::test2, &val, false);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
     const ResStringPool* pool = mTargetTable.getTableStringBlock(block);
@@ -84,7 +84,7 @@
 
     ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));
 
-    ssize_t newBlock = mTargetTable.getResource(R::string::test2, &val, false);
+    ssize_t newBlock = mTargetTable.getResource(base::R::string::test2, &val, false);
     ASSERT_GE(newBlock, 0);
     ASSERT_NE(block, newBlock);
     ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
@@ -101,7 +101,7 @@
     ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));
 
     ResTable::resource_name resName;
-    ASSERT_TRUE(mTargetTable.getResourceName(R::array::integerArray1, false, &resName));
+    ASSERT_TRUE(mTargetTable.getResourceName(base::R::array::integerArray1, false, &resName));
 
     ASSERT_TRUE(resName.package != NULL);
     ASSERT_TRUE(resName.type != NULL);
diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp
index 6bdf703..8016a82 100644
--- a/libs/androidfw/tests/ResTable_test.cpp
+++ b/libs/androidfw/tests/ResTable_test.cpp
@@ -19,7 +19,8 @@
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include "TestHelpers.h"
-#include "data/R.h"
+#include "data/basic/R.h"
+#include "data/lib/R.h"
 
 #include <gtest/gtest.h>
 
@@ -34,6 +35,8 @@
  */
 #include "data/basic/basic_arsc.h"
 
+#include "data/lib/lib_arsc.h"
+
 enum { MAY_NOT_BE_BAG = false };
 
 TEST(ResTableTest, shouldLoadSuccessfully) {
@@ -46,7 +49,7 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     Res_value val;
-    ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG);
+    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG);
 
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
@@ -66,7 +69,7 @@
                                              0, 0,
                                              defPackage.string(), defPackage.size());
     ASSERT_NE(uint32_t(0x00000000), resID);
-    ASSERT_EQ(R::string::test1, resID);
+    ASSERT_EQ(base::R::string::test1, resID);
 }
 
 TEST(ResTableTest, noParentThemeIsAppliedCorrectly) {
@@ -74,19 +77,19 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     ResTable::Theme theme(table);
-    ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::Theme1));
+    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme1));
 
     Res_value val;
     uint32_t specFlags = 0;
-    ssize_t index = theme.getAttribute(R::attr::attr1, &val, &specFlags);
+    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
     ASSERT_GE(index, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
     ASSERT_EQ(uint32_t(100), val.data);
 
-    index = theme.getAttribute(R::attr::attr2, &val, &specFlags);
+    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
     ASSERT_GE(index, 0);
     ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-    ASSERT_EQ(R::integer::number1, val.data);
+    ASSERT_EQ(base::R::integer::number1, val.data);
 }
 
 TEST(ResTableTest, parentThemeIsAppliedCorrectly) {
@@ -94,19 +97,34 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     ResTable::Theme theme(table);
-    ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::Theme2));
+    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme2));
 
     Res_value val;
     uint32_t specFlags = 0;
-    ssize_t index = theme.getAttribute(R::attr::attr1, &val, &specFlags);
+    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
     ASSERT_GE(index, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
     ASSERT_EQ(uint32_t(300), val.data);
 
-    index = theme.getAttribute(R::attr::attr2, &val, &specFlags);
+    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
     ASSERT_GE(index, 0);
     ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-    ASSERT_EQ(R::integer::number1, val.data);
+    ASSERT_EQ(base::R::integer::number1, val.data);
+}
+
+TEST(ResTableTest, libraryThemeIsAppliedCorrectly) {
+    ResTable table;
+    ASSERT_EQ(NO_ERROR, table.add(lib_arsc, lib_arsc_len));
+
+    ResTable::Theme theme(table);
+    ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));
+
+    Res_value val;
+    uint32_t specFlags = 0;
+    ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);
+    ASSERT_GE(index, 0);
+    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
+    ASSERT_EQ(uint32_t(700), val.data);
 }
 
 TEST(ResTableTest, referenceToBagIsNotResolved) {
@@ -114,15 +132,15 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     Res_value val;
-    ssize_t block = table.getResource(R::integer::number2, &val, MAY_NOT_BE_BAG);
+    ssize_t block = table.getResource(base::R::integer::number2, &val, MAY_NOT_BE_BAG);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-    ASSERT_EQ(R::array::integerArray1, val.data);
+    ASSERT_EQ(base::R::array::integerArray1, val.data);
 
     ssize_t newBlock = table.resolveReference(&val, block);
     EXPECT_EQ(block, newBlock);
     EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-    EXPECT_EQ(R::array::integerArray1, val.data);
+    EXPECT_EQ(base::R::array::integerArray1, val.data);
 }
 
 TEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {
@@ -130,12 +148,12 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     Res_value val;
-    ssize_t block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
+    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
 
     const ResTable::bag_entry* entry;
-    ssize_t count = table.lockBag(R::array::integerArray1, &entry);
+    ssize_t count = table.lockBag(base::R::array::integerArray1, &entry);
     ASSERT_GE(count, 0);
     table.unlockBag(entry);
 
@@ -144,11 +162,11 @@
     param.density = 320;
     table.setParameters(&param);
 
-    block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
+    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
 
-    count = table.lockBag(R::array::integerArray1, &entry);
+    count = table.lockBag(base::R::array::integerArray1, &entry);
     ASSERT_GE(count, 0);
     table.unlockBag(entry);
 }
@@ -158,7 +176,7 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     Res_value val;
-    ssize_t block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
+    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
     ASSERT_EQ(uint32_t(200), val.data);
@@ -171,7 +189,7 @@
     param.country[1] = 'E';
     table.setParameters(&param);
 
-    block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
+    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
     ASSERT_GE(block, 0);
     ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
     ASSERT_EQ(uint32_t(400), val.data);
diff --git a/libs/androidfw/tests/Split_test.cpp b/libs/androidfw/tests/Split_test.cpp
index 9fef963..82703f9 100644
--- a/libs/androidfw/tests/Split_test.cpp
+++ b/libs/androidfw/tests/Split_test.cpp
@@ -19,7 +19,7 @@
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include "TestHelpers.h"
-#include "data/R.h"
+#include "data/basic/R.h"
 
 #include <gtest/gtest.h>
 
@@ -78,7 +78,7 @@
 
     Res_value val;
     ResTable_config config;
-    ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
+    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
 
     // The returned block should tell us which string pool to get the value, if it is a string.
     EXPECT_GE(block, 0);
@@ -101,7 +101,7 @@
 
     Res_value val;
     ResTable_config config;
-    ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
+    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config);
 
     EXPECT_GE(block, 0);
 
@@ -120,12 +120,12 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     ResTable::resource_name baseName;
-    EXPECT_TRUE(table.getResourceName(R::string::test1, false, &baseName));
+    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &baseName));
 
     ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));
 
     ResTable::resource_name frName;
-    EXPECT_TRUE(table.getResourceName(R::string::test1, false, &frName));
+    EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &frName));
 
     EXPECT_EQ(
             String16(baseName.package, baseName.packageLen),
@@ -149,7 +149,7 @@
 
     Res_value val;
     uint32_t specFlags = 0;
-    ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL);
+    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL);
     EXPECT_GE(block, 0);
 
     EXPECT_EQ(static_cast<uint32_t>(0), specFlags);
@@ -157,7 +157,7 @@
     ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len));
 
     uint32_t frSpecFlags = 0;
-    block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL);
+    block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL);
     EXPECT_GE(block, 0);
 
     EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags);
@@ -168,12 +168,12 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     Res_value val;
-    ssize_t block = table.getResource(R::string::test3, &val, MAY_NOT_BE_BAG);
+    ssize_t block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);
     EXPECT_LT(block, 0);
 
     ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
 
-    block = table.getResource(R::string::test3, &val, MAY_NOT_BE_BAG);
+    block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG);
     EXPECT_GE(block, 0);
 
     EXPECT_EQ(Res_value::TYPE_STRING, val.dataType);
@@ -184,11 +184,11 @@
     ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
 
     ResTable::resource_name name;
-    EXPECT_FALSE(table.getResourceName(R::string::test3, false, &name));
+    EXPECT_FALSE(table.getResourceName(base::R::string::test3, false, &name));
 
     ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len));
 
-    EXPECT_TRUE(table.getResourceName(R::string::test3, false, &name));
+    EXPECT_TRUE(table.getResourceName(base::R::string::test3, false, &name));
 
     EXPECT_EQ(String16("com.android.test.basic"),
             String16(name.package, name.packageLen));
diff --git a/libs/androidfw/tests/data/R.h b/libs/androidfw/tests/data/basic/R.h
similarity index 88%
rename from libs/androidfw/tests/data/R.h
rename to libs/androidfw/tests/data/basic/R.h
index e4c65c7..363dcb9 100644
--- a/libs/androidfw/tests/data/R.h
+++ b/libs/androidfw/tests/data/basic/R.h
@@ -1,6 +1,7 @@
-#ifndef __R_H
-#define __R_H
+#ifndef __BASE_R_H
+#define __BASE_R_H
 
+namespace base {
 namespace R {
 
 namespace attr {
@@ -48,6 +49,7 @@
     };
 }
 
-}
+} // namespace R
+} // namespace base
 
-#endif // __R_H
+#endif // __BASE_R_H
diff --git a/libs/androidfw/tests/data/lib/AndroidManifest.xml b/libs/androidfw/tests/data/lib/AndroidManifest.xml
new file mode 100644
index 0000000..a56ac18
--- /dev/null
+++ b/libs/androidfw/tests/data/lib/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.test.basic">
+    <application>
+    </application>
+</manifest>
diff --git a/libs/androidfw/tests/data/lib/R.h b/libs/androidfw/tests/data/lib/R.h
new file mode 100644
index 0000000..13bf095
--- /dev/null
+++ b/libs/androidfw/tests/data/lib/R.h
@@ -0,0 +1,22 @@
+#ifndef __LIB_R_H
+#define __LIB_R_H
+
+namespace lib {
+namespace R {
+
+namespace attr {
+    enum {
+        attr1       = 0x02010000, // default
+    };
+}
+
+namespace style {
+    enum {
+        Theme        = 0x02020000,  // default
+    };
+}
+
+} // namespace R
+} // namespace lib
+
+#endif // __LIB_R_H
diff --git a/libs/androidfw/tests/data/lib/build b/libs/androidfw/tests/data/lib/build
new file mode 100755
index 0000000..8e6e70c
--- /dev/null
+++ b/libs/androidfw/tests/data/lib/build
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+aapt package -M AndroidManifest.xml -S res -F bundle.apk -f --shared-lib && \
+unzip bundle.apk resources.arsc && \
+mv resources.arsc lib.arsc && \
+xxd -i lib.arsc > lib_arsc.h
diff --git a/libs/androidfw/tests/data/lib/lib_arsc.h b/libs/androidfw/tests/data/lib/lib_arsc.h
new file mode 100644
index 0000000..d670c5b
--- /dev/null
+++ b/libs/androidfw/tests/data/lib/lib_arsc.h
@@ -0,0 +1,84 @@
+unsigned char lib_arsc[] = {
+  0x02, 0x00, 0x0c, 0x00, 0xc8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xa0, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,
+  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,
+  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00,
+  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00,
+  0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00,
+  0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00,
+  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00,
+  0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00,
+  0x03, 0x02, 0x0c, 0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,
+  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,
+  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00
+};
+unsigned int lib_arsc_len = 968;
diff --git a/libs/androidfw/tests/data/lib/res/values/values.xml b/libs/androidfw/tests/data/lib/res/values/values.xml
new file mode 100644
index 0000000..a77f0c7
--- /dev/null
+++ b/libs/androidfw/tests/data/lib/res/values/values.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <attr name="attr1" format="integer" />
+
+    <style name="Theme">
+        <item name="com.android.test.basic:attr1">700</item>
+    </style>
+</resources>