Skip to content

Commit 833f3cc

Browse files
author
Adam Lesinski
committed
AAPT support for feature splits
This change allows the developer to add a base package for which to build a feature split. The generated resource types will begin after the base APK's defined types so as not to collide or override resources. Multiple features can be generated by first choosing an arbitrary order for the features. Then for each feature, the base APK and any preceding features are specified with the --feature-of flags. So with a base APK 'A' and features, 'B', and 'C', 'B' would be built with aapt package [...] --feature-of A [...] and 'C' would be built with aapt package [...] --feature-of A --feature-of B [...] Change-Id: I1be66e3f8df9a737b21c71f8a93685376c7e6780
1 parent 5c09e8a commit 833f3cc

34 files changed

Lines changed: 929 additions & 663 deletions

include/androidfw/ResourceTypes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,8 @@ class ResTable
16841684
public:
16851685
inline virtual ~Accessor() { }
16861686

1687+
virtual const String16& getAssetsPackage() const = 0;
1688+
16871689
virtual uint32_t getCustomResource(const String16& package,
16881690
const String16& type,
16891691
const String16& name) const = 0;

libs/androidfw/ResourceTypes.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4630,11 +4630,13 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString,
46304630
type.size(), package.string(), package.size(), &specFlags);
46314631
if (rid != 0) {
46324632
if (enforcePrivate) {
4633-
if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
4634-
if (accessor != NULL) {
4635-
accessor->reportError(accessorCookie, "Resource is not public.");
4633+
if (accessor == NULL || accessor->getAssetsPackage() != package) {
4634+
if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
4635+
if (accessor != NULL) {
4636+
accessor->reportError(accessorCookie, "Resource is not public.");
4637+
}
4638+
return false;
46364639
}
4637-
return false;
46384640
}
46394641
}
46404642

libs/androidfw/tests/Idmap_test.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <utils/String8.h>
2020
#include <utils/String16.h>
2121
#include "TestHelpers.h"
22+
#include "data/R.h"
2223

2324
#include <gtest/gtest.h>
2425

@@ -43,16 +44,6 @@ namespace {
4344

4445
enum { MAY_NOT_BE_BAG = false };
4546

46-
static const uint32_t attr_attr1 = 0x7f010000;
47-
static const uint32_t attr_attr2 = 0x7f010001;
48-
static const uint32_t string_test1 = 0x7f020000;
49-
static const uint32_t string_test2 = 0x7f020001;
50-
static const uint32_t integer_number1 = 0x7f030000;
51-
static const uint32_t integer_number2 = 0x7f030001;
52-
static const uint32_t style_Theme1 = 0x7f040000;
53-
static const uint32_t style_Theme2 = 0x7f040001;
54-
static const uint32_t array_integerArray1 = 0x7f050000;
55-
5647
class IdmapTest : public ::testing::Test {
5748
protected:
5849
virtual void SetUp() {
@@ -79,7 +70,7 @@ TEST_F(IdmapTest, canLoadIdmap) {
7970

8071
TEST_F(IdmapTest, overlayOverridesResourceValue) {
8172
Res_value val;
82-
ssize_t block = mTargetTable.getResource(string_test2, &val, false);
73+
ssize_t block = mTargetTable.getResource(R::string::test2, &val, false);
8374
ASSERT_GE(block, 0);
8475
ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
8576
const ResStringPool* pool = mTargetTable.getTableStringBlock(block);
@@ -93,7 +84,7 @@ TEST_F(IdmapTest, overlayOverridesResourceValue) {
9384

9485
ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));
9586

96-
ssize_t newBlock = mTargetTable.getResource(string_test2, &val, false);
87+
ssize_t newBlock = mTargetTable.getResource(R::string::test2, &val, false);
9788
ASSERT_GE(newBlock, 0);
9889
ASSERT_NE(block, newBlock);
9990
ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
@@ -110,7 +101,7 @@ TEST_F(IdmapTest, overlaidResourceHasSameName) {
110101
ASSERT_EQ(NO_ERROR, mTargetTable.add(overlay_arsc, overlay_arsc_len, mData, mDataSize));
111102

112103
ResTable::resource_name resName;
113-
ASSERT_TRUE(mTargetTable.getResourceName(array_integerArray1, false, &resName));
104+
ASSERT_TRUE(mTargetTable.getResourceName(R::array::integerArray1, false, &resName));
114105

115106
ASSERT_TRUE(resName.package != NULL);
116107
ASSERT_TRUE(resName.type != NULL);

libs/androidfw/tests/ResTable_test.cpp

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <utils/String8.h>
2020
#include <utils/String16.h>
2121
#include "TestHelpers.h"
22+
#include "data/R.h"
2223

2324
#include <gtest/gtest.h>
2425

@@ -35,16 +36,6 @@ namespace {
3536

3637
enum { MAY_NOT_BE_BAG = false };
3738

38-
static const uint32_t attr_attr1 = 0x7f010000;
39-
static const uint32_t attr_attr2 = 0x7f010001;
40-
static const uint32_t string_test1 = 0x7f020000;
41-
static const uint32_t string_test2 = 0x7f020001;
42-
static const uint32_t integer_number1 = 0x7f030000;
43-
static const uint32_t integer_number2 = 0x7f030001;
44-
static const uint32_t style_Theme1 = 0x7f040000;
45-
static const uint32_t style_Theme2 = 0x7f040001;
46-
static const uint32_t array_integerArray1 = 0x7f050000;
47-
4839
TEST(ResTableTest, shouldLoadSuccessfully) {
4940
ResTable table;
5041
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
@@ -55,7 +46,7 @@ TEST(ResTableTest, simpleTypeIsRetrievedCorrectly) {
5546
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
5647

5748
Res_value val;
58-
ssize_t block = table.getResource(string_test1, &val, MAY_NOT_BE_BAG);
49+
ssize_t block = table.getResource(R::string::test1, &val, MAY_NOT_BE_BAG);
5950

6051
ASSERT_GE(block, 0);
6152
ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
@@ -75,76 +66,76 @@ TEST(ResTableTest, resourceNameIsResolved) {
7566
0, 0,
7667
defPackage.string(), defPackage.size());
7768
ASSERT_NE(uint32_t(0x00000000), resID);
78-
ASSERT_EQ(string_test1, resID);
69+
ASSERT_EQ(R::string::test1, resID);
7970
}
8071

8172
TEST(ResTableTest, noParentThemeIsAppliedCorrectly) {
8273
ResTable table;
8374
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
8475

8576
ResTable::Theme theme(table);
86-
ASSERT_EQ(NO_ERROR, theme.applyStyle(style_Theme1));
77+
ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::Theme1));
8778

8879
Res_value val;
8980
uint32_t specFlags = 0;
90-
ssize_t index = theme.getAttribute(attr_attr1, &val, &specFlags);
81+
ssize_t index = theme.getAttribute(R::attr::attr1, &val, &specFlags);
9182
ASSERT_GE(index, 0);
9283
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
9384
ASSERT_EQ(uint32_t(100), val.data);
9485

95-
index = theme.getAttribute(attr_attr2, &val, &specFlags);
86+
index = theme.getAttribute(R::attr::attr2, &val, &specFlags);
9687
ASSERT_GE(index, 0);
9788
ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
98-
ASSERT_EQ(integer_number1, val.data);
89+
ASSERT_EQ(R::integer::number1, val.data);
9990
}
10091

10192
TEST(ResTableTest, parentThemeIsAppliedCorrectly) {
10293
ResTable table;
10394
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
10495

10596
ResTable::Theme theme(table);
106-
ASSERT_EQ(NO_ERROR, theme.applyStyle(style_Theme2));
97+
ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::Theme2));
10798

10899
Res_value val;
109100
uint32_t specFlags = 0;
110-
ssize_t index = theme.getAttribute(attr_attr1, &val, &specFlags);
101+
ssize_t index = theme.getAttribute(R::attr::attr1, &val, &specFlags);
111102
ASSERT_GE(index, 0);
112103
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
113104
ASSERT_EQ(uint32_t(300), val.data);
114105

115-
index = theme.getAttribute(attr_attr2, &val, &specFlags);
106+
index = theme.getAttribute(R::attr::attr2, &val, &specFlags);
116107
ASSERT_GE(index, 0);
117108
ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
118-
ASSERT_EQ(integer_number1, val.data);
109+
ASSERT_EQ(R::integer::number1, val.data);
119110
}
120111

121112
TEST(ResTableTest, referenceToBagIsNotResolved) {
122113
ResTable table;
123114
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
124115

125116
Res_value val;
126-
ssize_t block = table.getResource(integer_number2, &val, MAY_NOT_BE_BAG);
117+
ssize_t block = table.getResource(R::integer::number2, &val, MAY_NOT_BE_BAG);
127118
ASSERT_GE(block, 0);
128119
ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
129-
ASSERT_EQ(array_integerArray1, val.data);
120+
ASSERT_EQ(R::array::integerArray1, val.data);
130121

131122
ssize_t newBlock = table.resolveReference(&val, block);
132123
EXPECT_EQ(block, newBlock);
133124
EXPECT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
134-
EXPECT_EQ(array_integerArray1, val.data);
125+
EXPECT_EQ(R::array::integerArray1, val.data);
135126
}
136127

137128
TEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {
138129
ResTable table;
139130
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
140131

141132
Res_value val;
142-
ssize_t block = table.getResource(integer_number1, &val, MAY_NOT_BE_BAG);
133+
ssize_t block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
143134
ASSERT_GE(block, 0);
144135
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
145136

146137
const ResTable::bag_entry* entry;
147-
ssize_t count = table.lockBag(array_integerArray1, &entry);
138+
ssize_t count = table.lockBag(R::array::integerArray1, &entry);
148139
ASSERT_GE(count, 0);
149140
table.unlockBag(entry);
150141

@@ -153,11 +144,11 @@ TEST(ResTableTest, resourcesStillAccessibleAfterParameterChange) {
153144
param.density = 320;
154145
table.setParameters(&param);
155146

156-
block = table.getResource(integer_number1, &val, MAY_NOT_BE_BAG);
147+
block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
157148
ASSERT_GE(block, 0);
158149
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
159150

160-
count = table.lockBag(array_integerArray1, &entry);
151+
count = table.lockBag(R::array::integerArray1, &entry);
161152
ASSERT_GE(count, 0);
162153
table.unlockBag(entry);
163154
}
@@ -167,7 +158,7 @@ TEST(ResTableTest, resourceIsOverridenWithBetterConfig) {
167158
ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
168159

169160
Res_value val;
170-
ssize_t block = table.getResource(integer_number1, &val, MAY_NOT_BE_BAG);
161+
ssize_t block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
171162
ASSERT_GE(block, 0);
172163
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
173164
ASSERT_EQ(uint32_t(200), val.data);
@@ -180,7 +171,7 @@ TEST(ResTableTest, resourceIsOverridenWithBetterConfig) {
180171
param.country[1] = 'E';
181172
table.setParameters(&param);
182173

183-
block = table.getResource(integer_number1, &val, MAY_NOT_BE_BAG);
174+
block = table.getResource(R::integer::number1, &val, MAY_NOT_BE_BAG);
184175
ASSERT_GE(block, 0);
185176
ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
186177
ASSERT_EQ(uint32_t(400), val.data);

0 commit comments

Comments
 (0)