libandroidfw: Add new support for shared libraries

This adds support for shared resource libraries in the new
ResTable/AssetManager implementation.

The dynamic package map encoded in resources.arsc is parsed
and stored with LoadedArsc, and combined to form a resolved table
in AssetManager2.

Benchmarks show that this implementation is an order of magnitude
faster on angler-userdebug (make libandroidfw_benchmarks).

Test: libandroidfw_tests
Change-Id: I57c80248728b63b162bf8269ac9495b53c3e7fa0
diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp
index 3a1fc8f..0203712 100644
--- a/libs/androidfw/tests/ApkAssets_test.cpp
+++ b/libs/androidfw/tests/ApkAssets_test.cpp
@@ -26,9 +26,28 @@
 TEST(ApkAssetsTest, LoadApk) {
   std::unique_ptr<ApkAssets> loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
   ASSERT_NE(nullptr, loaded_apk);
+  EXPECT_NE(nullptr, loaded_apk->GetLoadedArsc());
 
   std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml");
   ASSERT_NE(nullptr, asset);
 }
 
+TEST(ApkAssetsTest, LoadApkAsSharedLibrary) {
+  std::unique_ptr<ApkAssets> loaded_apk =
+      ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
+  ASSERT_NE(nullptr, loaded_apk);
+  const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc();
+  ASSERT_NE(nullptr, loaded_arsc);
+  ASSERT_EQ(1u, loaded_arsc->GetPackages().size());
+  EXPECT_FALSE(loaded_arsc->GetPackages()[0]->IsDynamic());
+
+  loaded_apk = ApkAssets::LoadAsSharedLibrary(GetTestDataPath() + "/appaslib/appaslib.apk");
+  ASSERT_NE(nullptr, loaded_apk);
+
+  loaded_arsc = loaded_apk->GetLoadedArsc();
+  ASSERT_NE(nullptr, loaded_arsc);
+  ASSERT_EQ(1u, loaded_arsc->GetPackages().size());
+  EXPECT_TRUE(loaded_arsc->GetPackages()[0]->IsDynamic());
+}
+
 }  // namespace android