1f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski/* 2f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * Copyright (C) 2014 The Android Open Source Project 3f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * 4f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * you may not use this file except in compliance with the License. 6f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * You may obtain a copy of the License at 7f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * 8f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * 10f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * See the License for the specific language governing permissions and 14f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski * limitations under the License. 15f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski */ 16f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 174c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski#include "androidfw/ResourceTypes.h" 18f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 191b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert#include <codecvt> 201b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert#include <locale> 211b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert#include <string> 221b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 234c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski#include "utils/String16.h" 244c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski#include "utils/String8.h" 254c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 26f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski#include "TestHelpers.h" 27ccf25c7bf69eb8c04246e3f79da31b52c2922a80Adam Lesinski#include "data/basic/R.h" 28da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "data/lib_one/R.h" 29f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 304c67a475a334e4f65238d439a3339195e03c03beAdam Lesinskinamespace basic = com::android::basic; 31da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskinamespace lib = com::android::lib_one; 32f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 334c67a475a334e4f65238d439a3339195e03c03beAdam Lesinskinamespace android { 34f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 354c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ShouldLoadSuccessfully) { 364c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 374c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 384c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 39f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 404c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 414c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 424c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski} 43f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 44c8f71aa67ea599cb80205496cb67e9e7a121299cAdam LesinskiTEST(ResTableTest, ShouldLoadSparseEntriesSuccessfully) { 45c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski std::string contents; 46c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc", 47c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski &contents)); 48c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 49c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ResTable table; 50c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 51c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 52c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ResTable_config config; 53c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski memset(&config, 0, sizeof(config)); 54c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski config.sdkVersion = 26; 55c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski table.setParameters(&config); 56c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 57c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski String16 name(u"com.android.sparse:integer/foo_9"); 58c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski uint32_t flags; 59c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski uint32_t resid = 60c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski table.identifierForName(name.string(), name.size(), nullptr, 0, nullptr, 0, &flags); 61c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ASSERT_NE(0u, resid); 62c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 63c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski Res_value val; 64c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ResTable_config selected_config; 65c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski ASSERT_GE( 66c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski table.getResource(resid, &val, false /*mayBeBag*/, 0u /*density*/, &flags, &selected_config), 67c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 0); 68c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski EXPECT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 69c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski EXPECT_EQ(900u, val.data); 70c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski} 71c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 724c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, SimpleTypeIsRetrievedCorrectly) { 734c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 744c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 754c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 76ccf25c7bf69eb8c04246e3f79da31b52c2922a80Adam Lesinski 774c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 784c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 79b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 804c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_TRUE(IsStringEqual(table, basic::R::string::test1, "test1")); 81f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 82f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 834c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ResourceNameIsResolved) { 844c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 854c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 864c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 874c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 884c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 894c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 904c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 914c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski String16 defPackage("com.android.basic"); 924c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski String16 testName("@string/test1"); 934c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski uint32_t resID = 944c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.identifierForName(testName.string(), testName.size(), 0, 0, 954c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski defPackage.string(), defPackage.size()); 964c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_NE(uint32_t(0x00000000), resID); 974c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(basic::R::string::test1, resID); 98f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 99f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1004c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, NoParentThemeIsAppliedCorrectly) { 1014c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 1024c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 1034c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 104f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1054c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 1064c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 107f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1084c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable::Theme theme(table); 1094c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, theme.applyStyle(basic::R::style::Theme1)); 110f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1114c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 1124c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski uint32_t specFlags = 0; 1134c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t index = theme.getAttribute(basic::R::attr::attr1, &val, &specFlags); 1144c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1154c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 1164c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(100), val.data); 117f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1184c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski index = theme.getAttribute(basic::R::attr::attr2, &val, &specFlags); 1194c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1204c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType); 1214c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(basic::R::integer::number1, val.data); 122f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 123f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1244c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ParentThemeIsAppliedCorrectly) { 1254c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 1264c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 1274c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 128f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1294c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 1304c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 131f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1324c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable::Theme theme(table); 1334c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, theme.applyStyle(basic::R::style::Theme2)); 134f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1354c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 1364c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski uint32_t specFlags = 0; 1374c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t index = theme.getAttribute(basic::R::attr::attr1, &val, &specFlags); 1384c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1394c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 1404c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(300), val.data); 141ccf25c7bf69eb8c04246e3f79da31b52c2922a80Adam Lesinski 1424c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski index = theme.getAttribute(basic::R::attr::attr2, &val, &specFlags); 1434c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1444c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType); 1454c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(basic::R::integer::number1, val.data); 146f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 147f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1484c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, LibraryThemeIsAppliedCorrectly) { 1494c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 150da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", 1514c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 152f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1534c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 1544c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 155f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1564c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable::Theme theme(table); 1574c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme)); 158f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1594c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 1604c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski uint32_t specFlags = 0; 1614c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags); 1624c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1634c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 1644c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(700), val.data); 165f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1664c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski index = theme.getAttribute(lib::R::attr::attr2, &val, &specFlags); 1674c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(index, 0); 1684c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 1694c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(700), val.data); 1704c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski} 171f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1724c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ReferenceToBagIsNotResolved) { 1734c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 1744c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 1754c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 1764c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1774c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 1784c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 1794c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1804c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 1814c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t block = 1824c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.getResource(basic::R::integer::number2, &val, MAY_NOT_BE_BAG); 1834c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 1844c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType); 1854c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(basic::R::array::integerArray1, val.data); 1864c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1874c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t newBlock = table.resolveReference(&val, block); 1884c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_EQ(block, newBlock); 1894c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType); 1904c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_EQ(basic::R::array::integerArray1, val.data); 1914c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski} 192f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 1934c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ResourcesStillAccessibleAfterParameterChange) { 1944c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 1954c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 1964c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 1974c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 1984c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 1994c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 2004c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2014c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 2024c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t block = 2034c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 2044c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 2054c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 2064c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2074c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski const ResTable::bag_entry* entry; 2084c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t count = table.lockBag(basic::R::array::integerArray1, &entry); 2094c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(count, 0); 2104c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.unlockBag(entry); 2114c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2124c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable_config param; 2134c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski memset(¶m, 0, sizeof(param)); 2144c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.density = 320; 2154c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.setParameters(¶m); 2164c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2174c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 2184c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 2194c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 2204c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2214c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski count = table.lockBag(basic::R::array::integerArray1, &entry); 2224c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(count, 0); 2234c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.unlockBag(entry); 224f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 225f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2264c67a475a334e4f65238d439a3339195e03c03beAdam LesinskiTEST(ResTableTest, ResourceIsOverridenWithBetterConfig) { 2274c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 2284c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 2294c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 2304c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2314c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 2324c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 2334c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2344c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 2354c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t block = 2364c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 2374c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 2384c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 2394c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(200), val.data); 2404c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2414c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable_config param; 2424c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski memset(¶m, 0, sizeof(param)); 2434c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[0] = 's'; 2444c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[1] = 'v'; 2454c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.country[0] = 'S'; 2464c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.country[1] = 'E'; 2474c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.setParameters(¶m); 2484c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 2494c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 2504c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 2514c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 2524c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(400), val.data); 253f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 254f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski 2552cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam LesinskiTEST(ResTableTest, emptyTableHasSensibleDefaults) { 2564c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski const int32_t assetCookie = 1; 2572cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski 2584c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 2594c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.addEmpty(assetCookie)); 2602cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski 2614c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Adding an empty table gives us one table! 2624c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(1), table.getTableCount()); 2632cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski 2644c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Adding an empty table doesn't mean we get packages. 2654c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(0), table.getBasePackageCount()); 2662cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski 2674c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 2684c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_LT(table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG), 2694c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 0); 2702cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski} 2712cb761e3ddb9d68ab430013e9cd15ecaab9fbc62Adam Lesinski 2721b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albertvoid testU16StringToInt(const char16_t* str, uint32_t expectedValue, 2731b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert bool expectSuccess, bool expectHex) { 2744c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski size_t len = std::char_traits<char16_t>::length(str); 2751b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2764c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Gtest can't print UTF-16 strings, so we have to convert to UTF-8 :( 2774c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; 2784c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string s = convert.to_bytes(std::u16string(str, len)); 2791b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2804c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value out = {}; 2814c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(expectSuccess, U16StringToInt(str, len, &out)) << "Failed with " 2824c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski << s; 2831b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2844c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski if (!expectSuccess) { 2854c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(out.TYPE_NULL, out.dataType) << "Failed with " << s; 2864c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski return; 2874c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } 2881b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2894c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski if (expectHex) { 2904c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(out.TYPE_INT_HEX, out.dataType) << "Failed with " << s; 2914c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } else { 2924c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(out.TYPE_INT_DEC, out.dataType) << "Failed with " << s; 2934c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski } 2941b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2954c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(expectedValue, out.data) << "Failed with " << s; 2961b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert} 2971b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 2981b4f316651096f0ef9301b4ffde4816a08a54ab5Dan AlbertTEST(ResTableTest, U16StringToInt) { 2994c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"", 0U, false, false); 3004c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u" ", 0U, false, false); 3014c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"\t\n", 0U, false, false); 3024c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3034c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"abcd", 0U, false, false); 3044c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"10abcd", 0U, false, false); 3054c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"42 42", 0U, false, false); 3064c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"- 42", 0U, false, false); 3074c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-", 0U, false, false); 3084c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3094c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x", 0U, false, true); 3104c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0xnope", 0U, false, true); 3114c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0X42", 0U, false, true); 3124c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x42 0x42", 0U, false, true); 3134c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-0x0", 0U, false, true); 3144c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-0x42", 0U, false, true); 3154c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"- 0x42", 0U, false, true); 3164c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3174c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Note that u" 42" would pass. This preserves the old behavior, but it may 3184c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // not be desired. 3194c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"42 ", 0U, false, false); 3204c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x42 ", 0U, false, true); 3214c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3224c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Decimal cases. 3234c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0", 0U, true, false); 3244c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-0", 0U, true, false); 3254c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"42", 42U, true, false); 3264c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u" 42", 42U, true, false); 3274c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-42", static_cast<uint32_t>(-42), true, false); 3284c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u" -42", static_cast<uint32_t>(-42), true, false); 3294c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"042", 42U, true, false); 3304c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-042", static_cast<uint32_t>(-42), true, false); 3314c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3324c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Hex cases. 3334c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x0", 0x0, true, true); 3344c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x42", 0x42, true, true); 3354c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u" 0x42", 0x42, true, true); 3364c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3374c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Just before overflow cases: 3384c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"2147483647", INT_MAX, true, false); 3394c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-2147483648", static_cast<uint32_t>(INT_MIN), true, 3404c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski false); 3414c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0xffffffff", UINT_MAX, true, true); 3424c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3434c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Overflow cases: 3444c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"2147483648", 0U, false, false); 3454c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"-2147483649", 0U, false, false); 3464c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski testU16StringToInt(u"0x1ffffffff", 0U, false, true); 3471b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert} 3481b4f316651096f0ef9301b4ffde4816a08a54ab5Dan Albert 349ff5808d223d6359448afc532717b8ccfdc5182d8Adam LesinskiTEST(ResTableTest, ShareButDontModifyResTable) { 3504c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 3514c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 3524c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 3534c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3544c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable sharedTable; 3554c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, sharedTable.add(contents.data(), contents.size())); 3564c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3574c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable_config param; 3584c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski memset(¶m, 0, sizeof(param)); 3594c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[0] = 'v'; 3604c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[1] = 's'; 3614c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski sharedTable.setParameters(¶m); 3624c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3634c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Check that we get the default value for @integer:number1 3644c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Res_value val; 3654c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ssize_t block = 3664c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski sharedTable.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 3674c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 3684c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 3694c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(600), val.data); 3704c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3714c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Create a new table that shares the entries of the shared table. 3724c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 3734c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(&sharedTable, false)); 3744c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3754c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Set a new configuration on the new table. 3764c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski memset(¶m, 0, sizeof(param)); 3774c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[0] = 's'; 3784c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.language[1] = 'v'; 3794c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.country[0] = 'S'; 3804c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski param.country[1] = 'E'; 3814c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.setParameters(¶m); 3824c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3834c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Check that we get a new value in the new table. 3844c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski block = table.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 3854c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 3864c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 3874c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(400), val.data); 3884c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 3894c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski // Check that we still get the old value in the shared table. 3904c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski block = 3914c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski sharedTable.getResource(basic::R::integer::number1, &val, MAY_NOT_BE_BAG); 3924c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_GE(block, 0); 3934c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); 3944c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(uint32_t(600), val.data); 395f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski} 396ff5808d223d6359448afc532717b8ccfdc5182d8Adam Lesinski 397b7e1ce07756aaca829828c2053eca0d66dd4d440Adam LesinskiTEST(ResTableTest, GetConfigurationsReturnsUniqueList) { 3984c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string contents; 3994c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 4004c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &contents)); 4014c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 4024c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski std::string system_contents; 4034c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/system/system.apk", 4044c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski "resources.arsc", &system_contents)); 4054c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski 4064c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable table; 4074c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, 4084c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.add(system_contents.data(), system_contents.size())); 4094c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 410b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4114c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski ResTable_config configSv; 4124c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski memset(&configSv, 0, sizeof(configSv)); 4134c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski configSv.language[0] = 's'; 4144c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski configSv.language[1] = 'v'; 415b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4164c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Vector<ResTable_config> configs; 4174c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.getConfigurations(&configs); 418b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4194c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_EQ(1, std::count(configs.begin(), configs.end(), configSv)); 420b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4214c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski Vector<String8> locales; 4224c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski table.getLocales(&locales); 423b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4244c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski EXPECT_EQ(1, std::count(locales.begin(), locales.end(), String8("sv"))); 425b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski} 426b7e1ce07756aaca829828c2053eca0d66dd4d440Adam Lesinski 4272ad530d76c55c86d28c893b904b4f12aca65443fRyan MitchellTEST(ResTableTest, TruncatedEncodeLength) { 4282ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell std::string contents; 4292ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/length_decode/length_decode_valid.apk", 4302ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell "resources.arsc", &contents)); 4312ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4322ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ResTable table; 4332ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size())); 4342ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4352ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell Res_value val; 4362ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ssize_t block = table.getResource(0x7f010001, &val, MAY_NOT_BE_BAG); 4372ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_GE(block, 0); 4382ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(Res_value::TYPE_STRING, val.dataType); 4392ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4402ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell const ResStringPool* pool = table.getTableStringBlock(block); 4412ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(pool != NULL); 4422ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_LT(val.data, pool->size()); 4432ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4442ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell // Make sure a string with a truncated length is read to its correct length 4452ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell size_t str_len; 4462ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell const char* target_str8 = pool->string8At(val.data, &str_len); 4472ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(target_str8 != NULL); 4482ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(size_t(40076), String8(target_str8, str_len).size()); 4492ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(target_str8[40075], ']'); 4502ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4512ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell const char16_t* target_str16 = pool->stringAt(val.data, &str_len); 4522ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(target_str16 != NULL); 4532ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(size_t(40076), String16(target_str16, str_len).size()); 4542ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(target_str8[40075], (char16_t) ']'); 4552ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4562ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell // Load an edited apk with the null terminator removed from the end of the 4572ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell // string 4582ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell std::string invalid_contents; 4592ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/length_decode/length_decode_invalid.apk", 4602ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell "resources.arsc", &invalid_contents)); 4612ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ResTable invalid_table; 4622ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(NO_ERROR, invalid_table.add(invalid_contents.data(), invalid_contents.size())); 4632ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4642ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell Res_value invalid_val; 4652ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ssize_t invalid_block = invalid_table.getResource(0x7f010001, &invalid_val, MAY_NOT_BE_BAG); 4662ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_GE(invalid_block, 0); 4672ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_EQ(Res_value::TYPE_STRING, invalid_val.dataType); 4682ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4692ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell const ResStringPool* invalid_pool = invalid_table.getTableStringBlock(invalid_block); 4702ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(invalid_pool != NULL); 4712ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_LT(invalid_val.data, invalid_pool->size()); 4722ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4732ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell // Make sure a string with a truncated length that is not null terminated errors 4742ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell // and does not return the string 4752ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(invalid_pool->string8At(invalid_val.data, &str_len) == NULL); 4762ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell ASSERT_TRUE(invalid_pool->stringAt(invalid_val.data, &str_len) == NULL); 4772ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell} 4782ad530d76c55c86d28c893b904b4f12aca65443fRyan Mitchell 4794c67a475a334e4f65238d439a3339195e03c03beAdam Lesinski} // namespace android 480