ResTable_test.cpp revision e23a91e2bdab06e3c0c64201e88e50ab76c6b74b
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#include "data/lib/R.h"
24
25#include <gtest/gtest.h>
26
27using namespace android;
28
29namespace {
30
31/**
32 * Include a binary resource table.
33 *
34 * Package: com.android.test.basic
35 */
36#include "data/basic/basic_arsc.h"
37
38#include "data/lib/lib_arsc.h"
39
40enum { MAY_NOT_BE_BAG = false };
41
42TEST(ResTableTest, shouldLoadSuccessfully) {
43    ResTable table;
44    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
45}
46
47TEST(ResTableTest, simpleTypeIsRetrievedCorrectly) {
48    ResTable table;
49    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
50
51    Res_value val;
52    ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG);
53
54    ASSERT_GE(block, 0);
55    ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
56
57    const ResStringPool* pool = table.getTableStringBlock(block);
58    ASSERT_TRUE(NULL != pool);
59    ASSERT_EQ(String8("test1"), pool->string8ObjectAt(val.data));
60}
61
62TEST(ResTableTest, resourceNameIsResolved) {
63    ResTable table;
64    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
65
66    String16 defPackage("com.android.test.basic");
67    String16 testName("@string/test1");
68    uint32_t resID = table.identifierForName(testName.string(), testName.size(),
69                                             0, 0,
70                                             defPackage.string(), defPackage.size());
71    ASSERT_NE(uint32_t(0x00000000), resID);
72    ASSERT_EQ(base::R::string::test1, resID);
73}
74
75TEST(ResTableTest, noParentThemeIsAppliedCorrectly) {
76    ResTable table;
77    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
78
79    ResTable::Theme theme(table);
80    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme1));
81
82    Res_value val;
83    uint32_t specFlags = 0;
84    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
85    ASSERT_GE(index, 0);
86    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
87    ASSERT_EQ(uint32_t(100), val.data);
88
89    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
90    ASSERT_GE(index, 0);
91    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
92    ASSERT_EQ(base::R::integer::number1, val.data);
93}
94
95TEST(ResTableTest, parentThemeIsAppliedCorrectly) {
96    ResTable table;
97    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
98
99    ResTable::Theme theme(table);
100    ASSERT_EQ(NO_ERROR, theme.applyStyle(base::R::style::Theme2));
101
102    Res_value val;
103    uint32_t specFlags = 0;
104    ssize_t index = theme.getAttribute(base::R::attr::attr1, &val, &specFlags);
105    ASSERT_GE(index, 0);
106    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
107    ASSERT_EQ(uint32_t(300), val.data);
108
109    index = theme.getAttribute(base::R::attr::attr2, &val, &specFlags);
110    ASSERT_GE(index, 0);
111    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
112    ASSERT_EQ(base::R::integer::number1, val.data);
113}
114
115TEST(ResTableTest, libraryThemeIsAppliedCorrectly) {
116    ResTable table;
117    ASSERT_EQ(NO_ERROR, table.add(lib_arsc, lib_arsc_len));
118
119    ResTable::Theme theme(table);
120    ASSERT_EQ(NO_ERROR, theme.applyStyle(lib::R::style::Theme));
121
122    Res_value val;
123    uint32_t specFlags = 0;
124    ssize_t index = theme.getAttribute(lib::R::attr::attr1, &val, &specFlags);
125    ASSERT_GE(index, 0);
126    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
127    ASSERT_EQ(uint32_t(700), val.data);
128}
129
130TEST(ResTableTest, referenceToBagIsNotResolved) {
131    ResTable table;
132    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
133
134    Res_value val;
135    ssize_t block = table.getResource(base::R::integer::number2, &val, MAY_NOT_BE_BAG);
136    ASSERT_GE(block, 0);
137    ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
138    ASSERT_EQ(base::R::array::integerArray1, val.data);
139
140    ssize_t newBlock = table.resolveReference(&val, block);
141    EXPECT_EQ(block, newBlock);
142    EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
143    EXPECT_EQ(base::R::array::integerArray1, val.data);
144}
145
146TEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {
147    ResTable table;
148    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
149
150    Res_value val;
151    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
152    ASSERT_GE(block, 0);
153    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
154
155    const ResTable::bag_entry* entry;
156    ssize_t count = table.lockBag(base::R::array::integerArray1, &entry);
157    ASSERT_GE(count, 0);
158    table.unlockBag(entry);
159
160    ResTable_config param;
161    memset(&param, 0, sizeof(param));
162    param.density = 320;
163    table.setParameters(&param);
164
165    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
166    ASSERT_GE(block, 0);
167    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
168
169    count = table.lockBag(base::R::array::integerArray1, &entry);
170    ASSERT_GE(count, 0);
171    table.unlockBag(entry);
172}
173
174TEST(ResTableTest, resourceIsOverridenWithBetterConfig) {
175    ResTable table;
176    ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
177
178    Res_value val;
179    ssize_t block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
180    ASSERT_GE(block, 0);
181    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
182    ASSERT_EQ(uint32_t(200), val.data);
183
184    ResTable_config param;
185    memset(&param, 0, sizeof(param));
186    param.language[0] = 's';
187    param.language[1] = 'v';
188    param.country[0] = 'S';
189    param.country[1] = 'E';
190    table.setParameters(&param);
191
192    block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG);
193    ASSERT_GE(block, 0);
194    ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
195    ASSERT_EQ(uint32_t(400), val.data);
196}
197
198TEST(ResTableTest, emptyTableHasSensibleDefaults) {
199    const int32_t expectedCookie = 1;
200
201    ResTable table;
202    ASSERT_EQ(NO_ERROR, table.addEmpty(expectedCookie));
203
204    ASSERT_EQ(uint32_t(1), table.getTableCount());
205    ASSERT_EQ(uint32_t(1), table.getBasePackageCount());
206    ASSERT_EQ(expectedCookie, table.getTableCookie(0));
207
208    const DynamicRefTable* dynamicRefTable = table.getDynamicRefTableForCookie(expectedCookie);
209    ASSERT_TRUE(dynamicRefTable != NULL);
210
211    Res_value val;
212    ASSERT_LT(table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG), 0);
213}
214
215}
216