Merge "ResXMLTree: Clone DynamicRefTable on creation" into pi-dev
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 298b699..007cddd 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1597,7 +1597,8 @@
 
 ResXMLTree::ResXMLTree(const DynamicRefTable* dynamicRefTable)
     : ResXMLParser(*this)
-    , mDynamicRefTable(dynamicRefTable)
+    , mDynamicRefTable((dynamicRefTable != nullptr) ? dynamicRefTable->clone()
+                                                    : std::unique_ptr<DynamicRefTable>(nullptr))
     , mError(NO_INIT), mOwnedData(NULL)
 {
     if (kDebugResXMLTree) {
@@ -1608,7 +1609,7 @@
 
 ResXMLTree::ResXMLTree()
     : ResXMLParser(*this)
-    , mDynamicRefTable(NULL)
+    , mDynamicRefTable(std::unique_ptr<DynamicRefTable>(nullptr))
     , mError(NO_INIT), mOwnedData(NULL)
 {
     if (kDebugResXMLTree) {
@@ -6864,6 +6865,13 @@
     mLookupTable[SYS_PACKAGE_ID] = SYS_PACKAGE_ID;
 }
 
+std::unique_ptr<DynamicRefTable> DynamicRefTable::clone() const {
+  std::unique_ptr<DynamicRefTable> clone = std::unique_ptr<DynamicRefTable>(
+      new DynamicRefTable(mAssignedPackageId, mAppAsLib));
+  clone->addMappings(*this);
+  return clone;
+}
+
 status_t DynamicRefTable::load(const ResTable_lib_header* const header)
 {
     const uint32_t entryCount = dtohl(header->count);
@@ -6904,7 +6912,7 @@
     for (size_t i = 0; i < entryCount; i++) {
         ssize_t index = mEntries.indexOfKey(other.mEntries.keyAt(i));
         if (index < 0) {
-            mEntries.add(other.mEntries.keyAt(i), other.mEntries[i]);
+            mEntries.add(String16(other.mEntries.keyAt(i)), other.mEntries[i]);
         } else {
             if (other.mEntries[i] != mEntries[index]) {
                 return UNKNOWN_ERROR;
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 63b9e3a..a028515 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -799,6 +799,11 @@
 class ResXMLTree : public ResXMLParser
 {
 public:
+    /**
+     * Creates a ResXMLTree with the specified DynamicRefTable for run-time package id translation.
+     * The tree stores a clone of the specified DynamicRefTable, so any changes to the original
+     * DynamicRefTable will not affect this tree after instantiation.
+     **/
     ResXMLTree(const DynamicRefTable* dynamicRefTable);
     ResXMLTree();
     ~ResXMLTree();
@@ -814,7 +819,7 @@
 
     status_t validateNode(const ResXMLTree_node* node) const;
 
-    const DynamicRefTable* const mDynamicRefTable;
+    std::unique_ptr<const DynamicRefTable> mDynamicRefTable;
 
     status_t                    mError;
     void*                       mOwnedData;
@@ -1655,6 +1660,9 @@
 
     void addMapping(uint8_t buildPackageId, uint8_t runtimePackageId);
 
+    // Creates a new clone of the reference table
+    std::unique_ptr<DynamicRefTable> clone() const;
+
     // Performs the actual conversion of build-time resource ID to run-time
     // resource ID.
     status_t lookupResourceId(uint32_t* resId) const;