Remove raw values from proto APK
Raw attribute values are not included in xml files when building binary
APKs but they are when building proto APKs. Remove raw attribute values
and create a new convert flag that (--keep-raw-values) that allows raw
value to be kept.
Also added flag to link to keep raw attribute values.
Bug: 115915884
Bug: 116700688
Test: aapt2_tests
Change-Id: Id50136b775b3f43d159ca06181282f6a7b8eaf40
diff --git a/tools/aapt2/test/Fixture.cpp b/tools/aapt2/test/Fixture.cpp
new file mode 100644
index 0000000..aae79fa
--- /dev/null
+++ b/tools/aapt2/test/Fixture.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test/Fixture.h"
+
+#include <dirent.h>
+
+#include "android-base/errors.h"
+#include "android-base/file.h"
+#include "android-base/stringprintf.h"
+#include "android-base/utf8.h"
+#include "androidfw/StringPiece.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "cmd/Compile.h"
+#include "cmd/Link.h"
+#include "io/FileStream.h"
+#include "io/Util.h"
+#include "util/Files.h"
+
+using testing::Eq;
+using testing::Ne;
+
+namespace aapt {
+
+void ClearDirectory(const android::StringPiece& path) {
+ const std::string root_dir = path.to_string();
+ std::unique_ptr<DIR, decltype(closedir)*> dir(opendir(root_dir.data()), closedir);
+ if (!dir) {
+ StdErrDiagnostics().Error(DiagMessage() << android::base::SystemErrorCodeToString(errno));
+ return;
+ }
+
+ while (struct dirent* entry = readdir(dir.get())) {
+ // Do not delete hidden files and do not recurse to the parent of this directory
+ if (util::StartsWith(entry->d_name, ".")) {
+ continue;
+ }
+
+ std::string full_path = file::BuildPath({root_dir, entry->d_name});
+ if (file::GetFileType(full_path) == file::FileType::kDirectory) {
+ ClearDirectory(full_path);
+#ifdef _WIN32
+ _rmdir(full_path.c_str());
+#else
+ rmdir(full_path.c_str());
+#endif
+ } else {
+ android::base::utf8::unlink(full_path.c_str());
+ }
+ }
+}
+
+void TestDirectoryFixture::SetUp() {
+ temp_dir_ = file::BuildPath({android::base::GetExecutableDirectory(),
+ "_temp",
+ testing::UnitTest::GetInstance()->current_test_case()->name(),
+ testing::UnitTest::GetInstance()->current_test_info()->name()});
+ ASSERT_TRUE(file::mkdirs(temp_dir_));
+ ClearDirectory(temp_dir_);
+}
+
+void TestDirectoryFixture::TearDown() {
+ ClearDirectory(temp_dir_);
+}
+
+bool TestDirectoryFixture::WriteFile(const std::string& path, const std::string& contents) {
+ CHECK(util::StartsWith(path, temp_dir_))
+ << "Attempting to create a file outside of test temporary directory.";
+
+ // Create any intermediate directories specified in the path
+ auto pos = std::find(path.rbegin(), path.rend(), file::sDirSep);
+ if (pos != path.rend()) {
+ std::string dirs = path.substr(0, (&*pos - path.data()));
+ file::mkdirs(dirs);
+ }
+
+ return android::base::WriteStringToFile(contents, path);
+}
+
+bool CommandTestFixture::CompileFile(const std::string& path, const std::string& contents,
+ const android::StringPiece& out_dir, IDiagnostics* diag) {
+ CHECK(WriteFile(path, contents));
+ CHECK(file::mkdirs(out_dir.data()));
+ return CompileCommand(diag).Execute({path, "-o", out_dir, "-v"}, &std::cerr) == 0;
+}
+
+bool CommandTestFixture::Link(const std::vector<std::string>& args,
+ const android::StringPiece& flat_dir, IDiagnostics* diag) {
+ std::vector<android::StringPiece> link_args;
+ for(const std::string& arg : args) {
+ link_args.emplace_back(arg);
+ }
+
+ // Link against the android SDK
+ std::string android_sdk = file::BuildPath({android::base::GetExecutableDirectory(),
+ "integration-tests", "CommandTests",
+ "android-28.jar"});
+ link_args.insert(link_args.end(), {"-I", android_sdk});
+
+ // Add the files from the compiled resources directory to the link file arguments
+ Maybe<std::vector<std::string>> compiled_files = file::FindFiles(flat_dir, diag);
+ if (compiled_files) {
+ for (std::string& compile_file : compiled_files.value()) {
+ compile_file = file::BuildPath({flat_dir, compile_file});
+ link_args.emplace_back(std::move(compile_file));
+ }
+ }
+
+ return LinkCommand(diag).Execute(link_args, &std::cerr) == 0;
+}
+
+std::string CommandTestFixture::GetDefaultManifest() {
+ const std::string manifest_file = GetTestPath("AndroidManifest.xml");
+ CHECK(WriteFile(manifest_file, R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.aapt.command.test">
+ </manifest>)"));
+ return manifest_file;
+}
+
+void CommandTestFixture::AssertLoadXml(LoadedApk *apk, const android::StringPiece &xml_path,
+ android::ResXMLTree *out_tree) {
+ ASSERT_THAT(apk, Ne(nullptr));
+
+ io::IFile* file = apk->GetFileCollection()->FindFile(xml_path);
+ ASSERT_THAT(file, Ne(nullptr));
+
+ std::unique_ptr<io::IData> data = file->OpenAsData();
+ ASSERT_THAT(data, Ne(nullptr));
+
+ out_tree->setTo(data->data(), data->size());
+ ASSERT_THAT(out_tree->getError(), Eq(android::OK));
+ while (out_tree->next() != android::ResXMLTree::START_TAG) {
+ ASSERT_THAT(out_tree->getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+ ASSERT_THAT(out_tree->getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
+ }
+}
+
+} // namespace aapt
\ No newline at end of file