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/String8.h> 20 #include <utils/String16.h> 21 #include "TestHelpers.h" 22 #include "data/basic/R.h" 23 24 #include <gtest/gtest.h> 25 26 using namespace android; 27 28 namespace { 29 30 /** 31 * Include a binary resource table. This table 32 * is a base table for an APK split. 33 * 34 * Package: com.android.test.basic 35 */ 36 #include "data/basic/basic_arsc.h" 37 38 /** 39 * Include a binary resource table. This table 40 * is a configuration split table for an APK split. 41 * 42 * Package: com.android.test.basic 43 */ 44 #include "data/basic/split_de_fr_arsc.h" 45 #include "data/basic/split_hdpi_v4_arsc.h" 46 #include "data/basic/split_xhdpi_v4_arsc.h" 47 #include "data/basic/split_xxhdpi_v4_arsc.h" 48 49 /** 50 * Include a binary resource table. This table 51 * is a feature split table for an APK split. 52 * 53 * Package: com.android.test.basic 54 */ 55 #include "data/feature/feature_arsc.h" 56 57 enum { MAY_NOT_BE_BAG = false }; 58 59 void makeConfigFrench(ResTable_config* config) { 60 memset(config, 0, sizeof(*config)); 61 config->language[0] = 'f'; 62 config->language[1] = 'r'; 63 } 64 65 TEST(SplitTest, TestLoadBase) { 66 ResTable table; 67 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 68 } 69 70 TEST(SplitTest, TestGetResourceFromBase) { 71 ResTable_config frenchConfig; 72 makeConfigFrench(&frenchConfig); 73 74 ResTable table; 75 table.setParameters(&frenchConfig); 76 77 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 78 79 ResTable_config expectedConfig; 80 memset(&expectedConfig, 0, sizeof(expectedConfig)); 81 82 Res_value val; 83 ResTable_config config; 84 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config); 85 86 // The returned block should tell us which string pool to get the value, if it is a string. 87 EXPECT_GE(block, 0); 88 89 // We expect the default resource to be selected since it is the only resource configuration. 90 EXPECT_EQ(0, expectedConfig.compare(config)); 91 92 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 93 } 94 95 TEST(SplitTest, TestGetResourceFromSplit) { 96 ResTable_config expectedConfig; 97 makeConfigFrench(&expectedConfig); 98 99 ResTable table; 100 table.setParameters(&expectedConfig); 101 102 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 103 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len)); 104 105 Res_value val; 106 ResTable_config config; 107 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, NULL, &config); 108 109 EXPECT_GE(block, 0); 110 111 EXPECT_EQ(0, expectedConfig.compare(config)); 112 113 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 114 } 115 116 TEST(SplitTest, ResourcesFromBaseAndSplitHaveSameNames) { 117 ResTable_config expectedConfig; 118 makeConfigFrench(&expectedConfig); 119 120 ResTable table; 121 table.setParameters(&expectedConfig); 122 123 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 124 125 ResTable::resource_name baseName; 126 EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &baseName)); 127 128 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len)); 129 130 ResTable::resource_name frName; 131 EXPECT_TRUE(table.getResourceName(base::R::string::test1, false, &frName)); 132 133 EXPECT_EQ( 134 String16(baseName.package, baseName.packageLen), 135 String16(frName.package, frName.packageLen)); 136 137 EXPECT_EQ( 138 String16(baseName.type, baseName.typeLen), 139 String16(frName.type, frName.typeLen)); 140 141 EXPECT_EQ( 142 String16(baseName.name, baseName.nameLen), 143 String16(frName.name, frName.nameLen)); 144 } 145 146 TEST(SplitTest, TypeEntrySpecFlagsAreUpdated) { 147 ResTable_config defaultConfig; 148 memset(&defaultConfig, 0, sizeof(defaultConfig)); 149 150 ResTable table; 151 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 152 153 Res_value val; 154 uint32_t specFlags = 0; 155 ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &specFlags, NULL); 156 EXPECT_GE(block, 0); 157 158 EXPECT_EQ(static_cast<uint32_t>(0), specFlags); 159 160 ASSERT_EQ(NO_ERROR, table.add(split_de_fr_arsc, split_de_fr_arsc_len)); 161 162 uint32_t frSpecFlags = 0; 163 block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG, 0, &frSpecFlags, NULL); 164 EXPECT_GE(block, 0); 165 166 EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags); 167 } 168 169 TEST(SplitTest, SelectBestDensity) { 170 ResTable_config baseConfig; 171 memset(&baseConfig, 0, sizeof(baseConfig)); 172 baseConfig.density = ResTable_config::DENSITY_XHIGH; 173 baseConfig.sdkVersion = 21; 174 175 ResTable table; 176 table.setParameters(&baseConfig); 177 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 178 ASSERT_EQ(NO_ERROR, table.add(split_hdpi_v4_arsc, split_hdpi_v4_arsc_len)); 179 180 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "hdpi")); 181 182 ASSERT_EQ(NO_ERROR, table.add(split_xhdpi_v4_arsc, split_xhdpi_v4_arsc_len)); 183 184 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi")); 185 186 ASSERT_EQ(NO_ERROR, table.add(split_xxhdpi_v4_arsc, split_xxhdpi_v4_arsc_len)); 187 188 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi")); 189 190 baseConfig.density = ResTable_config::DENSITY_XXHIGH; 191 table.setParameters(&baseConfig); 192 193 EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xxhdpi")); 194 } 195 196 TEST(SplitFeatureTest, TestNewResourceIsAccessible) { 197 ResTable table; 198 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 199 200 Res_value val; 201 ssize_t block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG); 202 EXPECT_LT(block, 0); 203 204 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len)); 205 206 block = table.getResource(base::R::string::test3, &val, MAY_NOT_BE_BAG); 207 EXPECT_GE(block, 0); 208 209 EXPECT_EQ(Res_value::TYPE_STRING, val.dataType); 210 } 211 212 TEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) { 213 ResTable table; 214 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 215 216 ResTable::resource_name name; 217 EXPECT_FALSE(table.getResourceName(base::R::string::test3, false, &name)); 218 219 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len)); 220 221 ASSERT_TRUE(table.getResourceName(base::R::string::test3, false, &name)); 222 223 EXPECT_EQ(String16("com.android.test.basic"), 224 String16(name.package, name.packageLen)); 225 226 EXPECT_EQ(String16("string"), 227 String16(name.type, name.typeLen)); 228 229 EXPECT_EQ(String16("test3"), 230 String16(name.name, name.nameLen)); 231 } 232 233 TEST(SplitFeatureTest, TestNewResourceIsAccessibleByName) { 234 ResTable table; 235 ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); 236 ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len)); 237 238 const String16 name("test3"); 239 const String16 type("string"); 240 const String16 package("com.android.test.basic"); 241 ASSERT_EQ(base::R::string::test3, table.identifierForName(name.string(), name.size(), 242 type.string(), type.size(), 243 package.string(), package.size())); 244 } 245 246 } // namespace 247