1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "androidfw/ResourceTypes.h" 18 19#include "utils/String16.h" 20#include "utils/String8.h" 21 22#include "TestHelpers.h" 23#include "data/basic/R.h" 24 25using com::android::basic::R; 26 27namespace android { 28 29static void makeConfigFrench(ResTable_config* config) { 30 memset(config, 0, sizeof(*config)); 31 config->language[0] = 'f'; 32 config->language[1] = 'r'; 33} 34 35class SplitTest : public ::testing::Test { 36 public: 37 void SetUp() override { 38 ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", 39 "resources.arsc", &basic_contents_)); 40 ASSERT_TRUE( 41 ReadFileFromZipToString(GetTestDataPath() + "/basic/basic_de_fr.apk", 42 "resources.arsc", &basic_de_fr_contents_)); 43 ASSERT_TRUE( 44 ReadFileFromZipToString(GetTestDataPath() + "/basic/basic_hdpi-v4.apk", 45 "resources.arsc", &basic_hdpi_contents_)); 46 ASSERT_TRUE( 47 ReadFileFromZipToString(GetTestDataPath() + "/basic/basic_xhdpi-v4.apk", 48 "resources.arsc", &basic_xhdpi_contents_)); 49 ASSERT_TRUE(ReadFileFromZipToString( 50 GetTestDataPath() + "/basic/basic_xxhdpi-v4.apk", "resources.arsc", 51 &basic_xxhdpi_contents_)); 52 ASSERT_TRUE( 53 ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", 54 "resources.arsc", &feature_contents_)); 55 } 56 57 protected: 58 std::string basic_contents_; 59 std::string basic_de_fr_contents_; 60 std::string basic_hdpi_contents_; 61 std::string basic_xhdpi_contents_; 62 std::string basic_xxhdpi_contents_; 63 std::string feature_contents_; 64}; 65 66TEST_F(SplitTest, TestLoadBase) { 67 ResTable table; 68 ASSERT_EQ(NO_ERROR, 69 table.add(basic_contents_.data(), basic_contents_.size())); 70} 71 72TEST_F(SplitTest, TestGetResourceFromBase) { 73 ResTable_config frenchConfig; 74 makeConfigFrench(&frenchConfig); 75 76 ResTable table; 77 table.setParameters(&frenchConfig); 78 79 ASSERT_EQ(NO_ERROR, 80 table.add(basic_contents_.data(), basic_contents_.size())); 81 82 ResTable_config expectedConfig; 83 memset(&expectedConfig, 0, sizeof(expectedConfig)); 84 85 Res_value val; 86 ResTable_config config; 87 ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, 88 NULL, &config); 89 90 // The returned block should tell us which string pool to get the value, if it 91 // is a string. 92 EXPECT_GE(block, 0); 93 94 // We expect the default resource to be selected since it is the only resource 95 // configuration. 96 EXPECT_EQ(0, expectedConfig.compare(config)); 97 98 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 99} 100 101TEST_F(SplitTest, TestGetResourceFromSplit) { 102 ResTable_config expectedConfig; 103 makeConfigFrench(&expectedConfig); 104 105 ResTable table; 106 table.setParameters(&expectedConfig); 107 108 ASSERT_EQ(NO_ERROR, 109 table.add(basic_contents_.data(), basic_contents_.size())); 110 ASSERT_EQ(NO_ERROR, table.add(basic_de_fr_contents_.data(), 111 basic_de_fr_contents_.size())); 112 113 Res_value val; 114 ResTable_config config; 115 ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, 116 NULL, &config); 117 118 EXPECT_GE(block, 0); 119 120 EXPECT_EQ(0, expectedConfig.compare(config)); 121 122 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 123} 124 125TEST_F(SplitTest, ResourcesFromBaseAndSplitHaveSameNames) { 126 ResTable_config expectedConfig; 127 makeConfigFrench(&expectedConfig); 128 129 ResTable table; 130 table.setParameters(&expectedConfig); 131 132 ASSERT_EQ(NO_ERROR, 133 table.add(basic_contents_.data(), basic_contents_.size())); 134 135 ResTable::resource_name baseName; 136 EXPECT_TRUE(table.getResourceName(R::string::test1, false, &baseName)); 137 138 ASSERT_EQ(NO_ERROR, table.add(basic_de_fr_contents_.data(), 139 basic_de_fr_contents_.size())); 140 141 ResTable::resource_name frName; 142 EXPECT_TRUE(table.getResourceName(R::string::test1, false, &frName)); 143 144 EXPECT_EQ(String16(baseName.package, baseName.packageLen), 145 String16(frName.package, frName.packageLen)); 146 147 EXPECT_EQ(String16(baseName.type, baseName.typeLen), 148 String16(frName.type, frName.typeLen)); 149 150 EXPECT_EQ(String16(baseName.name, baseName.nameLen), 151 String16(frName.name, frName.nameLen)); 152} 153 154TEST_F(SplitTest, TypeEntrySpecFlagsAreUpdated) { 155 ResTable_config defaultConfig; 156 memset(&defaultConfig, 0, sizeof(defaultConfig)); 157 158 ResTable table; 159 ASSERT_EQ(NO_ERROR, 160 table.add(basic_contents_.data(), basic_contents_.size())); 161 162 Res_value val; 163 uint32_t specFlags = 0; 164 ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, 165 &specFlags, NULL); 166 EXPECT_GE(block, 0); 167 168 EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), specFlags); 169 170 ASSERT_EQ(NO_ERROR, table.add(basic_de_fr_contents_.data(), 171 basic_de_fr_contents_.size())); 172 173 uint32_t frSpecFlags = 0; 174 block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG, 0, 175 &frSpecFlags, NULL); 176 ASSERT_GE(block, 0); 177 178 EXPECT_EQ(static_cast<uint32_t>(ResTable_config::CONFIG_LOCALE | ResTable_typeSpec::SPEC_PUBLIC), 179 frSpecFlags); 180} 181 182TEST_F(SplitTest, SelectBestDensity) { 183 ResTable_config baseConfig; 184 memset(&baseConfig, 0, sizeof(baseConfig)); 185 baseConfig.density = ResTable_config::DENSITY_XHIGH; 186 baseConfig.sdkVersion = 21; 187 188 ResTable table; 189 table.setParameters(&baseConfig); 190 ASSERT_EQ(NO_ERROR, 191 table.add(basic_contents_.data(), basic_contents_.size())); 192 ASSERT_EQ(NO_ERROR, table.add(basic_hdpi_contents_.data(), 193 basic_hdpi_contents_.size())); 194 195 EXPECT_TRUE(IsStringEqual(table, R::string::density, "hdpi")); 196 197 ASSERT_EQ(NO_ERROR, table.add(basic_xhdpi_contents_.data(), 198 basic_xhdpi_contents_.size())); 199 200 EXPECT_TRUE(IsStringEqual(table, R::string::density, "xhdpi")); 201 202 ASSERT_EQ(NO_ERROR, table.add(basic_xxhdpi_contents_.data(), 203 basic_xxhdpi_contents_.size())); 204 205 EXPECT_TRUE(IsStringEqual(table, R::string::density, "xhdpi")); 206 207 baseConfig.density = ResTable_config::DENSITY_XXHIGH; 208 table.setParameters(&baseConfig); 209 210 EXPECT_TRUE(IsStringEqual(table, R::string::density, "xxhdpi")); 211} 212 213TEST_F(SplitTest, TestNewResourceIsAccessible) { 214 ResTable table; 215 ASSERT_EQ(NO_ERROR, 216 table.add(basic_contents_.data(), basic_contents_.size())); 217 218 Res_value val; 219 ssize_t block = table.getResource(R::string::test3, &val, MAY_NOT_BE_BAG); 220 EXPECT_LT(block, 0); 221 222 ASSERT_EQ(NO_ERROR, 223 table.add(feature_contents_.data(), feature_contents_.size())); 224 225 block = table.getResource(R::string::test3, &val, MAY_NOT_BE_BAG); 226 ASSERT_GE(block, 0); 227 228 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 229} 230 231TEST_F(SplitTest, TestNewResourceNameHasCorrectName) { 232 ResTable table; 233 ASSERT_EQ(NO_ERROR, 234 table.add(basic_contents_.data(), basic_contents_.size())); 235 236 ResTable::resource_name name; 237 EXPECT_FALSE(table.getResourceName(R::string::test3, false, &name)); 238 239 ASSERT_EQ(NO_ERROR, 240 table.add(feature_contents_.data(), feature_contents_.size())); 241 242 ASSERT_TRUE(table.getResourceName(R::string::test3, false, &name)); 243 244 EXPECT_EQ(String16("com.android.basic"), 245 String16(name.package, name.packageLen)); 246 247 EXPECT_EQ(String16("string"), String16(name.type, name.typeLen)); 248 249 EXPECT_EQ(String16("test3"), String16(name.name, name.nameLen)); 250} 251 252TEST_F(SplitTest, TestNewResourceIsAccessibleByName) { 253 ResTable table; 254 ASSERT_EQ(NO_ERROR, 255 table.add(basic_contents_.data(), basic_contents_.size())); 256 ASSERT_EQ(NO_ERROR, 257 table.add(feature_contents_.data(), feature_contents_.size())); 258 259 const String16 name("test3"); 260 const String16 type("string"); 261 const String16 package("com.android.basic"); 262 ASSERT_EQ( 263 R::string::test3, 264 table.identifierForName(name.string(), name.size(), type.string(), 265 type.size(), package.string(), package.size())); 266} 267 268} // namespace 269