blob: a98ab0f76de488ff3ba9c12bb08d250330874d2d [file] [log] [blame]
Adam Lesinskic744ae82017-05-17 19:28:38 -07001/*
2 * Copyright (C) 2017 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 "link/XmlCompatVersioner.h"
18
19#include "Linkers.h"
20#include "test/Test.h"
21
Adam Lesinski6b372992017-08-09 10:54:23 -070022using ::aapt::test::ValueEq;
23using ::testing::Eq;
24using ::testing::IsNull;
25using ::testing::NotNull;
Adam Lesinskibbf42972018-02-14 13:36:09 -080026using ::testing::Pointee;
Adam Lesinski6b372992017-08-09 10:54:23 -070027using ::testing::SizeIs;
28
Adam Lesinskic744ae82017-05-17 19:28:38 -070029namespace aapt {
30
31constexpr auto TYPE_DIMENSION = android::ResTable_map::TYPE_DIMENSION;
32constexpr auto TYPE_STRING = android::ResTable_map::TYPE_STRING;
33
34struct R {
35 struct attr {
36 enum : uint32_t {
37 paddingLeft = 0x010100d6u, // (API 1)
38 paddingRight = 0x010100d8u, // (API 1)
39 progressBarPadding = 0x01010319u, // (API 11)
40 paddingStart = 0x010103b3u, // (API 17)
41 paddingHorizontal = 0x0101053du, // (API 26)
42 };
43 };
44};
45
46class XmlCompatVersionerTest : public ::testing::Test {
47 public:
48 void SetUp() override {
49 context_ =
50 test::ContextBuilder()
51 .SetCompilationPackage("com.app")
52 .SetPackageId(0x7f)
53 .SetPackageType(PackageType::kApp)
54 .SetMinSdkVersion(SDK_GINGERBREAD)
55 .AddSymbolSource(
56 test::StaticSymbolSourceBuilder()
57 .AddPublicSymbol("android:attr/paddingLeft", R::attr::paddingLeft,
Adam Lesinski73bff1e2017-12-08 16:06:10 -080058 util::make_unique<Attribute>(TYPE_DIMENSION))
Adam Lesinskic744ae82017-05-17 19:28:38 -070059 .AddPublicSymbol("android:attr/paddingRight", R::attr::paddingRight,
Adam Lesinski73bff1e2017-12-08 16:06:10 -080060 util::make_unique<Attribute>(TYPE_DIMENSION))
Adam Lesinskic744ae82017-05-17 19:28:38 -070061 .AddPublicSymbol("android:attr/progressBarPadding", R::attr::progressBarPadding,
Adam Lesinski73bff1e2017-12-08 16:06:10 -080062 util::make_unique<Attribute>(TYPE_DIMENSION))
Adam Lesinskic744ae82017-05-17 19:28:38 -070063 .AddPublicSymbol("android:attr/paddingStart", R::attr::paddingStart,
Adam Lesinski73bff1e2017-12-08 16:06:10 -080064 util::make_unique<Attribute>(TYPE_DIMENSION))
Adam Lesinskic744ae82017-05-17 19:28:38 -070065 .AddPublicSymbol("android:attr/paddingHorizontal", R::attr::paddingHorizontal,
Adam Lesinski73bff1e2017-12-08 16:06:10 -080066 util::make_unique<Attribute>(TYPE_DIMENSION))
Adam Lesinskic744ae82017-05-17 19:28:38 -070067 .AddSymbol("com.app:attr/foo", ResourceId(0x7f010000),
Adam Lesinski73bff1e2017-12-08 16:06:10 -080068 util::make_unique<Attribute>(TYPE_STRING))
Adam Lesinskic744ae82017-05-17 19:28:38 -070069 .Build())
70 .Build();
71 }
72
73 protected:
74 std::unique_ptr<IAaptContext> context_;
75};
76
77TEST_F(XmlCompatVersionerTest, NoRulesOnlyStripsAndCopies) {
Adam Lesinski6b372992017-08-09 10:54:23 -070078 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -070079 <View xmlns:android="http://schemas.android.com/apk/res/android"
80 xmlns:app="http://schemas.android.com/apk/res-auto"
81 android:paddingHorizontal="24dp"
82 app:foo="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -070083 foo="bar"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -070084
85 XmlReferenceLinker linker;
86 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
87
88 XmlCompatVersioner::Rules rules;
89 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
90
91 XmlCompatVersioner versioner(&rules);
92 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
93 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -070094 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -070095
96 xml::Element* el;
97
98 // Source XML file's sdkVersion == 0, so the first one must also have the same sdkVersion.
Adam Lesinski6b372992017-08-09 10:54:23 -070099 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
100 el = versioned_docs[0]->root.get();
101 ASSERT_THAT(el, NotNull());
102 EXPECT_THAT(el->attributes, SizeIs(2u));
103 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
104 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
105 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700106
Adam Lesinski6b372992017-08-09 10:54:23 -0700107 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
108 el = versioned_docs[1]->root.get();
109 ASSERT_THAT(el, NotNull());
110 EXPECT_THAT(el->attributes, SizeIs(3u));
111 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), NotNull());
112 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
113 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700114}
115
116TEST_F(XmlCompatVersionerTest, SingleRule) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700117 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700118 <View xmlns:android="http://schemas.android.com/apk/res/android"
119 xmlns:app="http://schemas.android.com/apk/res-auto"
120 android:paddingHorizontal="24dp"
121 app:foo="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -0700122 foo="bar"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700123
124 XmlReferenceLinker linker;
125 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
126
127 XmlCompatVersioner::Rules rules;
128 rules[R::attr::paddingHorizontal] =
129 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800130 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(TYPE_DIMENSION)},
131 ReplacementAttr{"paddingRight", R::attr::paddingRight, Attribute(TYPE_DIMENSION)}}));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700132
133 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
134
135 XmlCompatVersioner versioner(&rules);
136 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
137 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700138 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700139
140 xml::Element* el;
141
Adam Lesinski6b372992017-08-09 10:54:23 -0700142 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
143 el = versioned_docs[0]->root.get();
144 ASSERT_THAT(el, NotNull());
145 EXPECT_THAT(el->attributes, SizeIs(4u));
146 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
147 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
148 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700149
150 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700151 ASSERT_THAT(attr, NotNull());
152 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700153 ASSERT_TRUE(attr->compiled_attribute);
154
155 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700156 ASSERT_THAT(attr, NotNull());
157 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700158 ASSERT_TRUE(attr->compiled_attribute);
159
Adam Lesinski6b372992017-08-09 10:54:23 -0700160 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
161 el = versioned_docs[1]->root.get();
162 ASSERT_THAT(el, NotNull());
163 EXPECT_THAT(el->attributes, SizeIs(5u));
164 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), NotNull());
165 EXPECT_THAT(el->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
166 EXPECT_THAT(el->FindAttribute({}, "foo"), NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700167
168 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700169 ASSERT_THAT(attr, NotNull());
170 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700171 ASSERT_TRUE(attr->compiled_attribute);
172
173 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700174 ASSERT_THAT(attr, NotNull());
175 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700176 ASSERT_TRUE(attr->compiled_attribute);
177}
178
179TEST_F(XmlCompatVersionerTest, ChainedRule) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700180 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700181 <View xmlns:android="http://schemas.android.com/apk/res/android"
Adam Lesinski6b372992017-08-09 10:54:23 -0700182 android:paddingHorizontal="24dp" />)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700183
184 XmlReferenceLinker linker;
185 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
186
187 XmlCompatVersioner::Rules rules;
188 rules[R::attr::progressBarPadding] =
189 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800190 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(TYPE_DIMENSION)},
191 ReplacementAttr{"paddingRight", R::attr::paddingRight, Attribute(TYPE_DIMENSION)}}));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700192 rules[R::attr::paddingHorizontal] =
193 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>({ReplacementAttr{
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800194 "progressBarPadding", R::attr::progressBarPadding, Attribute(TYPE_DIMENSION)}}));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700195
196 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
197
198 XmlCompatVersioner versioner(&rules);
199 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
200 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700201 ASSERT_THAT(versioned_docs, SizeIs(3u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700202
203 xml::Element* el;
204
Adam Lesinski6b372992017-08-09 10:54:23 -0700205 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
206 el = versioned_docs[0]->root.get();
207 ASSERT_THAT(el, NotNull());
208 EXPECT_THAT(el->attributes, SizeIs(2u));
209 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700210
211 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700212 ASSERT_THAT(attr, NotNull());
213 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700214 ASSERT_TRUE(attr->compiled_attribute);
215
216 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700217 ASSERT_THAT(attr, NotNull());
218 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700219 ASSERT_TRUE(attr->compiled_attribute);
220
Adam Lesinski6b372992017-08-09 10:54:23 -0700221 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_HONEYCOMB));
222 el = versioned_docs[1]->root.get();
223 ASSERT_THAT(el, NotNull());
224 EXPECT_THAT(el->attributes, SizeIs(1u));
225 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
226 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingLeft"), IsNull());
227 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingRight"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700228
229 attr = el->FindAttribute(xml::kSchemaAndroid, "progressBarPadding");
Adam Lesinski6b372992017-08-09 10:54:23 -0700230 ASSERT_THAT(attr, NotNull());
231 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700232 ASSERT_TRUE(attr->compiled_attribute);
233
Adam Lesinski6b372992017-08-09 10:54:23 -0700234 EXPECT_THAT(versioned_docs[2]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
235 el = versioned_docs[2]->root.get();
236 ASSERT_THAT(el, NotNull());
237 EXPECT_THAT(el->attributes, SizeIs(2u));
238 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingLeft"), IsNull());
239 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingRight"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700240
241 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal");
Adam Lesinski6b372992017-08-09 10:54:23 -0700242 ASSERT_THAT(attr, NotNull());
243 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700244 ASSERT_TRUE(attr->compiled_attribute);
245
246 attr = el->FindAttribute(xml::kSchemaAndroid, "progressBarPadding");
Adam Lesinski6b372992017-08-09 10:54:23 -0700247 ASSERT_THAT(attr, NotNull());
248 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700249 ASSERT_TRUE(attr->compiled_attribute);
250}
251
252TEST_F(XmlCompatVersionerTest, DegradeRuleOverridesExistingAttribute) {
Adam Lesinski6b372992017-08-09 10:54:23 -0700253 auto doc = test::BuildXmlDomForPackageName(context_.get(), R"(
Adam Lesinskic744ae82017-05-17 19:28:38 -0700254 <View xmlns:android="http://schemas.android.com/apk/res/android"
255 android:paddingHorizontal="24dp"
256 android:paddingLeft="16dp"
Adam Lesinski6b372992017-08-09 10:54:23 -0700257 android:paddingRight="16dp"/>)");
Adam Lesinskic744ae82017-05-17 19:28:38 -0700258
259 XmlReferenceLinker linker;
260 ASSERT_TRUE(linker.Consume(context_.get(), doc.get()));
261
Adam Lesinski6b372992017-08-09 10:54:23 -0700262 Item* padding_horizontal_value =
263 doc->root->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal")->compiled_value.get();
264 ASSERT_THAT(padding_horizontal_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700265
266 XmlCompatVersioner::Rules rules;
267 rules[R::attr::paddingHorizontal] =
268 util::make_unique<DegradeToManyRule>(std::vector<ReplacementAttr>(
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800269 {ReplacementAttr{"paddingLeft", R::attr::paddingLeft, Attribute(TYPE_DIMENSION)},
270 ReplacementAttr{"paddingRight", R::attr::paddingRight, Attribute(TYPE_DIMENSION)}}));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700271
272 const util::Range<ApiVersion> api_range{SDK_GINGERBREAD, SDK_O + 1};
273
274 XmlCompatVersioner versioner(&rules);
275 std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
276 versioner.Process(context_.get(), doc.get(), api_range);
Adam Lesinski6b372992017-08-09 10:54:23 -0700277 ASSERT_THAT(versioned_docs, SizeIs(2u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700278
279 xml::Element* el;
280
Adam Lesinski6b372992017-08-09 10:54:23 -0700281 EXPECT_THAT(versioned_docs[0]->file.config.sdkVersion, Eq(0u));
282 el = versioned_docs[0]->root.get();
283 ASSERT_THAT(el, NotNull());
284 EXPECT_THAT(el->attributes, SizeIs(2u));
285 EXPECT_THAT(el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal"), IsNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700286
287 xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700288 ASSERT_THAT(attr, NotNull());
289 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700290 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinskibbf42972018-02-14 13:36:09 -0800291 ASSERT_THAT(attr->compiled_value, Pointee(ValueEq(padding_horizontal_value)));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700292
293 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700294 ASSERT_THAT(attr, NotNull());
295 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700296 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinskibbf42972018-02-14 13:36:09 -0800297 ASSERT_THAT(attr->compiled_value, Pointee(ValueEq(padding_horizontal_value)));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700298
Adam Lesinski6b372992017-08-09 10:54:23 -0700299 EXPECT_THAT(versioned_docs[1]->file.config.sdkVersion, Eq(SDK_LOLLIPOP_MR1));
300 el = versioned_docs[1]->root.get();
301 ASSERT_THAT(el, NotNull());
302 EXPECT_THAT(el->attributes, SizeIs(3u));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700303
304 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingHorizontal");
Adam Lesinski6b372992017-08-09 10:54:23 -0700305 ASSERT_THAT(attr, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700306 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinskibbf42972018-02-14 13:36:09 -0800307 ASSERT_THAT(attr->compiled_value, Pointee(ValueEq(padding_horizontal_value)));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700308
309 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingLeft");
Adam Lesinski6b372992017-08-09 10:54:23 -0700310 ASSERT_THAT(attr, NotNull());
311 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700312 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinskibbf42972018-02-14 13:36:09 -0800313 ASSERT_THAT(attr->compiled_value, Pointee(ValueEq(padding_horizontal_value)));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700314
315 attr = el->FindAttribute(xml::kSchemaAndroid, "paddingRight");
Adam Lesinski6b372992017-08-09 10:54:23 -0700316 ASSERT_THAT(attr, NotNull());
317 ASSERT_THAT(attr->compiled_value, NotNull());
Adam Lesinskic744ae82017-05-17 19:28:38 -0700318 ASSERT_TRUE(attr->compiled_attribute);
Adam Lesinskibbf42972018-02-14 13:36:09 -0800319 ASSERT_THAT(attr->compiled_value, Pointee(ValueEq(padding_horizontal_value)));
Adam Lesinskic744ae82017-05-17 19:28:38 -0700320}
321
322} // namespace aapt