Merge "Move StringPool to libandroidfw"

This commit is contained in:
Jeremy Meyer
2022-06-01 21:26:56 +00:00
committed by Android (Google) Code Review
136 changed files with 2264 additions and 2132 deletions

View File

@@ -61,6 +61,7 @@ cc_library {
"AssetManager2.cpp",
"AssetsProvider.cpp",
"AttributeResolution.cpp",
"BigBuffer.cpp",
"ChunkIterator.cpp",
"ConfigDescription.cpp",
"Idmap.cpp",
@@ -73,6 +74,7 @@ cc_library {
"ResourceTypes.cpp",
"ResourceUtils.cpp",
"StreamingZipInflater.cpp",
"StringPool.cpp",
"TypeWrappers.cpp",
"Util.cpp",
"ZipFileRO.cpp",
@@ -162,6 +164,7 @@ cc_test {
"tests/AssetManager2_test.cpp",
"tests/AttributeFinder_test.cpp",
"tests/AttributeResolution_test.cpp",
"tests/BigBuffer_test.cpp",
"tests/ByteBucketArray_test.cpp",
"tests/Config_test.cpp",
"tests/ConfigDescription_test.cpp",
@@ -174,6 +177,7 @@ cc_test {
"tests/ResTable_test.cpp",
"tests/Split_test.cpp",
"tests/StringPiece_test.cpp",
"tests/StringPool_test.cpp",
"tests/Theme_test.cpp",
"tests/TypeWrappers_test.cpp",
"tests/ZipUtils_test.cpp",

View File

@@ -601,6 +601,10 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry(
return base::unexpected(result.error());
}
if (type_idx == 0x1c) {
LOG(ERROR) << base::StringPrintf("foobar first result %s", result->package_name->c_str());
}
bool overlaid = false;
if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) {
for (const auto& id_map : package_group.overlays_) {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "util/BigBuffer.h"
#include <androidfw/BigBuffer.h>
#include <algorithm>
#include <memory>
@@ -22,7 +22,7 @@
#include "android-base/logging.h"
namespace aapt {
namespace android {
void* BigBuffer::NextBlockImpl(size_t size) {
if (!blocks_.empty()) {
@@ -84,4 +84,4 @@ std::string BigBuffer::to_string() const {
return result;
}
} // namespace aapt
} // namespace android

View File

@@ -14,7 +14,8 @@
* limitations under the License.
*/
#include "StringPool.h"
#include <androidfw/BigBuffer.h>
#include <androidfw/StringPool.h>
#include <algorithm>
#include <memory>
@@ -23,15 +24,14 @@
#include "android-base/logging.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "util/BigBuffer.h"
#include "util/Util.h"
#include "androidfw/Util.h"
using ::android::StringPiece;
namespace aapt {
namespace android {
StringPool::Ref::Ref() : entry_(nullptr) {}
StringPool::Ref::Ref() : entry_(nullptr) {
}
StringPool::Ref::Ref(const StringPool::Ref& rhs) : entry_(rhs.entry_) {
if (entry_ != nullptr) {
@@ -88,10 +88,10 @@ const StringPool::Context& StringPool::Ref::GetContext() const {
return entry_->context;
}
StringPool::StyleRef::StyleRef() : entry_(nullptr) {}
StringPool::StyleRef::StyleRef() : entry_(nullptr) {
}
StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs)
: entry_(rhs.entry_) {
StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs) : entry_(rhs.entry_) {
if (entry_ != nullptr) {
entry_->ref_++;
}
@@ -210,7 +210,7 @@ StringPool::StyleRef StringPool::MakeRef(const StyleString& str, const Context&
entry->context = context;
entry->index_ = styles_.size();
entry->ref_ = 0;
for (const aapt::Span& span : str.spans) {
for (const android::Span& span : str.spans) {
entry->spans.emplace_back(Span{MakeRef(span.name), span.first_char, span.last_char});
}
@@ -368,24 +368,23 @@ static bool EncodeString(const std::string& str, const bool utf8, BigBuffer* out
IDiagnostics* diag) {
if (utf8) {
const std::string& encoded = util::Utf8ToModifiedUtf8(str);
const ssize_t utf16_length = utf8_to_utf16_length(
reinterpret_cast<const uint8_t*>(encoded.data()), encoded.size());
const ssize_t utf16_length =
utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(encoded.data()), encoded.size());
CHECK(utf16_length >= 0);
// Make sure the lengths to be encoded do not exceed the maximum length that
// can be encoded using chars
if ((((size_t)encoded.size()) > EncodeLengthMax<char>())
|| (((size_t)utf16_length) > EncodeLengthMax<char>())) {
if ((((size_t)encoded.size()) > EncodeLengthMax<char>()) ||
(((size_t)utf16_length) > EncodeLengthMax<char>())) {
diag->Error(DiagMessage() << "string too large to encode using UTF-8 "
<< "written instead as '" << kStringTooLarge << "'");
<< "written instead as '" << kStringTooLarge << "'");
EncodeString(kStringTooLarge, utf8, out, diag);
return false;
}
const size_t total_size = EncodedLengthUnits<char>(utf16_length)
+ EncodedLengthUnits<char>(encoded.size()) + encoded.size() + 1;
const size_t total_size = EncodedLengthUnits<char>(utf16_length) +
EncodedLengthUnits<char>(encoded.size()) + encoded.size() + 1;
char* data = out->NextBlock<char>(total_size);
@@ -404,15 +403,14 @@ static bool EncodeString(const std::string& str, const bool utf8, BigBuffer* out
// length that can be encoded
if (((size_t)utf16_length) > EncodeLengthMax<char16_t>()) {
diag->Error(DiagMessage() << "string too large to encode using UTF-16 "
<< "written instead as '" << kStringTooLarge << "'");
<< "written instead as '" << kStringTooLarge << "'");
EncodeString(kStringTooLarge, utf8, out, diag);
return false;
}
// Total number of 16-bit words to write.
const size_t total_size = EncodedLengthUnits<char16_t>(utf16_length)
+ encoded.size() + 1;
const size_t total_size = EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1;
char16_t* data = out->NextBlock<char16_t>(total_size);
@@ -431,8 +429,7 @@ static bool EncodeString(const std::string& str, const bool utf8, BigBuffer* out
return true;
}
bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8,
IDiagnostics* diag) {
bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8, IDiagnostics* diag) {
bool no_error = true;
const size_t start_index = out->size();
android::ResStringPool_header* header = out->NextBlock<android::ResStringPool_header>();
@@ -490,8 +487,8 @@ bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8,
// ResStringPool_span structure worth of 0xFFFFFFFF at the end
// of the style block, so fill in the remaining 2 32bit words
// with 0xFFFFFFFF.
const size_t padding_length = sizeof(android::ResStringPool_span) -
sizeof(android::ResStringPool_span::name);
const size_t padding_length =
sizeof(android::ResStringPool_span) - sizeof(android::ResStringPool_span::name);
uint8_t* padding = out->NextBlock<uint8_t>(padding_length);
memset(padding, 0xff, padding_length);
out->Align4();
@@ -508,4 +505,4 @@ bool StringPool::FlattenUtf16(BigBuffer* out, const StringPool& pool, IDiagnosti
return Flatten(out, pool, false, diag);
}
} // namespace aapt
} // namespace android

View File

@@ -68,6 +68,107 @@ std::string Utf16ToUtf8(const StringPiece16& utf16) {
return utf8;
}
std::string Utf8ToModifiedUtf8(const std::string& utf8) {
// Java uses Modified UTF-8 which only supports the 1, 2, and 3 byte formats of UTF-8. To encode
// 4 byte UTF-8 codepoints, Modified UTF-8 allows the use of surrogate pairs in the same format
// of CESU-8 surrogate pairs. Calculate the size of the utf8 string with all 4 byte UTF-8
// codepoints replaced with 2 3 byte surrogate pairs
size_t modified_size = 0;
const size_t size = utf8.size();
for (size_t i = 0; i < size; i++) {
if (((uint8_t)utf8[i] >> 4) == 0xF) {
modified_size += 6;
i += 3;
} else {
modified_size++;
}
}
// Early out if no 4 byte codepoints are found
if (size == modified_size) {
return utf8;
}
std::string output;
output.reserve(modified_size);
for (size_t i = 0; i < size; i++) {
if (((uint8_t)utf8[i] >> 4) == 0xF) {
int32_t codepoint = utf32_from_utf8_at(utf8.data(), size, i, nullptr);
// Calculate the high and low surrogates as UTF-16 would
int32_t high = ((codepoint - 0x10000) / 0x400) + 0xD800;
int32_t low = ((codepoint - 0x10000) % 0x400) + 0xDC00;
// Encode each surrogate in UTF-8
output.push_back((char)(0xE4 | ((high >> 12) & 0xF)));
output.push_back((char)(0x80 | ((high >> 6) & 0x3F)));
output.push_back((char)(0x80 | (high & 0x3F)));
output.push_back((char)(0xE4 | ((low >> 12) & 0xF)));
output.push_back((char)(0x80 | ((low >> 6) & 0x3F)));
output.push_back((char)(0x80 | (low & 0x3F)));
i += 3;
} else {
output.push_back(utf8[i]);
}
}
return output;
}
std::string ModifiedUtf8ToUtf8(const std::string& modified_utf8) {
// The UTF-8 representation will have a byte length less than or equal to the Modified UTF-8
// representation.
std::string output;
output.reserve(modified_utf8.size());
size_t index = 0;
const size_t modified_size = modified_utf8.size();
while (index < modified_size) {
size_t next_index;
int32_t high_surrogate =
utf32_from_utf8_at(modified_utf8.data(), modified_size, index, &next_index);
if (high_surrogate < 0) {
return {};
}
// Check that the first codepoint is within the high surrogate range
if (high_surrogate >= 0xD800 && high_surrogate <= 0xDB7F) {
int32_t low_surrogate =
utf32_from_utf8_at(modified_utf8.data(), modified_size, next_index, &next_index);
if (low_surrogate < 0) {
return {};
}
// Check that the second codepoint is within the low surrogate range
if (low_surrogate >= 0xDC00 && low_surrogate <= 0xDFFF) {
const char32_t codepoint =
(char32_t)(((high_surrogate - 0xD800) * 0x400) + (low_surrogate - 0xDC00) + 0x10000);
// The decoded codepoint should represent a 4 byte, UTF-8 character
const size_t utf8_length = (size_t)utf32_to_utf8_length(&codepoint, 1);
if (utf8_length != 4) {
return {};
}
// Encode the UTF-8 representation of the codepoint into the string
char* start = &output[output.size()];
output.resize(output.size() + utf8_length);
utf32_to_utf8((char32_t*)&codepoint, 1, start, utf8_length + 1);
index = next_index;
continue;
}
}
// Append non-surrogate pairs to the output string
for (size_t i = index; i < next_index; i++) {
output.push_back(modified_utf8[i]);
}
index = next_index;
}
return output;
}
static std::vector<std::string> SplitAndTransform(
const StringPiece& str, char sep, const std::function<char(char)>& f) {
std::vector<std::string> parts;
@@ -90,6 +191,29 @@ std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) {
return SplitAndTransform(str, sep, ::tolower);
}
std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer) {
std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]);
uint8_t* p = data.get();
for (const auto& block : buffer) {
memcpy(p, block.buffer.get(), block.size);
p += block.size;
}
return data;
}
StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx) {
if (auto str = pool.stringAt(idx); str.ok()) {
return *str;
}
return StringPiece16();
}
std::string GetString(const android::ResStringPool& pool, size_t idx) {
if (auto str = pool.string8At(idx); str.ok()) {
return ModifiedUtf8ToUtf8(str->to_string());
}
return Utf16ToUtf8(GetString16(pool, idx));
}
} // namespace util
} // namespace android

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef AAPT_BIG_BUFFER_H
#define AAPT_BIG_BUFFER_H
#ifndef _ANDROID_BIG_BUFFER_H
#define _ANDROID_BIG_BUFFER_H
#include <cstring>
#include <memory>
@@ -26,7 +26,7 @@
#include "android-base/logging.h"
#include "android-base/macros.h"
namespace aapt {
namespace android {
/**
* Inspired by protobuf's ZeroCopyOutputStream, offers blocks of memory
@@ -133,22 +133,24 @@ class BigBuffer {
std::vector<Block> blocks_;
};
inline BigBuffer::BigBuffer(size_t block_size)
: block_size_(block_size), size_(0) {}
inline BigBuffer::BigBuffer(size_t block_size) : block_size_(block_size), size_(0) {
}
inline BigBuffer::BigBuffer(BigBuffer&& rhs) noexcept
: block_size_(rhs.block_size_),
size_(rhs.size_),
blocks_(std::move(rhs.blocks_)) {}
: block_size_(rhs.block_size_), size_(rhs.size_), blocks_(std::move(rhs.blocks_)) {
}
inline size_t BigBuffer::size() const { return size_; }
inline size_t BigBuffer::size() const {
return size_;
}
inline size_t BigBuffer::block_size() const { return block_size_; }
inline size_t BigBuffer::block_size() const {
return block_size_;
}
template <typename T>
inline T* BigBuffer::NextBlock(size_t count) {
static_assert(std::is_standard_layout<T>::value,
"T must be standard_layout type");
static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type");
CHECK(count != 0);
return reinterpret_cast<T*>(NextBlockImpl(sizeof(T) * count));
}
@@ -160,14 +162,15 @@ inline void BigBuffer::BackUp(size_t count) {
}
inline void BigBuffer::AppendBuffer(BigBuffer&& buffer) {
std::move(buffer.blocks_.begin(), buffer.blocks_.end(),
std::back_inserter(blocks_));
std::move(buffer.blocks_.begin(), buffer.blocks_.end(), std::back_inserter(blocks_));
size_ += buffer.size_;
buffer.blocks_.clear();
buffer.size_ = 0;
}
inline void BigBuffer::Pad(size_t bytes) { NextBlock<char>(bytes); }
inline void BigBuffer::Pad(size_t bytes) {
NextBlock<char>(bytes);
}
inline void BigBuffer::Align4() {
const size_t unaligned = size_ % 4;
@@ -184,6 +187,6 @@ inline BigBuffer::const_iterator BigBuffer::end() const {
return blocks_.end();
}
} // namespace aapt
} // namespace android
#endif // AAPT_BIG_BUFFER_H
#endif // _ANDROID_BIG_BUFFER_H

View File

@@ -0,0 +1,130 @@
/*
* Copyright (C) 2015 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.
*/
#ifndef _ANDROID_DIAGNOSTICS_H
#define _ANDROID_DIAGNOSTICS_H
#include <sstream>
#include <string>
#include "Source.h"
#include "android-base/macros.h"
#include "androidfw/StringPiece.h"
namespace android {
struct DiagMessageActual {
Source source;
std::string message;
};
struct DiagMessage {
public:
DiagMessage() = default;
explicit DiagMessage(const android::StringPiece& src) : source_(src) {
}
explicit DiagMessage(const Source& src) : source_(src) {
}
explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) {
}
template <typename T>
DiagMessage& operator<<(const T& value) {
message_ << value;
return *this;
}
DiagMessageActual Build() const {
return DiagMessageActual{source_, message_.str()};
}
private:
Source source_;
std::stringstream message_;
};
template <>
inline DiagMessage& DiagMessage::operator<<(const ::std::u16string& value) {
message_ << android::StringPiece16(value);
return *this;
}
struct IDiagnostics {
virtual ~IDiagnostics() = default;
enum class Level { Note, Warn, Error };
virtual void Log(Level level, DiagMessageActual& actualMsg) = 0;
virtual void Error(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Error, actual);
}
virtual void Warn(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Warn, actual);
}
virtual void Note(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Note, actual);
}
};
class SourcePathDiagnostics : public IDiagnostics {
public:
SourcePathDiagnostics(const Source& src, IDiagnostics* diag) : source_(src), diag_(diag) {
}
void Log(Level level, DiagMessageActual& actual_msg) override {
actual_msg.source.path = source_.path;
diag_->Log(level, actual_msg);
if (level == Level::Error) {
error = true;
}
}
bool HadError() {
return error;
}
private:
Source source_;
IDiagnostics* diag_;
bool error = false;
DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics);
};
class NoOpDiagnostics : public IDiagnostics {
public:
NoOpDiagnostics() = default;
void Log(Level level, DiagMessageActual& actual_msg) override {
(void)level;
(void)actual_msg;
}
DISALLOW_COPY_AND_ASSIGN(NoOpDiagnostics);
};
} // namespace android
#endif /* _ANDROID_DIAGNOSTICS_H */

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef AAPT_SOURCE_H
#define AAPT_SOURCE_H
#ifndef _ANDROID_SOURCE_H
#define _ANDROID_SOURCE_H
#include <optional>
#include <ostream>
@@ -24,7 +24,7 @@
#include "android-base/stringprintf.h"
#include "androidfw/StringPiece.h"
namespace aapt {
namespace android {
// Represents a file on disk. Used for logging and showing errors.
struct Source {
@@ -38,10 +38,12 @@ struct Source {
}
inline Source(const android::StringPiece& path, const android::StringPiece& archive)
: path(path.to_string()), archive(archive.to_string()) {}
: path(path.to_string()), archive(archive.to_string()) {
}
inline Source(const android::StringPiece& path, size_t line)
: path(path.to_string()), line(line) {}
: path(path.to_string()), line(line) {
}
inline Source WithLine(size_t line) const {
return Source(path, line);
@@ -84,6 +86,6 @@ inline bool operator<(const Source& lhs, const Source& rhs) {
return bool(rhs.line);
}
} // namespace aapt
} // namespace android
#endif // AAPT_SOURCE_H
#endif // _ANDROID_SOURCE_H

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef AAPT_STRING_POOL_H
#define AAPT_STRING_POOL_H
#ifndef _ANDROID_STRING_POOL_H
#define _ANDROID_STRING_POOL_H
#include <functional>
#include <memory>
@@ -23,14 +23,13 @@
#include <unordered_map>
#include <vector>
#include "BigBuffer.h"
#include "IDiagnostics.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
#include "util/BigBuffer.h"
namespace aapt {
namespace android {
struct Span {
std::string name;
@@ -67,8 +66,10 @@ class StringPool {
android::ConfigDescription config;
Context() = default;
Context(uint32_t p, const android::ConfigDescription& c) : priority(p), config(c) {}
explicit Context(uint32_t p) : priority(p) {}
Context(uint32_t p, const android::ConfigDescription& c) : priority(p), config(c) {
}
explicit Context(uint32_t p) : priority(p) {
}
explicit Context(const android::ConfigDescription& c) : priority(kNormalPriority), config(c) {
}
};
@@ -222,6 +223,6 @@ class StringPool {
std::unordered_multimap<android::StringPiece, Entry*> indexed_strings_;
};
} // namespace aapt
} // namespace android
#endif // AAPT_STRING_POOL_H
#endif // _ANDROID_STRING_POOL_H

View File

@@ -17,15 +17,18 @@
#ifndef UTIL_H_
#define UTIL_H_
#include <android-base/macros.h>
#include <util/map_ptr.h>
#include <cstdlib>
#include <memory>
#include <sstream>
#include <vector>
#include <android-base/macros.h>
#include <util/map_ptr.h>
#include "androidfw/BigBuffer.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "utils/ByteOrder.h"
#ifdef __ANDROID__
#define ANDROID_LOG(x) LOG(x)
@@ -125,6 +128,28 @@ std::u16string Utf8ToUtf16(const StringPiece& utf8);
// Converts a UTF-16 string to a UTF-8 string.
std::string Utf16ToUtf8(const StringPiece16& utf16);
// Converts a UTF8 string into Modified UTF8
std::string Utf8ToModifiedUtf8(const std::string& utf8);
// Converts a Modified UTF8 string into a UTF8 string
std::string ModifiedUtf8ToUtf8(const std::string& modified_utf8);
inline uint16_t HostToDevice16(uint16_t value) {
return htods(value);
}
inline uint32_t HostToDevice32(uint32_t value) {
return htodl(value);
}
inline uint16_t DeviceToHost16(uint16_t value) {
return dtohs(value);
}
inline uint32_t DeviceToHost32(uint32_t value) {
return dtohl(value);
}
std::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep);
template <typename T>
@@ -136,6 +161,18 @@ inline bool IsFourByteAligned(const void* data) {
return ((size_t)data & 0x3U) == 0;
}
// Helper method to extract a UTF-16 string from a StringPool. If the string is stored as UTF-8,
// the conversion to UTF-16 happens within ResStringPool.
android::StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx);
// Helper method to extract a UTF-8 string from a StringPool. If the string is stored as UTF-16,
// the conversion from UTF-16 to UTF-8 does not happen in ResStringPool and is done by this method,
// which maintains no state or cache. This means we must return an std::string copy.
std::string GetString(const android::ResStringPool& pool, size_t idx);
// Copies the entire BigBuffer into a single buffer.
std::unique_ptr<uint8_t[]> Copy(const android::BigBuffer& buffer);
} // namespace util
} // namespace android

View File

@@ -14,13 +14,14 @@
* limitations under the License.
*/
#include "util/BigBuffer.h"
#include "androidfw/BigBuffer.h"
#include "test/Test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::NotNull;
namespace aapt {
namespace android {
TEST(BigBufferTest, AllocateSingleBlock) {
BigBuffer buffer(4);
@@ -62,7 +63,7 @@ TEST(BigBufferTest, AppendAndMoveBlock) {
*b1 = 44;
buffer.AppendBuffer(std::move(buffer2));
EXPECT_EQ(0u, buffer2.size()); // NOLINT
EXPECT_EQ(0u, buffer2.size()); // NOLINT
EXPECT_EQ(buffer2.begin(), buffer2.end());
}
@@ -97,4 +98,4 @@ TEST(BigBufferTest, PadAndAlignProperly) {
ASSERT_EQ(8u, buffer.size());
}
} // namespace aapt
} // namespace android

View File

@@ -14,15 +14,15 @@
* limitations under the License.
*/
#include "StringPool.h"
#include "androidfw/StringPool.h"
#include <string>
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
#include "test/Test.h"
#include "util/Util.h"
#include "androidfw/Util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::android::StringPiece;
using ::android::StringPiece16;
@@ -31,7 +31,7 @@ using ::testing::Ne;
using ::testing::NotNull;
using ::testing::Pointee;
namespace aapt {
namespace android {
TEST(StringPoolTest, InsertOneString) {
StringPool pool;
@@ -176,8 +176,8 @@ TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
StringPool::Ref ref = pool.MakeRef("android");
StyleString str{{"android"}};
StringPool::StyleRef style_ref = pool.MakeRef(StyleString{{"android"}});
StyleString str{{"android"}, {}};
StringPool::StyleRef style_ref = pool.MakeRef(StyleString{{"android"}, {}});
EXPECT_THAT(ref.index(), Ne(style_ref.index()));
}
@@ -185,9 +185,9 @@ TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
TEST(StringPoolTest, StylesAndStringsAreSeparateAfterSorting) {
StringPool pool;
StringPool::StyleRef ref_a = pool.MakeRef(StyleString{{"beta"}});
StringPool::StyleRef ref_a = pool.MakeRef(StyleString{{"beta"}, {}});
StringPool::Ref ref_b = pool.MakeRef("alpha");
StringPool::StyleRef ref_c = pool.MakeRef(StyleString{{"alpha"}});
StringPool::StyleRef ref_c = pool.MakeRef(StyleString{{"alpha"}, {}});
EXPECT_THAT(ref_b.index(), Ne(ref_c.index()));
@@ -200,27 +200,27 @@ TEST(StringPoolTest, StylesAndStringsAreSeparateAfterSorting) {
TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
using namespace android; // For NO_ERROR on Windows.
StdErrDiagnostics diag;
NoOpDiagnostics diag;
StringPool pool;
BigBuffer buffer(1024);
StringPool::FlattenUtf8(&buffer, pool, &diag);
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer);
ResStringPool test;
ASSERT_THAT(test.setTo(data.get(), buffer.size()), Eq(NO_ERROR));
}
TEST(StringPoolTest, FlattenOddCharactersUtf16) {
using namespace android; // For NO_ERROR on Windows.
StdErrDiagnostics diag;
NoOpDiagnostics diag;
StringPool pool;
pool.MakeRef("\u093f");
BigBuffer buffer(1024);
StringPool::FlattenUtf16(&buffer, pool, &diag);
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer);
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
auto str = test.stringAt(0);
@@ -239,7 +239,7 @@ constexpr const char* sLongString =
TEST(StringPoolTest, Flatten) {
using namespace android; // For NO_ERROR on Windows.
StdErrDiagnostics diag;
NoOpDiagnostics diag;
StringPool pool;
@@ -264,38 +264,38 @@ TEST(StringPoolTest, Flatten) {
// Test both UTF-8 and UTF-16 buffers.
for (const BigBuffer& buffer : buffers) {
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer);
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
EXPECT_THAT(util::GetString(test, 1), Eq("hello"));
EXPECT_THAT(util::GetString16(test, 1), Eq(u"hello"));
EXPECT_THAT(android::util::GetString(test, 1), Eq("hello"));
EXPECT_THAT(android::util::GetString16(test, 1), Eq(u"hello"));
EXPECT_THAT(util::GetString(test, 2), Eq("goodbye"));
EXPECT_THAT(util::GetString16(test, 2), Eq(u"goodbye"));
EXPECT_THAT(android::util::GetString(test, 2), Eq("goodbye"));
EXPECT_THAT(android::util::GetString16(test, 2), Eq(u"goodbye"));
EXPECT_THAT(util::GetString(test, 3), Eq(sLongString));
EXPECT_THAT(util::GetString16(test, 3), Eq(util::Utf8ToUtf16(sLongString)));
EXPECT_THAT(android::util::GetString(test, 3), Eq(sLongString));
EXPECT_THAT(android::util::GetString16(test, 3), Eq(util::Utf8ToUtf16(sLongString)));
EXPECT_TRUE(test.stringAt(4).has_value() || test.string8At(4).has_value());
EXPECT_THAT(util::GetString(test, 0), Eq("style"));
EXPECT_THAT(util::GetString16(test, 0), Eq(u"style"));
EXPECT_THAT(android::util::GetString(test, 0), Eq("style"));
EXPECT_THAT(android::util::GetString16(test, 0), Eq(u"style"));
auto span_result = test.styleAt(0);
ASSERT_TRUE(span_result.has_value());
const ResStringPool_span* span = span_result->unsafe_ptr();
EXPECT_THAT(util::GetString(test, span->name.index), Eq("b"));
EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"b"));
EXPECT_THAT(android::util::GetString(test, span->name.index), Eq("b"));
EXPECT_THAT(android::util::GetString16(test, span->name.index), Eq(u"b"));
EXPECT_THAT(span->firstChar, Eq(0u));
EXPECT_THAT(span->lastChar, Eq(1u));
span++;
ASSERT_THAT(span->name.index, Ne(ResStringPool_span::END));
EXPECT_THAT(util::GetString(test, span->name.index), Eq("i"));
EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"i"));
EXPECT_THAT(android::util::GetString(test, span->name.index), Eq("i"));
EXPECT_THAT(android::util::GetString16(test, span->name.index), Eq(u"i"));
EXPECT_THAT(span->firstChar, Eq(2u));
EXPECT_THAT(span->lastChar, Eq(3u));
span++;
@@ -306,15 +306,15 @@ TEST(StringPoolTest, Flatten) {
TEST(StringPoolTest, ModifiedUTF8) {
using namespace android; // For NO_ERROR on Windows.
StdErrDiagnostics diag;
NoOpDiagnostics diag;
StringPool pool;
StringPool::Ref ref_a = pool.MakeRef("\xF0\x90\x90\x80"); // 𐐀 (U+10400)
StringPool::Ref ref_b = pool.MakeRef("foo \xF0\x90\x90\xB7 bar"); // 𐐷 (U+10437)
StringPool::Ref ref_a = pool.MakeRef("\xF0\x90\x90\x80"); // 𐐀 (U+10400)
StringPool::Ref ref_b = pool.MakeRef("foo \xF0\x90\x90\xB7 bar"); // 𐐷 (U+10437)
StringPool::Ref ref_c = pool.MakeRef("\xF0\x90\x90\x80\xF0\x90\x90\xB7");
BigBuffer buffer(1024);
StringPool::FlattenUtf8(&buffer, pool, &diag);
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer);
// Check that the codepoints are encoded using two three-byte surrogate pairs
ResStringPool test;
@@ -332,13 +332,13 @@ TEST(StringPoolTest, ModifiedUTF8) {
EXPECT_THAT(str->to_string(), Eq("\xED\xA0\x81\xED\xB0\x80\xED\xA0\x81\xED\xB0\xB7"));
// Check that retrieving the strings returns the original UTF-8 character bytes
EXPECT_THAT(util::GetString(test, 0), Eq("\xF0\x90\x90\x80"));
EXPECT_THAT(util::GetString(test, 1), Eq("foo \xF0\x90\x90\xB7 bar"));
EXPECT_THAT(util::GetString(test, 2), Eq("\xF0\x90\x90\x80\xF0\x90\x90\xB7"));
EXPECT_THAT(android::util::GetString(test, 0), Eq("\xF0\x90\x90\x80"));
EXPECT_THAT(android::util::GetString(test, 1), Eq("foo \xF0\x90\x90\xB7 bar"));
EXPECT_THAT(android::util::GetString(test, 2), Eq("\xF0\x90\x90\x80\xF0\x90\x90\xB7"));
}
TEST(StringPoolTest, MaxEncodingLength) {
StdErrDiagnostics diag;
NoOpDiagnostics diag;
using namespace android; // For NO_ERROR on Windows.
ResStringPool test;
@@ -348,15 +348,15 @@ TEST(StringPoolTest, MaxEncodingLength) {
// Make sure a UTF-8 string under the maximum length does not produce an error
EXPECT_THAT(StringPool::FlattenUtf8(&buffers[0], pool, &diag), Eq(true));
std::unique_ptr<uint8_t[]> data = util::Copy(buffers[0]);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffers[0]);
test.setTo(data.get(), buffers[0].size());
EXPECT_THAT(util::GetString(test, 0), Eq("aaaaaaaaaa"));
EXPECT_THAT(android::util::GetString(test, 0), Eq("aaaaaaaaaa"));
// Make sure a UTF-16 string under the maximum length does not produce an error
EXPECT_THAT(StringPool::FlattenUtf16(&buffers[1], pool, &diag), Eq(true));
data = util::Copy(buffers[1]);
data = android::util::Copy(buffers[1]);
test.setTo(data.get(), buffers[1].size());
EXPECT_THAT(util::GetString16(test, 0), Eq(u"aaaaaaaaaa"));
EXPECT_THAT(android::util::GetString16(test, 0), Eq(u"aaaaaaaaaa"));
StringPool pool2;
std::string longStr(50000, 'a');
@@ -368,11 +368,11 @@ TEST(StringPoolTest, MaxEncodingLength) {
// Make sure a string that exceeds the maximum length of UTF-8 produces an
// error and writes a shorter error string instead
EXPECT_THAT(StringPool::FlattenUtf8(&buffers2[0], pool2, &diag), Eq(false));
data = util::Copy(buffers2[0]);
data = android::util::Copy(buffers2[0]);
test.setTo(data.get(), buffers2[0].size());
EXPECT_THAT(util::GetString(test, 0), "this fits1");
EXPECT_THAT(util::GetString(test, 1), "STRING_TOO_LARGE");
EXPECT_THAT(util::GetString(test, 2), "this fits2");
EXPECT_THAT(android::util::GetString(test, 0), "this fits1");
EXPECT_THAT(android::util::GetString(test, 1), "STRING_TOO_LARGE");
EXPECT_THAT(android::util::GetString(test, 2), "this fits2");
// Make sure a string that a string that exceeds the maximum length of UTF-8
// but not UTF-16 does not error for UTF-16
@@ -380,9 +380,9 @@ TEST(StringPoolTest, MaxEncodingLength) {
std::u16string longStr16(50000, 'a');
pool3.MakeRef(longStr);
EXPECT_THAT(StringPool::FlattenUtf16(&buffers2[1], pool3, &diag), Eq(true));
data = util::Copy(buffers2[1]);
data = android::util::Copy(buffers2[1]);
test.setTo(data.get(), buffers2[1].size());
EXPECT_THAT(util::GetString16(test, 0), Eq(longStr16));
EXPECT_THAT(android::util::GetString16(test, 0), Eq(longStr16));
}
} // namespace aapt
} // namespace android

View File

@@ -137,7 +137,6 @@ cc_library_host_static {
"text/Printer.cpp",
"text/Unicode.cpp",
"text/Utf8Iterator.cpp",
"util/BigBuffer.cpp",
"util/Files.cpp",
"util/Util.cpp",
"Debug.cpp",
@@ -154,7 +153,6 @@ cc_library_host_static {
"ResourceUtils.cpp",
"ResourceValues.cpp",
"SdkConstants.cpp",
"StringPool.cpp",
"trace/TraceBuffer.cpp",
"xml/XmlActionExecutor.cpp",
"xml/XmlDom.cpp",

View File

@@ -17,6 +17,7 @@
#include "Debug.h"
#include <androidfw/TypeWrappers.h>
#include <androidfw/Util.h>
#include <format/binary/ResChunkPullParser.h>
#include <algorithm>
@@ -592,12 +593,12 @@ using namespace android;
class ChunkPrinter {
public:
ChunkPrinter(const void* data, size_t len, Printer* printer, IDiagnostics* diag)
ChunkPrinter(const void* data, size_t len, Printer* printer, android::IDiagnostics* diag)
: data_(data), data_len_(len), printer_(printer), diag_(diag) {
}
void PrintChunkHeader(const ResChunk_header* chunk) {
switch (util::DeviceToHost16(chunk->type)) {
switch (android::util::DeviceToHost16(chunk->type)) {
case RES_STRING_POOL_TYPE:
printer_->Print("[RES_STRING_POOL_TYPE]");
break;
@@ -620,13 +621,14 @@ class ChunkPrinter {
break;
}
printer_->Print(StringPrintf(" chunkSize: %u", util::DeviceToHost32(chunk->size)));
printer_->Print(StringPrintf(" headerSize: %u", util::DeviceToHost32(chunk->headerSize)));
printer_->Print(StringPrintf(" chunkSize: %u", android::util::DeviceToHost32(chunk->size)));
printer_->Print(
StringPrintf(" headerSize: %u", android::util::DeviceToHost32(chunk->headerSize)));
}
bool PrintTable(const ResTable_header* chunk) {
printer_->Print(
StringPrintf(" Package count: %u\n", util::DeviceToHost32(chunk->packageCount)));
StringPrintf(" Package count: %u\n", android::util::DeviceToHost32(chunk->packageCount)));
// Print the chunks contained within the table
printer_->Indent();
@@ -639,9 +641,10 @@ class ChunkPrinter {
void PrintResValue(const Res_value* value, const ConfigDescription& config,
const ResourceType* type) {
printer_->Print("[Res_value]");
printer_->Print(StringPrintf(" size: %u", util::DeviceToHost32(value->size)));
printer_->Print(StringPrintf(" dataType: 0x%02x", util::DeviceToHost32(value->dataType)));
printer_->Print(StringPrintf(" data: 0x%08x", util::DeviceToHost32(value->data)));
printer_->Print(StringPrintf(" size: %u", android::util::DeviceToHost32(value->size)));
printer_->Print(
StringPrintf(" dataType: 0x%02x", android::util::DeviceToHost32(value->dataType)));
printer_->Print(StringPrintf(" data: 0x%08x", android::util::DeviceToHost32(value->data)));
if (type) {
auto item =
@@ -655,19 +658,23 @@ class ChunkPrinter {
}
bool PrintTableType(const ResTable_type* chunk) {
printer_->Print(StringPrintf(" id: 0x%02x", util::DeviceToHost32(chunk->id)));
printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
printer_->Print(StringPrintf(
" name: %s", util::GetString(type_pool_, util::DeviceToHost32(chunk->id) - 1).c_str()));
printer_->Print(StringPrintf(" flags: 0x%02x", util::DeviceToHost32(chunk->flags)));
printer_->Print(StringPrintf(" entryCount: %u", util::DeviceToHost32(chunk->entryCount)));
printer_->Print(StringPrintf(" entryStart: %u", util::DeviceToHost32(chunk->entriesStart)));
" name: %s",
android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1)
.c_str()));
printer_->Print(StringPrintf(" flags: 0x%02x", android::util::DeviceToHost32(chunk->flags)));
printer_->Print(
StringPrintf(" entryCount: %u", android::util::DeviceToHost32(chunk->entryCount)));
printer_->Print(
StringPrintf(" entryStart: %u", android::util::DeviceToHost32(chunk->entriesStart)));
ConfigDescription config;
config.copyFromDtoH(chunk->config);
printer_->Print(StringPrintf(" config: %s\n", config.to_string().c_str()));
const ResourceType* type =
ParseResourceType(util::GetString(type_pool_, util::DeviceToHost32(chunk->id) - 1));
const ResourceType* type = ParseResourceType(
android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1));
printer_->Indent();
@@ -682,35 +689,42 @@ class ChunkPrinter {
: "[ResTable_entry]");
printer_->Print(StringPrintf(" id: 0x%04x", it.index()));
printer_->Print(StringPrintf(
" name: %s", util::GetString(key_pool_, util::DeviceToHost32(entry->key.index)).c_str()));
printer_->Print(StringPrintf(" keyIndex: %u", util::DeviceToHost32(entry->key.index)));
printer_->Print(StringPrintf(" size: %u", util::DeviceToHost32(entry->size)));
printer_->Print(StringPrintf(" flags: 0x%04x", util::DeviceToHost32(entry->flags)));
" name: %s",
android::util::GetString(key_pool_, android::util::DeviceToHost32(entry->key.index))
.c_str()));
printer_->Print(
StringPrintf(" keyIndex: %u", android::util::DeviceToHost32(entry->key.index)));
printer_->Print(StringPrintf(" size: %u", android::util::DeviceToHost32(entry->size)));
printer_->Print(StringPrintf(" flags: 0x%04x", android::util::DeviceToHost32(entry->flags)));
printer_->Indent();
if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
auto map_entry = (const ResTable_map_entry*)entry;
printer_->Print(StringPrintf(" count: 0x%04x", util::DeviceToHost32(map_entry->count)));
printer_->Print(
StringPrintf(" parent: 0x%08x\n", util::DeviceToHost32(map_entry->parent.ident)));
StringPrintf(" count: 0x%04x", android::util::DeviceToHost32(map_entry->count)));
printer_->Print(StringPrintf(" parent: 0x%08x\n",
android::util::DeviceToHost32(map_entry->parent.ident)));
// Print the name and value mappings
auto maps =
(const ResTable_map*)((const uint8_t*)entry + util::DeviceToHost32(entry->size));
for (size_t i = 0, count = util::DeviceToHost32(map_entry->count); i < count; i++) {
auto maps = (const ResTable_map*)((const uint8_t*)entry +
android::util::DeviceToHost32(entry->size));
for (size_t i = 0, count = android::util::DeviceToHost32(map_entry->count); i < count;
i++) {
PrintResValue(&(maps[i].value), config, type);
printer_->Print(StringPrintf(
" name: %s name-id:%d\n",
util::GetString(key_pool_, util::DeviceToHost32(maps[i].name.ident)).c_str(),
util::DeviceToHost32(maps[i].name.ident)));
android::util::GetString(key_pool_, android::util::DeviceToHost32(maps[i].name.ident))
.c_str(),
android::util::DeviceToHost32(maps[i].name.ident)));
}
} else {
printer_->Print("\n");
// Print the value of the entry
auto value = (const Res_value*)((const uint8_t*)entry + util::DeviceToHost32(entry->size));
auto value =
(const Res_value*)((const uint8_t*)entry + android::util::DeviceToHost32(entry->size));
PrintResValue(value, config, type);
}
@@ -735,33 +749,37 @@ class ChunkPrinter {
return;
}
pool->setTo(chunk,
util::DeviceToHost32((reinterpret_cast<const ResChunk_header*>(chunk))->size));
pool->setTo(chunk, android::util::DeviceToHost32(
(reinterpret_cast<const ResChunk_header*>(chunk))->size));
printer_->Print("\n");
for (size_t i = 0; i < pool->size(); i++) {
printer_->Print(StringPrintf("#%zd : %s\n", i, util::GetString(*pool, i).c_str()));
printer_->Print(StringPrintf("#%zd : %s\n", i, android::util::GetString(*pool, i).c_str()));
}
}
bool PrintPackage(const ResTable_package* chunk) {
printer_->Print(StringPrintf(" id: 0x%02x", util::DeviceToHost32(chunk->id)));
printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
size_t len = strnlen16((const char16_t*)chunk->name, std::size(chunk->name));
std::u16string package_name(len, u'\0');
package_name.resize(len);
for (size_t i = 0; i < len; i++) {
package_name[i] = util::DeviceToHost16(chunk->name[i]);
package_name[i] = android::util::DeviceToHost16(chunk->name[i]);
}
printer_->Print(StringPrintf("name: %s", String8(package_name.c_str()).c_str()));
printer_->Print(StringPrintf(" typeStrings: %u", util::DeviceToHost32(chunk->typeStrings)));
printer_->Print(
StringPrintf(" lastPublicType: %u", util::DeviceToHost32(chunk->lastPublicType)));
printer_->Print(StringPrintf(" keyStrings: %u", util::DeviceToHost32(chunk->keyStrings)));
printer_->Print(StringPrintf(" lastPublicKey: %u", util::DeviceToHost32(chunk->lastPublicKey)));
printer_->Print(StringPrintf(" typeIdOffset: %u\n", util::DeviceToHost32(chunk->typeIdOffset)));
StringPrintf(" typeStrings: %u", android::util::DeviceToHost32(chunk->typeStrings)));
printer_->Print(
StringPrintf(" lastPublicType: %u", android::util::DeviceToHost32(chunk->lastPublicType)));
printer_->Print(
StringPrintf(" keyStrings: %u", android::util::DeviceToHost32(chunk->keyStrings)));
printer_->Print(
StringPrintf(" lastPublicKey: %u", android::util::DeviceToHost32(chunk->lastPublicKey)));
printer_->Print(
StringPrintf(" typeIdOffset: %u\n", android::util::DeviceToHost32(chunk->typeIdOffset)));
// Print the chunks contained within the table
printer_->Indent();
@@ -776,7 +794,7 @@ class ChunkPrinter {
auto chunk = parser.chunk();
PrintChunkHeader(chunk);
switch (util::DeviceToHost16(chunk->type)) {
switch (android::util::DeviceToHost16(chunk->type)) {
case RES_STRING_POOL_TYPE:
PrintStringPool(reinterpret_cast<const ResStringPool_header*>(chunk));
break;
@@ -802,7 +820,7 @@ class ChunkPrinter {
}
if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
diag_->Error(DiagMessage(source_) << "corrupt resource table: " << parser.error());
diag_->Error(android::DiagMessage(source_) << "corrupt resource table: " << parser.error());
return false;
}
@@ -815,11 +833,11 @@ class ChunkPrinter {
}
private:
const Source source_;
const android::Source source_;
const void* data_;
const size_t data_len_;
Printer* printer_;
IDiagnostics* diag_;
android::IDiagnostics* diag_;
// The standard value string pool for resource values.
ResStringPool value_pool_;
@@ -832,12 +850,13 @@ class ChunkPrinter {
// in this table.
ResStringPool key_pool_;
StringPool out_pool_;
android::StringPool out_pool_;
};
} // namespace
void Debug::DumpChunks(const void* data, size_t len, Printer* printer, IDiagnostics* diag) {
void Debug::DumpChunks(const void* data, size_t len, Printer* printer,
android::IDiagnostics* diag) {
ChunkPrinter chunk_printer(data, len, printer, diag);
chunk_printer.Print();
}

View File

@@ -40,7 +40,8 @@ struct Debug {
static void DumpXml(const xml::XmlResource& doc, text::Printer* printer);
static void DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer);
static void DumpOverlayable(const ResourceTable& table, text::Printer* printer);
static void DumpChunks(const void* data, size_t len, text::Printer* printer, IDiagnostics* diag);
static void DumpChunks(const void* data, size_t len, text::Printer* printer,
android::IDiagnostics* diag);
};
} // namespace aapt

View File

@@ -13,86 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AAPT_DIAGNOSTICS_H
#define AAPT_DIAGNOSTICS_H
#ifndef AAPT_DIAGNOSTICS_H_
#define AAPT_DIAGNOSTICS_H_
#include <iostream>
#include <sstream>
#include <string>
#include "android-base/macros.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/Source.h"
#include "androidfw/StringPiece.h"
#include "Source.h"
#include "util/Util.h"
namespace aapt {
struct DiagMessageActual {
Source source;
std::string message;
};
struct DiagMessage {
public:
DiagMessage() = default;
explicit DiagMessage(const android::StringPiece& src) : source_(src) {}
explicit DiagMessage(const Source& src) : source_(src) {}
explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) {}
template <typename T>
DiagMessage& operator<<(const T& value) {
message_ << value;
return *this;
}
DiagMessageActual Build() const {
return DiagMessageActual{source_, message_.str()};
}
private:
Source source_;
std::stringstream message_;
};
template <>
inline DiagMessage& DiagMessage::operator<<(const ::std::u16string& value) {
message_ << android::StringPiece16(value);
return *this;
}
struct IDiagnostics {
virtual ~IDiagnostics() = default;
enum class Level { Note, Warn, Error };
virtual void Log(Level level, DiagMessageActual& actualMsg) = 0;
virtual void Error(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Error, actual);
}
virtual void Warn(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Warn, actual);
}
virtual void Note(const DiagMessage& message) {
DiagMessageActual actual = message.Build();
Log(Level::Note, actual);
}
};
class StdErrDiagnostics : public IDiagnostics {
class StdErrDiagnostics : public android::IDiagnostics {
public:
StdErrDiagnostics() = default;
void Log(Level level, DiagMessageActual& actual_msg) override {
void Log(Level level, android::DiagMessageActual& actual_msg) override {
const char* tag;
switch (level) {
@@ -125,31 +64,6 @@ class StdErrDiagnostics : public IDiagnostics {
DISALLOW_COPY_AND_ASSIGN(StdErrDiagnostics);
};
class SourcePathDiagnostics : public IDiagnostics {
public:
SourcePathDiagnostics(const Source& src, IDiagnostics* diag)
: source_(src), diag_(diag) {}
void Log(Level level, DiagMessageActual& actual_msg) override {
actual_msg.source.path = source_.path;
diag_->Log(level, actual_msg);
if (level == Level::Error) {
error = true;
}
}
bool HadError() {
return error;
}
private:
Source source_;
IDiagnostics* diag_;
bool error = false;
DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics);
};
} // namespace aapt
#endif /* AAPT_DIAGNOSTICS_H */
#endif /* AAPT_DIAGNOSTICS_H_ */

View File

@@ -72,12 +72,13 @@ static ApkFormat DetermineApkFormat(io::IFileCollection* apk) {
}
}
std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(const StringPiece& path, IDiagnostics* diag) {
Source source(path);
std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(const StringPiece& path,
android::IDiagnostics* diag) {
android::Source source(path);
std::string error;
std::unique_ptr<io::ZipFileCollection> apk = io::ZipFileCollection::Create(path, &error);
if (apk == nullptr) {
diag->Error(DiagMessage(path) << "failed opening zip: " << error);
diag->Error(android::DiagMessage(path) << "failed opening zip: " << error);
return {};
}
@@ -88,13 +89,14 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(const StringPiece& path, I
case ApkFormat::kProto:
return LoadProtoApkFromFileCollection(source, std::move(apk), diag);
default:
diag->Error(DiagMessage(path) << "could not identify format of APK");
diag->Error(android::DiagMessage(path) << "could not identify format of APK");
return {};
}
}
std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
const Source& source, unique_ptr<io::IFileCollection> collection, IDiagnostics* diag) {
const android::Source& source, unique_ptr<io::IFileCollection> collection,
android::IDiagnostics* diag) {
std::unique_ptr<ResourceTable> table;
io::IFile* table_file = collection->FindFile(kProtoResourceTablePath);
@@ -102,20 +104,20 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
pb::ResourceTable pb_table;
std::unique_ptr<io::InputStream> in = table_file->OpenInputStream();
if (in == nullptr) {
diag->Error(DiagMessage(source) << "failed to open " << kProtoResourceTablePath);
diag->Error(android::DiagMessage(source) << "failed to open " << kProtoResourceTablePath);
return {};
}
io::ProtoInputStreamReader proto_reader(in.get());
if (!proto_reader.ReadMessage(&pb_table)) {
diag->Error(DiagMessage(source) << "failed to read " << kProtoResourceTablePath);
diag->Error(android::DiagMessage(source) << "failed to read " << kProtoResourceTablePath);
return {};
}
std::string error;
table = util::make_unique<ResourceTable>(ResourceTable::Validation::kDisabled);
if (!DeserializeTableFromPb(pb_table, collection.get(), table.get(), &error)) {
diag->Error(DiagMessage(source)
diag->Error(android::DiagMessage(source)
<< "failed to deserialize " << kProtoResourceTablePath << ": " << error);
return {};
}
@@ -123,27 +125,27 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
io::IFile* manifest_file = collection->FindFile(kAndroidManifestPath);
if (manifest_file == nullptr) {
diag->Error(DiagMessage(source) << "failed to find " << kAndroidManifestPath);
diag->Error(android::DiagMessage(source) << "failed to find " << kAndroidManifestPath);
return {};
}
std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
if (manifest_in == nullptr) {
diag->Error(DiagMessage(source) << "failed to open " << kAndroidManifestPath);
diag->Error(android::DiagMessage(source) << "failed to open " << kAndroidManifestPath);
return {};
}
pb::XmlNode pb_node;
io::ProtoInputStreamReader proto_reader(manifest_in.get());
if (!proto_reader.ReadMessage(&pb_node)) {
diag->Error(DiagMessage(source) << "failed to read proto " << kAndroidManifestPath);
diag->Error(android::DiagMessage(source) << "failed to read proto " << kAndroidManifestPath);
return {};
}
std::string error;
std::unique_ptr<xml::XmlResource> manifest = DeserializeXmlResourceFromPb(pb_node, &error);
if (manifest == nullptr) {
diag->Error(DiagMessage(source)
diag->Error(android::DiagMessage(source)
<< "failed to deserialize proto " << kAndroidManifestPath << ": " << error);
return {};
}
@@ -152,7 +154,8 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadProtoApkFromFileCollection(
}
std::unique_ptr<LoadedApk> LoadedApk::LoadBinaryApkFromFileCollection(
const Source& source, unique_ptr<io::IFileCollection> collection, IDiagnostics* diag) {
const android::Source& source, unique_ptr<io::IFileCollection> collection,
android::IDiagnostics* diag) {
std::unique_ptr<ResourceTable> table;
io::IFile* table_file = collection->FindFile(kApkResourceTablePath);
@@ -160,7 +163,7 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadBinaryApkFromFileCollection(
table = util::make_unique<ResourceTable>(ResourceTable::Validation::kDisabled);
std::unique_ptr<io::IData> data = table_file->OpenAsData();
if (data == nullptr) {
diag->Error(DiagMessage(source) << "failed to open " << kApkResourceTablePath);
diag->Error(android::DiagMessage(source) << "failed to open " << kApkResourceTablePath);
return {};
}
BinaryResourceParser parser(diag, table.get(), source, data->data(), data->size(),
@@ -172,13 +175,13 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadBinaryApkFromFileCollection(
io::IFile* manifest_file = collection->FindFile(kAndroidManifestPath);
if (manifest_file == nullptr) {
diag->Error(DiagMessage(source) << "failed to find " << kAndroidManifestPath);
diag->Error(android::DiagMessage(source) << "failed to find " << kAndroidManifestPath);
return {};
}
std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
if (manifest_data == nullptr) {
diag->Error(DiagMessage(source) << "failed to open " << kAndroidManifestPath);
diag->Error(android::DiagMessage(source) << "failed to open " << kAndroidManifestPath);
return {};
}
@@ -186,7 +189,7 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadBinaryApkFromFileCollection(
std::unique_ptr<xml::XmlResource> manifest =
xml::Inflate(manifest_data->data(), manifest_data->size(), &error);
if (manifest == nullptr) {
diag->Error(DiagMessage(source)
diag->Error(android::DiagMessage(source)
<< "failed to parse binary " << kAndroidManifestPath << ": " << error);
return {};
}
@@ -235,7 +238,7 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
// Skip resources that are not referenced if requested.
if (is_resource && referenced_resources.find(output_path) == referenced_resources.end()) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage()
context->GetDiagnostics()->Note(android::DiagMessage()
<< "Removing resource '" << path << "' from APK.");
}
continue;
@@ -243,14 +246,15 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
if (!filters->Keep(path)) {
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage() << "Filtered '" << path << "' from APK.");
context->GetDiagnostics()->Note(android::DiagMessage()
<< "Filtered '" << path << "' from APK.");
}
continue;
}
// The resource table needs to be re-serialized since it might have changed.
if (format_ == ApkFormat::kBinary && path == kApkResourceTablePath) {
BigBuffer buffer(4096);
android::BigBuffer buffer(4096);
// TODO(adamlesinski): How to determine if there were sparse entries (and if to encode
// with sparse entries) b/35389232.
TableFlattener flattener(options, &buffer);
@@ -282,12 +286,12 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
return false;
}
} else if (manifest != nullptr && path == "AndroidManifest.xml") {
BigBuffer buffer(8192);
android::BigBuffer buffer(8192);
XmlFlattenerOptions xml_flattener_options;
xml_flattener_options.use_utf16 = true;
XmlFlattener xml_flattener(&buffer, xml_flattener_options);
if (!xml_flattener.Consume(context, manifest)) {
context->GetDiagnostics()->Error(DiagMessage(path) << "flattening failed");
context->GetDiagnostics()->Error(android::DiagMessage(path) << "flattening failed");
return false;
}
@@ -308,10 +312,10 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, ResourceTable* split_table
}
std::unique_ptr<xml::XmlResource> LoadedApk::LoadXml(const std::string& file_path,
IDiagnostics* diag) const {
android::IDiagnostics* diag) const {
io::IFile* file = apk_->FindFile(file_path);
if (file == nullptr) {
diag->Error(DiagMessage() << "failed to find file");
diag->Error(android::DiagMessage() << "failed to find file");
return nullptr;
}
@@ -319,34 +323,34 @@ std::unique_ptr<xml::XmlResource> LoadedApk::LoadXml(const std::string& file_pat
if (format_ == ApkFormat::kProto) {
std::unique_ptr<io::InputStream> in = file->OpenInputStream();
if (!in) {
diag->Error(DiagMessage() << "failed to open file");
diag->Error(android::DiagMessage() << "failed to open file");
return nullptr;
}
pb::XmlNode pb_node;
io::ProtoInputStreamReader proto_reader(in.get());
if (!proto_reader.ReadMessage(&pb_node)) {
diag->Error(DiagMessage() << "failed to parse file as proto XML");
diag->Error(android::DiagMessage() << "failed to parse file as proto XML");
return nullptr;
}
std::string err;
doc = DeserializeXmlResourceFromPb(pb_node, &err);
if (!doc) {
diag->Error(DiagMessage() << "failed to deserialize proto XML: " << err);
diag->Error(android::DiagMessage() << "failed to deserialize proto XML: " << err);
return nullptr;
}
} else if (format_ == ApkFormat::kBinary) {
std::unique_ptr<io::IData> data = file->OpenAsData();
if (!data) {
diag->Error(DiagMessage() << "failed to open file");
diag->Error(android::DiagMessage() << "failed to open file");
return nullptr;
}
std::string err;
doc = xml::Inflate(data->data(), data->size(), &err);
if (!doc) {
diag->Error(DiagMessage() << "failed to parse file as binary XML: " << err);
diag->Error(android::DiagMessage() << "failed to parse file as binary XML: " << err);
return nullptr;
}
}

View File

@@ -46,17 +46,19 @@ class LoadedApk {
// Loads both binary and proto APKs from disk.
static std::unique_ptr<LoadedApk> LoadApkFromPath(const ::android::StringPiece& path,
IDiagnostics* diag);
android::IDiagnostics* diag);
// Loads a proto APK from the given file collection.
static std::unique_ptr<LoadedApk> LoadProtoApkFromFileCollection(
const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
const android::Source& source, std::unique_ptr<io::IFileCollection> collection,
android::IDiagnostics* diag);
// Loads a binary APK from the given file collection.
static std::unique_ptr<LoadedApk> LoadBinaryApkFromFileCollection(
const Source& source, std::unique_ptr<io::IFileCollection> collection, IDiagnostics* diag);
const android::Source& source, std::unique_ptr<io::IFileCollection> collection,
android::IDiagnostics* diag);
LoadedApk(const Source& source, std::unique_ptr<io::IFileCollection> apk,
LoadedApk(const android::Source& source, std::unique_ptr<io::IFileCollection> apk,
std::unique_ptr<ResourceTable> table, std::unique_ptr<xml::XmlResource> manifest,
const ApkFormat& format)
: source_(source),
@@ -82,7 +84,7 @@ class LoadedApk {
return table_.get();
}
const Source& GetSource() {
const android::Source& GetSource() {
return source_;
}
@@ -111,12 +113,13 @@ class LoadedApk {
IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
/** Loads the file as an xml document. */
std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path, IDiagnostics* diag) const;
std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path,
android::IDiagnostics* diag) const;
private:
DISALLOW_COPY_AND_ASSIGN(LoadedApk);
Source source_;
android::Source source_;
std::unique_ptr<io::IFileCollection> apk_;
std::unique_ptr<ResourceTable> table_;
std::unique_ptr<xml::XmlResource> manifest_;

View File

@@ -27,6 +27,7 @@
#include "Diagnostics.h"
#include "android-base/stringprintf.h"
#include "android-base/utf8.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "cmd/ApkInfo.h"
#include "cmd/Command.h"
@@ -63,7 +64,7 @@ class VersionCommand : public Command {
/** The main entry point of AAPT. */
class MainCommand : public Command {
public:
explicit MainCommand(text::Printer* printer, IDiagnostics* diagnostics)
explicit MainCommand(text::Printer* printer, android::IDiagnostics* diagnostics)
: Command("aapt2"), diagnostics_(diagnostics) {
AddOptionalSubcommand(util::make_unique<CompileCommand>(diagnostics));
AddOptionalSubcommand(util::make_unique<LinkCommand>(diagnostics));
@@ -77,9 +78,9 @@ class MainCommand : public Command {
int Action(const std::vector<std::string>& args) override {
if (args.size() == 0) {
diagnostics_->Error(DiagMessage() << "no subcommand specified");
diagnostics_->Error(android::DiagMessage() << "no subcommand specified");
} else {
diagnostics_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
diagnostics_->Error(android::DiagMessage() << "unknown subcommand '" << args[0] << "'");
}
Usage(&std::cerr);
@@ -87,7 +88,7 @@ class MainCommand : public Command {
}
private:
IDiagnostics* diagnostics_;
android::IDiagnostics* diagnostics_;
};
/*
@@ -98,7 +99,7 @@ class MainCommand : public Command {
*/
class DaemonCommand : public Command {
public:
explicit DaemonCommand(io::FileOutputStream* out, IDiagnostics* diagnostics)
explicit DaemonCommand(io::FileOutputStream* out, android::IDiagnostics* diagnostics)
: Command("daemon", "m"), out_(out), diagnostics_(diagnostics) {
SetDescription("Runs aapt in daemon mode. Each subsequent line is a single parameter to the\n"
"command. The end of an invocation is signaled by providing an empty line.");
@@ -147,7 +148,7 @@ class DaemonCommand : public Command {
private:
io::FileOutputStream* out_;
IDiagnostics* diagnostics_;
android::IDiagnostics* diagnostics_;
std::optional<std::string> trace_folder_;
};

View File

@@ -25,8 +25,8 @@
#include <tuple>
#include <vector>
#include "Source.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/Source.h"
#include "androidfw/StringPiece.h"
#include "utils/JenkinsHash.h"
@@ -228,7 +228,7 @@ struct ResourceFile {
Type type;
// Source
Source source;
android::Source source;
// Exported symbols
std::vector<SourcedResourceName> exported_symbols;

View File

@@ -102,7 +102,7 @@ struct ParsedResource {
ResourceName name;
ConfigDescription config;
std::string product;
Source source;
android::Source source;
ResourceId id;
Visibility::Level visibility_level = Visibility::Level::kUndefined;
@@ -117,7 +117,8 @@ struct ParsedResource {
};
// Recursively adds resources to the ResourceTable.
static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) {
static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* diag,
ParsedResource* res) {
StringPiece trimmed_comment = util::TrimWhitespace(res->comment);
if (trimmed_comment.size() != res->comment.size()) {
// Only if there was a change do we re-assign.
@@ -175,15 +176,11 @@ static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, Parsed
// Convenient aliases for more readable function calls.
enum { kAllowRawString = true, kNoRawString = false };
ResourceParser::ResourceParser(IDiagnostics* diag, ResourceTable* table,
const Source& source,
const ConfigDescription& config,
ResourceParser::ResourceParser(android::IDiagnostics* diag, ResourceTable* table,
const android::Source& source, const ConfigDescription& config,
const ResourceParserOptions& options)
: diag_(diag),
table_(table),
source_(source),
config_(config),
options_(options) {}
: diag_(diag), table_(table), source_(source), config_(config), options_(options) {
}
// Base class Node for representing the various Spans and UntranslatableSections of an XML string.
// This will be used to traverse and flatten the XML string into a single std::string, with all
@@ -245,7 +242,7 @@ class UntranslatableNode : public Node {
// Build a string from XML that converts nested elements into Span objects.
bool ResourceParser::FlattenXmlSubtree(
xml::XmlPullParser* parser, std::string* out_raw_string, StyleString* out_style_string,
xml::XmlPullParser* parser, std::string* out_raw_string, android::StyleString* out_style_string,
std::vector<UntranslatableSection>* out_untranslatable_sections) {
std::string raw_string;
std::string current_text;
@@ -308,7 +305,7 @@ bool ResourceParser::FlattenXmlSubtree(
// Check that an 'untranslatable' tag is not already being processed. Nested
// <xliff:g> tags are illegal.
if (untranslatable_start_depth) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "illegal nested XLIFF 'g' tag");
return false;
} else {
@@ -323,7 +320,7 @@ bool ResourceParser::FlattenXmlSubtree(
}
} else {
// Besides XLIFF, any other namespaced tag is unsupported and ignored.
diag_->Warn(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Warn(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "ignoring element '" << parser->element_name()
<< "' with unknown namespace '" << parser->element_namespace() << "'");
node_stack.push_back(node_stack.back()->AddChild(util::make_unique<Node>()));
@@ -383,7 +380,8 @@ bool ResourceParser::FlattenXmlSubtree(
StringBuilder builder;
root.Build(&builder);
if (!builder) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << builder.GetError());
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< builder.GetError());
return false;
}
@@ -405,7 +403,7 @@ bool ResourceParser::Parse(xml::XmlPullParser* parser) {
}
if (!parser->element_namespace().empty() || parser->element_name() != "resources") {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "root element must be <resources>");
return false;
}
@@ -415,7 +413,7 @@ bool ResourceParser::Parse(xml::XmlPullParser* parser) {
};
if (parser->event() == xml::XmlPullParser::Event::kBadDocument) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "xml parser error: " << parser->error());
return false;
}
@@ -437,7 +435,7 @@ bool ResourceParser::ParseResources(xml::XmlPullParser* parser) {
if (event == xml::XmlPullParser::Event::kText) {
if (!util::TrimWhitespace(parser->text()).empty()) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "plain text not allowed here");
error = true;
}
@@ -486,8 +484,9 @@ bool ResourceParser::ParseResources(xml::XmlPullParser* parser) {
for (const ResourceName& stripped_resource : stripped_resources) {
if (!table_->FindResource(stripped_resource)) {
// Failed to find the resource.
diag_->Error(DiagMessage(source_) << "resource '" << stripped_resource
<< "' was filtered out but no product variant remains");
diag_->Error(android::DiagMessage(source_)
<< "resource '" << stripped_resource
<< "' was filtered out but no product variant remains");
error = true;
}
}
@@ -562,7 +561,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
if (std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
resource_type = maybe_type.value().to_string();
} else {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "<item> must have a 'type' attribute");
return false;
}
@@ -573,9 +572,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
// overridden.
resource_format = ParseFormatTypeNoEnumsOrFlags(maybe_format.value());
if (!resource_format) {
diag_->Error(DiagMessage(out_resource->source)
<< "'" << maybe_format.value()
<< "' is an invalid format");
diag_->Error(android::DiagMessage(out_resource->source)
<< "'" << maybe_format.value() << "' is an invalid format");
return false;
}
}
@@ -586,7 +584,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
if (std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
resource_type = maybe_type.value().to_string();
} else {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "<bag> must have a 'type' attribute");
return false;
}
@@ -598,9 +596,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
if (resource_type == "id") {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
<< "<" << parser->element_name()
<< "> missing 'name' attribute");
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> missing 'name' attribute");
return false;
}
@@ -626,9 +623,9 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
out_resource->value = util::make_unique<Id>();
} else if (!ref || ref->name.value().type.type != ResourceType::kId) {
// If an inner element exists, the inner element must be a reference to another resource id
diag_->Error(DiagMessage(out_resource->source)
<< "<" << parser->element_name()
<< "> inner element must either be a resource reference or empty");
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name()
<< "> inner element must either be a resource reference or empty");
return false;
}
}
@@ -636,7 +633,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
return true;
} else if (resource_type == "macro") {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> missing 'name' attribute");
return false;
}
@@ -653,7 +650,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
// This is an item, record its type and format and start parsing.
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> missing 'name' attribute");
return false;
}
@@ -682,7 +679,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
if (resource_type != kPublicGroupTag && resource_type != kStagingPublicGroupTag &&
resource_type != kStagingPublicGroupFinalTag && resource_type != "overlayable") {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> missing 'name' attribute");
return false;
}
@@ -705,9 +702,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(resource_type);
if (parsed_type) {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
<< "<" << parser->element_name()
<< "> missing 'name' attribute");
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> missing 'name' attribute");
return false;
}
@@ -715,7 +711,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
out_resource->name.entry = maybe_name.value().to_string();
out_resource->value = ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
if (!out_resource->value) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid value for type '" << *parsed_type << "'. Expected a reference");
return false;
}
@@ -724,8 +720,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
}
// If the resource type was not recognized, write the error and return false.
diag_->Error(DiagMessage(out_resource->source)
<< "unknown resource type '" << resource_type << "'");
diag_->Error(android::DiagMessage(out_resource->source)
<< "unknown resource type '" << resource_type << "'");
return false;
}
@@ -738,8 +734,8 @@ bool ResourceParser::ParseItem(xml::XmlPullParser* parser,
out_resource->value = ParseXml(parser, format, kNoRawString);
if (!out_resource->value) {
diag_->Error(DiagMessage(out_resource->source) << "invalid "
<< out_resource->name.type);
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid " << out_resource->name.type);
return false;
}
return true;
@@ -750,7 +746,7 @@ std::optional<FlattenedXmlSubTree> ResourceParser::CreateFlattenSubTree(
const size_t begin_xml_line = parser->line_number();
std::string raw_value;
StyleString style_string;
android::StyleString style_string;
std::vector<UntranslatableSection> untranslatable_sections;
if (!FlattenXmlSubtree(parser, &raw_value, &style_string, &untranslatable_sections)) {
return {};
@@ -783,13 +779,13 @@ std::unique_ptr<Item> ResourceParser::ParseXml(const FlattenedXmlSubTree& xmlsub
const uint32_t type_mask, const bool allow_raw_value,
ResourceTable& table,
const android::ConfigDescription& config,
IDiagnostics& diag) {
android::IDiagnostics& diag) {
if (!xmlsub_tree.style_string.spans.empty()) {
// This can only be a StyledString.
std::unique_ptr<StyledString> styled_string =
util::make_unique<StyledString>(table.string_pool.MakeRef(
xmlsub_tree.style_string,
StringPool::Context(StringPool::Context::kNormalPriority, config)));
android::StringPool::Context(android::StringPool::Context::kNormalPriority, config)));
styled_string->untranslatable_sections = xmlsub_tree.untranslatable_sections;
return std::move(styled_string);
}
@@ -817,8 +813,8 @@ std::unique_ptr<Item> ResourceParser::ParseXml(const FlattenedXmlSubTree& xmlsub
// Try making a regular string.
if (type_mask & android::ResTable_map::TYPE_STRING) {
// Use the trimmed, escaped string.
std::unique_ptr<String> string = util::make_unique<String>(
table.string_pool.MakeRef(xmlsub_tree.style_string.str, StringPool::Context(config)));
std::unique_ptr<String> string = util::make_unique<String>(table.string_pool.MakeRef(
xmlsub_tree.style_string.str, android::StringPool::Context(config)));
string->untranslatable_sections = xmlsub_tree.untranslatable_sections;
return std::move(string);
}
@@ -826,7 +822,7 @@ std::unique_ptr<Item> ResourceParser::ParseXml(const FlattenedXmlSubTree& xmlsub
if (allow_raw_value) {
// We can't parse this so return a RawString if we are allowed.
return util::make_unique<RawString>(table.string_pool.MakeRef(
util::TrimWhitespace(xmlsub_tree.raw_value), StringPool::Context(config)));
util::TrimWhitespace(xmlsub_tree.raw_value), android::StringPool::Context(config)));
} else if (util::TrimWhitespace(xmlsub_tree.raw_value).empty()) {
// If the text is empty, and the value is not allowed to be a string, encode it as a @null.
return ResourceUtils::MakeNull();
@@ -840,7 +836,7 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser,
if (std::optional<StringPiece> formatted_attr = xml::FindAttribute(parser, "formatted")) {
std::optional<bool> maybe_formatted = ResourceUtils::ParseBool(formatted_attr.value());
if (!maybe_formatted) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid value for 'formatted'. Must be a boolean");
return false;
}
@@ -851,7 +847,7 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser,
if (std::optional<StringPiece> translatable_attr = xml::FindAttribute(parser, "translatable")) {
std::optional<bool> maybe_translatable = ResourceUtils::ParseBool(translatable_attr.value());
if (!maybe_translatable) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid value for 'translatable'. Must be a boolean");
return false;
}
@@ -861,7 +857,7 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser,
out_resource->value =
ParseXml(parser, android::ResTable_map::TYPE_STRING, kNoRawString);
if (!out_resource->value) {
diag_->Error(DiagMessage(out_resource->source) << "not a valid string");
diag_->Error(android::DiagMessage(out_resource->source) << "not a valid string");
return false;
}
@@ -870,7 +866,7 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser,
if (formatted && translatable) {
if (!util::VerifyJavaStringFormat(*string_value->value)) {
DiagMessage msg(out_resource->source);
android::DiagMessage msg(out_resource->source);
msg << "multiple substitutions specified in non-positional format; "
"did you mean to add the formatted=\"false\" attribute?";
if (options_.error_on_positional_arguments) {
@@ -895,7 +891,7 @@ bool ResourceParser::ParseMacro(xml::XmlPullParser* parser, ParsedResource* out_
}
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<macro> tags cannot be declared in configurations other than the default "
"configuration'");
return false;
@@ -919,28 +915,27 @@ bool ResourceParser::ParseMacro(xml::XmlPullParser* parser, ParsedResource* out_
bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource) {
if (options_.visibility) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<public> tag not allowed with --visibility flag");
return false;
}
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
diag_->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for <public> tag");
}
std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
if (!maybe_type) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<public> must have a 'type' attribute");
return false;
}
std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(maybe_type.value());
if (!parsed_type) {
diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '"
<< maybe_type.value()
<< "' in <public>");
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid resource type '" << maybe_type.value() << "' in <public>");
return false;
}
@@ -949,7 +944,7 @@ bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, ParsedResource* out
if (std::optional<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "id")) {
std::optional<ResourceId> maybe_id = ResourceUtils::ParseResourceId(maybe_id_str.value());
if (!maybe_id) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid resource ID '" << maybe_id_str.value() << "' in <public>");
return false;
}
@@ -967,16 +962,16 @@ bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, ParsedResource* out
template <typename Func>
bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resource,
const char* tag_name, IDiagnostics* diag, Func&& func) {
const char* tag_name, android::IDiagnostics* diag, Func&& func) {
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag->Warn(DiagMessage(out_resource->source)
diag->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for <" << tag_name
<< "> tag");
}
std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
if (!maybe_type) {
diag->Error(DiagMessage(out_resource->source)
diag->Error(android::DiagMessage(out_resource->source)
<< "<" << tag_name << "> must have a 'type' attribute");
return false;
}
@@ -984,7 +979,7 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
std::optional<ResourceNamedTypeRef> maybe_parsed_type =
ParseResourceNamedType(maybe_type.value());
if (!maybe_parsed_type) {
diag->Error(DiagMessage(out_resource->source)
diag->Error(android::DiagMessage(out_resource->source)
<< "invalid resource type '" << maybe_type.value() << "' in <" << tag_name << ">");
return false;
}
@@ -992,14 +987,14 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
std::optional<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "first-id");
if (!maybe_id_str) {
diag->Error(DiagMessage(out_resource->source)
diag->Error(android::DiagMessage(out_resource->source)
<< "<" << tag_name << "> must have a 'first-id' attribute");
return false;
}
std::optional<ResourceId> maybe_id = ResourceUtils::ParseResourceId(maybe_id_str.value());
if (!maybe_id) {
diag->Error(DiagMessage(out_resource->source)
diag->Error(android::DiagMessage(out_resource->source)
<< "invalid resource ID '" << maybe_id_str.value() << "' in <" << tag_name << ">");
return false;
}
@@ -1017,25 +1012,27 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
continue;
}
const Source item_source = out_resource->source.WithLine(parser->line_number());
const android::Source item_source = out_resource->source.WithLine(parser->line_number());
const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
if (element_namespace.empty() && element_name == "public") {
auto maybe_name = xml::FindNonEmptyAttribute(parser, "name");
if (!maybe_name) {
diag->Error(DiagMessage(item_source) << "<public> must have a 'name' attribute");
diag->Error(android::DiagMessage(item_source) << "<public> must have a 'name' attribute");
error = true;
continue;
}
if (xml::FindNonEmptyAttribute(parser, "id")) {
diag->Error(DiagMessage(item_source) << "'id' is ignored within <" << tag_name << ">");
diag->Error(android::DiagMessage(item_source)
<< "'id' is ignored within <" << tag_name << ">");
error = true;
continue;
}
if (xml::FindNonEmptyAttribute(parser, "type")) {
diag->Error(DiagMessage(item_source) << "'type' is ignored within <" << tag_name << ">");
diag->Error(android::DiagMessage(item_source)
<< "'type' is ignored within <" << tag_name << ">");
error = true;
continue;
}
@@ -1059,7 +1056,7 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
next_id.id++;
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag->Error(DiagMessage(item_source) << ":" << element_name << ">");
diag->Error(android::DiagMessage(item_source) << ":" << element_name << ">");
error = true;
}
}
@@ -1086,7 +1083,7 @@ bool ResourceParser::ParseStagingPublicGroupFinal(xml::XmlPullParser* parser,
bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource) {
if (options_.visibility) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << kPublicGroupTag << "> tag not allowed with --visibility flag");
return false;
}
@@ -1102,15 +1099,14 @@ bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser,
ParsedResource* out_resource) {
std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
if (!maybe_type) {
diag_->Error(DiagMessage(out_resource->source)
<< "<" << parser->element_name()
<< "> must have a 'type' attribute");
diag_->Error(android::DiagMessage(out_resource->source)
<< "<" << parser->element_name() << "> must have a 'type' attribute");
return false;
}
std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(maybe_type.value());
if (!parsed_type) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid resource type '" << maybe_type.value() << "' in <"
<< parser->element_name() << ">");
return false;
@@ -1122,12 +1118,12 @@ bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser,
bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource) {
if (options_.visibility) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "<java-symbol> and <symbol> tags not allowed with --visibility flag");
return false;
}
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
diag_->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for <"
<< parser->element_name() << "> tag");
}
@@ -1142,15 +1138,14 @@ bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out
bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource) {
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config
<< "' for <overlayable> tag");
diag_->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for <overlayable> tag");
}
std::optional<StringPiece> overlayable_name = xml::FindNonEmptyAttribute(parser, "name");
if (!overlayable_name) {
diag_->Error(DiagMessage(out_resource->source)
<< "<overlayable> tag must have a 'name' attribute");
diag_->Error(android::DiagMessage(out_resource->source)
<< "<overlayable> tag must have a 'name' attribute");
return false;
}
@@ -1158,7 +1153,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
android::base::StringPrintf("%s://", Overlayable::kActorScheme);
std::optional<StringPiece> overlayable_actor = xml::FindNonEmptyAttribute(parser, "actor");
if (overlayable_actor && !util::StartsWith(overlayable_actor.value(), kActorUriScheme)) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "specified <overlayable> tag 'actor' attribute must use the scheme '"
<< Overlayable::kActorScheme << "'");
return false;
@@ -1192,13 +1187,13 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
continue;
}
const Source element_source = source_.WithLine(parser->line_number());
const android::Source element_source = source_.WithLine(parser->line_number());
const std::string& element_name = parser->element_name();
const std::string& element_namespace = parser->element_namespace();
if (element_namespace.empty() && element_name == "item") {
if (current_policies == PolicyFlags::NONE) {
diag_->Error(DiagMessage(element_source)
<< "<item> within an <overlayable> must be inside a <policy> block");
diag_->Error(android::DiagMessage(element_source)
<< "<item> within an <overlayable> must be inside a <policy> block");
error = true;
continue;
}
@@ -1206,7 +1201,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
// Items specify the name and type of resource that should be overlayable
std::optional<StringPiece> item_name = xml::FindNonEmptyAttribute(parser, "name");
if (!item_name) {
diag_->Error(DiagMessage(element_source)
diag_->Error(android::DiagMessage(element_source)
<< "<item> within an <overlayable> must have a 'name' attribute");
error = true;
continue;
@@ -1214,7 +1209,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
std::optional<StringPiece> item_type = xml::FindNonEmptyAttribute(parser, "type");
if (!item_type) {
diag_->Error(DiagMessage(element_source)
diag_->Error(android::DiagMessage(element_source)
<< "<item> within an <overlayable> must have a 'type' attribute");
error = true;
continue;
@@ -1222,7 +1217,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
std::optional<ResourceNamedTypeRef> type = ParseResourceNamedType(item_type.value());
if (!type) {
diag_->Error(DiagMessage(element_source)
diag_->Error(android::DiagMessage(element_source)
<< "invalid resource type '" << item_type.value()
<< "' in <item> within an <overlayable>");
error = true;
@@ -1243,7 +1238,8 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
} else if (element_namespace.empty() && element_name == "policy") {
if (current_policies != PolicyFlags::NONE) {
// If the policy list is not empty, then we are currently inside a policy element
diag_->Error(DiagMessage(element_source) << "<policy> blocks cannot be recursively nested");
diag_->Error(android::DiagMessage(element_source)
<< "<policy> blocks cannot be recursively nested");
error = true;
break;
} else if (std::optional<StringPiece> maybe_type =
@@ -1258,7 +1254,7 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
return trimmed_part == it.first;
});
if (policy == kPolicyStringToFlag.end()) {
diag_->Error(DiagMessage(element_source)
diag_->Error(android::DiagMessage(element_source)
<< "<policy> has unsupported type '" << trimmed_part << "'");
error = true;
continue;
@@ -1267,14 +1263,15 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource
current_policies |= policy->second;
}
} else {
diag_->Error(DiagMessage(element_source)
diag_->Error(android::DiagMessage(element_source)
<< "<policy> must have a 'type' attribute");
error = true;
continue;
}
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(element_source) << "invalid element <" << element_name << "> "
<< " in <overlayable>");
diag_->Error(android::DiagMessage(element_source)
<< "invalid element <" << element_name << "> "
<< " in <overlayable>");
error = true;
break;
}
@@ -1306,9 +1303,9 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
// Attributes only end up in default configuration.
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config
<< "' for attribute " << out_resource->name);
diag_->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for attribute "
<< out_resource->name);
out_resource->config = ConfigDescription::DefaultConfig();
}
@@ -1318,7 +1315,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
if (maybe_format) {
type_mask = ParseFormatAttribute(maybe_format.value());
if (type_mask == 0) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "invalid attribute format '" << maybe_format.value() << "'");
return false;
}
@@ -1329,7 +1326,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
if (std::optional<StringPiece> maybe_min_str = xml::FindAttribute(parser, "min")) {
StringPiece min_str = util::TrimWhitespace(maybe_min_str.value());
if (!min_str.empty()) {
std::u16string min_str16 = util::Utf8ToUtf16(min_str);
std::u16string min_str16 = android::util::Utf8ToUtf16(min_str);
android::Res_value value;
if (android::ResTable::stringToInt(min_str16.data(), min_str16.size(), &value)) {
maybe_min = static_cast<int32_t>(value.data);
@@ -1337,7 +1334,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
}
if (!maybe_min) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "invalid 'min' value '" << min_str << "'");
return false;
}
@@ -1346,7 +1343,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
if (std::optional<StringPiece> maybe_max_str = xml::FindAttribute(parser, "max")) {
StringPiece max_str = util::TrimWhitespace(maybe_max_str.value());
if (!max_str.empty()) {
std::u16string max_str16 = util::Utf8ToUtf16(max_str);
std::u16string max_str16 = android::util::Utf8ToUtf16(max_str);
android::Res_value value;
if (android::ResTable::stringToInt(max_str16.data(), max_str16.size(), &value)) {
maybe_max = static_cast<int32_t>(value.data);
@@ -1354,7 +1351,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
}
if (!maybe_max) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "invalid 'max' value '" << max_str << "'");
return false;
}
@@ -1362,7 +1359,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
if ((maybe_min || maybe_max) &&
(type_mask & android::ResTable_map::TYPE_INTEGER) == 0) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "'min' and 'max' can only be used when format='integer'");
return false;
}
@@ -1387,13 +1384,13 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
continue;
}
const Source item_source = source_.WithLine(parser->line_number());
const android::Source item_source = source_.WithLine(parser->line_number());
const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
if (element_namespace.empty() && (element_name == "flag" || element_name == "enum")) {
if (element_name == "enum") {
if (type_mask & android::ResTable_map::TYPE_FLAGS) {
diag_->Error(DiagMessage(item_source)
diag_->Error(android::DiagMessage(item_source)
<< "can not define an <enum>; already defined a <flag>");
error = true;
continue;
@@ -1402,7 +1399,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
} else if (element_name == "flag") {
if (type_mask & android::ResTable_map::TYPE_ENUM) {
diag_->Error(DiagMessage(item_source)
diag_->Error(android::DiagMessage(item_source)
<< "can not define a <flag>; already defined an <enum>");
error = true;
continue;
@@ -1427,11 +1424,10 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
auto insert_result = items.insert(std::move(symbol));
if (!insert_result.second) {
const Attribute::Symbol& existing_symbol = *insert_result.first;
diag_->Error(DiagMessage(item_source)
<< "duplicate symbol '"
<< existing_symbol.symbol.name.value().entry << "'");
diag_->Error(android::DiagMessage(item_source)
<< "duplicate symbol '" << existing_symbol.symbol.name.value().entry << "'");
diag_->Note(DiagMessage(existing_symbol.symbol.GetSource())
diag_->Note(android::DiagMessage(existing_symbol.symbol.GetSource())
<< "first defined here");
error = true;
}
@@ -1439,7 +1435,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
error = true;
}
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(item_source) << ":" << element_name << ">");
diag_->Error(android::DiagMessage(item_source) << ":" << element_name << ">");
error = true;
}
@@ -1462,28 +1458,27 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
std::optional<Attribute::Symbol> ResourceParser::ParseEnumOrFlagItem(xml::XmlPullParser* parser,
const StringPiece& tag) {
const Source source = source_.WithLine(parser->line_number());
const android::Source source = source_.WithLine(parser->line_number());
std::optional<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
if (!maybe_name) {
diag_->Error(DiagMessage(source) << "no attribute 'name' found for tag <"
<< tag << ">");
diag_->Error(android::DiagMessage(source)
<< "no attribute 'name' found for tag <" << tag << ">");
return {};
}
std::optional<StringPiece> maybe_value = xml::FindNonEmptyAttribute(parser, "value");
if (!maybe_value) {
diag_->Error(DiagMessage(source) << "no attribute 'value' found for tag <"
<< tag << ">");
diag_->Error(android::DiagMessage(source)
<< "no attribute 'value' found for tag <" << tag << ">");
return {};
}
std::u16string value16 = util::Utf8ToUtf16(maybe_value.value());
std::u16string value16 = android::util::Utf8ToUtf16(maybe_value.value());
android::Res_value val;
if (!android::ResTable::stringToInt(value16.data(), value16.size(), &val)) {
diag_->Error(DiagMessage(source) << "invalid value '" << maybe_value.value()
<< "' for <" << tag
<< ">; must be an integer");
diag_->Error(android::DiagMessage(source) << "invalid value '" << maybe_value.value()
<< "' for <" << tag << ">; must be an integer");
return {};
}
@@ -1494,17 +1489,18 @@ std::optional<Attribute::Symbol> ResourceParser::ParseEnumOrFlagItem(xml::XmlPul
}
bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
const Source source = source_.WithLine(parser->line_number());
const android::Source source = source_.WithLine(parser->line_number());
std::optional<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
if (!maybe_name) {
diag_->Error(DiagMessage(source) << "<item> must have a 'name' attribute");
diag_->Error(android::DiagMessage(source) << "<item> must have a 'name' attribute");
return false;
}
std::optional<Reference> maybe_key = ResourceUtils::ParseXmlAttributeName(maybe_name.value());
if (!maybe_key) {
diag_->Error(DiagMessage(source) << "invalid attribute name '" << maybe_name.value() << "'");
diag_->Error(android::DiagMessage(source)
<< "invalid attribute name '" << maybe_name.value() << "'");
return false;
}
@@ -1513,7 +1509,7 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString);
if (!value) {
diag_->Error(DiagMessage(source) << "could not parse style item");
diag_->Error(android::DiagMessage(source) << "could not parse style item");
return false;
}
@@ -1534,7 +1530,7 @@ bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* par
std::string err_str;
style->parent = ResourceUtils::ParseStyleParentReference(maybe_parent.value(), &err_str);
if (!style->parent) {
diag_->Error(DiagMessage(out_resource->source) << err_str);
diag_->Error(android::DiagMessage(out_resource->source) << err_str);
return false;
}
@@ -1568,7 +1564,7 @@ bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* par
error |= !ParseStyleItem(parser, style.get());
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< ":" << element_name << ">");
error = true;
}
@@ -1587,7 +1583,7 @@ bool ResourceParser::ParseArray(xml::XmlPullParser* parser, ParsedResource* out_
if (std::optional<StringPiece> format_attr = xml::FindNonEmptyAttribute(parser, "format")) {
resource_format = ParseFormatTypeNoEnumsOrFlags(format_attr.value());
if (resource_format == 0u) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "'" << format_attr.value() << "' is an invalid format");
return false;
}
@@ -1615,7 +1611,7 @@ bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
if (std::optional<StringPiece> translatable_attr = xml::FindAttribute(parser, "translatable")) {
std::optional<bool> maybe_translatable = ResourceUtils::ParseBool(translatable_attr.value());
if (!maybe_translatable) {
diag_->Error(DiagMessage(out_resource->source)
diag_->Error(android::DiagMessage(out_resource->source)
<< "invalid value for 'translatable'. Must be a boolean");
return false;
}
@@ -1631,13 +1627,13 @@ bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
continue;
}
const Source item_source = source_.WithLine(parser->line_number());
const android::Source item_source = source_.WithLine(parser->line_number());
const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
if (element_namespace.empty() && element_name == "item") {
std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString);
if (!item) {
diag_->Error(DiagMessage(item_source) << "could not parse array item");
diag_->Error(android::DiagMessage(item_source) << "could not parse array item");
error = true;
continue;
}
@@ -1645,9 +1641,8 @@ bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
array->elements.emplace_back(std::move(item));
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
<< "unknown tag <" << element_namespace << ":"
<< element_name << ">");
diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
<< "unknown tag <" << element_namespace << ":" << element_name << ">");
error = true;
}
}
@@ -1675,15 +1670,14 @@ bool ResourceParser::ParsePlural(xml::XmlPullParser* parser,
continue;
}
const Source item_source = source_.WithLine(parser->line_number());
const android::Source item_source = source_.WithLine(parser->line_number());
const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
if (element_namespace.empty() && element_name == "item") {
std::optional<StringPiece> maybe_quantity = xml::FindNonEmptyAttribute(parser, "quantity");
if (!maybe_quantity) {
diag_->Error(DiagMessage(item_source)
<< "<item> in <plurals> requires attribute "
<< "'quantity'");
diag_->Error(android::DiagMessage(item_source) << "<item> in <plurals> requires attribute "
<< "'quantity'");
error = true;
continue;
}
@@ -1704,16 +1698,16 @@ bool ResourceParser::ParsePlural(xml::XmlPullParser* parser,
} else if (trimmed_quantity == "other") {
index = Plural::Other;
} else {
diag_->Error(DiagMessage(item_source)
<< "<item> in <plural> has invalid value '"
<< trimmed_quantity << "' for attribute 'quantity'");
diag_->Error(android::DiagMessage(item_source)
<< "<item> in <plural> has invalid value '" << trimmed_quantity
<< "' for attribute 'quantity'");
error = true;
continue;
}
if (plural->values[index]) {
diag_->Error(DiagMessage(item_source) << "duplicate quantity '"
<< trimmed_quantity << "'");
diag_->Error(android::DiagMessage(item_source)
<< "duplicate quantity '" << trimmed_quantity << "'");
error = true;
continue;
}
@@ -1727,9 +1721,8 @@ bool ResourceParser::ParsePlural(xml::XmlPullParser* parser,
plural->values[index]->SetSource(item_source);
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(item_source) << "unknown tag <"
<< element_namespace << ":"
<< element_name << ">");
diag_->Error(android::DiagMessage(item_source)
<< "unknown tag <" << element_namespace << ":" << element_name << ">");
error = true;
}
}
@@ -1758,9 +1751,9 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
// Declare-styleable only ends up in default config;
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config
<< "' for styleable " << out_resource->name.entry);
diag_->Warn(android::DiagMessage(out_resource->source)
<< "ignoring configuration '" << out_resource->config << "' for styleable "
<< out_resource->name.entry);
out_resource->config = ConfigDescription::DefaultConfig();
}
@@ -1778,13 +1771,14 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
continue;
}
const Source item_source = source_.WithLine(parser->line_number());
const android::Source item_source = source_.WithLine(parser->line_number());
const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
if (element_namespace.empty() && element_name == "attr") {
std::optional<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
if (!maybe_name) {
diag_->Error(DiagMessage(item_source) << "<attr> tag must have a 'name' attribute");
diag_->Error(android::DiagMessage(item_source)
<< "<attr> tag must have a 'name' attribute");
error = true;
continue;
}
@@ -1794,8 +1788,8 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
// Eg. <attr name="android:text" />
std::optional<Reference> maybe_ref = ResourceUtils::ParseXmlAttributeName(maybe_name.value());
if (!maybe_ref) {
diag_->Error(DiagMessage(item_source) << "<attr> tag has invalid name '"
<< maybe_name.value() << "'");
diag_->Error(android::DiagMessage(item_source)
<< "<attr> tag has invalid name '" << maybe_name.value() << "'");
error = true;
continue;
}
@@ -1833,9 +1827,8 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
}
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(item_source) << "unknown tag <"
<< element_namespace << ":"
<< element_name << ">");
diag_->Error(android::DiagMessage(item_source)
<< "unknown tag <" << element_namespace << ":" << element_name << ">");
error = true;
}

View File

@@ -20,14 +20,13 @@
#include <memory>
#include <optional>
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "StringPool.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "androidfw/StringPool.h"
#include "xml/XmlPullParser.h"
namespace aapt {
@@ -59,10 +58,10 @@ struct ResourceParserOptions {
struct FlattenedXmlSubTree {
std::string raw_value;
StyleString style_string;
android::StyleString style_string;
std::vector<UntranslatableSection> untranslatable_sections;
xml::IPackageDeclStack* namespace_resolver;
Source source;
android::Source source;
};
/*
@@ -70,7 +69,7 @@ struct FlattenedXmlSubTree {
*/
class ResourceParser {
public:
ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
ResourceParser(android::IDiagnostics* diag, ResourceTable* table, const android::Source& source,
const android::ConfigDescription& config,
const ResourceParserOptions& options = {});
bool Parse(xml::XmlPullParser* parser);
@@ -78,7 +77,7 @@ class ResourceParser {
static std::unique_ptr<Item> ParseXml(const FlattenedXmlSubTree& xmlsub_tree, uint32_t type_mask,
bool allow_raw_value, ResourceTable& table,
const android::ConfigDescription& config,
IDiagnostics& diag);
android::IDiagnostics& diag);
private:
DISALLOW_COPY_AND_ASSIGN(ResourceParser);
@@ -93,7 +92,7 @@ class ResourceParser {
// `out_untranslatable_sections` contains the sections of the string that should not be
// translated.
bool FlattenXmlSubtree(xml::XmlPullParser* parser, std::string* out_raw_string,
StyleString* out_style_string,
android::StyleString* out_style_string,
std::vector<UntranslatableSection>* out_untranslatable_sections);
/*
@@ -133,9 +132,9 @@ class ResourceParser {
bool ParseArrayImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, uint32_t typeMask);
bool ParsePlural(xml::XmlPullParser* parser, ParsedResource* out_resource);
IDiagnostics* diag_;
android::IDiagnostics* diag_;
ResourceTable* table_;
Source source_;
android::Source source_;
android::ConfigDescription config_;
ResourceParserOptions options_;
};

View File

@@ -50,7 +50,7 @@ constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
ResourceTable table;
ResourceParser parser(context->GetDiagnostics(), &table, Source{"test"}, {});
ResourceParser parser(context->GetDiagnostics(), &table, android::Source{"test"}, {});
std::string input = kXmlPreamble;
input += R"(<attr name="foo"/>)";
@@ -71,7 +71,7 @@ class ResourceParserTest : public ::testing::Test {
::testing::AssertionResult TestParse(const StringPiece& str, const ConfigDescription& config) {
ResourceParserOptions parserOptions;
ResourceParser parser(context_->GetDiagnostics(), &table_, Source{"test"}, config,
ResourceParser parser(context_->GetDiagnostics(), &table_, android::Source{"test"}, config,
parserOptions);
std::string input = kXmlPreamble;
@@ -711,7 +711,7 @@ TEST_F(ResourceParserTest, ParseDeclareStyleablePreservingVisibility) {
</declare-styleable>
<public type="styleable" name="bar" />
</resources>)");
ResourceParser parser(context_->GetDiagnostics(), &table_, Source{"test"},
ResourceParser parser(context_->GetDiagnostics(), &table_, android::Source{"test"},
ConfigDescription::DefaultConfig(),
ResourceParserOptions{.preserve_visibility_of_styleables = true});

View File

@@ -464,20 +464,21 @@ ResourceTableView ResourceTable::GetPartitionedView(const ResourceTableViewOptio
return view;
}
bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag) {
CHECK(diag != nullptr) << "Diagnostic pointer is null";
const bool validate = validation_ == Validation::kEnabled;
const Source source = res.value ? res.value->GetSource() : Source{};
const android::Source source = res.value ? res.value->GetSource() : android::Source{};
if (validate && !res.allow_mangled && !IsValidResourceEntryName(res.name.entry)) {
diag->Error(DiagMessage(source)
diag->Error(android::DiagMessage(source)
<< "resource '" << res.name << "' has invalid entry name '" << res.name.entry);
return false;
}
if (res.id.has_value() && !res.id->first.is_valid()) {
diag->Error(DiagMessage(source) << "trying to add resource '" << res.name << "' with ID "
<< res.id->first << " but that ID is invalid");
diag->Error(android::DiagMessage(source)
<< "trying to add resource '" << res.name << "' with ID " << res.id->first
<< " but that ID is invalid");
return false;
}
@@ -513,7 +514,7 @@ bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
if (res.id.has_value()) {
if (entry->id && entry->id.value() != res.id->first) {
if (res.id->second != OnIdConflict::CREATE_ENTRY) {
diag->Error(DiagMessage(source)
diag->Error(android::DiagMessage(source)
<< "trying to add resource '" << res.name << "' with ID " << res.id->first
<< " but resource already has ID " << entry->id.value());
return false;
@@ -541,9 +542,9 @@ bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
if (res.overlayable.has_value()) {
if (entry->overlayable_item) {
diag->Error(DiagMessage(res.overlayable->source)
diag->Error(android::DiagMessage(res.overlayable->source)
<< "duplicate overlayable declaration for resource '" << res.name << "'");
diag->Error(DiagMessage(entry->overlayable_item.value().source)
diag->Error(android::DiagMessage(entry->overlayable_item.value().source)
<< "previous declaration here");
return false;
}
@@ -581,9 +582,10 @@ bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
break;
case CollisionResult::kConflict:
diag->Error(DiagMessage(source) << "duplicate value for resource '" << res.name << "' "
<< "with config '" << res.config << "'");
diag->Error(DiagMessage(source) << "resource previously defined here");
diag->Error(android::DiagMessage(source)
<< "duplicate value for resource '" << res.name << "' "
<< "with config '" << res.config << "'");
diag->Error(android::DiagMessage(source) << "resource previously defined here");
return false;
case CollisionResult::kKeepOriginal:

View File

@@ -17,17 +17,6 @@
#ifndef AAPT_RESOURCE_TABLE_H
#define AAPT_RESOURCE_TABLE_H
#include "Diagnostics.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "Source.h"
#include "StringPool.h"
#include "io/File.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"
#include <functional>
#include <map>
#include <memory>
@@ -36,6 +25,16 @@
#include <unordered_map>
#include <vector>
#include "Resource.h"
#include "ResourceValues.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/Source.h"
#include "androidfw/StringPiece.h"
#include "androidfw/StringPool.h"
#include "io/File.h"
using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
namespace aapt {
@@ -49,7 +48,7 @@ struct Visibility {
};
Level level = Level::kUndefined;
Source source;
android::Source source;
std::string comment;
// Indicates that the resource id may change across builds and that the public R.java identifier
@@ -60,14 +59,14 @@ struct Visibility {
// Represents <add-resource> in an overlay.
struct AllowNew {
Source source;
android::Source source;
std::string comment;
};
// Represents the staged resource id of a finalized resource.
struct StagedId {
ResourceId id;
Source source;
android::Source source;
};
struct Overlayable {
@@ -75,13 +74,14 @@ struct Overlayable {
Overlayable(const android::StringPiece& name, const android::StringPiece& actor)
: name(name.to_string()), actor(actor.to_string()) {}
Overlayable(const android::StringPiece& name, const android::StringPiece& actor,
const Source& source)
: name(name.to_string()), actor(actor.to_string()), source(source ){}
const android::Source& source)
: name(name.to_string()), actor(actor.to_string()), source(source) {
}
static const char* kActorScheme;
std::string name;
std::string actor;
Source source;
android::Source source;
};
// Represents a declaration that a resource is overlayable at runtime.
@@ -91,7 +91,7 @@ struct OverlayableItem {
std::shared_ptr<Overlayable> overlayable;
PolicyFlags policies = PolicyFlags::NONE;
std::string comment;
Source source;
android::Source source;
};
class ResourceConfigValue {
@@ -300,7 +300,7 @@ class ResourceTable {
ResourceTable() = default;
explicit ResourceTable(Validation validation);
bool AddResource(NewResource&& res, IDiagnostics* diag);
bool AddResource(NewResource&& res, android::IDiagnostics* diag);
// Retrieves a sorted a view of the packages, types, and entries sorted in ascending resource id
// order.
@@ -333,7 +333,7 @@ class ResourceTable {
// When `string_pool` references are destroyed (as they will be when `packages` is destroyed),
// they decrement a refCount, which would cause invalid memory access if the pool was already
// destroyed.
StringPool string_pool;
android::StringPool string_pool;
// The list of packages in this table, sorted alphabetically by package name and increasing
// package ID (missing ID being the lowest).

View File

@@ -15,15 +15,16 @@
*/
#include "ResourceTable.h"
#include "Diagnostics.h"
#include "ResourceValues.h"
#include "test/Test.h"
#include "util/Util.h"
#include <algorithm>
#include <ostream>
#include <string>
#include "ResourceValues.h"
#include "androidfw/IDiagnostics.h"
#include "test/Test.h"
#include "util/Util.h"
using ::android::ConfigDescription;
using ::android::StringPiece;
using ::testing::Eq;
@@ -263,13 +264,13 @@ TEST(ResourceTableTest, SetAllowNew) {
TEST(ResourceTableTest, SetOverlayable) {
ResourceTable table;
auto overlayable = std::make_shared<Overlayable>("Name", "overlay://theme",
Source("res/values/overlayable.xml", 40));
auto overlayable = std::make_shared<Overlayable>(
"Name", "overlay://theme", android::Source("res/values/overlayable.xml", 40));
OverlayableItem overlayable_item(overlayable);
overlayable_item.policies |= PolicyFlags::PRODUCT_PARTITION;
overlayable_item.policies |= PolicyFlags::VENDOR_PARTITION;
overlayable_item.comment = "comment";
overlayable_item.source = Source("res/values/overlayable.xml", 42);
overlayable_item.source = android::Source("res/values/overlayable.xml", 42);
const ResourceName name = test::ParseNameOrDie("android:string/foo");
ASSERT_TRUE(table.AddResource(NewResourceBuilder(name).SetOverlayable(overlayable_item).Build(),

View File

@@ -44,7 +44,7 @@ static std::optional<ResourceNamedType> ToResourceNamedType(const char16_t* type
const char* type, size_t type_len) {
std::optional<ResourceNamedTypeRef> parsed_type;
if (type16) {
auto converted = util::Utf16ToUtf8(StringPiece16(type16, type_len));
auto converted = android::util::Utf16ToUtf8(StringPiece16(type16, type_len));
parsed_type = ParseResourceNamedType(converted);
} else if (type) {
parsed_type = ParseResourceNamedType(StringPiece(type, type_len));
@@ -64,8 +64,7 @@ std::optional<ResourceName> ToResourceName(const android::ResTable::resource_nam
return {};
}
name_out.package =
util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen));
name_out.package = android::util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen));
std::optional<ResourceNamedType> type =
ToResourceNamedType(name_in.type, name_in.name8, name_in.typeLen);
@@ -75,8 +74,7 @@ std::optional<ResourceName> ToResourceName(const android::ResTable::resource_nam
name_out.type = *type;
if (name_in.name) {
name_out.entry =
util::Utf16ToUtf8(StringPiece16(name_in.name, name_in.nameLen));
name_out.entry = android::util::Utf16ToUtf8(StringPiece16(name_in.name, name_in.nameLen));
} else if (name_in.name8) {
name_out.entry.assign(name_in.name8, name_in.nameLen);
} else {
@@ -101,8 +99,7 @@ std::optional<ResourceName> ToResourceName(const android::AssetManager2::Resourc
name_out.type = *type;
if (name_in.entry16) {
name_out.entry =
util::Utf16ToUtf8(StringPiece16(name_in.entry16, name_in.entry_len));
name_out.entry = android::util::Utf16ToUtf8(StringPiece16(name_in.entry16, name_in.entry_len));
} else if (name_in.entry) {
name_out.entry = std::string(name_in.entry, name_in.entry_len);
} else {
@@ -498,7 +495,7 @@ std::optional<bool> ParseBool(const StringPiece& str) {
}
std::optional<uint32_t> ParseInt(const StringPiece& str) {
std::u16string str16 = util::Utf8ToUtf16(str);
std::u16string str16 = android::util::Utf8ToUtf16(str);
android::Res_value value;
if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
return value.data;
@@ -509,7 +506,7 @@ std::optional<uint32_t> ParseInt(const StringPiece& str) {
std::optional<ResourceId> ParseResourceId(const StringPiece& str) {
StringPiece trimmed_str(util::TrimWhitespace(str));
std::u16string str16 = util::Utf8ToUtf16(trimmed_str);
std::u16string str16 = android::util::Utf8ToUtf16(trimmed_str);
android::Res_value value;
if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
if (value.dataType == android::Res_value::TYPE_INT_HEX) {
@@ -525,7 +522,7 @@ std::optional<ResourceId> ParseResourceId(const StringPiece& str) {
std::optional<int> ParseSdkVersion(const StringPiece& str) {
StringPiece trimmed_str(util::TrimWhitespace(str));
std::u16string str16 = util::Utf8ToUtf16(trimmed_str);
std::u16string str16 = android::util::Utf8ToUtf16(trimmed_str);
android::Res_value value;
if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
return static_cast<int>(value.data);
@@ -562,7 +559,7 @@ std::unique_ptr<BinaryPrimitive> MakeBool(bool val) {
}
std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) {
std::u16string str16 = util::Utf8ToUtf16(util::TrimWhitespace(str));
std::u16string str16 = android::util::Utf8ToUtf16(util::TrimWhitespace(str));
android::Res_value value;
if (!android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
return {};
@@ -575,7 +572,7 @@ std::unique_ptr<BinaryPrimitive> MakeInt(uint32_t val) {
}
std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str) {
std::u16string str16 = util::Utf8ToUtf16(util::TrimWhitespace(str));
std::u16string str16 = android::util::Utf8ToUtf16(util::TrimWhitespace(str));
android::Res_value value;
if (!android::ResTable::stringToFloat(str16.data(), str16.size(), &value)) {
return {};
@@ -737,7 +734,7 @@ std::string BuildResourceFileName(const ResourceFile& res_file, const NameMangle
std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const ConfigDescription& config,
const android::ResStringPool& src_pool,
const android::Res_value& res_value,
StringPool* dst_pool) {
android::StringPool* dst_pool) {
if (type == ResourceType::kId) {
if (res_value.dataType != android::Res_value::TYPE_REFERENCE &&
res_value.dataType != android::Res_value::TYPE_DYNAMIC_REFERENCE) {
@@ -748,30 +745,32 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const Config
// fall through to regular reference deserialization logic
}
const uint32_t data = util::DeviceToHost32(res_value.data);
const uint32_t data = android::util::DeviceToHost32(res_value.data);
switch (res_value.dataType) {
case android::Res_value::TYPE_STRING: {
const std::string str = util::GetString(src_pool, data);
const std::string str = android::util::GetString(src_pool, data);
auto spans_result = src_pool.styleAt(data);
// Check if the string has a valid style associated with it.
if (spans_result.has_value() &&
(*spans_result)->name.index != android::ResStringPool_span::END) {
const android::ResStringPool_span* spans = spans_result->unsafe_ptr();
StyleString style_str = {str};
android::StyleString style_str = {str};
while (spans->name.index != android::ResStringPool_span::END) {
style_str.spans.push_back(Span{util::GetString(src_pool, spans->name.index),
spans->firstChar, spans->lastChar});
style_str.spans.push_back(
android::Span{android::util::GetString(src_pool, spans->name.index), spans->firstChar,
spans->lastChar});
spans++;
}
return util::make_unique<StyledString>(dst_pool->MakeRef(
style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
style_str,
android::StringPool::Context(android::StringPool::Context::kNormalPriority, config)));
} else {
if (type != ResourceType::kString && util::StartsWith(str, "res/")) {
// This must be a FileReference.
std::unique_ptr<FileReference> file_ref =
util::make_unique<FileReference>(dst_pool->MakeRef(
str, StringPool::Context(StringPool::Context::kHighPriority, config)));
std::unique_ptr<FileReference> file_ref = util::make_unique<FileReference>(
dst_pool->MakeRef(str, android::StringPool::Context(
android::StringPool::Context::kHighPriority, config)));
if (type == ResourceType::kRaw) {
file_ref->type = ResourceFile::Type::kUnknown;
} else if (util::EndsWith(*file_ref->path, ".xml")) {
@@ -783,7 +782,8 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const Config
}
// There are no styles associated with this string, so treat it as a simple string.
return util::make_unique<String>(dst_pool->MakeRef(str, StringPool::Context(config)));
return util::make_unique<String>(
dst_pool->MakeRef(str, android::StringPool::Context(config)));
}
} break;
@@ -950,7 +950,7 @@ StringBuilder::SpanHandle StringBuilder::StartSpan(const std::string& name) {
// When we start a span, all state associated with whitespace truncation and quotation is ended.
ResetTextState();
Span span;
android::Span span;
span.name = name;
span.first_char = span.last_char = utf16_len_;
xml_string_.spans.push_back(std::move(span));

View File

@@ -20,15 +20,14 @@
#include <functional>
#include <memory>
#include "NameMangler.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "androidfw/AssetManager2.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "NameMangler.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "StringPool.h"
#include "androidfw/StringPool.h"
namespace aapt {
namespace ResourceUtils {
@@ -230,14 +229,14 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type,
const android::ConfigDescription& config,
const android::ResStringPool& src_pool,
const android::Res_value& res_value,
StringPool* dst_pool);
android::StringPool* dst_pool);
// A string flattened from an XML hierarchy, which maintains tags and untranslatable sections
// in parallel data structures.
struct FlattenedXmlString {
std::string text;
std::vector<UntranslatableSection> untranslatable_sections;
std::vector<Span> spans;
std::vector<android::Span> spans;
};
// Flattens an XML hierarchy into a FlattenedXmlString, formatting the text, escaping characters,

View File

@@ -111,7 +111,7 @@ TEST(ResourceUtilsTest, ParsePrivateReference) {
TEST(ResourceUtilsTest, ParseBinaryDynamicReference) {
android::Res_value value = {};
value.data = util::HostToDevice32(0x01);
value.data = android::util::HostToDevice32(0x01);
value.dataType = android::Res_value::TYPE_DYNAMIC_REFERENCE;
std::unique_ptr<Item> item = ResourceUtils::ParseBinaryResValue(ResourceType::kId,
android::ConfigDescription(),

View File

@@ -75,7 +75,8 @@ void BaseItem<Derived>::Accept(ConstValueVisitor* visitor) const {
visitor->Visit(static_cast<const Derived*>(this));
}
RawString::RawString(const StringPool::Ref& ref) : value(ref) {}
RawString::RawString(const android::StringPool::Ref& ref) : value(ref) {
}
bool RawString::Equals(const Value* value) const {
const RawString* other = ValueCast<RawString>(value);
@@ -87,7 +88,7 @@ bool RawString::Equals(const Value* value) const {
bool RawString::Flatten(android::Res_value* out_value) const {
out_value->dataType = android::Res_value::TYPE_STRING;
out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
return true;
}
@@ -136,7 +137,7 @@ bool Reference::Flatten(android::Res_value* out_value) const {
out_value->dataType = android::Res_value::TYPE_ATTRIBUTE;
}
}
out_value->data = util::HostToDevice32(resid.id);
out_value->data = android::util::HostToDevice32(resid.id);
return true;
}
@@ -216,7 +217,7 @@ bool Id::Equals(const Value* value) const {
bool Id::Flatten(android::Res_value* out) const {
out->dataType = android::Res_value::TYPE_INT_BOOLEAN;
out->data = util::HostToDevice32(0);
out->data = android::util::HostToDevice32(0);
return true;
}
@@ -224,7 +225,7 @@ void Id::Print(std::ostream* out) const {
*out << "(id)";
}
String::String(const StringPool::Ref& ref) : value(ref) {
String::String(const android::StringPool::Ref& ref) : value(ref) {
}
bool String::Equals(const Value* value) const {
@@ -258,7 +259,7 @@ bool String::Flatten(android::Res_value* out_value) const {
}
out_value->dataType = android::Res_value::TYPE_STRING;
out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
return true;
}
@@ -272,7 +273,7 @@ void String::PrettyPrint(Printer* printer) const {
printer->Print("\"");
}
StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {
StyledString::StyledString(const android::StringPool::StyleRef& ref) : value(ref) {
}
bool StyledString::Equals(const Value* value) const {
@@ -305,18 +306,18 @@ bool StyledString::Flatten(android::Res_value* out_value) const {
}
out_value->dataType = android::Res_value::TYPE_STRING;
out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index()));
out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(value.index()));
return true;
}
void StyledString::Print(std::ostream* out) const {
*out << "(styled string) \"" << value->value << "\"";
for (const StringPool::Span& span : value->spans) {
for (const android::StringPool::Span& span : value->spans) {
*out << " " << *span.name << ":" << span.first_char << "," << span.last_char;
}
}
FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {
FileReference::FileReference(const android::StringPool::Ref& _path) : path(_path) {
}
bool FileReference::Equals(const Value* value) const {
@@ -333,7 +334,7 @@ bool FileReference::Flatten(android::Res_value* out_value) const {
}
out_value->dataType = android::Res_value::TYPE_STRING;
out_value->data = util::HostToDevice32(static_cast<uint32_t>(path.index()));
out_value->data = android::util::HostToDevice32(static_cast<uint32_t>(path.index()));
return true;
}
@@ -373,7 +374,7 @@ bool BinaryPrimitive::Equals(const Value* value) const {
bool BinaryPrimitive::Flatten(::android::Res_value* out_value) const {
out_value->dataType = value.dataType;
out_value->data = util::HostToDevice32(value.data);
out_value->data = android::util::HostToDevice32(value.data);
return true;
}
@@ -678,7 +679,7 @@ void Attribute::Print(std::ostream* out) const {
}
static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& value,
DiagMessage* out_msg) {
android::DiagMessage* out_msg) {
*out_msg << "expected";
if (attr.type_mask & android::ResTable_map::TYPE_BOOLEAN) {
*out_msg << " boolean";
@@ -723,7 +724,7 @@ static void BuildAttributeMismatchMessage(const Attribute& attr, const Item& val
*out_msg << " but got " << value;
}
bool Attribute::Matches(const Item& item, DiagMessage* out_msg) const {
bool Attribute::Matches(const Item& item, android::DiagMessage* out_msg) const {
constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
@@ -732,7 +733,7 @@ bool Attribute::Matches(const Item& item, DiagMessage* out_msg) const {
android::Res_value val = {};
item.Flatten(&val);
const uint32_t flattened_data = util::DeviceToHost32(val.data);
const uint32_t flattened_data = android::util::DeviceToHost32(val.data);
// Always allow references.
const uint32_t actual_type = ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType);
@@ -872,7 +873,7 @@ void Style::Print(std::ostream* out) const {
*out << " [" << util::Joiner(entries, ", ") << "]";
}
Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
Style::Entry CloneEntry(const Style::Entry& entry, android::StringPool* pool) {
Style::Entry cloned_entry{entry.key};
if (entry.value != nullptr) {
CloningValueTransformer cloner(pool);
@@ -881,7 +882,7 @@ Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
return cloned_entry;
}
void Style::MergeWith(Style* other, StringPool* pool) {
void Style::MergeWith(Style* other, android::StringPool* pool) {
if (other->parent) {
parent = other->parent;
}
@@ -1077,7 +1078,7 @@ std::unique_ptr<T> CopyValueFields(std::unique_ptr<T> new_value, const T* value)
return new_value;
}
CloningValueTransformer::CloningValueTransformer(StringPool* new_pool)
CloningValueTransformer::CloningValueTransformer(android::StringPool* new_pool)
: ValueTransformer(new_pool) {
}

View File

@@ -22,13 +22,12 @@
#include <ostream>
#include <vector>
#include "Resource.h"
#include "ValueTransformer.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
#include "Resource.h"
#include "StringPool.h"
#include "ValueTransformer.h"
#include "androidfw/StringPool.h"
#include "io/File.h"
#include "text/Printer.h"
@@ -67,15 +66,15 @@ class Value {
}
// Returns the source where this value was defined.
const Source& GetSource() const {
const android::Source& GetSource() const {
return source_;
}
void SetSource(const Source& source) {
void SetSource(const android::Source& source) {
source_ = source;
}
void SetSource(Source&& source) {
void SetSource(android::Source&& source) {
source_ = std::move(source);
}
@@ -113,7 +112,7 @@ class Value {
friend std::ostream& operator<<(std::ostream& out, const Value& value);
protected:
Source source_;
android::Source source_;
std::string comment_;
bool weak_ = false;
bool translatable_ = true;
@@ -197,9 +196,9 @@ struct Id : public TransformableItem<Id, BaseItem<Id>> {
// A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace.
// This shall *NOT* end up in the final resource table.
struct RawString : public TransformableItem<RawString, BaseItem<RawString>> {
StringPool::Ref value;
android::StringPool::Ref value;
explicit RawString(const StringPool::Ref& ref);
explicit RawString(const android::StringPool::Ref& ref);
bool Equals(const Value* value) const override;
bool Flatten(android::Res_value* out_value) const override;
@@ -225,14 +224,14 @@ inline bool operator!=(const UntranslatableSection& a, const UntranslatableSecti
}
struct String : public TransformableItem<String, BaseItem<String>> {
StringPool::Ref value;
android::StringPool::Ref value;
// Sections of the string to NOT translate. Mainly used
// for pseudolocalization. This data is NOT persisted
// in any format.
std::vector<UntranslatableSection> untranslatable_sections;
explicit String(const StringPool::Ref& ref);
explicit String(const android::StringPool::Ref& ref);
bool Equals(const Value* value) const override;
bool Flatten(android::Res_value* out_value) const override;
@@ -241,14 +240,14 @@ struct String : public TransformableItem<String, BaseItem<String>> {
};
struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> {
StringPool::StyleRef value;
android::StringPool::StyleRef value;
// Sections of the string to NOT translate. Mainly used
// for pseudolocalization. This data is NOT persisted
// in any format.
std::vector<UntranslatableSection> untranslatable_sections;
explicit StyledString(const StringPool::StyleRef& ref);
explicit StyledString(const android::StringPool::StyleRef& ref);
bool Equals(const Value* value) const override;
bool Flatten(android::Res_value* out_value) const override;
@@ -256,7 +255,7 @@ struct StyledString : public TransformableItem<StyledString, BaseItem<StyledStri
};
struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> {
StringPool::Ref path;
android::StringPool::Ref path;
// A handle to the file object from which this file can be read.
// This field is NOT persisted in any format. It is transient.
@@ -267,7 +266,7 @@ struct FileReference : public TransformableItem<FileReference, BaseItem<FileRefe
ResourceFile::Type type = ResourceFile::Type::kUnknown;
FileReference() = default;
explicit FileReference(const StringPool::Ref& path);
explicit FileReference(const android::StringPool::Ref& path);
bool Equals(const Value* value) const override;
bool Flatten(android::Res_value* out_value) const override;
@@ -315,7 +314,7 @@ struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> {
static std::string MaskString(uint32_t type_mask);
void Print(std::ostream* out) const override;
bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const;
bool Matches(const Item& item, android::DiagMessage* out_msg = nullptr) const;
};
struct Style : public TransformableValue<Style, BaseValue<Style>> {
@@ -338,7 +337,7 @@ struct Style : public TransformableValue<Style, BaseValue<Style>> {
// Merges `style` into this Style. All identical attributes of `style` take precedence, including
// the parent, if there is one.
void MergeWith(Style* style, StringPool* pool);
void MergeWith(Style* style, android::StringPool* pool);
};
struct Array : public TransformableValue<Array, BaseValue<Array>> {
@@ -367,7 +366,7 @@ struct Styleable : public TransformableValue<Styleable, BaseValue<Styleable>> {
struct Macro : public TransformableValue<Macro, BaseValue<Macro>> {
std::string raw_value;
StyleString style_string;
android::StyleString style_string;
std::vector<UntranslatableSection> untranslatable_sections;
struct Namespace {
@@ -399,7 +398,7 @@ typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type o
}
struct CloningValueTransformer : public ValueTransformer {
explicit CloningValueTransformer(StringPool* new_pool);
explicit CloningValueTransformer(android::StringPool* new_pool);
std::unique_ptr<Reference> TransformDerived(const Reference* value) override;
std::unique_ptr<Id> TransformDerived(const Id* value) override;

View File

@@ -37,7 +37,7 @@ constexpr const uint32_t TYPE_STRING = android::ResTable_map::TYPE_STRING;
} // namespace
TEST(ResourceValuesTest, PluralEquals) {
StringPool pool;
android::StringPool pool;
Plural a;
a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
@@ -56,7 +56,7 @@ TEST(ResourceValuesTest, PluralEquals) {
}
TEST(ResourceValuesTest, PluralClone) {
StringPool pool;
android::StringPool pool;
Plural a;
a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
@@ -68,7 +68,7 @@ TEST(ResourceValuesTest, PluralClone) {
}
TEST(ResourceValuesTest, ArrayEquals) {
StringPool pool;
android::StringPool pool;
Array a;
a.elements.push_back(util::make_unique<String>(pool.MakeRef("one")));
@@ -92,7 +92,7 @@ TEST(ResourceValuesTest, ArrayEquals) {
}
TEST(ResourceValuesTest, ArrayClone) {
StringPool pool;
android::StringPool pool;
Array a;
a.elements.push_back(util::make_unique<String>(pool.MakeRef("one")));
@@ -104,7 +104,7 @@ TEST(ResourceValuesTest, ArrayClone) {
}
TEST(ResourceValuesTest, StyleEquals) {
StringPool pool;
android::StringPool pool;
std::unique_ptr<Style> a = test::StyleBuilder()
.SetParent("android:style/Parent")
@@ -168,10 +168,10 @@ TEST(ResourceValuesTest, StyleClone) {
}
TEST(ResourcesValuesTest, StringClones) {
StringPool pool_a;
StringPool pool_b;
android::StringPool pool_a;
android::StringPool pool_b;
String str_a(pool_a.MakeRef("hello", StringPool::Context(test::ParseConfigOrDie("en"))));
String str_a(pool_a.MakeRef("hello", android::StringPool::Context(test::ParseConfigOrDie("en"))));
ASSERT_THAT(pool_a, SizeIs(1u));
EXPECT_THAT(pool_a.strings()[0]->context.config, Eq(test::ParseConfigOrDie("en")));
@@ -185,8 +185,8 @@ TEST(ResourcesValuesTest, StringClones) {
}
TEST(ResourceValuesTest, StyleMerges) {
StringPool pool_a;
StringPool pool_b;
android::StringPool pool_a;
android::StringPool pool_b;
std::unique_ptr<Style> a =
test::StyleBuilder()
@@ -204,7 +204,7 @@ TEST(ResourceValuesTest, StyleMerges) {
a->MergeWith(b.get(), &pool_a);
StringPool pool;
android::StringPool pool;
std::unique_ptr<Style> expected =
test::StyleBuilder()
.SetParent("android:style/OverlayParent")

View File

@@ -636,4 +636,4 @@ message StyleString {
message UntranslatableSection {
uint64 start_index = 1;
uint64 end_index = 2;
}
}

View File

@@ -19,7 +19,7 @@
#include <memory>
#include "StringPool.h"
#include "androidfw/StringPool.h"
namespace aapt {
@@ -82,7 +82,7 @@ struct Macro;
struct ValueTransformer {
// `new_pool` is the new StringPool that newly created Values should use for string storing string
// values.
explicit ValueTransformer(StringPool* new_pool);
explicit ValueTransformer(android::StringPool* new_pool);
virtual ~ValueTransformer() = default;
AAPT_TRANSFORM_ITEM(Id);
@@ -101,7 +101,7 @@ struct ValueTransformer {
AAPT_TRANSFORM_VALUE(Macro);
protected:
StringPool* const pool_;
android::StringPool* const pool_;
};
#undef AAPT_TRANSFORM_VALUE
@@ -127,4 +127,4 @@ struct TransformableItem : public TransformableValue<Derived, Base> {
// Implementation
#include "ValueTransformer_inline.h"
#endif // AAPT_VALUE_TRANSFORMER_H
#endif // AAPT_VALUE_TRANSFORMER_H

View File

@@ -19,7 +19,7 @@
namespace aapt {
inline ValueTransformer::ValueTransformer(StringPool* new_pool) : pool_(new_pool) {
inline ValueTransformer::ValueTransformer(android::StringPool* new_pool) : pool_(new_pool) {
}
template <typename Derived, typename Base>
@@ -44,4 +44,4 @@ Item* TransformableItem<Derived, Base>::TransformItemImpl(ValueTransformer& tran
} // namespace aapt
#endif // AAPT_VALUE_TRANSFORMER_IMPL_H
#endif // AAPT_VALUE_TRANSFORMER_IMPL_H

View File

@@ -21,10 +21,10 @@
#include <iostream>
#include <memory>
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "android-base/file.h" // for O_BINARY
#include "android-base/utf8.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "dump/DumpManifest.h"
#include "format/proto/ProtoSerialize.h"
@@ -35,7 +35,7 @@ namespace aapt {
int ExportApkInfo(LoadedApk* apk, bool include_resource_table,
const std::unordered_set<std::string>& xml_resources, pb::ApkInfo* out_apk_info,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
auto result = DumpBadgingProto(apk, out_apk_info->mutable_badging(), diag);
if (result != 0) {
return result;
@@ -74,14 +74,14 @@ int ApkInfoCommand::Action(const std::vector<std::string>& args) {
int result =
ExportApkInfo(apk.get(), include_resource_table_, xml_resources_, &out_apk_info, diag_);
if (result != 0) {
diag_->Error(DiagMessage() << "Failed to serialize ApkInfo into proto.");
diag_->Error(android::DiagMessage() << "Failed to serialize ApkInfo into proto.");
return result;
}
int mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
int outfd = ::android::base::utf8::open(output_path_.c_str(), mode, 0666);
if (outfd == -1) {
diag_->Error(DiagMessage() << "Failed to open output file.");
diag_->Error(android::DiagMessage() << "Failed to open output file.");
return 1;
}

View File

@@ -18,13 +18,13 @@
#define AAPT2_APKINFO_H
#include "Command.h"
#include "Diagnostics.h"
#include "androidfw/IDiagnostics.h"
namespace aapt {
class ApkInfoCommand : public Command {
public:
explicit ApkInfoCommand(IDiagnostics* diag) : Command("apkinfo"), diag_(diag) {
explicit ApkInfoCommand(android::IDiagnostics* diag) : Command("apkinfo"), diag_(diag) {
SetDescription("Dump information about an APK in binary proto format.");
AddRequiredFlag("-o", "Output path", &output_path_, Command::kPath);
AddOptionalSwitch("--include-resource-table", "Include the resource table data into output.",
@@ -38,7 +38,7 @@ class ApkInfoCommand : public Command {
int Action(const std::vector<std::string>& args) override;
private:
IDiagnostics* diag_;
android::IDiagnostics* diag_;
std::string output_path_;
bool include_resource_table_ = false;
std::unordered_set<std::string> xml_resources_;

View File

@@ -43,12 +43,7 @@ void AssertProducedAndExpectedInfo(const std::string& produced_path,
EXPECT_EQ(produced_apk_info.DebugString(), expected);
}
class NoopDiagnostics : public IDiagnostics {
public:
void Log(Level level, DiagMessageActual& actualMsg) override {
}
};
static NoopDiagnostics noop_diag;
static android::NoOpDiagnostics noop_diag;
TEST_F(ApkInfoTest, ApkInfoWithBadging) {
auto apk_path = file::BuildPath(
@@ -80,4 +75,4 @@ TEST_F(ApkInfoTest, FullApkInfo) {
AssertProducedAndExpectedInfo(out_info_path, expected_path);
}
} // namespace aapt
} // namespace aapt

View File

@@ -17,19 +17,17 @@
#include "Compile.h"
#include <dirent.h>
#include <string>
#include "ResourceParser.h"
#include "ResourceTable.h"
#include "android-base/errors.h"
#include "android-base/file.h"
#include "android-base/utf8.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "Diagnostics.h"
#include "ResourceParser.h"
#include "ResourceTable.h"
#include "cmd/Util.h"
#include "compile/IdAssigner.h"
#include "compile/InlineXmlFormatParser.h"
@@ -39,6 +37,8 @@
#include "format/Archive.h"
#include "format/Container.h"
#include "format/proto/ProtoSerialize.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "io/BigBufferStream.h"
#include "io/FileStream.h"
#include "io/FileSystem.h"
@@ -61,7 +61,7 @@ using ::google::protobuf::io::CopyingOutputStreamAdaptor;
namespace aapt {
struct ResourcePathData {
Source source;
android::Source source;
std::string resource_dir;
std::string name;
std::string extension;
@@ -122,9 +122,8 @@ static std::optional<ResourcePathData> ExtractResourcePathData(const std::string
}
}
const Source res_path = options.source_path
? StringPiece(options.source_path.value())
: StringPiece(path);
const android::Source res_path =
options.source_path ? StringPiece(options.source_path.value()) : StringPiece(path);
return ResourcePathData{res_path, dir_str.to_string(), name.to_string(),
extension.to_string(), config_str.to_string(), config};
@@ -154,8 +153,8 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
{
auto fin = file->OpenInputStream();
if (fin->HadError()) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source)
<< "failed to open file: " << fin->GetError());
context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
<< "failed to open file: " << fin->GetError());
return false;
}
@@ -191,7 +190,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
// Create the file/zip entry.
if (!writer->StartEntry(output_path, 0)) {
context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open");
context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to open");
return false;
}
@@ -204,13 +203,13 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
pb::ResourceTable pb_table;
SerializeTableToPb(table, &pb_table, context->GetDiagnostics());
if (!container_writer.AddResTableEntry(pb_table)) {
context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to write");
context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to write");
return false;
}
}
if (!writer->FinishEntry()) {
context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to finish entry");
context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to finish entry");
return false;
}
@@ -218,7 +217,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
io::FileOutputStream fout_text(options.generate_text_symbols_path.value());
if (fout_text.HadError()) {
context->GetDiagnostics()->Error(DiagMessage()
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed writing to'"
<< options.generate_text_symbols_path.value()
<< "': " << fout_text.GetError());
@@ -282,11 +281,11 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
static bool WriteHeaderAndDataToWriter(const StringPiece& output_path, const ResourceFile& file,
io::KnownSizeInputStream* in, IArchiveWriter* writer,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
TRACE_CALL();
// Start the entry so we can write the header.
if (!writer->StartEntry(output_path, 0)) {
diag->Error(DiagMessage(output_path) << "failed to open file");
diag->Error(android::DiagMessage(output_path) << "failed to open file");
return false;
}
@@ -300,20 +299,20 @@ static bool WriteHeaderAndDataToWriter(const StringPiece& output_path, const Res
SerializeCompiledFileToPb(file, &pb_compiled_file);
if (!container_writer.AddResFileEntry(pb_compiled_file, in)) {
diag->Error(DiagMessage(output_path) << "failed to write entry data");
diag->Error(android::DiagMessage(output_path) << "failed to write entry data");
return false;
}
}
if (!writer->FinishEntry()) {
diag->Error(DiagMessage(output_path) << "failed to finish writing data");
diag->Error(android::DiagMessage(output_path) << "failed to finish writing data");
return false;
}
return true;
}
static bool FlattenXmlToOutStream(const StringPiece& output_path, const xml::XmlResource& xmlres,
ContainerWriter* container_writer, IDiagnostics* diag) {
ContainerWriter* container_writer, android::IDiagnostics* diag) {
pb::internal::CompiledFile pb_compiled_file;
SerializeCompiledFileToPb(xmlres.file, &pb_compiled_file);
@@ -324,7 +323,7 @@ static bool FlattenXmlToOutStream(const StringPiece& output_path, const xml::Xml
io::StringInputStream serialized_in(serialized_xml);
if (!container_writer->AddResFileEntry(pb_compiled_file, &serialized_in)) {
diag->Error(DiagMessage(output_path) << "failed to write entry data");
diag->Error(android::DiagMessage(output_path) << "failed to write entry data");
return false;
}
return true;
@@ -334,12 +333,12 @@ static bool IsValidFile(IAaptContext* context, const std::string& input_path) {
const file::FileType file_type = file::GetFileType(input_path);
if (file_type != file::FileType::kRegular && file_type != file::FileType::kSymlink) {
if (file_type == file::FileType::kDirectory) {
context->GetDiagnostics()->Error(DiagMessage(input_path)
context->GetDiagnostics()->Error(android::DiagMessage(input_path)
<< "resource file cannot be a directory");
} else if (file_type == file::FileType::kNonExistant) {
context->GetDiagnostics()->Error(DiagMessage(input_path) << "file not found");
context->GetDiagnostics()->Error(android::DiagMessage(input_path) << "file not found");
} else {
context->GetDiagnostics()->Error(DiagMessage(input_path)
context->GetDiagnostics()->Error(android::DiagMessage(input_path)
<< "not a valid resource file");
}
return false;
@@ -352,14 +351,14 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
const std::string& output_path) {
TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML");
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling XML");
}
std::unique_ptr<xml::XmlResource> xmlres;
{
auto fin = file->OpenInputStream();
if (fin->HadError()) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source)
context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
<< "failed to open file: " << fin->GetError());
return false;
}
@@ -389,7 +388,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
// Start the entry so we can write the header.
if (!writer->StartEntry(output_path, 0)) {
context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open file");
context->GetDiagnostics()->Error(android::DiagMessage(output_path) << "failed to open file");
return false;
}
@@ -416,7 +415,8 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
}
if (!writer->FinishEntry()) {
context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to finish writing data");
context->GetDiagnostics()->Error(android::DiagMessage(output_path)
<< "failed to finish writing data");
return false;
}
@@ -424,7 +424,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
io::FileOutputStream fout_text(options.generate_text_symbols_path.value());
if (fout_text.HadError()) {
context->GetDiagnostics()->Error(DiagMessage()
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed writing to'"
<< options.generate_text_symbols_path.value()
<< "': " << fout_text.GetError());
@@ -452,10 +452,10 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
const std::string& output_path) {
TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling PNG");
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling PNG");
}
BigBuffer buffer(4096);
android::BigBuffer buffer(4096);
ResourceFile res_file;
res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), path_data.name);
res_file.config = path_data.config;
@@ -465,11 +465,12 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
{
auto data = file->OpenAsData();
if (!data) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to open file ");
context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
<< "failed to open file ");
return false;
}
BigBuffer crunched_png_buffer(4096);
android::BigBuffer crunched_png_buffer(4096);
io::BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);
// Ensure that we only keep the chunks we care about if we end up
@@ -486,7 +487,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
std::string err;
nine_patch = NinePatch::Create(image->rows.get(), image->width, image->height, &err);
if (!nine_patch) {
context->GetDiagnostics()->Error(DiagMessage() << err);
context->GetDiagnostics()->Error(android::DiagMessage() << err);
return false;
}
@@ -503,8 +504,8 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
}
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "9-patch: "
<< *nine_patch);
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
<< "9-patch: " << *nine_patch);
}
}
@@ -522,13 +523,13 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
// The re-encoded PNG is larger than the original, and there is
// no mandatory transformation. Use the original.
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source)
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
<< "original PNG is smaller than crunched PNG"
<< ", using original");
}
png_chunk_filter.Rewind();
BigBuffer filtered_png_buffer(4096);
android::BigBuffer filtered_png_buffer(4096);
io::BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer);
io::Copy(&filtered_png_buffer_out, &png_chunk_filter);
buffer.AppendBuffer(std::move(filtered_png_buffer));
@@ -538,13 +539,13 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
// For debugging only, use the legacy PNG cruncher and compare the resulting file sizes.
// This will help catch exotic cases where the new code may generate larger PNGs.
std::stringstream legacy_stream(content.to_string());
BigBuffer legacy_buffer(4096);
android::BigBuffer legacy_buffer(4096);
Png png(context->GetDiagnostics());
if (!png.process(path_data.source, &legacy_stream, &legacy_buffer, {})) {
return false;
}
context->GetDiagnostics()->Note(DiagMessage(path_data.source)
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source)
<< "legacy=" << legacy_buffer.size()
<< " new=" << buffer.size());
}
@@ -560,7 +561,7 @@ static bool CompileFile(IAaptContext* context, const CompileOptions& options,
const std::string& output_path) {
TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling file");
context->GetDiagnostics()->Note(android::DiagMessage(path_data.source) << "compiling file");
}
ResourceFile res_file;
@@ -571,7 +572,8 @@ static bool CompileFile(IAaptContext* context, const CompileOptions& options,
auto data = file->OpenAsData();
if (!data) {
context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to open file ");
context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
<< "failed to open file ");
return false;
}
@@ -581,7 +583,7 @@ static bool CompileFile(IAaptContext* context, const CompileOptions& options,
class CompileContext : public IAaptContext {
public:
explicit CompileContext(IDiagnostics* diagnostics) : diagnostics_(diagnostics) {
explicit CompileContext(android::IDiagnostics* diagnostics) : diagnostics_(diagnostics) {
}
PackageType GetPackageType() override {
@@ -597,7 +599,7 @@ class CompileContext : public IAaptContext {
return verbose_;
}
IDiagnostics* GetDiagnostics() override {
android::IDiagnostics* GetDiagnostics() override {
return diagnostics_;
}
@@ -633,7 +635,7 @@ class CompileContext : public IAaptContext {
private:
DISALLOW_COPY_AND_ASSIGN(CompileContext);
IDiagnostics* diagnostics_;
android::IDiagnostics* diagnostics_;
bool verbose_ = false;
};
@@ -665,7 +667,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
path, inputs->GetDirSeparator(), &err_str, options)) {
path_data = maybe_path_data.value();
} else {
context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << err_str);
context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource()) << err_str);
error = true;
continue;
}
@@ -688,8 +690,8 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
}
}
} else {
context->GetDiagnostics()->Error(DiagMessage()
<< "invalid file path '" << path_data.source << "'");
context->GetDiagnostics()->Error(android::DiagMessage()
<< "invalid file path '" << path_data.source << "'");
error = true;
continue;
}
@@ -699,15 +701,16 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter*
if (compile_func != &CompileFile && !options.legacy_mode
&& std::count(path_data.name.begin(), path_data.name.end(), '.') != 0) {
error = true;
context->GetDiagnostics()->Error(DiagMessage(file->GetSource())
<< "file name cannot contain '.' other than for"
<< " specifying the extension");
context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
<< "file name cannot contain '.' other than for"
<< " specifying the extension");
continue;
}
const std::string out_path = BuildIntermediateContainerFilename(path_data);
if (!compile_func(context, options, path_data, file, output_writer, out_path)) {
context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "file failed to compile");
context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
<< "file failed to compile");
error = true;
}
}
@@ -728,9 +731,10 @@ int CompileCommand::Action(const std::vector<std::string>& args) {
} else if (visibility_.value() == "default") {
options_.visibility = Visibility::Level::kUndefined;
} else {
context.GetDiagnostics()->Error(
DiagMessage() << "Unrecognized visibility level passes to --visibility: '"
<< visibility_.value() << "'. Accepted levels: public, private, default");
context.GetDiagnostics()->Error(android::DiagMessage()
<< "Unrecognized visibility level passes to --visibility: '"
<< visibility_.value()
<< "'. Accepted levels: public, private, default");
return 1;
}
}
@@ -739,17 +743,17 @@ int CompileCommand::Action(const std::vector<std::string>& args) {
// Collect the resources files to compile
if (options_.res_dir && options_.res_zip) {
context.GetDiagnostics()->Error(DiagMessage()
<< "only one of --dir and --zip can be specified");
context.GetDiagnostics()->Error(android::DiagMessage()
<< "only one of --dir and --zip can be specified");
return 1;
} else if ((options_.res_dir || options_.res_zip) &&
options_.source_path && args.size() > 1) {
context.GetDiagnostics()->Error(DiagMessage(kPath)
<< "Cannot use an overriding source path with multiple files.");
return 1;
context.GetDiagnostics()->Error(android::DiagMessage(kPath)
<< "Cannot use an overriding source path with multiple files.");
return 1;
} else if (options_.res_dir) {
if (!args.empty()) {
context.GetDiagnostics()->Error(DiagMessage() << "files given but --dir specified");
context.GetDiagnostics()->Error(android::DiagMessage() << "files given but --dir specified");
Usage(&std::cerr);
return 1;
}
@@ -758,12 +762,12 @@ int CompileCommand::Action(const std::vector<std::string>& args) {
std::string err;
file_collection = io::FileCollection::Create(options_.res_dir.value(), &err);
if (!file_collection) {
context.GetDiagnostics()->Error(DiagMessage(options_.res_dir.value()) << err);
context.GetDiagnostics()->Error(android::DiagMessage(options_.res_dir.value()) << err);
return 1;
}
} else if (options_.res_zip) {
if (!args.empty()) {
context.GetDiagnostics()->Error(DiagMessage() << "files given but --zip specified");
context.GetDiagnostics()->Error(android::DiagMessage() << "files given but --zip specified");
Usage(&std::cerr);
return 1;
}
@@ -772,7 +776,7 @@ int CompileCommand::Action(const std::vector<std::string>& args) {
std::string err;
file_collection = io::ZipFileCollection::Create(options_.res_zip.value(), &err);
if (!file_collection) {
context.GetDiagnostics()->Error(DiagMessage(options_.res_zip.value()) << err);
context.GetDiagnostics()->Error(android::DiagMessage(options_.res_zip.value()) << err);
return 1;
}
} else {

View File

@@ -17,15 +17,15 @@
#ifndef AAPT2_COMPILE_H
#define AAPT2_COMPILE_H
#include <optional>
#include <androidfw/StringPiece.h>
#include <optional>
#include "Command.h"
#include "ResourceTable.h"
#include "androidfw/IDiagnostics.h"
#include "format/Archive.h"
#include "process/IResourceTableConsumer.h"
#include "Command.h"
#include "Diagnostics.h"
#include "ResourceTable.h"
namespace aapt {
@@ -47,8 +47,8 @@ struct CompileOptions {
/** Parses flags and compiles resources to be used in linking. */
class CompileCommand : public Command {
public:
explicit CompileCommand(IDiagnostics* diagnostic) : Command("compile", "c"),
diagnostic_(diagnostic) {
explicit CompileCommand(android::IDiagnostics* diagnostic)
: Command("compile", "c"), diagnostic_(diagnostic) {
SetDescription("Compiles resources to be linked into an apk.");
AddRequiredFlag("-o", "Output path", &options_.output_path, Command::kPath);
AddOptionalFlag("--dir", "Directory to scan for resources", &options_.res_dir, Command::kPath);
@@ -81,7 +81,7 @@ class CompileCommand : public Command {
int Action(const std::vector<std::string>& args) override;
private:
IDiagnostics* diagnostic_;
android::IDiagnostics* diagnostic_;
CompileOptions options_;
std::optional<std::string> visibility_;
std::optional<std::string> trace_folder_;

View File

@@ -219,7 +219,7 @@ static void AssertTranslations(CommandTestFixture *ctf, std::string file_name,
ASSERT_NE(table, nullptr);
table->string_pool.Sort();
const std::vector<std::unique_ptr<StringPool::Entry>>& pool_strings =
const std::vector<std::unique_ptr<android::StringPool::Entry>>& pool_strings =
table->string_pool.strings();
// The actual / expected vectors have the same size
@@ -316,7 +316,7 @@ TEST_F(CompilerTest, RelativePathTest) {
std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(apk_path, &diag);
ResourceTable* resource_table = apk.get()->GetResourceTable();
const std::vector<std::unique_ptr<StringPool::Entry>>& pool_strings =
const std::vector<std::unique_ptr<android::StringPool::Entry>>& pool_strings =
resource_table->string_pool.strings();
ASSERT_EQ(pool_strings.size(), 2);

View File

@@ -18,6 +18,7 @@
#include <vector>
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "ValueVisitor.h"
#include "android-base/macros.h"
@@ -42,8 +43,9 @@ namespace aapt {
class IApkSerializer {
public:
IApkSerializer(IAaptContext* context, const Source& source) : context_(context),
source_(source) {}
IApkSerializer(IAaptContext* context, const android::Source& source)
: context_(context), source_(source) {
}
virtual bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
IArchiveWriter* writer, uint32_t compression_flags) = 0;
@@ -54,21 +56,22 @@ class IApkSerializer {
protected:
IAaptContext* context_;
Source source_;
android::Source source_;
};
class BinaryApkSerializer : public IApkSerializer {
public:
BinaryApkSerializer(IAaptContext* context, const Source& source,
BinaryApkSerializer(IAaptContext* context, const android::Source& source,
const TableFlattenerOptions& table_flattener_options,
const XmlFlattenerOptions& xml_flattener_options)
: IApkSerializer(context, source),
table_flattener_options_(table_flattener_options),
xml_flattener_options_(xml_flattener_options) {}
xml_flattener_options_(xml_flattener_options) {
}
bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
IArchiveWriter* writer, uint32_t compression_flags) override {
BigBuffer buffer(4096);
android::BigBuffer buffer(4096);
xml_flattener_options_.use_utf16 = utf16;
XmlFlattener flattener(&buffer, xml_flattener_options_);
if (!flattener.Consume(context_, xml)) {
@@ -80,7 +83,7 @@ class BinaryApkSerializer : public IApkSerializer {
}
bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
BigBuffer buffer(4096);
android::BigBuffer buffer(4096);
TableFlattener table_flattener(table_flattener_options_, &buffer);
if (!table_flattener.Consume(context_, table)) {
return false;
@@ -95,7 +98,7 @@ class BinaryApkSerializer : public IApkSerializer {
if (file->type == ResourceFile::Type::kProtoXml) {
unique_ptr<io::InputStream> in = file->file->OpenInputStream();
if (in == nullptr) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to open file " << *file->path);
return false;
}
@@ -103,7 +106,7 @@ class BinaryApkSerializer : public IApkSerializer {
pb::XmlNode pb_node;
io::ProtoInputStreamReader proto_reader(in.get());
if (!proto_reader.ReadMessage(&pb_node)) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to parse proto XML " << *file->path);
return false;
}
@@ -111,15 +114,15 @@ class BinaryApkSerializer : public IApkSerializer {
std::string error;
unique_ptr<xml::XmlResource> xml = DeserializeXmlResourceFromPb(pb_node, &error);
if (xml == nullptr) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
<< "failed to deserialize proto XML "
<< *file->path << ": " << error);
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to deserialize proto XML " << *file->path
<< ": " << error);
return false;
}
if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer,
file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to serialize to binary XML: " << *file->path);
return false;
}
@@ -127,7 +130,7 @@ class BinaryApkSerializer : public IApkSerializer {
file->type = ResourceFile::Type::kBinaryXml;
} else {
if (!io::CopyFileToArchivePreserveCompression(context_, file->file, *file->path, writer)) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to copy file " << *file->path);
return false;
}
@@ -145,8 +148,9 @@ class BinaryApkSerializer : public IApkSerializer {
class ProtoApkSerializer : public IApkSerializer {
public:
ProtoApkSerializer(IAaptContext* context, const Source& source)
: IApkSerializer(context, source) {}
ProtoApkSerializer(IAaptContext* context, const android::Source& source)
: IApkSerializer(context, source) {
}
bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
IArchiveWriter* writer, uint32_t compression_flags) override {
@@ -166,7 +170,7 @@ class ProtoApkSerializer : public IApkSerializer {
if (file->type == ResourceFile::Type::kBinaryXml) {
std::unique_ptr<io::IData> data = file->file->OpenAsData();
if (!data) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to open file " << *file->path);
return false;
}
@@ -174,14 +178,14 @@ class ProtoApkSerializer : public IApkSerializer {
std::string error;
std::unique_ptr<xml::XmlResource> xml = xml::Inflate(data->data(), data->size(), &error);
if (xml == nullptr) {
context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to parse binary XML: "
<< error);
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to parse binary XML: " << error);
return false;
}
if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer,
file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to serialize to proto XML: " << *file->path);
return false;
}
@@ -189,7 +193,7 @@ class ProtoApkSerializer : public IApkSerializer {
file->type = ResourceFile::Type::kProtoXml;
} else {
if (!io::CopyFileToArchivePreserveCompression(context_, file->file, *file->path, writer)) {
context_->GetDiagnostics()->Error(DiagMessage(source_)
context_->GetDiagnostics()->Error(android::DiagMessage(source_)
<< "failed to copy file " << *file->path);
return false;
}
@@ -215,7 +219,7 @@ class Context : public IAaptContext {
return &symbols_;
}
IDiagnostics* GetDiagnostics() override {
android::IDiagnostics* GetDiagnostics() override {
return &diag_;
}
@@ -270,7 +274,7 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
} else if (output_format == ApkFormat::kProto) {
serializer.reset(new ProtoApkSerializer(context, apk->GetSource()));
} else {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "Cannot convert APK to unknown format");
return 1;
}
@@ -279,7 +283,7 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/,
output_writer, (manifest != nullptr && manifest->WasCompressed())
? ArchiveEntry::kCompress : 0u)) {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "failed to serialize AndroidManifest.xml");
return 1;
}
@@ -298,7 +302,7 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
FileReference* file = ValueCast<FileReference>(config_value->value.get());
if (file != nullptr) {
if (file->file == nullptr) {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "no file associated with " << *file);
return 1;
}
@@ -306,7 +310,7 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
// Only serialize if we haven't seen this file before
if (files_written.insert(*file->path).second) {
if (!serializer->SerializeFile(file, output_writer)) {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "failed to serialize file " << *file->path);
return 1;
}
@@ -319,7 +323,7 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
// Converted resource table
if (!serializer->SerializeTable(converted_table, output_writer)) {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "failed to serialize the resource table");
return 1;
}
@@ -340,8 +344,8 @@ int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer
}
if (!io::CopyFileToArchivePreserveCompression(context, file, path, output_writer)) {
context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
<< "failed to copy file " << path);
context->GetDiagnostics()->Error(android::DiagMessage(apk->GetSource())
<< "failed to copy file " << path);
return 1;
}
}
@@ -363,7 +367,7 @@ int ConvertCommand::Action(const std::vector<std::string>& args) {
const StringPiece& path = args[0];
unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(path, context.GetDiagnostics());
if (apk == nullptr) {
context.GetDiagnostics()->Error(DiagMessage(path) << "failed to load APK");
context.GetDiagnostics()->Error(android::DiagMessage(path) << "failed to load APK");
return 1;
}
@@ -386,8 +390,9 @@ int ConvertCommand::Action(const std::vector<std::string>& args) {
} else if (output_format_.value() == ConvertCommand::kOutputFormatProto) {
format = ApkFormat::kProto;
} else {
context.GetDiagnostics()->Error(DiagMessage(path) << "Invalid value for flag --output-format: "
<< output_format_.value());
context.GetDiagnostics()->Error(android::DiagMessage(path)
<< "Invalid value for flag --output-format: "
<< output_format_.value());
return 1;
}

View File

@@ -101,7 +101,8 @@ TEST_F(ConvertTest, KeepRawXmlStrings) {
// Check that the raw string index has been set to the correct string pool entry
int32_t raw_index = tree.getAttributeValueStringID(0);
ASSERT_THAT(raw_index, Ne(-1));
EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
EXPECT_THAT(android::util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)),
Eq("007"));
}
TEST_F(ConvertTest, DuplicateEntriesWrittenOnce) {

View File

@@ -16,10 +16,10 @@
#include "Diff.h"
#include "android-base/macros.h"
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "ValueVisitor.h"
#include "android-base/macros.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
@@ -45,7 +45,7 @@ class DiffContext : public IAaptContext {
return 0x0;
}
IDiagnostics* GetDiagnostics() override {
android::IDiagnostics* GetDiagnostics() override {
return &diagnostics_;
}
@@ -78,7 +78,7 @@ class DiffContext : public IAaptContext {
SymbolTable symbol_table_;
};
static void EmitDiffLine(const Source& source, const StringPiece& message) {
static void EmitDiffLine(const android::Source& source, const StringPiece& message) {
std::cerr << source << ": " << message << "\n";
}
@@ -385,7 +385,7 @@ int DiffCommand::Action(const std::vector<std::string>& args) {
return 1;
}
IDiagnostics* diag = context.GetDiagnostics();
android::IDiagnostics* diag = context.GetDiagnostics();
std::unique_ptr<LoadedApk> apk_a = LoadedApk::LoadApkFromPath(args[0], diag);
std::unique_ptr<LoadedApk> apk_b = LoadedApk::LoadApkFromPath(args[1], diag);
if (!apk_a || !apk_b) {

View File

@@ -57,8 +57,8 @@ static const char* ResourceFileTypeToString(const ResourceFile::Type& type) {
return "UNKNOWN";
}
static void DumpCompiledFile(const ResourceFile& file, const Source& source, off64_t offset,
size_t len, Printer* printer) {
static void DumpCompiledFile(const ResourceFile& file, const android::Source& source,
off64_t offset, size_t len, Printer* printer) {
printer->Print("Resource: ");
printer->Println(file.name.to_string());
@@ -83,7 +83,7 @@ class DumpContext : public IAaptContext {
return PackageType::kApp;
}
IDiagnostics* GetDiagnostics() override {
android::IDiagnostics* GetDiagnostics() override {
return &diagnostics_;
}
@@ -138,7 +138,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
print_options.show_values = !no_values_;
if (args.size() < 1) {
diag_->Error(DiagMessage() << "No dump container specified");
diag_->Error(android::DiagMessage() << "No dump container specified");
return 1;
}
@@ -146,7 +146,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
for (auto container : args) {
io::FileInputStream input(container);
if (input.HadError()) {
context.GetDiagnostics()->Error(DiagMessage(container)
context.GetDiagnostics()->Error(android::DiagMessage(container)
<< "failed to open file: " << input.GetError());
error = true;
continue;
@@ -155,7 +155,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
// Try as a compiled file.
ContainerReader reader(&input);
if (reader.HadError()) {
context.GetDiagnostics()->Error(DiagMessage(container)
context.GetDiagnostics()->Error(android::DiagMessage(container)
<< "failed to read container: " << reader.GetError());
error = true;
continue;
@@ -170,7 +170,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
pb::ResourceTable pb_table;
if (!entry->GetResTable(&pb_table)) {
context.GetDiagnostics()->Error(DiagMessage(container)
context.GetDiagnostics()->Error(android::DiagMessage(container)
<< "failed to parse proto table: " << entry->GetError());
error = true;
continue;
@@ -179,7 +179,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
ResourceTable table;
error.clear();
if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
context.GetDiagnostics()->Error(DiagMessage(container)
context.GetDiagnostics()->Error(android::DiagMessage(container)
<< "failed to parse table: " << error);
error = true;
continue;
@@ -194,7 +194,7 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
off64_t offset;
size_t length;
if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
context.GetDiagnostics()->Error(DiagMessage(container)
context.GetDiagnostics()->Error(android::DiagMessage(container)
<< "failed to parse compiled proto file: "
<< entry->GetError());
error = true;
@@ -203,14 +203,14 @@ int DumpAPCCommand::Action(const std::vector<std::string>& args) {
ResourceFile file;
if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
context.GetDiagnostics()->Warn(DiagMessage(container)
context.GetDiagnostics()->Warn(android::DiagMessage(container)
<< "failed to parse compiled file: " << error);
error = true;
continue;
}
printer_->Indent();
DumpCompiledFile(file, Source(container), offset, length, printer_);
DumpCompiledFile(file, android::Source(container), offset, length, printer_);
printer_->Undent();
}
}
@@ -228,7 +228,7 @@ int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
int DumpConfigsCommand::Dump(LoadedApk* apk) {
ResourceTable* table = apk->GetResourceTable();
if (!table) {
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to retrieve resource table");
return 1;
}
@@ -268,13 +268,13 @@ int DumpPackageNameCommand::Dump(LoadedApk* apk) {
int DumpStringsCommand::Dump(LoadedApk* apk) {
ResourceTable* table = apk->GetResourceTable();
if (!table) {
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to retrieve resource table");
return 1;
}
// Load the run-time xml string pool using the flattened data
BigBuffer buffer(4096);
StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
android::BigBuffer buffer(4096);
android::StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
auto data = buffer.to_string();
android::ResStringPool pool(data.data(), data.size(), false);
Debug::DumpResStringPool(&pool, GetPrinter());
@@ -291,14 +291,14 @@ int DumpStyleParentCommand::Dump(LoadedApk* apk) {
const auto table = apk->GetResourceTable();
if (!table) {
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to retrieve resource table");
return 1;
}
std::optional<ResourceTable::SearchResult> target = table->FindResource(target_style);
if (!target) {
GetDiagnostics()->Error(
DiagMessage() << "Target style \"" << target_style.entry << "\" does not exist");
GetDiagnostics()->Error(android::DiagMessage()
<< "Target style \"" << target_style.entry << "\" does not exist");
return 1;
}
@@ -315,7 +315,7 @@ int DumpTableCommand::Dump(LoadedApk* apk) {
ResourceTable* table = apk->GetResourceTable();
if (!table) {
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to retrieve resource table");
return 1;
}
@@ -340,7 +340,7 @@ int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
}
// Flatten the xml document to get a binary representation of the proto xml file
BigBuffer buffer(4096);
android::BigBuffer buffer(4096);
XmlFlattenerOptions options = {};
options.keep_raw_values = true;
XmlFlattener flattener(&buffer, options);
@@ -356,7 +356,7 @@ int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
} else if (apk->GetApkFormat() == ApkFormat::kBinary) {
io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
if (!file) {
GetDiagnostics()->Error(DiagMessage(xml_file)
GetDiagnostics()->Error(android::DiagMessage(xml_file)
<< "File '" << xml_file << "' not found in APK");
error = true;
continue;
@@ -364,7 +364,7 @@ int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
std::unique_ptr<io::IData> data = file->OpenAsData();
if (!data) {
GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
GetDiagnostics()->Error(android::DiagMessage() << "Failed to open " << xml_file);
error = true;
continue;
}
@@ -372,7 +372,7 @@ int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
// Load the run-time xml tree from the file data
tree.setTo(data->data(), data->size(), /** copyData */ true);
} else {
GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
GetDiagnostics()->Error(android::DiagMessage(apk->GetSource()) << "Unknown APK format");
error = true;
continue;
}
@@ -396,7 +396,7 @@ int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
int DumpOverlayableCommand::Dump(LoadedApk* apk) {
ResourceTable* table = apk->GetResourceTable();
if (!table) {
GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to retrieve resource table");
return 1;
}
@@ -563,13 +563,13 @@ const char DumpBadgerCommand::kBadgerData[2925] = {
int DumpChunks::Dump(LoadedApk* apk) {
auto file = apk->GetFileCollection()->FindFile("resources.arsc");
if (!file) {
GetDiagnostics()->Error(DiagMessage() << "Failed to find resources.arsc in APK");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to find resources.arsc in APK");
return 1;
}
auto data = file->OpenAsData();
if (!data) {
GetDiagnostics()->Error(DiagMessage() << "Failed to open resources.arsc ");
GetDiagnostics()->Error(android::DiagMessage() << "Failed to open resources.arsc ");
return 1;
}

View File

@@ -33,29 +33,30 @@ namespace aapt {
**/
class DumpApkCommand : public Command {
public:
explicit DumpApkCommand(const std::string&& name, text::Printer* printer, IDiagnostics* diag)
explicit DumpApkCommand(const std::string&& name, text::Printer* printer,
android::IDiagnostics* diag)
: Command(name), printer_(printer), diag_(diag) {
SetDescription("Dump information about an APK or APC.");
SetDescription("Dump information about an APK or APC.");
}
text::Printer* GetPrinter() {
return printer_;
}
IDiagnostics* GetDiagnostics() {
android::IDiagnostics* GetDiagnostics() {
return diag_;
}
std::optional<std::string> GetPackageName(LoadedApk* apk) {
xml::Element* manifest_el = apk->GetManifest()->root.get();
if (!manifest_el) {
GetDiagnostics()->Error(DiagMessage() << "No AndroidManifest.");
GetDiagnostics()->Error(android::DiagMessage() << "No AndroidManifest.");
return {};
}
xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
if (!attr) {
GetDiagnostics()->Error(DiagMessage() << "No package name.");
GetDiagnostics()->Error(android::DiagMessage() << "No package name.");
return {};
}
return attr->value;
@@ -66,7 +67,7 @@ class DumpApkCommand : public Command {
int Action(const std::vector<std::string>& args) final {
if (args.size() < 1) {
diag_->Error(DiagMessage() << "No dump apk specified.");
diag_->Error(android::DiagMessage() << "No dump apk specified.");
return 1;
}
@@ -86,13 +87,13 @@ class DumpApkCommand : public Command {
private:
text::Printer* printer_;
IDiagnostics* diag_;
android::IDiagnostics* diag_;
};
/** Command that prints contents of files generated from the compilation stage. */
class DumpAPCCommand : public Command {
public:
explicit DumpAPCCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpAPCCommand(text::Printer* printer, android::IDiagnostics* diag)
: Command("apc"), printer_(printer), diag_(diag) {
SetDescription("Print the contents of the AAPT2 Container (APC) generated fom compilation.");
AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
@@ -104,7 +105,7 @@ class DumpAPCCommand : public Command {
private:
text::Printer* printer_;
IDiagnostics* diag_;
android::IDiagnostics* diag_;
bool no_values_ = false;
bool verbose_ = false;
};
@@ -124,7 +125,7 @@ class DumpBadgerCommand : public Command {
class DumpBadgingCommand : public DumpApkCommand {
public:
explicit DumpBadgingCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpBadgingCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("badging", printer, diag) {
SetDescription("Print information extracted from the manifest of the APK.");
AddOptionalSwitch("--include-meta-data", "Include meta-data information.",
@@ -149,7 +150,7 @@ class DumpBadgingCommand : public DumpApkCommand {
class DumpConfigsCommand : public DumpApkCommand {
public:
explicit DumpConfigsCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpConfigsCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("configurations", printer, diag) {
SetDescription("Print every configuration used by a resource in the APK.");
}
@@ -159,7 +160,7 @@ class DumpConfigsCommand : public DumpApkCommand {
class DumpPackageNameCommand : public DumpApkCommand {
public:
explicit DumpPackageNameCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpPackageNameCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("packagename", printer, diag) {
SetDescription("Print the package name of the APK.");
}
@@ -169,7 +170,7 @@ class DumpPackageNameCommand : public DumpApkCommand {
class DumpPermissionsCommand : public DumpApkCommand {
public:
explicit DumpPermissionsCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpPermissionsCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("permissions", printer, diag) {
SetDescription("Print the permissions extracted from the manifest of the APK.");
}
@@ -183,7 +184,7 @@ class DumpPermissionsCommand : public DumpApkCommand {
class DumpStringsCommand : public DumpApkCommand {
public:
explicit DumpStringsCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpStringsCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("strings", printer, diag) {
SetDescription("Print the contents of the resource table string pool in the APK.");
}
@@ -194,7 +195,7 @@ class DumpStringsCommand : public DumpApkCommand {
/** Prints the graph of parents of a style in an APK. */
class DumpStyleParentCommand : public DumpApkCommand {
public:
explicit DumpStyleParentCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpStyleParentCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("styleparents", printer, diag) {
SetDescription("Print the parents of a style in an APK.");
AddRequiredFlag("--style", "The name of the style to print", &style_);
@@ -208,7 +209,7 @@ class DumpStyleParentCommand : public DumpApkCommand {
class DumpTableCommand : public DumpApkCommand {
public:
explicit DumpTableCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpTableCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("resources", printer, diag) {
SetDescription("Print the contents of the resource table from the APK.");
AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
@@ -225,7 +226,7 @@ class DumpTableCommand : public DumpApkCommand {
class DumpXmlStringsCommand : public DumpApkCommand {
public:
explicit DumpXmlStringsCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpXmlStringsCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("xmlstrings", printer, diag) {
SetDescription("Print the string pool of a compiled xml in an APK.");
AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
@@ -239,7 +240,8 @@ class DumpXmlStringsCommand : public DumpApkCommand {
class DumpChunks : public DumpApkCommand {
public:
DumpChunks(text::Printer* printer, IDiagnostics* diag) : DumpApkCommand("chunks", printer, diag) {
DumpChunks(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("chunks", printer, diag) {
SetDescription("Print the chunk information of the compiled resources.arsc in the APK.");
}
@@ -249,7 +251,7 @@ class DumpChunks : public DumpApkCommand {
/** Prints the tree of a compiled xml in an APK. */
class DumpXmlTreeCommand : public DumpApkCommand {
public:
explicit DumpXmlTreeCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpXmlTreeCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("xmltree", printer, diag) {
SetDescription("Print the tree of a compiled xml in an APK.");
AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
@@ -263,7 +265,7 @@ class DumpXmlTreeCommand : public DumpApkCommand {
class DumpOverlayableCommand : public DumpApkCommand {
public:
explicit DumpOverlayableCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpOverlayableCommand(text::Printer* printer, android::IDiagnostics* diag)
: DumpApkCommand("overlayable", printer, diag) {
SetDescription("Print the <overlayable> resources of an APK.");
}
@@ -274,7 +276,7 @@ class DumpOverlayableCommand : public DumpApkCommand {
/** The default dump command. Performs no action because a subcommand is required. */
class DumpCommand : public Command {
public:
explicit DumpCommand(text::Printer* printer, IDiagnostics* diag)
explicit DumpCommand(text::Printer* printer, android::IDiagnostics* diag)
: Command("dump", "d"), diag_(diag) {
AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(printer, diag_));
AddOptionalSubcommand(util::make_unique<DumpBadgingCommand>(printer, diag_));
@@ -293,16 +295,16 @@ class DumpCommand : public Command {
int Action(const std::vector<std::string>& args) override {
if (args.size() == 0) {
diag_->Error(DiagMessage() << "no subcommand specified");
diag_->Error(android::DiagMessage() << "no subcommand specified");
} else {
diag_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
diag_->Error(android::DiagMessage() << "unknown subcommand '" << args[0] << "'");
}
Usage(&std::cerr);
return 1;
}
private:
IDiagnostics* diag_;
android::IDiagnostics* diag_;
};
} // namespace aapt

View File

@@ -30,12 +30,7 @@ namespace aapt {
using DumpTest = CommandTestFixture;
class NoopDiagnostics : public IDiagnostics {
public:
void Log(Level level, DiagMessageActual& actualMsg) override {
}
};
static NoopDiagnostics noop_diag;
static android::NoOpDiagnostics noop_diag;
void DumpBadgingToString(LoadedApk* loaded_apk, std::string* output, bool include_meta_data = false,
bool only_permissions = false) {
@@ -97,4 +92,4 @@ TEST_F(DumpTest, DumpBadgingPermissionsOnly) {
ASSERT_EQ(output, expected);
}
} // namespace aapt
} // namespace aapt

File diff suppressed because it is too large Load Diff

View File

@@ -20,12 +20,12 @@
#include <regex>
#include "Command.h"
#include "Diagnostics.h"
#include "Resource.h"
#include "split/TableSplitter.h"
#include "androidfw/IDiagnostics.h"
#include "format/binary/TableFlattener.h"
#include "format/proto/ProtoSerialize.h"
#include "link/ManifestFixer.h"
#include "split/TableSplitter.h"
#include "trace/TraceBuffer.h"
namespace aapt {
@@ -111,8 +111,7 @@ struct LinkOptions {
class LinkCommand : public Command {
public:
explicit LinkCommand(IDiagnostics* diag) : Command("link", "l"),
diag_(diag) {
explicit LinkCommand(android::IDiagnostics* diag) : Command("link", "l"), diag_(diag) {
SetDescription("Links resources into an apk.");
AddRequiredFlag("-o", "Output path.", &options_.output_path, Command::kPath);
AddRequiredFlag("--manifest", "Path to the Android manifest to build.",
@@ -316,7 +315,7 @@ class LinkCommand : public Command {
int Action(const std::vector<std::string>& args) override;
private:
IDiagnostics* diag_;
android::IDiagnostics* diag_;
LinkOptions options_;
std::vector<std::string> overlay_arg_list_;

View File

@@ -19,6 +19,7 @@
#include <android-base/file.h>
#include "AppInfo.h"
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "test/Test.h"
@@ -87,7 +88,8 @@ TEST_F(LinkTest, KeepRawXmlStrings) {
// Check that the raw string index has been set to the correct string pool entry
int32_t raw_index = tree.getAttributeValueStringID(0);
ASSERT_THAT(raw_index, Ne(-1));
EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
EXPECT_THAT(android::util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)),
Eq("007"));
}
TEST_F(LinkTest, NoCompressAssets) {
@@ -410,7 +412,7 @@ struct SourceXML {
static void BuildApk(const std::vector<SourceXML>& source_files, const std::string& apk_path,
LinkCommandBuilder&& link_args, CommandTestFixture* fixture,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
TemporaryDir res_dir;
TemporaryDir compiled_res_dir;
for (auto& source_file : source_files) {
@@ -423,7 +425,7 @@ static void BuildApk(const std::vector<SourceXML>& source_files, const std::stri
static void BuildSDK(const std::vector<SourceXML>& source_files, const std::string& apk_path,
const std::string& java_root_path, CommandTestFixture* fixture,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
auto android_manifest = ManifestBuilder(fixture).SetPackageName("android").Build();
auto android_link_args = LinkCommandBuilder(fixture)
@@ -435,7 +437,7 @@ static void BuildSDK(const std::vector<SourceXML>& source_files, const std::stri
}
static void BuildNonFinalizedSDK(const std::string& apk_path, const std::string& java_path,
CommandTestFixture* fixture, IDiagnostics* diag) {
CommandTestFixture* fixture, android::IDiagnostics* diag) {
const std::string android_values =
R"(<resources>
<public type="attr" name="finalized_res" id="0x01010001"/>
@@ -471,7 +473,7 @@ static void BuildNonFinalizedSDK(const std::string& apk_path, const std::string&
}
static void BuildFinalizedSDK(const std::string& apk_path, const std::string& java_path,
CommandTestFixture* fixture, IDiagnostics* diag) {
CommandTestFixture* fixture, android::IDiagnostics* diag) {
const std::string android_values =
R"(<resources>
<public type="attr" name="finalized_res" id="0x01010001"/>
@@ -511,7 +513,7 @@ static void BuildFinalizedSDK(const std::string& apk_path, const std::string& ja
static void BuildAppAgainstSDK(const std::string& apk_path, const std::string& java_path,
const std::string& sdk_path, CommandTestFixture* fixture,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
const std::string app_values =
R"(<resources xmlns:android="http://schemas.android.com/apk/res/android">
<attr name="bar" />

View File

@@ -19,18 +19,17 @@
#include <memory>
#include <vector>
#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "ResourceUtils.h"
#include "SdkConstants.h"
#include "ValueVisitor.h"
#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "cmd/Util.h"
#include "configuration/ConfigurationParser.h"
#include "filter/AbiFilter.h"
@@ -69,7 +68,7 @@ class OptimizeContext : public IAaptContext {
return PackageType::kApp;
}
IDiagnostics* GetDiagnostics() override {
android::IDiagnostics* GetDiagnostics() override {
return &diagnostics_;
}
@@ -130,12 +129,12 @@ class Optimizer {
int Run(std::unique_ptr<LoadedApk> apk) {
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(DiagMessage() << "Optimizing APK...");
context_->GetDiagnostics()->Note(android::DiagMessage() << "Optimizing APK...");
}
if (!options_.resources_exclude_list.empty()) {
ResourceFilter filter(options_.resources_exclude_list);
if (!filter.Consume(context_, apk->GetResourceTable())) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed filtering resources");
context_->GetDiagnostics()->Error(android::DiagMessage() << "failed filtering resources");
return 1;
}
}
@@ -147,20 +146,21 @@ class Optimizer {
ResourceDeduper deduper;
if (!deduper.Consume(context_, apk->GetResourceTable())) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed deduping resources");
context_->GetDiagnostics()->Error(android::DiagMessage() << "failed deduping resources");
return 1;
}
if (options_.shorten_resource_paths) {
ResourcePathShortener shortener(options_.table_flattener_options.shortened_path_map);
if (!shortener.Consume(context_, apk->GetResourceTable())) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed shortening resource paths");
context_->GetDiagnostics()->Error(android::DiagMessage()
<< "failed shortening resource paths");
return 1;
}
if (options_.shortened_paths_map_path
&& !WriteShortenedPathsMap(options_.table_flattener_options.shortened_path_map,
options_.shortened_paths_map_path.value())) {
context_->GetDiagnostics()->Error(DiagMessage()
context_->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to write shortened resource paths to file");
return 1;
}
@@ -183,9 +183,10 @@ class Optimizer {
auto split_constraints_iter = options_.split_constraints.begin();
for (std::unique_ptr<ResourceTable>& split_table : splitter.splits()) {
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(
DiagMessage(*path_iter) << "generating split with configurations '"
<< util::Joiner(split_constraints_iter->configs, ", ") << "'");
context_->GetDiagnostics()->Note(android::DiagMessage(*path_iter)
<< "generating split with configurations '"
<< util::Joiner(split_constraints_iter->configs, ", ")
<< "'");
}
// Generate an AndroidManifest.xml for each split.
@@ -228,7 +229,7 @@ class Optimizer {
private:
bool WriteSplitApk(ResourceTable* table, xml::XmlResource* manifest, IArchiveWriter* writer) {
BigBuffer manifest_buffer(4096);
android::BigBuffer manifest_buffer(4096);
XmlFlattener xml_flattener(&manifest_buffer, {});
if (!xml_flattener.Consume(context_, manifest)) {
return false;
@@ -255,7 +256,7 @@ class Optimizer {
if (file_ref->file == nullptr) {
ResourceNameRef name(pkg->name, type->named_type, entry->name);
context_->GetDiagnostics()->Warn(DiagMessage(file_ref->GetSource())
context_->GetDiagnostics()->Warn(android::DiagMessage(file_ref->GetSource())
<< "file for resource " << name << " with config '"
<< config_value->config << "' not found");
continue;
@@ -276,7 +277,7 @@ class Optimizer {
}
}
BigBuffer table_buffer(4096);
android::BigBuffer table_buffer(4096);
TableFlattener table_flattener(options_.table_flattener_options, &table_buffer);
if (!table_flattener.Consume(context_, table)) {
return false;
@@ -311,18 +312,18 @@ bool ParseConfig(const std::string& content, IAaptContext* context, OptimizeOpti
auto split_line = util::Split(line, '#');
if (split_line.size() < 2) {
context->GetDiagnostics()->Error(DiagMessage(line) << "No # found in line");
context->GetDiagnostics()->Error(android::DiagMessage(line) << "No # found in line");
return false;
}
StringPiece resource_string = split_line[0];
StringPiece directives = split_line[1];
ResourceNameRef resource_name;
if (!ResourceUtils::ParseResourceName(resource_string, &resource_name)) {
context->GetDiagnostics()->Error(DiagMessage(line) << "Malformed resource name");
context->GetDiagnostics()->Error(android::DiagMessage(line) << "Malformed resource name");
return false;
}
if (!resource_name.package.empty()) {
context->GetDiagnostics()->Error(DiagMessage(line)
context->GetDiagnostics()->Error(android::DiagMessage(line)
<< "Package set for resource. Only use type/name");
return false;
}
@@ -341,7 +342,7 @@ bool ParseConfig(const std::string& content, IAaptContext* context, OptimizeOpti
bool ExtractConfig(const std::string& path, IAaptContext* context, OptimizeOptions* options) {
std::string content;
if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) {
context->GetDiagnostics()->Error(DiagMessage(path) << "failed reading config file");
context->GetDiagnostics()->Error(android::DiagMessage(path) << "failed reading config file");
return false;
}
return ParseConfig(content, context, options);
@@ -356,7 +357,7 @@ bool ExtractAppDataFromManifest(OptimizeContext* context, const LoadedApk* apk,
auto app_info = ExtractAppInfoFromBinaryManifest(*manifest, context->GetDiagnostics());
if (!app_info) {
context->GetDiagnostics()->Error(DiagMessage()
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to extract data from AndroidManifest.xml");
return false;
}
@@ -376,7 +377,7 @@ int OptimizeCommand::Action(const std::vector<std::string>& args) {
const std::string& apk_path = args[0];
OptimizeContext context;
context.SetVerbose(verbose_);
IDiagnostics* diag = context.GetDiagnostics();
android::IDiagnostics* diag = context.GetDiagnostics();
if (config_path_) {
std::string& path = config_path_.value();
@@ -384,12 +385,12 @@ int OptimizeCommand::Action(const std::vector<std::string>& args) {
if (for_path) {
options_.apk_artifacts = for_path.value().WithDiagnostics(diag).Parse(apk_path);
if (!options_.apk_artifacts) {
diag->Error(DiagMessage() << "Failed to parse the output artifact list");
diag->Error(android::DiagMessage() << "Failed to parse the output artifact list");
return 1;
}
} else {
diag->Error(DiagMessage() << "Could not parse config file " << path);
diag->Error(android::DiagMessage() << "Could not parse config file " << path);
return 1;
}
@@ -411,11 +412,13 @@ int OptimizeCommand::Action(const std::vector<std::string>& args) {
// Since we know that we are going to process the APK (not just print targets), make sure we
// have somewhere to write them to.
if (!options_.output_dir) {
diag->Error(DiagMessage() << "Output directory is required when using a configuration file");
diag->Error(android::DiagMessage()
<< "Output directory is required when using a configuration file");
return 1;
}
} else if (print_only_) {
diag->Error(DiagMessage() << "Asked to print artifacts without providing a configurations");
diag->Error(android::DiagMessage()
<< "Asked to print artifacts without providing a configurations");
return 1;
}

View File

@@ -17,9 +17,9 @@
#include "Optimize.h"
#include "AppInfo.h"
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "Resource.h"
#include "androidfw/IDiagnostics.h"
#include "test/Test.h"
using testing::Contains;

View File

@@ -34,10 +34,12 @@ using ::android::base::StringPrintf;
namespace aapt {
std::optional<uint16_t> ParseTargetDensityParameter(const StringPiece& arg, IDiagnostics* diag) {
std::optional<uint16_t> ParseTargetDensityParameter(const StringPiece& arg,
android::IDiagnostics* diag) {
ConfigDescription preferred_density_config;
if (!ConfigDescription::Parse(arg, &preferred_density_config)) {
diag->Error(DiagMessage() << "invalid density '" << arg << "' for --preferred-density option");
diag->Error(android::DiagMessage()
<< "invalid density '" << arg << "' for --preferred-density option");
return {};
}
@@ -46,14 +48,14 @@ std::optional<uint16_t> ParseTargetDensityParameter(const StringPiece& arg, IDia
if (preferred_density_config.diff(ConfigDescription::DefaultConfig()) !=
ConfigDescription::CONFIG_DENSITY) {
diag->Error(DiagMessage() << "invalid preferred density '" << arg << "'. "
<< "Preferred density must only be a density value");
diag->Error(android::DiagMessage() << "invalid preferred density '" << arg << "'. "
<< "Preferred density must only be a density value");
return {};
}
return preferred_density_config.density;
}
bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag, std::string* out_path,
bool ParseSplitParameter(const StringPiece& arg, android::IDiagnostics* diag, std::string* out_path,
SplitConstraints* out_split) {
CHECK(diag != nullptr);
CHECK(out_path != nullptr);
@@ -67,9 +69,9 @@ bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag, std::string
std::vector<std::string> parts = util::Split(arg, sSeparator);
if (parts.size() != 2) {
diag->Error(DiagMessage() << "invalid split parameter '" << arg << "'");
diag->Note(DiagMessage() << "should be --split path/to/output.apk" << sSeparator
<< "<config>[,<config>...].");
diag->Error(android::DiagMessage() << "invalid split parameter '" << arg << "'");
diag->Note(android::DiagMessage() << "should be --split path/to/output.apk" << sSeparator
<< "<config>[,<config>...].");
return false;
}
@@ -78,8 +80,8 @@ bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag, std::string
for (const StringPiece& config_str : util::Tokenize(parts[1], ',')) {
ConfigDescription config;
if (!ConfigDescription::Parse(config_str, &config)) {
diag->Error(DiagMessage() << "invalid config '" << config_str << "' in split parameter '"
<< arg << "'");
diag->Error(android::DiagMessage()
<< "invalid config '" << config_str << "' in split parameter '" << arg << "'");
return false;
}
out_split->configs.insert(config);
@@ -88,7 +90,7 @@ bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag, std::string
}
std::unique_ptr<IConfigFilter> ParseConfigFilterParameters(const std::vector<std::string>& args,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::unique_ptr<AxisConfigFilter> filter = util::make_unique<AxisConfigFilter>();
for (const std::string& config_arg : args) {
for (const StringPiece& config_str : util::Tokenize(config_arg, ',')) {
@@ -97,12 +99,13 @@ std::unique_ptr<IConfigFilter> ParseConfigFilterParameters(const std::vector<std
if (lv.InitFromFilterString(config_str)) {
lv.WriteTo(&config);
} else if (!ConfigDescription::Parse(config_str, &config)) {
diag->Error(DiagMessage() << "invalid config '" << config_str << "' for -c option");
diag->Error(android::DiagMessage()
<< "invalid config '" << config_str << "' for -c option");
return {};
}
if (config.density != 0) {
diag->Warn(DiagMessage() << "ignoring density '" << config << "' for -c option");
diag->Warn(android::DiagMessage() << "ignoring density '" << config << "' for -c option");
} else {
filter->AddConfig(config);
}
@@ -331,7 +334,7 @@ static std::optional<int> ExtractSdkVersion(const xml::Attribute& attr, std::str
}
std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
// Make sure the first element is <manifest> with package attribute.
const xml::Element* manifest_el = xml_res.root.get();
if (manifest_el == nullptr) {
@@ -341,20 +344,21 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
AppInfo app_info;
if (!manifest_el->namespace_uri.empty() || manifest_el->name != "manifest") {
diag->Error(DiagMessage(xml_res.file.source) << "root tag must be <manifest>");
diag->Error(android::DiagMessage(xml_res.file.source) << "root tag must be <manifest>");
return {};
}
const xml::Attribute* package_attr = manifest_el->FindAttribute({}, "package");
if (!package_attr) {
diag->Error(DiagMessage(xml_res.file.source) << "<manifest> must have a 'package' attribute");
diag->Error(android::DiagMessage(xml_res.file.source)
<< "<manifest> must have a 'package' attribute");
return {};
}
std::string error_msg;
std::optional<std::string> maybe_package = ExtractCompiledString(*package_attr, &error_msg);
if (!maybe_package) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid package name: " << error_msg);
return {};
}
@@ -364,7 +368,7 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode")) {
std::optional<uint32_t> maybe_code = ExtractCompiledInt(*version_code_attr, &error_msg);
if (!maybe_code) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid android:versionCode: " << error_msg);
return {};
}
@@ -375,8 +379,8 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) {
std::optional<uint32_t> maybe_code = ExtractCompiledInt(*version_code_major_attr, &error_msg);
if (!maybe_code) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid android:versionCodeMajor: " << error_msg);
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid android:versionCodeMajor: " << error_msg);
return {};
}
app_info.version_code_major = maybe_code.value();
@@ -386,7 +390,7 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) {
std::optional<uint32_t> maybe_code = ExtractCompiledInt(*revision_code_attr, &error_msg);
if (!maybe_code) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid android:revisionCode: " << error_msg);
return {};
}
@@ -397,7 +401,7 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
std::optional<std::string> maybe_split_name =
ExtractCompiledString(*split_name_attr, &error_msg);
if (!maybe_split_name) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(manifest_el->line_number))
<< "invalid split name: " << error_msg);
return {};
}
@@ -409,7 +413,7 @@ std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource&
uses_sdk_el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion")) {
std::optional<int> maybe_sdk = ExtractSdkVersion(*min_sdk, &error_msg);
if (!maybe_sdk) {
diag->Error(DiagMessage(xml_res.file.source.WithLine(uses_sdk_el->line_number))
diag->Error(android::DiagMessage(xml_res.file.source.WithLine(uses_sdk_el->line_number))
<< "invalid android:minSdkVersion: " << error_msg);
return {};
}

View File

@@ -19,11 +19,10 @@
#include <regex>
#include "androidfw/StringPiece.h"
#include "AppInfo.h"
#include "Diagnostics.h"
#include "SdkConstants.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "filter/ConfigFilter.h"
#include "split/TableSplitter.h"
#include "xml/XmlDom.h"
@@ -33,18 +32,18 @@ namespace aapt {
// Parses a configuration density (ex. hdpi, xxhdpi, 234dpi, anydpi, etc).
// Returns Nothing and logs a human friendly error message if the string was not legal.
std::optional<uint16_t> ParseTargetDensityParameter(const android::StringPiece& arg,
IDiagnostics* diag);
android::IDiagnostics* diag);
// Parses a string of the form 'path/to/output.apk:<config>[,<config>...]' and fills in
// `out_path` with the path and `out_split` with the set of ConfigDescriptions.
// Returns false and logs a human friendly error message if the string was not legal.
bool ParseSplitParameter(const android::StringPiece& arg, IDiagnostics* diag, std::string* out_path,
SplitConstraints* out_split);
bool ParseSplitParameter(const android::StringPiece& arg, android::IDiagnostics* diag,
std::string* out_path, SplitConstraints* out_split);
// Parses a set of config filter strings of the form 'en,fr-rFR' and returns an IConfigFilter.
// Returns nullptr and logs a human friendly error message if the string was not legal.
std::unique_ptr<IConfigFilter> ParseConfigFilterParameters(const std::vector<std::string>& args,
IDiagnostics* diag);
android::IDiagnostics* diag);
// Adjust the SplitConstraints so that their SDK version is stripped if it
// is less than or equal to the min_sdk. Otherwise the resources that have had
@@ -60,7 +59,7 @@ std::unique_ptr<xml::XmlResource> GenerateSplitManifest(const AppInfo& app_info,
// Extracts relevant info from the AndroidManifest.xml.
std::optional<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res,
IDiagnostics* diag);
android::IDiagnostics* diag);
// Returns a copy of 'name' which conforms to the regex '[a-zA-Z]+[a-zA-Z0-9_]*' by
// replacing nonconforming characters with underscores.

View File

@@ -102,7 +102,7 @@ TEST (UtilTest, LongVersionCodeUndefined) {
TEST (UtilTest, ParseSplitParameters) {
IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
android::IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
std::string path;
SplitConstraints constraints;
ConfigDescription expected_configuration;
@@ -356,7 +356,7 @@ TEST (UtilTest, ParseSplitParameters) {
TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
IDiagnostics* diagnostics = context.get()->GetDiagnostics();
android::IDiagnostics* diagnostics = context.get()->GetDiagnostics();
std::vector<SplitConstraints> test_constraints;
std::string path;

View File

@@ -107,10 +107,10 @@ struct IdAssignerContext {
// Returns whether the id was reserved successfully.
// Reserving identifiers must be completed before `NextId` is called for the first time.
bool ReserveId(const ResourceName& name, ResourceId id, const Visibility& visibility,
IDiagnostics* diag);
android::IDiagnostics* diag);
// Retrieves the next available resource id that has not been reserved.
std::optional<ResourceId> NextId(const ResourceName& name, IDiagnostics* diag);
std::optional<ResourceId> NextId(const ResourceName& name, android::IDiagnostics* diag);
private:
std::string package_name_;
@@ -267,11 +267,11 @@ Result<ResourceId> TypeGroup::NextId() {
}
bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
const Visibility& visibility, IDiagnostics* diag) {
const Visibility& visibility, android::IDiagnostics* diag) {
if (package_id_ != id.package_id()) {
diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
<< " because package already has ID " << std::hex
<< (int)id.package_id());
diag->Error(android::DiagMessage()
<< "can't assign ID " << id << " to resource " << name
<< " because package already has ID " << std::hex << (int)id.package_id());
return false;
}
@@ -282,8 +282,8 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
// another type.
auto assign_result = type_id_finder_.ReserveId(key, id.type_id());
if (!assign_result.has_value()) {
diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
<< " because type " << assign_result.error());
diag->Error(android::DiagMessage() << "can't assign ID " << id << " to resource " << name
<< " because type " << assign_result.error());
return false;
}
type = types_.emplace(key, TypeGroup(package_id_, id.type_id())).first;
@@ -293,24 +293,25 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
// Ensure that non-staged resources can only exist in one type ID.
auto non_staged_type = non_staged_type_ids_.emplace(name.type.type, id.type_id());
if (!non_staged_type.second && non_staged_type.first->second != id.type_id()) {
diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name
<< " because type already has ID " << std::hex
<< (int)id.type_id());
diag->Error(android::DiagMessage()
<< "can't assign ID " << id << " to resource " << name
<< " because type already has ID " << std::hex << (int)id.type_id());
return false;
}
}
auto assign_result = type->second.ReserveId(name, id);
if (!assign_result.has_value()) {
diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " << name << " because "
<< assign_result.error());
diag->Error(android::DiagMessage() << "can't assign ID " << id << " to resource " << name
<< " because " << assign_result.error());
return false;
}
return true;
}
std::optional<ResourceId> IdAssignerContext::NextId(const ResourceName& name, IDiagnostics* diag) {
std::optional<ResourceId> IdAssignerContext::NextId(const ResourceName& name,
android::IDiagnostics* diag) {
// The package name is not known during the compile stage.
// Resources without a package name are considered a part of the app being linked.
CHECK(name.package.empty() || name.package == package_name_);
@@ -331,8 +332,8 @@ std::optional<ResourceId> IdAssignerContext::NextId(const ResourceName& name, ID
auto assign_result = type->second.NextId();
if (!assign_result.has_value()) {
diag->Error(DiagMessage() << "can't assign resource ID to resource " << name << " because "
<< assign_result.error());
diag->Error(android::DiagMessage() << "can't assign resource ID to resource " << name
<< " because " << assign_result.error());
return {};
}
return assign_result.value();

View File

@@ -47,19 +47,19 @@ class Visitor : public xml::PackageAwareVisitor {
return;
}
const Source src = xml_resource_->file.source.WithLine(el->line_number);
const android::Source src = xml_resource_->file.source.WithLine(el->line_number);
xml::Attribute* attr = el->FindAttribute({}, "name");
if (!attr) {
context_->GetDiagnostics()->Error(DiagMessage(src) << "missing 'name' attribute");
context_->GetDiagnostics()->Error(android::DiagMessage(src) << "missing 'name' attribute");
error_ = true;
return;
}
std::optional<Reference> ref = ResourceUtils::ParseXmlAttributeName(attr->value);
if (!ref) {
context_->GetDiagnostics()->Error(DiagMessage(src) << "invalid XML attribute '" << attr->value
<< "'");
context_->GetDiagnostics()->Error(android::DiagMessage(src)
<< "invalid XML attribute '" << attr->value << "'");
error_ = true;
return;
}
@@ -67,7 +67,7 @@ class Visitor : public xml::PackageAwareVisitor {
const ResourceName& name = ref.value().name.value();
std::optional<xml::ExtractedPackage> maybe_pkg = TransformPackageAlias(name.package);
if (!maybe_pkg) {
context_->GetDiagnostics()->Error(DiagMessage(src)
context_->GetDiagnostics()->Error(android::DiagMessage(src)
<< "invalid namespace prefix '" << name.package << "'");
error_ = true;
return;
@@ -136,15 +136,15 @@ bool InlineXmlFormatParser::Consume(IAaptContext* context, xml::XmlResource* doc
// Extracted elements must be the only child of <aapt:attr>.
// Make sure there is one root node in the children (ignore empty text).
for (std::unique_ptr<xml::Node>& child : decl.el->children) {
const Source child_source = doc->file.source.WithLine(child->line_number);
const android::Source child_source = doc->file.source.WithLine(child->line_number);
if (xml::Text* t = xml::NodeCast<xml::Text>(child.get())) {
if (!util::TrimWhitespace(t->text).empty()) {
context->GetDiagnostics()->Error(DiagMessage(child_source)
context->GetDiagnostics()->Error(android::DiagMessage(child_source)
<< "can't extract text into its own resource");
return false;
}
} else if (new_doc->root) {
context->GetDiagnostics()->Error(DiagMessage(child_source)
context->GetDiagnostics()->Error(android::DiagMessage(child_source)
<< "inline XML resources must have a single root");
return false;
} else {
@@ -160,7 +160,7 @@ bool InlineXmlFormatParser::Consume(IAaptContext* context, xml::XmlResource* doc
// Get the parent element of <aapt:attr>
xml::Element* parent_el = decl.el->parent;
if (!parent_el) {
context->GetDiagnostics()->Error(DiagMessage(new_doc->file.source)
context->GetDiagnostics()->Error(android::DiagMessage(new_doc->file.source)
<< "no suitable parent for inheriting attribute");
return false;
}

View File

@@ -24,11 +24,10 @@
#include <string>
#include <vector>
#include "androidfw/BigBuffer.h"
#include "androidfw/ResourceTypes.h"
#include "Source.h"
#include "androidfw/Source.h"
#include "trace/TraceBuffer.h"
#include "util/BigBuffer.h"
#include "util/Util.h"
namespace aapt {
@@ -91,7 +90,7 @@ static void readDataFromStream(png_structp readPtr, png_bytep data,
static void writeDataToStream(png_structp writePtr, png_bytep data,
png_size_t length) {
BigBuffer* outBuffer = reinterpret_cast<BigBuffer*>(png_get_io_ptr(writePtr));
android::BigBuffer* outBuffer = reinterpret_cast<android::BigBuffer*>(png_get_io_ptr(writePtr));
png_bytep buf = outBuffer->NextBlock<png_byte>(length);
memcpy(buf, data, length);
}
@@ -99,15 +98,15 @@ static void writeDataToStream(png_structp writePtr, png_bytep data,
static void flushDataToStream(png_structp /*writePtr*/) {}
static void logWarning(png_structp readPtr, png_const_charp warningMessage) {
IDiagnostics* diag =
reinterpret_cast<IDiagnostics*>(png_get_error_ptr(readPtr));
diag->Warn(DiagMessage() << warningMessage);
android::IDiagnostics* diag =
reinterpret_cast<android::IDiagnostics*>(png_get_error_ptr(readPtr));
diag->Warn(android::DiagMessage() << warningMessage);
}
static bool readPng(IDiagnostics* diag, png_structp readPtr, png_infop infoPtr,
static bool readPng(android::IDiagnostics* diag, png_structp readPtr, png_infop infoPtr,
PngInfo* outInfo) {
if (setjmp(png_jmpbuf(readPtr))) {
diag->Error(DiagMessage() << "failed reading png");
diag->Error(android::DiagMessage() << "failed reading png");
return false;
}
@@ -245,10 +244,9 @@ PNG_COLOR_TYPE_RGB_ALPHA) {
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ABS(a) ((a) < 0 ? -(a) : (a))
static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo,
int grayscaleTolerance, png_colorp rgbPalette,
png_bytep alphaPalette, int* paletteEntries,
bool* hasTransparency, int* colorType,
static void analyze_image(android::IDiagnostics* diag, const PngInfo& imageInfo,
int grayscaleTolerance, png_colorp rgbPalette, png_bytep alphaPalette,
int* paletteEntries, bool* hasTransparency, int* colorType,
png_bytepp outRows) {
int w = imageInfo.width;
int h = imageInfo.height;
@@ -383,8 +381,8 @@ static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo,
*colorType = PNG_COLOR_TYPE_PALETTE;
} else {
if (maxGrayDeviation <= grayscaleTolerance) {
diag->Note(DiagMessage() << "forcing image to gray (max deviation = "
<< maxGrayDeviation << ")");
diag->Note(android::DiagMessage()
<< "forcing image to gray (max deviation = " << maxGrayDeviation << ")");
*colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;
} else {
*colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
@@ -431,10 +429,10 @@ static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo,
}
}
static bool writePng(IDiagnostics* diag, png_structp writePtr,
png_infop infoPtr, PngInfo* info, int grayScaleTolerance) {
static bool writePng(android::IDiagnostics* diag, png_structp writePtr, png_infop infoPtr,
PngInfo* info, int grayScaleTolerance) {
if (setjmp(png_jmpbuf(writePtr))) {
diag->Error(DiagMessage() << "failed to write png");
diag->Error(android::DiagMessage() << "failed to write png");
return false;
}
@@ -463,8 +461,8 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr,
png_set_compression_level(writePtr, Z_BEST_COMPRESSION);
if (kDebug) {
diag->Note(DiagMessage() << "writing image: w = " << info->width
<< ", h = " << info->height);
diag->Note(android::DiagMessage()
<< "writing image: w = " << info->width << ", h = " << info->height);
}
png_color rgbPalette[256];
@@ -486,24 +484,21 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr,
if (kDebug) {
switch (colorType) {
case PNG_COLOR_TYPE_PALETTE:
diag->Note(DiagMessage() << "has " << paletteEntries << " colors"
<< (hasTransparency ? " (with alpha)" : "")
<< ", using PNG_COLOR_TYPE_PALLETTE");
diag->Note(android::DiagMessage() << "has " << paletteEntries << " colors"
<< (hasTransparency ? " (with alpha)" : "")
<< ", using PNG_COLOR_TYPE_PALLETTE");
break;
case PNG_COLOR_TYPE_GRAY:
diag->Note(DiagMessage()
<< "is opaque gray, using PNG_COLOR_TYPE_GRAY");
diag->Note(android::DiagMessage() << "is opaque gray, using PNG_COLOR_TYPE_GRAY");
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
diag->Note(DiagMessage()
<< "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
diag->Note(android::DiagMessage() << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
break;
case PNG_COLOR_TYPE_RGB:
diag->Note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
diag->Note(android::DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
diag->Note(DiagMessage()
<< "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA");
diag->Note(android::DiagMessage() << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA");
break;
}
}
@@ -537,7 +532,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr,
// base 9 patch data
if (kDebug) {
diag->Note(DiagMessage() << "adding 9-patch info..");
diag->Note(android::DiagMessage() << "adding 9-patch info..");
}
memcpy((char*)unknowns[pIndex].name, "npTc", 5);
unknowns[pIndex].data = (png_byte*)info->serialize9Patch();
@@ -614,11 +609,10 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr,
&interlaceType, &compressionType, nullptr);
if (kDebug) {
diag->Note(DiagMessage() << "image written: w = " << width
<< ", h = " << height << ", d = " << bitDepth
<< ", colors = " << colorType
<< ", inter = " << interlaceType
<< ", comp = " << compressionType);
diag->Note(android::DiagMessage()
<< "image written: w = " << width << ", h = " << height << ", d = " << bitDepth
<< ", colors = " << colorType << ", inter = " << interlaceType
<< ", comp = " << compressionType);
}
return true;
}
@@ -1232,20 +1226,20 @@ getout:
return true;
}
bool Png::process(const Source& source, std::istream* input,
BigBuffer* outBuffer, const PngOptions& options) {
bool Png::process(const android::Source& source, std::istream* input, android::BigBuffer* outBuffer,
const PngOptions& options) {
TRACE_CALL();
png_byte signature[kPngSignatureSize];
// Read the PNG signature first.
if (!input->read(reinterpret_cast<char*>(signature), kPngSignatureSize)) {
mDiag->Error(DiagMessage() << strerror(errno));
mDiag->Error(android::DiagMessage() << strerror(errno));
return false;
}
// If the PNG signature doesn't match, bail early.
if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
mDiag->Error(DiagMessage() << "not a valid png file");
mDiag->Error(android::DiagMessage() << "not a valid png file");
return false;
}
@@ -1258,13 +1252,13 @@ bool Png::process(const Source& source, std::istream* input,
readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
if (!readPtr) {
mDiag->Error(DiagMessage() << "failed to allocate read ptr");
mDiag->Error(android::DiagMessage() << "failed to allocate read ptr");
goto bail;
}
infoPtr = png_create_info_struct(readPtr);
if (!infoPtr) {
mDiag->Error(DiagMessage() << "failed to allocate info ptr");
mDiag->Error(android::DiagMessage() << "failed to allocate info ptr");
goto bail;
}
@@ -1281,7 +1275,7 @@ bool Png::process(const Source& source, std::istream* input,
if (util::EndsWith(source.path, ".9.png")) {
std::string errorMsg;
if (!do9Patch(&pngInfo, &errorMsg)) {
mDiag->Error(DiagMessage() << errorMsg);
mDiag->Error(android::DiagMessage() << errorMsg);
goto bail;
}
}
@@ -1289,13 +1283,13 @@ bool Png::process(const Source& source, std::istream* input,
writePtr =
png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
if (!writePtr) {
mDiag->Error(DiagMessage() << "failed to allocate write ptr");
mDiag->Error(android::DiagMessage() << "failed to allocate write ptr");
goto bail;
}
writeInfoPtr = png_create_info_struct(writePtr);
if (!writeInfoPtr) {
mDiag->Error(DiagMessage() << "failed to allocate write info ptr");
mDiag->Error(android::DiagMessage() << "failed to allocate write info ptr");
goto bail;
}

View File

@@ -21,13 +21,12 @@
#include <string>
#include "android-base/macros.h"
#include "Diagnostics.h"
#include "Source.h"
#include "androidfw/BigBuffer.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/Source.h"
#include "compile/Image.h"
#include "io/Io.h"
#include "process/IResourceTableConsumer.h"
#include "util/BigBuffer.h"
namespace aapt {
@@ -43,15 +42,16 @@ struct PngOptions {
*/
class Png {
public:
explicit Png(IDiagnostics* diag) : mDiag(diag) {}
explicit Png(android::IDiagnostics* diag) : mDiag(diag) {
}
bool process(const Source& source, std::istream* input, BigBuffer* outBuffer,
bool process(const android::Source& source, std::istream* input, android::BigBuffer* outBuffer,
const PngOptions& options);
private:
DISALLOW_COPY_AND_ASSIGN(Png);
IDiagnostics* mDiag;
android::IDiagnostics* mDiag;
};
/**
@@ -90,7 +90,8 @@ class PngChunkFilter : public io::InputStream {
/**
* Reads a PNG from the InputStream into memory as an RGBA Image.
*/
std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in);
std::unique_ptr<Image> ReadPng(IAaptContext* context, const android::Source& source,
io::InputStream* in);
/**
* Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream

View File

@@ -67,14 +67,14 @@ class PngWriteStructDeleter {
// Custom warning logging method that uses IDiagnostics.
static void LogWarning(png_structp png_ptr, png_const_charp warning_msg) {
IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr);
diag->Warn(DiagMessage() << warning_msg);
android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
diag->Warn(android::DiagMessage() << warning_msg);
}
// Custom error logging method that uses IDiagnostics.
static void LogError(png_structp png_ptr, png_const_charp error_msg) {
IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr);
diag->Error(DiagMessage() << error_msg);
android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
diag->Error(android::DiagMessage() << error_msg);
// Causes libpng to longjmp to the spot where setjmp was set. This is how libpng does
// error handling. If this custom error handler method were to return, libpng would, by
@@ -143,10 +143,11 @@ static void WriteDataToStream(png_structp png_ptr, png_bytep buffer, png_size_t
}
}
std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
std::unique_ptr<Image> ReadPng(IAaptContext* context, const android::Source& source,
io::InputStream* in) {
TRACE_CALL();
// Create a diagnostics that has the source information encoded.
SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
android::SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
// Read the first 8 bytes of the file looking for the PNG signature.
// Bail early if it does not match.
@@ -154,15 +155,16 @@ std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::
size_t buffer_size;
if (!in->Next((const void**)&signature, &buffer_size)) {
if (in->HadError()) {
source_diag.Error(DiagMessage() << "failed to read PNG signature: " << in->GetError());
source_diag.Error(android::DiagMessage()
<< "failed to read PNG signature: " << in->GetError());
} else {
source_diag.Error(DiagMessage() << "not enough data for PNG signature");
source_diag.Error(android::DiagMessage() << "not enough data for PNG signature");
}
return {};
}
if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
source_diag.Error(DiagMessage() << "file signature does not match PNG signature");
source_diag.Error(android::DiagMessage() << "file signature does not match PNG signature");
return {};
}
@@ -174,14 +176,14 @@ std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::
// version of libpng.
png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (read_ptr == nullptr) {
source_diag.Error(DiagMessage() << "failed to create libpng read png_struct");
source_diag.Error(android::DiagMessage() << "failed to create libpng read png_struct");
return {};
}
// Create and initialize the memory for image header and data.
png_infop info_ptr = png_create_info_struct(read_ptr);
if (info_ptr == nullptr) {
source_diag.Error(DiagMessage() << "failed to create libpng read png_info");
source_diag.Error(android::DiagMessage() << "failed to create libpng read png_info");
png_destroy_read_struct(&read_ptr, nullptr, nullptr);
return {};
}
@@ -254,7 +256,7 @@ std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::
// something
// that can always be represented by 9-patch.
if (width > std::numeric_limits<int32_t>::max() || height > std::numeric_limits<int32_t>::max()) {
source_diag.Error(DiagMessage()
source_diag.Error(android::DiagMessage()
<< "PNG image dimensions are too large: " << width << "x" << height);
return {};
}
@@ -490,14 +492,16 @@ bool WritePng(IAaptContext* context, const Image* image,
// version of libpng.
png_structp write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (write_ptr == nullptr) {
context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng write png_struct");
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to create libpng write png_struct");
return false;
}
// Allocate memory to store image header data.
png_infop write_info_ptr = png_create_info_struct(write_ptr);
if (write_info_ptr == nullptr) {
context->GetDiagnostics()->Error(DiagMessage() << "failed to create libpng write png_info");
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to create libpng write png_info");
png_destroy_write_struct(&write_ptr, nullptr);
return false;
}
@@ -575,7 +579,7 @@ bool WritePng(IAaptContext* context, const Image* image,
}
if (context->IsVerbose()) {
DiagMessage msg;
android::DiagMessage msg;
msg << " paletteSize=" << color_palette.size()
<< " alphaPaletteSize=" << alpha_palette.size()
<< " maxGrayDeviation=" << max_gray_deviation
@@ -590,7 +594,7 @@ bool WritePng(IAaptContext* context, const Image* image,
nine_patch != nullptr, color_palette.size(), alpha_palette.size());
if (context->IsVerbose()) {
DiagMessage msg;
android::DiagMessage msg;
msg << "encoding PNG ";
if (nine_patch) {
msg << "(with 9-patch) as ";

View File

@@ -21,6 +21,7 @@
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "androidfw/Util.h"
#include "compile/Pseudolocalizer.h"
#include "util/Util.h"
@@ -53,7 +54,7 @@ inline static bool operator<(const UnifiedSpan& left, const UnifiedSpan& right)
return false;
}
inline static UnifiedSpan SpanToUnifiedSpan(const StringPool::Span& span) {
inline static UnifiedSpan SpanToUnifiedSpan(const android::StringPool::Span& span) {
return UnifiedSpan{*span.name, span.first_char, span.last_char};
}
@@ -111,7 +112,7 @@ static std::vector<UnifiedSpan> MergeSpans(const StyledString& string) {
std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
Pseudolocalizer::Method method,
StringPool* pool) {
android::StringPool* pool) {
Pseudolocalizer localizer(method);
// Collect the spans and untranslatable sections into one set of spans, sorted by first_char.
@@ -121,7 +122,7 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
// All Span indices are UTF-16 based, according to the resources.arsc format expected by the
// runtime. So we will do all our processing in UTF-16, then convert back.
const std::u16string text16 = util::Utf8ToUtf16(string->value->value);
const std::u16string text16 = android::util::Utf8ToUtf16(string->value->value);
// Convenient wrapper around the text that allows us to work with StringPieces.
const StringPiece16 text(text16);
@@ -154,7 +155,7 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
cursor += substr.size();
// Pseudolocalize the substring.
std::string new_substr = util::Utf16ToUtf8(substr);
std::string new_substr = android::util::Utf16ToUtf8(substr);
if (translatable) {
new_substr = localizer.Text(new_substr);
}
@@ -181,7 +182,7 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
cursor += substr.size();
// Pseudolocalize the substring.
std::string new_substr = util::Utf16ToUtf8(substr);
std::string new_substr = android::util::Utf16ToUtf8(substr);
if (translatable) {
new_substr = localizer.Text(new_substr);
}
@@ -199,16 +200,18 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
}
// Finish the pseudolocalization at the end of the string.
new_string += localizer.Text(util::Utf16ToUtf8(text.substr(cursor, text.size() - cursor)));
new_string +=
localizer.Text(android::util::Utf16ToUtf8(text.substr(cursor, text.size() - cursor)));
new_string += localizer.End();
StyleString localized;
android::StyleString localized;
localized.str = std::move(new_string);
// Convert the UnifiedSpans into regular Spans, skipping the UntranslatableSections.
for (UnifiedSpan& span : merged_spans) {
if (span.tag) {
localized.spans.push_back(Span{std::move(span.tag.value()), span.first_char, span.last_char});
localized.spans.push_back(
android::Span{std::move(span.tag.value()), span.first_char, span.last_char});
}
}
return util::make_unique<StyledString>(pool->MakeRef(localized));
@@ -222,8 +225,9 @@ class Visitor : public ValueVisitor {
std::unique_ptr<Value> value;
std::unique_ptr<Item> item;
Visitor(StringPool* pool, Pseudolocalizer::Method method)
: pool_(pool), method_(method), localizer_(method) {}
Visitor(android::StringPool* pool, Pseudolocalizer::Method method)
: pool_(pool), method_(method), localizer_(method) {
}
void Visit(Plural* plural) override {
CloningValueTransformer cloner(pool_);
@@ -284,7 +288,7 @@ class Visitor : public ValueVisitor {
private:
DISALLOW_COPY_AND_ASSIGN(Visitor);
StringPool* pool_;
android::StringPool* pool_;
Pseudolocalizer::Method method_;
Pseudolocalizer localizer_;
};
@@ -313,8 +317,8 @@ ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base,
}
void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
ResourceConfigValue* original_value,
StringPool* pool, ResourceEntry* entry) {
ResourceConfigValue* original_value, android::StringPool* pool,
ResourceEntry* entry) {
Visitor visitor(pool, method);
original_value->value->Accept(&visitor);

View File

@@ -17,14 +17,15 @@
#ifndef AAPT_COMPILE_PSEUDOLOCALEGENERATOR_H
#define AAPT_COMPILE_PSEUDOLOCALEGENERATOR_H
#include "StringPool.h"
#include "androidfw/StringPool.h"
#include "compile/Pseudolocalizer.h"
#include "process/IResourceTableConsumer.h"
namespace aapt {
std::unique_ptr<StyledString> PseudolocalizeStyledString(
StyledString* string, Pseudolocalizer::Method method, StringPool* pool);
std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
Pseudolocalizer::Method method,
android::StringPool* pool);
struct PseudolocaleGenerator : public IResourceTableConsumer {
bool Consume(IAaptContext* context, ResourceTable* table) override;

View File

@@ -24,10 +24,11 @@ using ::android::ConfigDescription;
namespace aapt {
TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
StringPool pool;
StyleString original_style;
android::StringPool pool;
android::StyleString original_style;
original_style.str = "Hello world!";
original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
original_style.spans = {android::Span{"i", 1, 10}, android::Span{"b", 2, 3},
android::Span{"b", 6, 7}};
std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -48,7 +49,7 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
EXPECT_EQ(std::u16string(u"Hello ").size(), new_string->value->spans[2].first_char);
EXPECT_EQ(std::u16string(u"Hello w").size(), new_string->value->spans[2].last_char);
original_style.spans.insert(original_style.spans.begin(), Span{"em", 0, 11u});
original_style.spans.insert(original_style.spans.begin(), android::Span{"em", 0, 11u});
new_string = PseudolocalizeStyledString(
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -71,10 +72,10 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
}
TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentNestedTags) {
StringPool pool;
StyleString original_style;
android::StringPool pool;
android::StyleString original_style;
original_style.str = "bold";
original_style.spans = {Span{"b", 0, 3}, Span{"i", 0, 3}};
original_style.spans = {android::Span{"b", 0, 3}, android::Span{"i", 0, 3}};
std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -93,10 +94,10 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentNestedTags) {
}
TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentTagsUnsorted) {
StringPool pool;
StyleString original_style;
android::StringPool pool;
android::StyleString original_style;
original_style.str = "bold";
original_style.spans = {Span{"i", 2, 3}, Span{"b", 0, 1}};
original_style.spans = {android::Span{"i", 2, 3}, android::Span{"b", 0, 1}};
std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -115,11 +116,11 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentTagsUnsorted) {
}
TEST(PseudolocaleGeneratorTest, PseudolocalizeNestedAndAdjacentTags) {
StringPool pool;
StyleString original_style;
android::StringPool pool;
android::StyleString original_style;
original_style.str = "This sentence is not what you think it is at all.";
original_style.spans = {Span{"b", 16u, 19u}, Span{"em", 29u, 47u}, Span{"i", 38u, 40u},
Span{"b", 44u, 47u}};
original_style.spans = {android::Span{"b", 16u, 19u}, android::Span{"em", 29u, 47u},
android::Span{"i", 38u, 40u}, android::Span{"b", 44u, 47u}};
std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -154,10 +155,10 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeNestedAndAdjacentTags) {
}
TEST(PseudolocaleGeneratorTest, PseudolocalizePartsOfString) {
StringPool pool;
StyleString original_style;
android::StringPool pool;
android::StyleString original_style;
original_style.str = "This should NOT be pseudolocalized.";
original_style.spans = {Span{"em", 4u, 14u}, Span{"i", 18u, 33u}};
original_style.spans = {android::Span{"em", 4u, 14u}, android::Span{"i", 18u, 33u}};
std::unique_ptr<StyledString> original_string =
util::make_unique<StyledString>(pool.MakeRef(original_style));
original_string->untranslatable_sections = {UntranslatableSection{11u, 15u}};
@@ -263,9 +264,10 @@ TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) {
std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
{
StyleString original_style;
android::StyleString original_style;
original_style.str = "Hello world!";
original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
original_style.spans = {android::Span{"i", 1, 10}, android::Span{"b", 2, 3},
android::Span{"b", 6, 7}};
auto styled_string =
util::make_unique<StyledString>(table->string_pool.MakeRef(original_style));

View File

@@ -19,11 +19,10 @@
#include <memory>
#include "ResourceValues.h"
#include "android-base/macros.h"
#include "androidfw/StringPiece.h"
#include "ResourceValues.h"
#include "StringPool.h"
#include "androidfw/StringPool.h"
namespace aapt {

View File

@@ -38,8 +38,9 @@ struct IdCollector : public xml::Visitor {
using xml::Visitor::Visit;
explicit IdCollector(std::vector<SourcedResourceName>* out_symbols,
SourcePathDiagnostics* source_diag) : out_symbols_(out_symbols),
source_diag_(source_diag) {}
android::SourcePathDiagnostics* source_diag)
: out_symbols_(out_symbols), source_diag_(source_diag) {
}
void Visit(xml::Element* element) override {
for (xml::Attribute& attr : element->attributes) {
@@ -48,8 +49,8 @@ struct IdCollector : public xml::Visitor {
if (ResourceUtils::ParseReference(attr.value, &name, &create, nullptr)) {
if (create && name.type.type == ResourceType::kId) {
if (!text::IsValidResourceEntryName(name.entry)) {
source_diag_->Error(DiagMessage(element->line_number)
<< "id '" << name << "' has an invalid entry name");
source_diag_->Error(android::DiagMessage(element->line_number)
<< "id '" << name << "' has an invalid entry name");
} else {
auto iter = std::lower_bound(out_symbols_->begin(),
out_symbols_->end(), name, cmp_name);
@@ -67,7 +68,7 @@ struct IdCollector : public xml::Visitor {
private:
std::vector<SourcedResourceName>* out_symbols_;
SourcePathDiagnostics* source_diag_;
android::SourcePathDiagnostics* source_diag_;
};
} // namespace
@@ -75,7 +76,7 @@ struct IdCollector : public xml::Visitor {
bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) {
TRACE_CALL();
xmlRes->file.exported_symbols.clear();
SourcePathDiagnostics source_diag(xmlRes->file.source, context->GetDiagnostics());
android::SourcePathDiagnostics source_diag(xmlRes->file.source, context->GetDiagnostics());
IdCollector collector(&xmlRes->file.exported_symbols, &source_diag);
xmlRes->root->Accept(&collector);
return !source_diag.HadError();

View File

@@ -23,12 +23,11 @@
#include <string>
#include <utility>
#include "ResourceUtils.h"
#include "android-base/file.h"
#include "android-base/logging.h"
#include "androidfw/ConfigDescription.h"
#include "Diagnostics.h"
#include "ResourceUtils.h"
#include "androidfw/IDiagnostics.h"
#include "configuration/ConfigurationParser.internal.h"
#include "io/File.h"
#include "io/FileSystem.h"
@@ -88,15 +87,10 @@ const std::array<StringPiece, 8> kAbiToStringMap = {
constexpr const char* kAaptXmlNs = "http://schemas.android.com/tools/aapt";
/** A default noop diagnostics context. */
class NoopDiagnostics : public IDiagnostics {
public:
void Log(Level level, DiagMessageActual& actualMsg) override {}
};
NoopDiagnostics noop_;
android::NoOpDiagnostics noop_;
/** Returns the value of the label attribute for a given element. */
std::string GetLabel(const Element* element, IDiagnostics* diag) {
std::string GetLabel(const Element* element, android::IDiagnostics* diag) {
std::string label;
for (const auto& attr : element->attributes) {
if (attr.name == "label") {
@@ -106,18 +100,18 @@ std::string GetLabel(const Element* element, IDiagnostics* diag) {
}
if (label.empty()) {
diag->Error(DiagMessage() << "No label found for element " << element->name);
diag->Error(android::DiagMessage() << "No label found for element " << element->name);
}
return label;
}
/** Returns the value of the version-code-order attribute for a given element. */
std::optional<int32_t> GetVersionCodeOrder(const Element* element, IDiagnostics* diag) {
std::optional<int32_t> GetVersionCodeOrder(const Element* element, android::IDiagnostics* diag) {
const xml::Attribute* version = element->FindAttribute("", "version-code-order");
if (version == nullptr) {
std::string label = GetLabel(element, diag);
diag->Error(DiagMessage() << "No version-code-order found for element '" << element->name
<< "' with label '" << label << "'");
diag->Error(android::DiagMessage() << "No version-code-order found for element '"
<< element->name << "' with label '" << label << "'");
return {};
}
return std::stoi(version->value);
@@ -159,14 +153,14 @@ bool CopyXmlReferences(const std::optional<std::string>& name, const Group<T>& g
* present and the placeholder was.
*/
bool ReplacePlaceholder(const StringPiece& placeholder, const std::optional<StringPiece>& value,
std::string* name, IDiagnostics* diag) {
std::string* name, android::IDiagnostics* diag) {
size_t offset = name->find(placeholder.data());
bool found = (offset != std::string::npos);
// Make sure the placeholder was present if the desired value is present.
if (!found) {
if (value) {
diag->Error(DiagMessage() << "Missing placeholder for artifact: " << placeholder);
diag->Error(android::DiagMessage() << "Missing placeholder for artifact: " << placeholder);
return false;
}
return true;
@@ -176,7 +170,8 @@ bool ReplacePlaceholder(const StringPiece& placeholder, const std::optional<Stri
// Make sure the placeholder was not present if the desired value was not present.
if (!value) {
diag->Error(DiagMessage() << "Placeholder present but no value for artifact: " << placeholder);
diag->Error(android::DiagMessage()
<< "Placeholder present but no value for artifact: " << placeholder);
return false;
}
@@ -184,7 +179,7 @@ bool ReplacePlaceholder(const StringPiece& placeholder, const std::optional<Stri
// Make sure there was only one instance of the placeholder.
if (name->find(placeholder.data()) != std::string::npos) {
diag->Error(DiagMessage() << "Placeholder present multiple times: " << placeholder);
diag->Error(android::DiagMessage() << "Placeholder present multiple times: " << placeholder);
return false;
}
return true;
@@ -195,12 +190,12 @@ bool ReplacePlaceholder(const StringPiece& placeholder, const std::optional<Stri
* element was successfully processed, otherwise returns false.
*/
using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag)>;
xml::Element* element, android::IDiagnostics* diag)>;
/** Binds an ActionHandler to the current configuration being populated. */
xml::XmlNodeAction::ActionFuncWithDiag Bind(configuration::PostProcessingConfiguration* config,
const ActionHandler& handler) {
return [config, handler](xml::Element* root_element, SourcePathDiagnostics* diag) {
return [config, handler](xml::Element* root_element, android::SourcePathDiagnostics* diag) {
return handler(config, root_element, diag);
};
}
@@ -209,10 +204,10 @@ xml::XmlNodeAction::ActionFuncWithDiag Bind(configuration::PostProcessingConfigu
std::optional<OutputArtifact> ToOutputArtifact(const ConfiguredArtifact& artifact,
const std::string& apk_name,
const PostProcessingConfiguration& config,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
if (!artifact.name && !config.artifact_format) {
diag->Error(
DiagMessage() << "Artifact does not have a name and no global name template defined");
diag->Error(android::DiagMessage()
<< "Artifact does not have a name and no global name template defined");
return {};
}
@@ -221,54 +216,54 @@ std::optional<OutputArtifact> ToOutputArtifact(const ConfiguredArtifact& artifac
: artifact.ToArtifactName(config.artifact_format.value(), apk_name, diag);
if (!artifact_name) {
diag->Error(DiagMessage() << "Could not determine split APK artifact name");
diag->Error(android::DiagMessage() << "Could not determine split APK artifact name");
return {};
}
OutputArtifact output_artifact;
output_artifact.name = artifact_name.value();
SourcePathDiagnostics src_diag{{output_artifact.name}, diag};
android::SourcePathDiagnostics src_diag{{output_artifact.name}, diag};
bool has_errors = false;
if (!CopyXmlReferences(artifact.abi_group, config.abi_groups, &output_artifact.abis)) {
src_diag.Error(DiagMessage() << "Could not lookup required ABIs: "
<< artifact.abi_group.value());
src_diag.Error(android::DiagMessage()
<< "Could not lookup required ABIs: " << artifact.abi_group.value());
has_errors = true;
}
if (!CopyXmlReferences(artifact.locale_group, config.locale_groups, &output_artifact.locales)) {
src_diag.Error(DiagMessage() << "Could not lookup required locales: "
<< artifact.locale_group.value());
src_diag.Error(android::DiagMessage()
<< "Could not lookup required locales: " << artifact.locale_group.value());
has_errors = true;
}
if (!CopyXmlReferences(artifact.screen_density_group, config.screen_density_groups,
&output_artifact.screen_densities)) {
src_diag.Error(DiagMessage() << "Could not lookup required screen densities: "
<< artifact.screen_density_group.value());
src_diag.Error(android::DiagMessage() << "Could not lookup required screen densities: "
<< artifact.screen_density_group.value());
has_errors = true;
}
if (!CopyXmlReferences(artifact.device_feature_group, config.device_feature_groups,
&output_artifact.features)) {
src_diag.Error(DiagMessage() << "Could not lookup required device features: "
<< artifact.device_feature_group.value());
src_diag.Error(android::DiagMessage() << "Could not lookup required device features: "
<< artifact.device_feature_group.value());
has_errors = true;
}
if (!CopyXmlReferences(artifact.gl_texture_group, config.gl_texture_groups,
&output_artifact.textures)) {
src_diag.Error(DiagMessage() << "Could not lookup required OpenGL texture formats: "
<< artifact.gl_texture_group.value());
src_diag.Error(android::DiagMessage() << "Could not lookup required OpenGL texture formats: "
<< artifact.gl_texture_group.value());
has_errors = true;
}
if (artifact.android_sdk) {
auto entry = config.android_sdks.find(artifact.android_sdk.value());
if (entry == config.android_sdks.end()) {
src_diag.Error(DiagMessage() << "Could not lookup required Android SDK version: "
<< artifact.android_sdk.value());
src_diag.Error(android::DiagMessage() << "Could not lookup required Android SDK version: "
<< artifact.android_sdk.value());
has_errors = true;
} else {
output_artifact.android_sdk = {entry->second};
@@ -288,9 +283,9 @@ namespace configuration {
/** Returns the binary reprasentation of the XML configuration. */
std::optional<PostProcessingConfiguration> ExtractConfiguration(const std::string& contents,
const std::string& config_path,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
StringInputStream in(contents);
std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, diag, Source(config_path));
std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, diag, android::Source(config_path));
if (!doc) {
return {};
}
@@ -298,14 +293,14 @@ std::optional<PostProcessingConfiguration> ExtractConfiguration(const std::strin
// Strip any namespaces from the XML as the XmlActionExecutor ignores anything with a namespace.
Element* root = doc->root.get();
if (root == nullptr) {
diag->Error(DiagMessage() << "Could not find the root element in the XML document");
diag->Error(android::DiagMessage() << "Could not find the root element in the XML document");
return {};
}
std::string& xml_ns = root->namespace_uri;
if (!xml_ns.empty()) {
if (xml_ns != kAaptXmlNs) {
diag->Error(DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
diag->Error(android::DiagMessage() << "Unknown namespace found on root element: " << xml_ns);
return {};
}
@@ -336,7 +331,7 @@ std::optional<PostProcessingConfiguration> ExtractConfiguration(const std::strin
Bind(&config, DeviceFeatureGroupTagHandler));
if (!executor.Execute(XmlActionExecutorPolicy::kNone, diag, doc.get())) {
diag->Error(DiagMessage() << "Could not process XML document");
diag->Error(android::DiagMessage() << "Could not process XML document");
return {};
}
@@ -351,7 +346,7 @@ const StringPiece& AbiToString(Abi abi) {
* Returns the common artifact base name from a template string.
*/
std::optional<std::string> ToBaseName(std::string result, const StringPiece& apk_name,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
const StringPiece ext = file::GetExtension(apk_name);
size_t end_index = apk_name.to_string().rfind(ext.to_string());
const std::string base_name =
@@ -385,7 +380,7 @@ std::optional<std::string> ToBaseName(std::string result, const StringPiece& apk
std::optional<std::string> ConfiguredArtifact::ToArtifactName(const StringPiece& format,
const StringPiece& apk_name,
IDiagnostics* diag) const {
android::IDiagnostics* diag) const {
std::optional<std::string> base = ToBaseName(format.to_string(), apk_name, diag);
if (!base) {
return {};
@@ -420,7 +415,7 @@ std::optional<std::string> ConfiguredArtifact::ToArtifactName(const StringPiece&
}
std::optional<std::string> ConfiguredArtifact::Name(const StringPiece& apk_name,
IDiagnostics* diag) const {
android::IDiagnostics* diag) const {
if (!name) {
return {};
}
@@ -473,7 +468,7 @@ std::optional<std::vector<OutputArtifact>> ConfigurationParser::Parse(
}
if (!config.ValidateVersionCodeOrdering(diag_)) {
diag_->Error(DiagMessage() << "could not validate post processing configuration");
diag_->Error(android::DiagMessage() << "could not validate post processing configuration");
valid = false;
}
@@ -493,7 +488,7 @@ namespace configuration {
namespace handler {
bool ArtifactTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
ConfiguredArtifact artifact{};
for (const auto& attr : root_element->attributes) {
if (attr.name == "name") {
@@ -511,8 +506,8 @@ bool ArtifactTagHandler(PostProcessingConfiguration* config, Element* root_eleme
} else if (attr.name == "device-feature-group") {
artifact.device_feature_group = {attr.value};
} else {
diag->Note(DiagMessage() << "Unknown artifact attribute: " << attr.name << " = "
<< attr.value);
diag->Note(android::DiagMessage()
<< "Unknown artifact attribute: " << attr.name << " = " << attr.value);
}
}
config->artifacts.push_back(artifact);
@@ -520,7 +515,7 @@ bool ArtifactTagHandler(PostProcessingConfiguration* config, Element* root_eleme
};
bool ArtifactFormatTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* /* diag */) {
android::IDiagnostics* /* diag */) {
for (auto& node : root_element->children) {
xml::Text* t;
if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
@@ -532,7 +527,7 @@ bool ArtifactFormatTagHandler(PostProcessingConfiguration* config, Element* root
};
bool AbiGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -560,7 +555,7 @@ bool AbiGroupTagHandler(PostProcessingConfiguration* config, Element* root_eleme
for (auto* child : root_element->GetChildElements()) {
if (child->name != "abi") {
diag->Error(DiagMessage() << "Unexpected element in ABI group: " << child->name);
diag->Error(android::DiagMessage() << "Unexpected element in ABI group: " << child->name);
valid = false;
} else {
for (auto& node : child->children) {
@@ -570,7 +565,7 @@ bool AbiGroupTagHandler(PostProcessingConfiguration* config, Element* root_eleme
if (abi != kStringToAbiMap.end()) {
group.push_back(abi->second);
} else {
diag->Error(DiagMessage() << "Could not parse ABI value: " << t->text);
diag->Error(android::DiagMessage() << "Could not parse ABI value: " << t->text);
valid = false;
}
break;
@@ -583,7 +578,7 @@ bool AbiGroupTagHandler(PostProcessingConfiguration* config, Element* root_eleme
};
bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -609,9 +604,8 @@ bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element*
// Copy the density with the minimum SDK version stripped out.
group.push_back(config_descriptor.CopyWithoutSdkVersion());
} else {
diag->Error(DiagMessage()
<< "Could not parse config descriptor for empty screen-density-group: "
<< label);
diag->Error(android::DiagMessage()
<< "Could not parse config descriptor for empty screen-density-group: " << label);
valid = false;
}
@@ -620,8 +614,8 @@ bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element*
for (auto* child : root_element->GetChildElements()) {
if (child->name != "screen-density") {
diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
<< child->name);
diag->Error(android::DiagMessage()
<< "Unexpected root_element in screen density group: " << child->name);
valid = false;
} else {
for (auto& node : child->children) {
@@ -636,7 +630,7 @@ bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element*
// Copy the density with the minimum SDK version stripped out.
group.push_back(config_descriptor.CopyWithoutSdkVersion());
} else {
diag->Error(DiagMessage()
diag->Error(android::DiagMessage()
<< "Could not parse config descriptor for screen-density: " << text);
valid = false;
}
@@ -650,7 +644,7 @@ bool ScreenDensityGroupTagHandler(PostProcessingConfiguration* config, Element*
};
bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -676,9 +670,8 @@ bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_el
// Copy the locale with the minimum SDK version stripped out.
group.push_back(config_descriptor.CopyWithoutSdkVersion());
} else {
diag->Error(DiagMessage()
<< "Could not parse config descriptor for empty screen-density-group: "
<< label);
diag->Error(android::DiagMessage()
<< "Could not parse config descriptor for empty screen-density-group: " << label);
valid = false;
}
@@ -687,8 +680,8 @@ bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_el
for (auto* child : root_element->GetChildElements()) {
if (child->name != "locale") {
diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
<< child->name);
diag->Error(android::DiagMessage()
<< "Unexpected root_element in screen density group: " << child->name);
valid = false;
} else {
for (auto& node : child->children) {
@@ -703,7 +696,7 @@ bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_el
// Copy the locale with the minimum SDK version stripped out.
group.push_back(config_descriptor.CopyWithoutSdkVersion());
} else {
diag->Error(DiagMessage()
diag->Error(android::DiagMessage()
<< "Could not parse config descriptor for screen-density: " << text);
valid = false;
}
@@ -717,7 +710,7 @@ bool LocaleGroupTagHandler(PostProcessingConfiguration* config, Element* root_el
};
bool AndroidSdkTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
AndroidSdk entry = AndroidSdk::ForMinSdk(-1);
bool valid = true;
for (const auto& attr : root_element->attributes) {
@@ -746,13 +739,14 @@ bool AndroidSdkTagHandler(PostProcessingConfiguration* config, Element* root_ele
}
if (!valid_attr) {
diag->Error(DiagMessage() << "Invalid attribute: " << attr.name << " = " << attr.value);
diag->Error(android::DiagMessage()
<< "Invalid attribute: " << attr.name << " = " << attr.value);
valid = false;
}
}
if (entry.min_sdk_version == -1) {
diag->Error(DiagMessage() << "android-sdk is missing minSdkVersion attribute");
diag->Error(android::DiagMessage() << "android-sdk is missing minSdkVersion attribute");
valid = false;
}
@@ -760,7 +754,7 @@ bool AndroidSdkTagHandler(PostProcessingConfiguration* config, Element* root_ele
for (auto node : root_element->GetChildElements()) {
if (node->name == "manifest") {
if (entry.manifest) {
diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
diag->Warn(android::DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
continue;
}
entry.manifest = {AndroidManifest()};
@@ -772,7 +766,7 @@ bool AndroidSdkTagHandler(PostProcessingConfiguration* config, Element* root_ele
};
bool GlTextureGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -791,7 +785,8 @@ bool GlTextureGroupTagHandler(PostProcessingConfiguration* config, Element* root
GlTexture result;
for (auto* child : root_element->GetChildElements()) {
if (child->name != "gl-texture") {
diag->Error(DiagMessage() << "Unexpected element in GL texture group: " << child->name);
diag->Error(android::DiagMessage()
<< "Unexpected element in GL texture group: " << child->name);
valid = false;
} else {
for (const auto& attr : child->attributes) {
@@ -803,7 +798,8 @@ bool GlTextureGroupTagHandler(PostProcessingConfiguration* config, Element* root
for (auto* element : child->GetChildElements()) {
if (element->name != "texture-path") {
diag->Error(DiagMessage() << "Unexpected element in gl-texture element: " << child->name);
diag->Error(android::DiagMessage()
<< "Unexpected element in gl-texture element: " << child->name);
valid = false;
continue;
}
@@ -822,7 +818,7 @@ bool GlTextureGroupTagHandler(PostProcessingConfiguration* config, Element* root
};
bool DeviceFeatureGroupTagHandler(PostProcessingConfiguration* config, Element* root_element,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
std::string label = GetLabel(root_element, diag);
if (label.empty()) {
return false;
@@ -840,8 +836,8 @@ bool DeviceFeatureGroupTagHandler(PostProcessingConfiguration* config, Element*
for (auto* child : root_element->GetChildElements()) {
if (child->name != "supports-feature") {
diag->Error(DiagMessage() << "Unexpected root_element in device feature group: "
<< child->name);
diag->Error(android::DiagMessage()
<< "Unexpected root_element in device feature group: " << child->name);
valid = false;
} else {
for (auto& node : child->children) {

View File

@@ -24,8 +24,7 @@
#include <vector>
#include "androidfw/ConfigDescription.h"
#include "Diagnostics.h"
#include "androidfw/IDiagnostics.h"
namespace aapt {
@@ -126,9 +125,6 @@ struct OutputArtifact {
} // namespace configuration
// Forward declaration of classes used in the API.
struct IDiagnostics;
/**
* XML configuration file parser for the split and optimize commands.
*/
@@ -145,7 +141,7 @@ class ConfigurationParser {
}
/** Sets the diagnostics context to use when parsing. */
ConfigurationParser& WithDiagnostics(IDiagnostics* diagnostics) {
ConfigurationParser& WithDiagnostics(android::IDiagnostics* diagnostics) {
diag_ = diagnostics;
return *this;
}
@@ -166,7 +162,7 @@ class ConfigurationParser {
ConfigurationParser(std::string contents, const std::string& config_path);
/** Returns the current diagnostics context to any subclasses. */
IDiagnostics* diagnostics() {
android::IDiagnostics* diagnostics() {
return diag_;
}
@@ -176,7 +172,7 @@ class ConfigurationParser {
/** Path to the input configuration. */
const std::string config_path_;
/** The diagnostics context to send messages to. */
IDiagnostics* diag_;
android::IDiagnostics* diag_;
};
} // namespace aapt

View File

@@ -47,15 +47,16 @@ using Entry = std::unordered_map<std::string, T>;
template <class T>
using Group = Entry<OrderedEntry<T>>;
template<typename T>
bool IsGroupValid(const Group<T>& group, const std::string& name, IDiagnostics* diag) {
template <typename T>
bool IsGroupValid(const Group<T>& group, const std::string& name, android::IDiagnostics* diag) {
std::set<int32_t> orders;
for (const auto& p : group) {
orders.insert(p.second.order);
}
bool valid = orders.size() == group.size();
if (!valid) {
diag->Error(DiagMessage() << name << " have overlapping version-code-order attributes");
diag->Error(android::DiagMessage()
<< name << " have overlapping version-code-order attributes");
}
return valid;
}
@@ -139,10 +140,11 @@ struct ConfiguredArtifact {
/** Convert an artifact name template into a name string based on configuration contents. */
std::optional<std::string> ToArtifactName(const android::StringPiece& format,
const android::StringPiece& apk_name,
IDiagnostics* diag) const;
android::IDiagnostics* diag) const;
/** Convert an artifact name template into a name string based on configuration contents. */
std::optional<std::string> Name(const android::StringPiece& apk_name, IDiagnostics* diag) const;
std::optional<std::string> Name(const android::StringPiece& apk_name,
android::IDiagnostics* diag) const;
};
/** AAPT2 XML configuration file binary representation. */
@@ -157,7 +159,7 @@ struct PostProcessingConfiguration {
Group<GlTexture> gl_texture_groups;
Entry<AndroidSdk> android_sdks;
bool ValidateVersionCodeOrdering(IDiagnostics* diag) {
bool ValidateVersionCodeOrdering(android::IDiagnostics* diag) {
bool valid = IsGroupValid(abi_groups, "abi-groups", diag);
valid &= IsGroupValid(screen_density_groups, "screen-density-groups", diag);
valid &= IsGroupValid(locale_groups, "locale-groups", diag);
@@ -215,41 +217,41 @@ struct PostProcessingConfiguration {
/** Parses the provided XML document returning the post processing configuration. */
std::optional<PostProcessingConfiguration> ExtractConfiguration(const std::string& contents,
const std::string& config_path,
IDiagnostics* diag);
android::IDiagnostics* diag);
namespace handler {
/** Handler for <artifact> tags. */
bool ArtifactTagHandler(configuration::PostProcessingConfiguration* config, xml::Element* element,
IDiagnostics* diag);
android::IDiagnostics* diag);
/** Handler for <artifact-format> tags. */
bool ArtifactFormatTagHandler(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag);
xml::Element* element, android::IDiagnostics* diag);
/** Handler for <abi-group> tags. */
bool AbiGroupTagHandler(configuration::PostProcessingConfiguration* config, xml::Element* element,
IDiagnostics* diag);
android::IDiagnostics* diag);
/** Handler for <screen-density-group> tags. */
bool ScreenDensityGroupTagHandler(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag);
xml::Element* element, android::IDiagnostics* diag);
/** Handler for <locale-group> tags. */
bool LocaleGroupTagHandler(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag);
xml::Element* element, android::IDiagnostics* diag);
/** Handler for <android-sdk> tags. */
bool AndroidSdkTagHandler(configuration::PostProcessingConfiguration* config, xml::Element* element,
IDiagnostics* diag);
android::IDiagnostics* diag);
/** Handler for <gl-texture-group> tags. */
bool GlTextureGroupTagHandler(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag);
xml::Element* element, android::IDiagnostics* diag);
/** Handler for <device-feature-group> tags. */
bool DeviceFeatureGroupTagHandler(configuration::PostProcessingConfiguration* config,
xml::Element* element, IDiagnostics* diag);
xml::Element* element, android::IDiagnostics* diag);
} // namespace handler
} // namespace configuration

View File

@@ -441,7 +441,7 @@ class ManifestExtractor {
return config;
}
bool Extract(IDiagnostics* diag);
bool Extract(android::IDiagnostics* diag);
bool Dump(text::Printer* printer);
bool DumpProto(pb::Badging* out_badging);
@@ -2443,17 +2443,17 @@ static void ToProto(ManifestExtractor::Element* el, pb::Badging* out_badging) {
}
}
bool ManifestExtractor::Extract(IDiagnostics* diag) {
bool ManifestExtractor::Extract(android::IDiagnostics* diag) {
// Load the manifest
doc_ = apk_->LoadXml("AndroidManifest.xml", diag);
if (doc_ == nullptr) {
diag->Error(DiagMessage() << "failed to find AndroidManifest.xml");
diag->Error(android::DiagMessage() << "failed to find AndroidManifest.xml");
return false;
}
xml::Element* element = doc_->root.get();
if (element->name != "manifest") {
diag->Error(DiagMessage() << "manifest does not start with <manifest> tag");
diag->Error(android::DiagMessage() << "manifest does not start with <manifest> tag");
return false;
}
@@ -2993,7 +2993,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Visit(xml::Elemen
}
int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
IDiagnostics* diag) {
android::IDiagnostics* diag) {
ManifestExtractor extractor(apk, options);
if (!extractor.Extract(diag)) {
return 1;
@@ -3001,7 +3001,7 @@ int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* pr
return extractor.Dump(printer) ? 0 : 1;
}
int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, IDiagnostics* diag) {
int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, android::IDiagnostics* diag) {
DumpManifestOptions options{/* include_meta_data= */ true,
/* only_permissions= */ false};
ManifestExtractor extractor(apk, options);

View File

@@ -18,8 +18,8 @@
#define AAPT2_DUMP_MANIFEST_H
#include "ApkInfo.pb.h"
#include "Diagnostics.h"
#include "LoadedApk.h"
#include "androidfw/IDiagnostics.h"
#include "text/Printer.h"
namespace aapt {
@@ -33,11 +33,11 @@ struct DumpManifestOptions {
/** Print information extracted from the manifest of the APK. */
int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
IDiagnostics* diag);
android::IDiagnostics* diag);
/** Extracts badging data from the manifest of the APK and stores it in Badging proto. */
int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, IDiagnostics* diag);
int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, android::IDiagnostics* diag);
} // namespace aapt
#endif // AAPT2_DUMP_MANIFEST_H
#endif // AAPT2_DUMP_MANIFEST_H

View File

@@ -25,9 +25,9 @@
#include "android-base/macros.h"
#include "android-base/utf8.h"
#include "androidfw/StringPiece.h"
#include "ziparchive/zip_writer.h"
#include "util/Files.h"
#include "util/Util.h"
#include "ziparchive/zip_writer.h"
using ::android::StringPiece;
using ::android::base::SystemErrorCodeToString;
@@ -256,21 +256,21 @@ class ZipFileWriter : public IArchiveWriter {
} // namespace
std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(IDiagnostics* diag,
std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(android::IDiagnostics* diag,
const StringPiece& path) {
std::unique_ptr<DirectoryWriter> writer = util::make_unique<DirectoryWriter>();
if (!writer->Open(path)) {
diag->Error(DiagMessage(path) << writer->GetError());
diag->Error(android::DiagMessage(path) << writer->GetError());
return {};
}
return std::move(writer);
}
std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(IDiagnostics* diag,
std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(android::IDiagnostics* diag,
const StringPiece& path) {
std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>();
if (!writer->Open(path)) {
diag->Error(DiagMessage(path) << writer->GetError());
diag->Error(android::DiagMessage(path) << writer->GetError());
return {};
}
return std::move(writer);

View File

@@ -22,12 +22,11 @@
#include <string>
#include <vector>
#include "androidfw/BigBuffer.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/StringPiece.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "Diagnostics.h"
#include "io/Io.h"
#include "util/BigBuffer.h"
#include "util/Files.h"
namespace aapt {
@@ -70,10 +69,10 @@ class IArchiveWriter : public ::google::protobuf::io::CopyingOutputStream {
virtual std::string GetError() const = 0;
};
std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(IDiagnostics* diag,
std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(android::IDiagnostics* diag,
const android::StringPiece& path);
std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(IDiagnostics* diag,
std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(android::IDiagnostics* diag,
const android::StringPiece& path);
} // namespace aapt

View File

@@ -19,14 +19,13 @@
#include <inttypes.h>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "Resources.pb.h"
#include "ResourcesInternal.pb.h"
#include "androidfw/BigBuffer.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "io/Io.h"
#include "io/Util.h"
#include "util/BigBuffer.h"
namespace aapt {

View File

@@ -24,12 +24,12 @@
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "Source.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Source.h"
#include "androidfw/TypeWrappers.h"
#include "format/binary/ResChunkPullParser.h"
#include "util/Util.h"
@@ -50,7 +50,7 @@ static std::u16string strcpy16_dtoh(const char16_t* src, size_t len) {
std::u16string dst;
dst.resize(utf16_len);
for (size_t i = 0; i < utf16_len; i++) {
dst[i] = util::DeviceToHost16(src[i]);
dst[i] = android::util::DeviceToHost16(src[i]);
}
return dst;
}
@@ -87,8 +87,8 @@ class ReferenceIdToNameVisitor : public DescendingValueVisitor {
} // namespace
BinaryResourceParser::BinaryResourceParser(IDiagnostics* diag, ResourceTable* table,
const Source& source, const void* data, size_t len,
io::IFileCollection* files)
const android::Source& source, const void* data,
size_t len, io::IFileCollection* files)
: diag_(diag), table_(table), source_(source), data_(data), data_len_(len), files_(files) {
}
@@ -96,13 +96,13 @@ bool BinaryResourceParser::Parse() {
ResChunkPullParser parser(data_, data_len_);
if (!ResChunkPullParser::IsGoodEvent(parser.Next())) {
diag_->Error(DiagMessage(source_) << "corrupt resources.arsc: " << parser.error());
diag_->Error(android::DiagMessage(source_) << "corrupt resources.arsc: " << parser.error());
return false;
}
if (parser.chunk()->type != android::RES_TABLE_TYPE) {
diag_->Error(DiagMessage(source_) << StringPrintf("unknown chunk of type 0x%02x",
static_cast<int>(parser.chunk()->type)));
diag_->Error(android::DiagMessage(source_) << StringPrintf(
"unknown chunk of type 0x%02x", static_cast<int>(parser.chunk()->type)));
return false;
}
@@ -112,18 +112,18 @@ bool BinaryResourceParser::Parse() {
if (parser.Next() != ResChunkPullParser::Event::kEndDocument) {
if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
diag_->Warn(DiagMessage(source_)
diag_->Warn(android::DiagMessage(source_)
<< "invalid chunk trailing RES_TABLE_TYPE: " << parser.error());
} else {
diag_->Warn(DiagMessage(source_)
diag_->Warn(android::DiagMessage(source_)
<< StringPrintf("unexpected chunk of type 0x%02x trailing RES_TABLE_TYPE",
static_cast<int>(parser.chunk()->type)));
}
}
if (!staged_entries_to_remove_.empty()) {
diag_->Error(DiagMessage(source_) << "didn't find " << staged_entries_to_remove_.size()
<< " original staged resources");
diag_->Error(android::DiagMessage(source_) << "didn't find " << staged_entries_to_remove_.size()
<< " original staged resources");
return false;
}
@@ -134,20 +134,20 @@ bool BinaryResourceParser::Parse() {
bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) {
const ResTable_header* table_header = ConvertTo<ResTable_header>(chunk);
if (!table_header) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_header chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_header chunk");
return false;
}
ResChunkPullParser parser(GetChunkData(&table_header->header),
GetChunkDataLen(&table_header->header));
while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
switch (util::DeviceToHost16(parser.chunk()->type)) {
switch (android::util::DeviceToHost16(parser.chunk()->type)) {
case android::RES_STRING_POOL_TYPE:
if (value_pool_.getError() == NO_INIT) {
status_t err =
value_pool_.setTo(parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
status_t err = value_pool_.setTo(parser.chunk(),
android::util::DeviceToHost32(parser.chunk()->size));
if (err != NO_ERROR) {
diag_->Error(DiagMessage(source_)
diag_->Error(android::DiagMessage(source_)
<< "corrupt string pool in ResTable: " << value_pool_.getError());
return false;
}
@@ -155,7 +155,7 @@ bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) {
// Reserve some space for the strings we are going to add.
table_->string_pool.HintWillAdd(value_pool_.size(), value_pool_.styleCount());
} else {
diag_->Warn(DiagMessage(source_) << "unexpected string pool in ResTable");
diag_->Warn(android::DiagMessage(source_) << "unexpected string pool in ResTable");
}
break;
@@ -166,15 +166,15 @@ bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) {
break;
default:
diag_->Warn(DiagMessage(source_)
diag_->Warn(android::DiagMessage(source_)
<< "unexpected chunk type "
<< static_cast<int>(util::DeviceToHost16(parser.chunk()->type)));
<< static_cast<int>(android::util::DeviceToHost16(parser.chunk()->type)));
break;
}
}
if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
diag_->Error(DiagMessage(source_) << "corrupt resource table: " << parser.error());
diag_->Error(android::DiagMessage(source_) << "corrupt resource table: " << parser.error());
return false;
}
return true;
@@ -185,13 +185,13 @@ bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
const ResTable_package* package_header = ConvertTo<ResTable_package, kMinPackageSize>(chunk);
if (!package_header) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_package chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_package chunk");
return false;
}
uint32_t package_id = util::DeviceToHost32(package_header->id);
uint32_t package_id = android::util::DeviceToHost32(package_header->id);
if (package_id > std::numeric_limits<uint8_t>::max()) {
diag_->Error(DiagMessage(source_) << "package ID is too big (" << package_id << ")");
diag_->Error(android::DiagMessage(source_) << "package ID is too big (" << package_id << ")");
return false;
}
@@ -199,9 +199,10 @@ bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
std::u16string package_name = strcpy16_dtoh((const char16_t*)package_header->name,
arraysize(package_header->name));
ResourceTablePackage* package = table_->FindOrCreatePackage(util::Utf16ToUtf8(package_name));
ResourceTablePackage* package =
table_->FindOrCreatePackage(android::util::Utf16ToUtf8(package_name));
if (!package) {
diag_->Error(DiagMessage(source_)
diag_->Error(android::DiagMessage(source_)
<< "incompatible package '" << package_name << "' with ID " << package_id);
return false;
}
@@ -214,26 +215,28 @@ bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
ResChunkPullParser parser(GetChunkData(&package_header->header),
GetChunkDataLen(&package_header->header));
while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
switch (util::DeviceToHost16(parser.chunk()->type)) {
switch (android::util::DeviceToHost16(parser.chunk()->type)) {
case android::RES_STRING_POOL_TYPE:
if (type_pool_.getError() == NO_INIT) {
status_t err =
type_pool_.setTo(parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
type_pool_.setTo(parser.chunk(), android::util::DeviceToHost32(parser.chunk()->size));
if (err != NO_ERROR) {
diag_->Error(DiagMessage(source_) << "corrupt type string pool in "
<< "ResTable_package: " << type_pool_.getError());
diag_->Error(android::DiagMessage(source_)
<< "corrupt type string pool in "
<< "ResTable_package: " << type_pool_.getError());
return false;
}
} else if (key_pool_.getError() == NO_INIT) {
status_t err =
key_pool_.setTo(parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
key_pool_.setTo(parser.chunk(), android::util::DeviceToHost32(parser.chunk()->size));
if (err != NO_ERROR) {
diag_->Error(DiagMessage(source_) << "corrupt key string pool in "
<< "ResTable_package: " << key_pool_.getError());
diag_->Error(android::DiagMessage(source_)
<< "corrupt key string pool in "
<< "ResTable_package: " << key_pool_.getError());
return false;
}
} else {
diag_->Warn(DiagMessage(source_) << "unexpected string pool");
diag_->Warn(android::DiagMessage(source_) << "unexpected string pool");
}
break;
@@ -268,15 +271,15 @@ bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
break;
default:
diag_->Warn(DiagMessage(source_)
diag_->Warn(android::DiagMessage(source_)
<< "unexpected chunk type "
<< static_cast<int>(util::DeviceToHost16(parser.chunk()->type)));
<< static_cast<int>(android::util::DeviceToHost16(parser.chunk()->type)));
break;
}
}
if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_package: " << parser.error());
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_package: " << parser.error());
return false;
}
@@ -290,18 +293,19 @@ bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) {
bool BinaryResourceParser::ParseTypeSpec(const ResourceTablePackage* package,
const ResChunk_header* chunk, uint8_t package_id) {
if (type_pool_.getError() != NO_ERROR) {
diag_->Error(DiagMessage(source_) << "missing type string pool");
diag_->Error(android::DiagMessage(source_) << "missing type string pool");
return false;
}
const ResTable_typeSpec* type_spec = ConvertTo<ResTable_typeSpec>(chunk);
if (!type_spec) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_typeSpec chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_typeSpec chunk");
return false;
}
if (type_spec->id == 0) {
diag_->Error(DiagMessage(source_) << "ResTable_typeSpec has invalid id: " << type_spec->id);
diag_->Error(android::DiagMessage(source_)
<< "ResTable_typeSpec has invalid id: " << type_spec->id);
return false;
}
@@ -312,25 +316,26 @@ bool BinaryResourceParser::ParseTypeSpec(const ResourceTablePackage* package,
// There can only be 2^16 entries in a type, because that is the ID
// space for entries (EEEE) in the resource ID 0xPPTTEEEE.
if (entry_count > std::numeric_limits<uint16_t>::max()) {
diag_->Error(DiagMessage(source_)
diag_->Error(android::DiagMessage(source_)
<< "ResTable_typeSpec has too many entries (" << entry_count << ")");
return false;
}
const size_t data_size = util::DeviceToHost32(type_spec->header.size) -
util::DeviceToHost16(type_spec->header.headerSize);
const size_t data_size = android::util::DeviceToHost32(type_spec->header.size) -
android::util::DeviceToHost16(type_spec->header.headerSize);
if (entry_count * sizeof(uint32_t) > data_size) {
diag_->Error(DiagMessage(source_) << "ResTable_typeSpec too small to hold entries.");
diag_->Error(android::DiagMessage(source_) << "ResTable_typeSpec too small to hold entries.");
return false;
}
// Record the type_spec_flags for later. We don't know resource names yet, and we need those
// to mark resources as overlayable.
const uint32_t* type_spec_flags = reinterpret_cast<const uint32_t*>(
reinterpret_cast<uintptr_t>(type_spec) + util::DeviceToHost16(type_spec->header.headerSize));
reinterpret_cast<uintptr_t>(type_spec) +
android::util::DeviceToHost16(type_spec->header.headerSize));
for (size_t i = 0; i < entry_count; i++) {
ResourceId id(package_id, type_spec->id, static_cast<size_t>(i));
entry_type_spec_flags_[id] = util::DeviceToHost32(type_spec_flags[i]);
entry_type_spec_flags_[id] = android::util::DeviceToHost32(type_spec_flags[i]);
}
return true;
}
@@ -338,12 +343,12 @@ bool BinaryResourceParser::ParseTypeSpec(const ResourceTablePackage* package,
bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
const ResChunk_header* chunk, uint8_t package_id) {
if (type_pool_.getError() != NO_ERROR) {
diag_->Error(DiagMessage(source_) << "missing type string pool");
diag_->Error(android::DiagMessage(source_) << "missing type string pool");
return false;
}
if (key_pool_.getError() != NO_ERROR) {
diag_->Error(DiagMessage(source_) << "missing key string pool");
diag_->Error(android::DiagMessage(source_) << "missing key string pool");
return false;
}
@@ -351,22 +356,23 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
// a lot and has its own code to handle variable size.
const ResTable_type* type = ConvertTo<ResTable_type, kResTableTypeMinSize>(chunk);
if (!type) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_type chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_type chunk");
return false;
}
if (type->id == 0) {
diag_->Error(DiagMessage(source_) << "ResTable_type has invalid id: " << (int)type->id);
diag_->Error(android::DiagMessage(source_)
<< "ResTable_type has invalid id: " << (int)type->id);
return false;
}
ConfigDescription config;
config.copyFromDtoH(type->config);
const std::string type_str = util::GetString(type_pool_, type->id - 1);
const std::string type_str = android::util::GetString(type_pool_, type->id - 1);
std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(type_str);
if (!parsed_type) {
diag_->Warn(DiagMessage(source_)
diag_->Warn(android::DiagMessage(source_)
<< "invalid type name '" << type_str << "' for type with ID " << type->id);
return true;
}
@@ -378,8 +384,9 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
continue;
}
const ResourceName name(package->name, *parsed_type,
util::GetString(key_pool_, util::DeviceToHost32(entry->key.index)));
const ResourceName name(
package->name, *parsed_type,
android::util::GetString(key_pool_, android::util::DeviceToHost32(entry->key.index)));
const ResourceId res_id(package_id, type->id, static_cast<uint16_t>(it.index()));
std::unique_ptr<Value> resource_value;
@@ -390,13 +397,14 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
resource_value = ParseMapEntry(name, config, mapEntry);
} else {
const Res_value* value =
(const Res_value*)((const uint8_t*)entry + util::DeviceToHost32(entry->size));
(const Res_value*)((const uint8_t*)entry + android::util::DeviceToHost32(entry->size));
resource_value = ParseValue(name, config, *value);
}
if (!resource_value) {
diag_->Error(DiagMessage(source_) << "failed to parse value for resource " << name << " ("
<< res_id << ") with configuration '" << config << "'");
diag_->Error(android::DiagMessage(source_)
<< "failed to parse value for resource " << name << " (" << res_id
<< ") with configuration '" << config << "'");
return false;
}
@@ -450,7 +458,7 @@ bool BinaryResourceParser::ParseLibrary(const ResChunk_header* chunk) {
const size_t count = entries.size();
for (size_t i = 0; i < count; i++) {
table_->included_packages_[entries.valueAt(i)] =
util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).string()));
android::util::Utf16ToUtf8(StringPiece16(entries.keyAt(i).string()));
}
return true;
}
@@ -458,36 +466,39 @@ bool BinaryResourceParser::ParseLibrary(const ResChunk_header* chunk) {
bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) {
const ResTable_overlayable_header* header = ConvertTo<ResTable_overlayable_header>(chunk);
if (!header) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_category_header chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_category_header chunk");
return false;
}
auto overlayable = std::make_shared<Overlayable>();
overlayable->name = util::Utf16ToUtf8(strcpy16_dtoh((const char16_t*)header->name,
arraysize(header->name)));
overlayable->actor = util::Utf16ToUtf8(strcpy16_dtoh((const char16_t*)header->actor,
arraysize(header->name)));
overlayable->name = android::util::Utf16ToUtf8(
strcpy16_dtoh((const char16_t*)header->name, arraysize(header->name)));
overlayable->actor = android::util::Utf16ToUtf8(
strcpy16_dtoh((const char16_t*)header->actor, arraysize(header->name)));
ResChunkPullParser parser(GetChunkData(chunk),
GetChunkDataLen(chunk));
while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
if (util::DeviceToHost16(parser.chunk()->type) == android::RES_TABLE_OVERLAYABLE_POLICY_TYPE) {
if (android::util::DeviceToHost16(parser.chunk()->type) ==
android::RES_TABLE_OVERLAYABLE_POLICY_TYPE) {
const ResTable_overlayable_policy_header* policy_header =
ConvertTo<ResTable_overlayable_policy_header>(parser.chunk());
const ResTable_ref* const ref_begin = reinterpret_cast<const ResTable_ref*>(
((uint8_t *)policy_header) + util::DeviceToHost32(policy_header->header.headerSize));
const ResTable_ref* const ref_end = ref_begin
+ util::DeviceToHost32(policy_header->entry_count);
((uint8_t*)policy_header) +
android::util::DeviceToHost32(policy_header->header.headerSize));
const ResTable_ref* const ref_end =
ref_begin + android::util::DeviceToHost32(policy_header->entry_count);
for (auto ref_iter = ref_begin; ref_iter != ref_end; ++ref_iter) {
ResourceId res_id(util::DeviceToHost32(ref_iter->ident));
ResourceId res_id(android::util::DeviceToHost32(ref_iter->ident));
const auto iter = id_index_.find(res_id);
// If the overlayable chunk comes before the type chunks, the resource ids and resource name
// pairing will not exist at this point.
if (iter == id_index_.cend()) {
diag_->Error(DiagMessage(source_) << "failed to find resource name for overlayable"
<< " resource " << res_id);
diag_->Error(android::DiagMessage(source_)
<< "failed to find resource name for overlayable"
<< " resource " << res_id);
return false;
}
@@ -511,23 +522,23 @@ bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) {
bool BinaryResourceParser::ParseStagedAliases(const ResChunk_header* chunk) {
auto header = ConvertTo<ResTable_staged_alias_header>(chunk);
if (!header) {
diag_->Error(DiagMessage(source_) << "corrupt ResTable_staged_alias_header chunk");
diag_->Error(android::DiagMessage(source_) << "corrupt ResTable_staged_alias_header chunk");
return false;
}
const auto ref_begin = reinterpret_cast<const ResTable_staged_alias_entry*>(
((uint8_t*)header) + util::DeviceToHost32(header->header.headerSize));
const auto ref_end = ref_begin + util::DeviceToHost32(header->count);
((uint8_t*)header) + android::util::DeviceToHost32(header->header.headerSize));
const auto ref_end = ref_begin + android::util::DeviceToHost32(header->count);
for (auto ref_iter = ref_begin; ref_iter != ref_end; ++ref_iter) {
const auto staged_id = ResourceId(util::DeviceToHost32(ref_iter->stagedResId));
const auto finalized_id = ResourceId(util::DeviceToHost32(ref_iter->finalizedResId));
const auto staged_id = ResourceId(android::util::DeviceToHost32(ref_iter->stagedResId));
const auto finalized_id = ResourceId(android::util::DeviceToHost32(ref_iter->finalizedResId));
// If the staged alias chunk comes before the type chunks, the resource ids and resource name
// pairing will not exist at this point.
const auto iter = id_index_.find(finalized_id);
if (iter == id_index_.cend()) {
diag_->Error(DiagMessage(source_) << "failed to find resource name for finalized"
<< " resource ID " << finalized_id);
diag_->Error(android::DiagMessage(source_) << "failed to find resource name for finalized"
<< " resource ID " << finalized_id);
return false;
}
@@ -563,9 +574,9 @@ std::unique_ptr<Item> BinaryResourceParser::ParseValue(const ResourceNameRef& na
if (file_ref != nullptr) {
file_ref->file = files_->FindFile(*file_ref->path);
if (file_ref->file == nullptr) {
diag_->Warn(DiagMessage() << "resource " << name << " for config '" << config
<< "' is a file reference to '" << *file_ref->path
<< "' but no such path exists");
diag_->Warn(android::DiagMessage() << "resource " << name << " for config '" << config
<< "' is a file reference to '" << *file_ref->path
<< "' but no such path exists");
}
}
}
@@ -594,8 +605,8 @@ std::unique_ptr<Value> BinaryResourceParser::ParseMapEntry(const ResourceNameRef
// We can ignore the value here.
return util::make_unique<Id>();
default:
diag_->Error(DiagMessage() << "illegal map type '" << name.type << "' ("
<< (int)name.type.type << ")");
diag_->Error(android::DiagMessage()
<< "illegal map type '" << name.type << "' (" << (int)name.type.type << ")");
break;
}
return {};
@@ -605,18 +616,18 @@ std::unique_ptr<Style> BinaryResourceParser::ParseStyle(const ResourceNameRef& n
const ConfigDescription& config,
const ResTable_map_entry* map) {
std::unique_ptr<Style> style = util::make_unique<Style>();
if (util::DeviceToHost32(map->parent.ident) != 0) {
if (android::util::DeviceToHost32(map->parent.ident) != 0) {
// The parent is a regular reference to a resource.
style->parent = Reference(util::DeviceToHost32(map->parent.ident));
style->parent = Reference(android::util::DeviceToHost32(map->parent.ident));
}
for (const ResTable_map& map_entry : map) {
if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) {
if (Res_INTERNALID(android::util::DeviceToHost32(map_entry.name.ident))) {
continue;
}
Style::Entry style_entry;
style_entry.key = Reference(util::DeviceToHost32(map_entry.name.ident));
style_entry.key = Reference(android::util::DeviceToHost32(map_entry.name.ident));
style_entry.value = ParseValue(name, config, map_entry.value);
if (!style_entry.value) {
return {};
@@ -630,20 +641,20 @@ std::unique_ptr<Attribute> BinaryResourceParser::ParseAttr(const ResourceNameRef
const ConfigDescription& config,
const ResTable_map_entry* map) {
std::unique_ptr<Attribute> attr = util::make_unique<Attribute>();
attr->SetWeak((util::DeviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0);
attr->SetWeak((android::util::DeviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0);
// First we must discover what type of attribute this is. Find the type mask.
auto type_mask_iter = std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool {
return util::DeviceToHost32(entry.name.ident) == ResTable_map::ATTR_TYPE;
return android::util::DeviceToHost32(entry.name.ident) == ResTable_map::ATTR_TYPE;
});
if (type_mask_iter != end(map)) {
attr->type_mask = util::DeviceToHost32(type_mask_iter->value.data);
attr->type_mask = android::util::DeviceToHost32(type_mask_iter->value.data);
}
for (const ResTable_map& map_entry : map) {
if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) {
switch (util::DeviceToHost32(map_entry.name.ident)) {
if (Res_INTERNALID(android::util::DeviceToHost32(map_entry.name.ident))) {
switch (android::util::DeviceToHost32(map_entry.name.ident)) {
case ResTable_map::ATTR_MIN:
attr->min_int = static_cast<int32_t>(map_entry.value.data);
break;
@@ -656,9 +667,9 @@ std::unique_ptr<Attribute> BinaryResourceParser::ParseAttr(const ResourceNameRef
if (attr->type_mask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
Attribute::Symbol symbol;
symbol.value = util::DeviceToHost32(map_entry.value.data);
symbol.value = android::util::DeviceToHost32(map_entry.value.data);
symbol.type = map_entry.value.dataType;
symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident));
symbol.symbol = Reference(android::util::DeviceToHost32(map_entry.name.ident));
attr->symbols.push_back(std::move(symbol));
}
}
@@ -687,7 +698,7 @@ std::unique_ptr<Plural> BinaryResourceParser::ParsePlural(const ResourceNameRef&
return {};
}
switch (util::DeviceToHost32(map_entry.name.ident)) {
switch (android::util::DeviceToHost32(map_entry.name.ident)) {
case ResTable_map::ATTR_ZERO:
plural->values[Plural::Zero] = std::move(item);
break;

View File

@@ -19,13 +19,13 @@
#include <string>
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "Source.h"
#include "androidfw/Source.h"
#include "androidfw/Util.h"
#include "process/IResourceTableConsumer.h"
#include "util/Util.h"
@@ -40,8 +40,9 @@ class BinaryResourceParser {
public:
// Creates a parser, which will read `len` bytes from `data`, and add any resources parsed to
// `table`. `source` is for logging purposes.
BinaryResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
const void* data, size_t data_len, io::IFileCollection* files = nullptr);
BinaryResourceParser(android::IDiagnostics* diag, ResourceTable* table,
const android::Source& source, const void* data, size_t data_len,
io::IFileCollection* files = nullptr);
// Parses the binary resource table and returns true if successful.
bool Parse();
@@ -91,10 +92,10 @@ class BinaryResourceParser {
*/
bool CollectMetaData(const android::ResTable_map& map_entry, Value* value);
IDiagnostics* diag_;
android::IDiagnostics* diag_;
ResourceTable* table_;
const Source source_;
const android::Source source_;
const void* data_;
const size_t data_len_;
@@ -132,11 +133,11 @@ namespace android {
// Iterator functionality for ResTable_map_entry.
inline const ResTable_map* begin(const ResTable_map_entry* map) {
return (const ResTable_map*)((const uint8_t*)map + ::aapt::util::DeviceToHost32(map->size));
return (const ResTable_map*)((const uint8_t*)map + android::util::DeviceToHost32(map->size));
}
inline const ResTable_map* end(const ResTable_map_entry* map) {
return begin(map) + aapt::util::DeviceToHost32(map->count);
return begin(map) + android::util::DeviceToHost32(map->count);
}
} // namespace android

View File

@@ -18,16 +18,15 @@
#define AAPT_FORMAT_BINARY_CHUNKWRITER_H
#include "android-base/macros.h"
#include "androidfw/BigBuffer.h"
#include "androidfw/ResourceTypes.h"
#include "util/BigBuffer.h"
#include "util/Util.h"
namespace aapt {
class ChunkWriter {
public:
explicit inline ChunkWriter(BigBuffer* buffer) : buffer_(buffer) {
explicit inline ChunkWriter(android::BigBuffer* buffer) : buffer_(buffer) {
}
ChunkWriter(ChunkWriter&&) = default;
ChunkWriter& operator=(ChunkWriter&&) = default;
@@ -37,8 +36,8 @@ class ChunkWriter {
start_size_ = buffer_->size();
T* chunk = buffer_->NextBlock<T>();
header_ = &chunk->header;
header_->type = util::HostToDevice16(type);
header_->headerSize = util::HostToDevice16(sizeof(T));
header_->type = android::util::HostToDevice16(type);
header_->headerSize = android::util::HostToDevice16(sizeof(T));
return chunk;
}
@@ -47,7 +46,7 @@ class ChunkWriter {
return buffer_->NextBlock<T>(count);
}
inline BigBuffer* buffer() {
inline android::BigBuffer* buffer() {
return buffer_;
}
@@ -61,14 +60,14 @@ class ChunkWriter {
inline android::ResChunk_header* Finish() {
buffer_->Align4();
header_->size = util::HostToDevice32(buffer_->size() - start_size_);
header_->size = android::util::HostToDevice32(buffer_->size() - start_size_);
return header_;
}
private:
DISALLOW_COPY_AND_ASSIGN(ChunkWriter);
BigBuffer* buffer_;
android::BigBuffer* buffer_;
size_t start_size_ = 0;
android::ResChunk_header* header_ = nullptr;
};
@@ -77,8 +76,8 @@ template <>
inline android::ResChunk_header* ChunkWriter::StartChunk(uint16_t type) {
start_size_ = buffer_->size();
header_ = buffer_->NextBlock<android::ResChunk_header>();
header_->type = util::HostToDevice16(type);
header_->headerSize = util::HostToDevice16(sizeof(android::ResChunk_header));
header_->type = android::util::HostToDevice16(type);
header_->headerSize = android::util::HostToDevice16(sizeof(android::ResChunk_header));
return header_;
}

View File

@@ -17,12 +17,13 @@
#include "format/binary/ResChunkPullParser.h"
#include <inttypes.h>
#include <cstddef>
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
#include "util/Util.h"
namespace aapt {
@@ -32,8 +33,9 @@ using android::base::StringPrintf;
static std::string ChunkHeaderDump(const ResChunk_header* header) {
return StringPrintf("(type=%02" PRIx16 " header_size=%" PRIu16 " size=%" PRIu32 ")",
util::DeviceToHost16(header->type), util::DeviceToHost16(header->headerSize),
util::DeviceToHost32(header->size));
android::util::DeviceToHost16(header->type),
android::util::DeviceToHost16(header->headerSize),
android::util::DeviceToHost32(header->size));
}
ResChunkPullParser::Event ResChunkPullParser::Next() {
@@ -45,7 +47,7 @@ ResChunkPullParser::Event ResChunkPullParser::Next() {
current_chunk_ = data_;
} else {
current_chunk_ = (const ResChunk_header*)(((const char*)current_chunk_) +
util::DeviceToHost32(current_chunk_->size));
android::util::DeviceToHost32(current_chunk_->size));
}
const std::ptrdiff_t diff = (const char*)current_chunk_ - (const char*)data_;
@@ -61,16 +63,16 @@ ResChunkPullParser::Event ResChunkPullParser::Next() {
return (event_ = Event::kBadDocument);
}
if (util::DeviceToHost16(current_chunk_->headerSize) < sizeof(ResChunk_header)) {
if (android::util::DeviceToHost16(current_chunk_->headerSize) < sizeof(ResChunk_header)) {
error_ = "chunk has too small header";
current_chunk_ = nullptr;
return (event_ = Event::kBadDocument);
} else if (util::DeviceToHost32(current_chunk_->size) <
util::DeviceToHost16(current_chunk_->headerSize)) {
} else if (android::util::DeviceToHost32(current_chunk_->size) <
android::util::DeviceToHost16(current_chunk_->headerSize)) {
error_ = "chunk's total size is smaller than header " + ChunkHeaderDump(current_chunk_);
current_chunk_ = nullptr;
return (event_ = Event::kBadDocument);
} else if (offset + util::DeviceToHost32(current_chunk_->size) > len_) {
} else if (offset + android::util::DeviceToHost32(current_chunk_->size) > len_) {
error_ = "chunk's data extends past the end of the document " + ChunkHeaderDump(current_chunk_);
current_chunk_ = nullptr;
return (event_ = Event::kBadDocument);

View File

@@ -21,7 +21,7 @@
#include "android-base/macros.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
#include "util/Util.h"
namespace aapt {
@@ -69,18 +69,19 @@ class ResChunkPullParser {
template <typename T, size_t MinSize = sizeof(T)>
inline static const T* ConvertTo(const android::ResChunk_header* chunk) {
if (util::DeviceToHost16(chunk->headerSize) < MinSize) {
if (android::util::DeviceToHost16(chunk->headerSize) < MinSize) {
return nullptr;
}
return reinterpret_cast<const T*>(chunk);
}
inline static const uint8_t* GetChunkData(const android::ResChunk_header* chunk) {
return reinterpret_cast<const uint8_t*>(chunk) + util::DeviceToHost16(chunk->headerSize);
return reinterpret_cast<const uint8_t*>(chunk) + android::util::DeviceToHost16(chunk->headerSize);
}
inline static uint32_t GetChunkDataLen(const android::ResChunk_header* chunk) {
return util::DeviceToHost32(chunk->size) - util::DeviceToHost16(chunk->headerSize);
return android::util::DeviceToHost32(chunk->size) -
android::util::DeviceToHost16(chunk->headerSize);
}
//

View File

@@ -21,19 +21,18 @@
#include <sstream>
#include <type_traits>
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceUtils.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "SdkConstants.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/BigBuffer.h"
#include "androidfw/ResourceUtils.h"
#include "format/binary/ChunkWriter.h"
#include "format/binary/ResourceTypeExtensions.h"
#include "trace/TraceBuffer.h"
#include "util/BigBuffer.h"
using namespace android;
@@ -54,7 +53,7 @@ static void strcpy16_htod(uint16_t* dst, size_t len, const StringPiece16& src) {
size_t i;
const char16_t* src_data = src.data();
for (i = 0; i < len - 1 && i < src.size(); i++) {
dst[i] = util::HostToDevice16((uint16_t)src_data[i]);
dst[i] = android::util::HostToDevice16((uint16_t)src_data[i]);
}
dst[i] = 0;
}
@@ -116,7 +115,7 @@ class MapFlattenVisitor : public ConstValueVisitor {
if (style->parent) {
const Reference& parent_ref = style->parent.value();
CHECK(bool(parent_ref.id)) << "parent has no ID";
out_entry_->parent.ident = util::HostToDevice32(parent_ref.id.value().id);
out_entry_->parent.ident = android::util::HostToDevice32(parent_ref.id.value().id);
}
// Sort the style.
@@ -195,7 +194,7 @@ class MapFlattenVisitor : public ConstValueVisitor {
* needs to be done to prepare the entry.
*/
void Finish() {
out_entry_->count = util::HostToDevice32(entry_count_);
out_entry_->count = android::util::HostToDevice32(entry_count_);
}
private:
@@ -203,7 +202,7 @@ class MapFlattenVisitor : public ConstValueVisitor {
void FlattenKey(const Reference* key, ResTable_map* out_entry) {
CHECK(bool(key->id)) << "key has no ID";
out_entry->name.ident = util::HostToDevice32(key->id.value().id);
out_entry->name.ident = android::util::HostToDevice32(key->id.value().id);
}
void FlattenValue(const Item* value, ResTable_map* out_entry) {
@@ -214,7 +213,7 @@ class MapFlattenVisitor : public ConstValueVisitor {
ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>();
FlattenKey(key, out_entry);
FlattenValue(value, out_entry);
out_entry->value.size = util::HostToDevice16(sizeof(out_entry->value));
out_entry->value.size = android::util::HostToDevice16(sizeof(out_entry->value));
entry_count_++;
}
@@ -225,7 +224,7 @@ class MapFlattenVisitor : public ConstValueVisitor {
struct OverlayableChunk {
std::string actor;
Source source;
android::Source source;
std::map<PolicyFlags, std::set<ResourceId>> policy_ids;
};
@@ -248,31 +247,33 @@ class PackageFlattener {
TRACE_CALL();
ChunkWriter pkg_writer(buffer);
ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
pkg_header->id = util::HostToDevice32(package_.id.value());
pkg_header->id = android::util::HostToDevice32(package_.id.value());
// AAPT truncated the package name, so do the same.
// Shared libraries require full package names, so don't truncate theirs.
if (context_->GetPackageType() != PackageType::kApp &&
package_.name.size() >= arraysize(pkg_header->name)) {
diag_->Error(DiagMessage() << "package name '" << package_.name
<< "' is too long. "
"Shared libraries cannot have truncated package names");
diag_->Error(android::DiagMessage()
<< "package name '" << package_.name
<< "' is too long. "
"Shared libraries cannot have truncated package names");
return false;
}
// Copy the package name in device endianness.
strcpy16_htod(pkg_header->name, arraysize(pkg_header->name), util::Utf8ToUtf16(package_.name));
strcpy16_htod(pkg_header->name, arraysize(pkg_header->name),
android::util::Utf8ToUtf16(package_.name));
// Serialize the types. We do this now so that our type and key strings
// are populated. We write those first.
BigBuffer type_buffer(1024);
android::BigBuffer type_buffer(1024);
FlattenTypes(&type_buffer);
pkg_header->typeStrings = util::HostToDevice32(pkg_writer.size());
StringPool::FlattenUtf16(pkg_writer.buffer(), type_pool_, diag_);
pkg_header->typeStrings = android::util::HostToDevice32(pkg_writer.size());
android::StringPool::FlattenUtf16(pkg_writer.buffer(), type_pool_, diag_);
pkg_header->keyStrings = util::HostToDevice32(pkg_writer.size());
StringPool::FlattenUtf8(pkg_writer.buffer(), key_pool_, diag_);
pkg_header->keyStrings = android::util::HostToDevice32(pkg_writer.size());
android::StringPool::FlattenUtf8(pkg_writer.buffer(), key_pool_, diag_);
// Append the types.
buffer->AppendBuffer(std::move(type_buffer));
@@ -317,9 +318,9 @@ class PackageFlattener {
out_entry->flags |= ResTable_entry::FLAG_COMPLEX;
}
out_entry->flags = util::HostToDevice16(out_entry->flags);
out_entry->key.index = util::HostToDevice32(entry->entry_key);
out_entry->size = util::HostToDevice16(sizeof(T));
out_entry->flags = android::util::HostToDevice16(out_entry->flags);
out_entry->key.index = android::util::HostToDevice32(entry->entry_key);
out_entry->size = android::util::HostToDevice16(sizeof(T));
return result;
}
@@ -328,7 +329,7 @@ class PackageFlattener {
WriteEntry<ResTable_entry, true>(entry, buffer);
Res_value* outValue = buffer->NextBlock<Res_value>();
CHECK(item->Flatten(outValue)) << "flatten failed";
outValue->size = util::HostToDevice16(sizeof(*outValue));
outValue->size = android::util::HostToDevice16(sizeof(*outValue));
} else {
ResTable_entry_ext* out_entry = WriteEntry<ResTable_entry_ext, false>(entry, buffer);
MapFlattenVisitor visitor(out_entry, buffer);
@@ -353,12 +354,12 @@ class PackageFlattener {
std::vector<uint32_t> offsets;
offsets.resize(num_total_entries, 0xffffffffu);
BigBuffer values_buffer(512);
android::BigBuffer values_buffer(512);
for (FlatEntry& flat_entry : *entries) {
CHECK(static_cast<size_t>(flat_entry.entry->id.value()) < num_total_entries);
offsets[flat_entry.entry->id.value()] = values_buffer.size();
if (!FlattenValue(&flat_entry, &values_buffer)) {
diag_->Error(DiagMessage()
diag_->Error(android::DiagMessage()
<< "failed to flatten resource '"
<< ResourceNameRef(package_.name, type.named_type, flat_entry.entry->name)
<< "' for configuration '" << config << "'");
@@ -382,27 +383,27 @@ class PackageFlattener {
sparse_encode && ((100 * entries->size()) / num_total_entries) < kSparseEncodingThreshold;
if (sparse_encode) {
type_header->entryCount = util::HostToDevice32(entries->size());
type_header->entryCount = android::util::HostToDevice32(entries->size());
type_header->flags |= ResTable_type::FLAG_SPARSE;
ResTable_sparseTypeEntry* indices =
type_writer.NextBlock<ResTable_sparseTypeEntry>(entries->size());
for (size_t i = 0; i < num_total_entries; i++) {
if (offsets[i] != ResTable_type::NO_ENTRY) {
CHECK((offsets[i] & 0x03) == 0);
indices->idx = util::HostToDevice16(i);
indices->offset = util::HostToDevice16(offsets[i] / 4u);
indices->idx = android::util::HostToDevice16(i);
indices->offset = android::util::HostToDevice16(offsets[i] / 4u);
indices++;
}
}
} else {
type_header->entryCount = util::HostToDevice32(num_total_entries);
type_header->entryCount = android::util::HostToDevice32(num_total_entries);
uint32_t* indices = type_writer.NextBlock<uint32_t>(num_total_entries);
for (size_t i = 0; i < num_total_entries; i++) {
indices[i] = util::HostToDevice32(offsets[i]);
indices[i] = android::util::HostToDevice32(offsets[i]);
}
}
type_header->entriesStart = util::HostToDevice32(type_writer.size());
type_header->entriesStart = android::util::HostToDevice32(type_writer.size());
type_writer.buffer()->AppendBuffer(std::move(values_buffer));
type_writer.Finish();
return true;
@@ -416,12 +417,12 @@ class PackageFlattener {
ChunkWriter alias_writer(buffer);
auto header =
alias_writer.StartChunk<ResTable_staged_alias_header>(RES_TABLE_STAGED_ALIAS_TYPE);
header->count = util::HostToDevice32(aliases_.size());
header->count = android::util::HostToDevice32(aliases_.size());
auto mapping = alias_writer.NextBlock<ResTable_staged_alias_entry>(aliases_.size());
for (auto& p : aliases_) {
mapping->stagedResId = util::HostToDevice32(p.first);
mapping->finalizedResId = util::HostToDevice32(p.second);
mapping->stagedResId = android::util::HostToDevice32(p.first);
mapping->finalizedResId = android::util::HostToDevice32(p.second);
++mapping;
}
alias_writer.Finish();
@@ -461,11 +462,11 @@ class PackageFlattener {
OverlayableChunk& chunk = iter->second;
if (!(chunk.source == item.overlayable->source)) {
// The name of an overlayable set of resources must be unique
context_->GetDiagnostics()->Error(DiagMessage(item.overlayable->source)
<< "duplicate overlayable name"
<< item.overlayable->name << "'");
context_->GetDiagnostics()->Error(DiagMessage(chunk.source)
<< "previous declaration here");
context_->GetDiagnostics()->Error(android::DiagMessage(item.overlayable->source)
<< "duplicate overlayable name"
<< item.overlayable->name << "'");
context_->GetDiagnostics()->Error(android::DiagMessage(chunk.source)
<< "previous declaration here");
return false;
}
@@ -474,7 +475,7 @@ class PackageFlattener {
}
if (item.policies == 0) {
context_->GetDiagnostics()->Error(DiagMessage(item.overlayable->source)
context_->GetDiagnostics()->Error(android::DiagMessage(item.overlayable->source)
<< "overlayable " << entry.name
<< " does not specify policy");
return false;
@@ -499,38 +500,36 @@ class PackageFlattener {
auto* overlayable_type =
overlayable_writer.StartChunk<ResTable_overlayable_header>(RES_TABLE_OVERLAYABLE_TYPE);
if (name.size() >= arraysize(overlayable_type->name)) {
diag_->Error(DiagMessage() << "overlayable name '" << name
<< "' exceeds maximum length ("
<< arraysize(overlayable_type->name)
<< " utf16 characters)");
diag_->Error(android::DiagMessage()
<< "overlayable name '" << name << "' exceeds maximum length ("
<< arraysize(overlayable_type->name) << " utf16 characters)");
return false;
}
strcpy16_htod(overlayable_type->name, arraysize(overlayable_type->name),
util::Utf8ToUtf16(name));
android::util::Utf8ToUtf16(name));
if (overlayable.actor.size() >= arraysize(overlayable_type->actor)) {
diag_->Error(DiagMessage() << "overlayable name '" << overlayable.actor
<< "' exceeds maximum length ("
<< arraysize(overlayable_type->actor)
<< " utf16 characters)");
diag_->Error(android::DiagMessage()
<< "overlayable name '" << overlayable.actor << "' exceeds maximum length ("
<< arraysize(overlayable_type->actor) << " utf16 characters)");
return false;
}
strcpy16_htod(overlayable_type->actor, arraysize(overlayable_type->actor),
util::Utf8ToUtf16(overlayable.actor));
android::util::Utf8ToUtf16(overlayable.actor));
// Write each policy block for the overlayable
for (auto& policy_ids : overlayable.policy_ids) {
ChunkWriter policy_writer(buffer);
auto* policy_type = policy_writer.StartChunk<ResTable_overlayable_policy_header>(
RES_TABLE_OVERLAYABLE_POLICY_TYPE);
policy_type->policy_flags =
static_cast<PolicyFlags>(util::HostToDevice32(static_cast<uint32_t>(policy_ids.first)));
policy_type->entry_count = util::HostToDevice32(static_cast<uint32_t>(
policy_ids.second.size()));
policy_type->policy_flags = static_cast<PolicyFlags>(
android::util::HostToDevice32(static_cast<uint32_t>(policy_ids.first)));
policy_type->entry_count =
android::util::HostToDevice32(static_cast<uint32_t>(policy_ids.second.size()));
// Write the ids after the policy header
auto* id_block = policy_writer.NextBlock<ResTable_ref>(policy_ids.second.size());
for (const ResourceId& id : policy_ids.second) {
id_block->ident = util::HostToDevice32(id.id);
id_block->ident = android::util::HostToDevice32(id.id);
id_block++;
}
policy_writer.Finish();
@@ -559,7 +558,7 @@ class PackageFlattener {
// Since the entries are sorted by ID, the last one will be the biggest.
const size_t num_entries = sorted_entries.back().id.value() + 1;
spec_header->entryCount = util::HostToDevice32(num_entries);
spec_header->entryCount = android::util::HostToDevice32(num_entries);
// Reserve space for the masks of each resource in this type. These
// show for which configuration axis the resource changes.
@@ -571,17 +570,18 @@ class PackageFlattener {
// Populate the config masks for this entry.
uint32_t& entry_config_masks = config_masks[entry_id];
if (entry.visibility.level == Visibility::Level::kPublic) {
entry_config_masks |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
entry_config_masks |= android::util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
}
if (entry.visibility.staged_api) {
entry_config_masks |= util::HostToDevice32(ResTable_typeSpec::SPEC_STAGED_API);
entry_config_masks |= android::util::HostToDevice32(ResTable_typeSpec::SPEC_STAGED_API);
}
const size_t config_count = entry.values.size();
for (size_t i = 0; i < config_count; i++) {
const ConfigDescription& config = entry.values[i]->config;
for (size_t j = i + 1; j < config_count; j++) {
config_masks[entry_id] |= util::HostToDevice32(config.diff(entry.values[j]->config));
config_masks[entry_id] |=
android::util::HostToDevice32(config.diff(entry.values[j]->config));
}
}
}
@@ -668,33 +668,33 @@ class PackageFlattener {
const size_t num_entries = (package_.id.value() == 0x00 ? 1 : 0) + shared_libs_->size();
CHECK(num_entries > 0);
lib_header->count = util::HostToDevice32(num_entries);
lib_header->count = android::util::HostToDevice32(num_entries);
ResTable_lib_entry* lib_entry = buffer->NextBlock<ResTable_lib_entry>(num_entries);
if (package_.id.value() == 0x00) {
// Add this package
lib_entry->packageId = util::HostToDevice32(0x00);
lib_entry->packageId = android::util::HostToDevice32(0x00);
strcpy16_htod(lib_entry->packageName, arraysize(lib_entry->packageName),
util::Utf8ToUtf16(package_.name));
android::util::Utf8ToUtf16(package_.name));
++lib_entry;
}
for (auto& map_entry : *shared_libs_) {
lib_entry->packageId = util::HostToDevice32(map_entry.first);
lib_entry->packageId = android::util::HostToDevice32(map_entry.first);
strcpy16_htod(lib_entry->packageName, arraysize(lib_entry->packageName),
util::Utf8ToUtf16(map_entry.second));
android::util::Utf8ToUtf16(map_entry.second));
++lib_entry;
}
lib_writer.Finish();
}
IAaptContext* context_;
IDiagnostics* diag_;
android::IDiagnostics* diag_;
const ResourceTablePackageView package_;
const std::map<size_t, std::string>* shared_libs_;
bool use_sparse_entries_;
StringPool type_pool_;
StringPool key_pool_;
android::StringPool type_pool_;
android::StringPool key_pool_;
bool collapse_key_stringpool_;
const std::set<ResourceName>& name_collapse_exemptions_;
std::map<uint32_t, uint32_t> aliases_;
@@ -706,26 +706,27 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
TRACE_CALL();
// We must do this before writing the resources, since the string pool IDs may change.
table->string_pool.Prune();
table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
int diff = util::compare(a.priority, b.priority);
if (diff == 0) {
diff = a.config.compare(b.config);
}
return diff;
});
table->string_pool.Sort(
[](const android::StringPool::Context& a, const android::StringPool::Context& b) -> int {
int diff = util::compare(a.priority, b.priority);
if (diff == 0) {
diff = a.config.compare(b.config);
}
return diff;
});
// Write the ResTable header.
const auto& table_view =
table->GetPartitionedView(ResourceTableViewOptions{.create_alias_entries = true});
ChunkWriter table_writer(buffer_);
ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE);
table_header->packageCount = util::HostToDevice32(table_view.packages.size());
table_header->packageCount = android::util::HostToDevice32(table_view.packages.size());
// Flatten the values string pool.
StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool,
context->GetDiagnostics());
android::StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool,
context->GetDiagnostics());
BigBuffer package_buffer(1024);
android::BigBuffer package_buffer(1024);
// Flatten each package.
for (auto& package : table_view.packages) {
@@ -738,7 +739,7 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
if (!result.second && result.first->second != package.name) {
// A mapping for this package ID already exists, and is a different package. Error!
context->GetDiagnostics()->Error(
DiagMessage() << android::base::StringPrintf(
android::DiagMessage() << android::base::StringPrintf(
"can't map package ID %02x to '%s'. Already mapped to '%s'", package_id,
package.name.c_str(), result.first->second.c_str()));
return false;

View File

@@ -17,12 +17,11 @@
#ifndef AAPT_FORMAT_BINARY_TABLEFLATTENER_H
#define AAPT_FORMAT_BINARY_TABLEFLATTENER_H
#include "android-base/macros.h"
#include "Resource.h"
#include "ResourceTable.h"
#include "android-base/macros.h"
#include "androidfw/BigBuffer.h"
#include "process/IResourceTableConsumer.h"
#include "util/BigBuffer.h"
namespace aapt {
@@ -51,7 +50,7 @@ struct TableFlattenerOptions {
class TableFlattener : public IResourceTableConsumer {
public:
explicit TableFlattener(const TableFlattenerOptions& options, BigBuffer* buffer)
explicit TableFlattener(const TableFlattenerOptions& options, android::BigBuffer* buffer)
: options_(options), buffer_(buffer) {
}
@@ -61,7 +60,7 @@ class TableFlattener : public IResourceTableConsumer {
DISALLOW_COPY_AND_ASSIGN(TableFlattener);
TableFlattenerOptions options_;
BigBuffer* buffer_;
android::BigBuffer* buffer_;
};
} // namespace aapt

View File

@@ -45,7 +45,7 @@ class TableFlattenerTest : public ::testing::Test {
::testing::AssertionResult Flatten(IAaptContext* context, const TableFlattenerOptions& options,
ResourceTable* table, std::string* out_content) {
BigBuffer buffer(1024);
android::BigBuffer buffer(1024);
TableFlattener flattener(options, &buffer);
if (!flattener.Consume(context, table)) {
return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
@@ -254,13 +254,13 @@ TEST_F(TableFlattenerTest, FlattenArray) {
// Parse the flattened resource table
ResChunkPullParser parser(result.data(), result.size());
ASSERT_TRUE(parser.IsGoodEvent(parser.Next()));
ASSERT_EQ(util::DeviceToHost16(parser.chunk()->type), RES_TABLE_TYPE);
ASSERT_EQ(android::util::DeviceToHost16(parser.chunk()->type), RES_TABLE_TYPE);
// Retrieve the package of the entry
ResChunkPullParser table_parser(GetChunkData(parser.chunk()), GetChunkDataLen(parser.chunk()));
const ResChunk_header* package_chunk = nullptr;
while (table_parser.IsGoodEvent(table_parser.Next())) {
if (util::DeviceToHost16(table_parser.chunk()->type) == RES_TABLE_PACKAGE_TYPE) {
if (android::util::DeviceToHost16(table_parser.chunk()->type) == RES_TABLE_PACKAGE_TYPE) {
package_chunk = table_parser.chunk();
break;
}
@@ -272,7 +272,7 @@ TEST_F(TableFlattenerTest, FlattenArray) {
GetChunkDataLen(table_parser.chunk()));
const ResChunk_header* type_chunk = nullptr;
while (package_parser.IsGoodEvent(package_parser.Next())) {
if (util::DeviceToHost16(package_parser.chunk()->type) == RES_TABLE_TYPE_TYPE) {
if (android::util::DeviceToHost16(package_parser.chunk()->type) == RES_TABLE_TYPE_TYPE) {
type_chunk = package_parser.chunk();
break;
}
@@ -282,7 +282,7 @@ TEST_F(TableFlattenerTest, FlattenArray) {
ASSERT_NE(type_chunk, nullptr);
TypeVariant typeVariant((const ResTable_type*) type_chunk);
auto entry = (const ResTable_map_entry*)*typeVariant.beginEntries();
ASSERT_EQ(util::DeviceToHost16(entry->count), 2u);
ASSERT_EQ(android::util::DeviceToHost16(entry->count), 2u);
// Check that the value and name of the array entries are correct
auto values = (const ResTable_map*)(((const uint8_t *)entry) + entry->size);

View File

@@ -64,11 +64,11 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
public:
using xml::ConstVisitor::Visit;
StringPool pool;
std::map<uint8_t, StringPool> package_pools;
android::StringPool pool;
std::map<uint8_t, android::StringPool> package_pools;
struct StringFlattenDest {
StringPool::Ref ref;
android::StringPool::Ref ref;
ResStringPool_ref* dest;
};
@@ -96,8 +96,8 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
ChunkWriter writer(buffer_);
ResXMLTree_node* flat_node = writer.StartChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
flat_node->lineNumber = util::HostToDevice32(node->line_number);
flat_node->comment.index = util::HostToDevice32(-1);
flat_node->lineNumber = android::util::HostToDevice32(node->line_number);
flat_node->comment.index = android::util::HostToDevice32(-1);
ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>();
AddString(text, kLowPriority, &flat_text->data);
@@ -116,8 +116,8 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
ChunkWriter start_writer(buffer_);
ResXMLTree_node* flat_node =
start_writer.StartChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE);
flat_node->lineNumber = util::HostToDevice32(node->line_number);
flat_node->comment.index = util::HostToDevice32(-1);
flat_node->lineNumber = android::util::HostToDevice32(node->line_number);
flat_node->comment.index = android::util::HostToDevice32(-1);
ResXMLTree_attrExt* flat_elem = start_writer.NextBlock<ResXMLTree_attrExt>();
@@ -126,8 +126,8 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
true /* treat_empty_string_as_null */);
AddString(node->name, kLowPriority, &flat_elem->name, true /* treat_empty_string_as_null */);
flat_elem->attributeStart = util::HostToDevice16(sizeof(*flat_elem));
flat_elem->attributeSize = util::HostToDevice16(sizeof(ResXMLTree_attribute));
flat_elem->attributeStart = android::util::HostToDevice16(sizeof(*flat_elem));
flat_elem->attributeSize = android::util::HostToDevice16(sizeof(ResXMLTree_attribute));
WriteAttributes(node, flat_elem, &start_writer);
@@ -140,8 +140,8 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
ChunkWriter end_writer(buffer_);
ResXMLTree_node* flat_end_node =
end_writer.StartChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE);
flat_end_node->lineNumber = util::HostToDevice32(node->line_number);
flat_end_node->comment.index = util::HostToDevice32(-1);
flat_end_node->lineNumber = android::util::HostToDevice32(node->line_number);
flat_end_node->comment.index = android::util::HostToDevice32(-1);
ResXMLTree_endElementExt* flat_end_elem = end_writer.NextBlock<ResXMLTree_endElementExt>();
AddString(node->namespace_uri, kLowPriority, &flat_end_elem->ns,
@@ -169,17 +169,17 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
bool treat_empty_string_as_null = false) {
if (str.empty() && treat_empty_string_as_null) {
// Some parts of the runtime treat null differently than empty string.
dest->index = util::DeviceToHost32(-1);
dest->index = android::util::DeviceToHost32(-1);
} else {
string_refs.push_back(
StringFlattenDest{pool.MakeRef(str, StringPool::Context(priority)), dest});
StringFlattenDest{pool.MakeRef(str, android::StringPool::Context(priority)), dest});
}
}
// We are adding strings to a StringPool whose strings will be sorted and merged with other
// string pools. That means we can't encode the ID of a string directly. Instead, we defer the
// writing of the ID here, until after the StringPool is merged and sorted.
void AddString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
void AddString(const android::StringPool::Ref& ref, android::ResStringPool_ref* dest) {
string_refs.push_back(StringFlattenDest{ref, dest});
}
@@ -187,8 +187,8 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
ChunkWriter writer(buffer_);
ResXMLTree_node* flatNode = writer.StartChunk<ResXMLTree_node>(type);
flatNode->lineNumber = util::HostToDevice32(decl.line_number);
flatNode->comment.index = util::HostToDevice32(-1);
flatNode->lineNumber = android::util::HostToDevice32(decl.line_number);
flatNode->comment.index = android::util::HostToDevice32(-1);
ResXMLTree_namespaceExt* flat_ns = writer.NextBlock<ResXMLTree_namespaceExt>();
AddString(decl.prefix, kLowPriority, &flat_ns->prefix);
@@ -217,7 +217,7 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
std::sort(filtered_attrs_.begin(), filtered_attrs_.end(), cmp_xml_attribute_by_id);
flat_elem->attributeCount = util::HostToDevice16(filtered_attrs_.size());
flat_elem->attributeCount = android::util::HostToDevice16(filtered_attrs_.size());
ResXMLTree_attribute* flat_attr =
writer->NextBlock<ResXMLTree_attribute>(filtered_attrs_.size());
@@ -226,12 +226,12 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
// Assign the indices for specific attributes.
if (xml_attr->compiled_attribute && xml_attr->compiled_attribute.value().id &&
xml_attr->compiled_attribute.value().id.value() == kIdAttr) {
flat_elem->idIndex = util::HostToDevice16(attribute_index);
flat_elem->idIndex = android::util::HostToDevice16(attribute_index);
} else if (xml_attr->namespace_uri.empty()) {
if (xml_attr->name == "class") {
flat_elem->classIndex = util::HostToDevice16(attribute_index);
flat_elem->classIndex = android::util::HostToDevice16(attribute_index);
} else if (xml_attr->name == "style") {
flat_elem->styleIndex = util::HostToDevice16(attribute_index);
flat_elem->styleIndex = android::util::HostToDevice16(attribute_index);
}
}
attribute_index++;
@@ -241,7 +241,7 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
AddString(xml_attr->namespace_uri, kLowPriority, &flat_attr->ns,
true /* treat_empty_string_as_null */);
flat_attr->rawValue.index = util::HostToDevice32(-1);
flat_attr->rawValue.index = android::util::HostToDevice32(-1);
if (!xml_attr->compiled_attribute || !xml_attr->compiled_attribute.value().id) {
// The attribute has no associated ResourceID, so the string order doesn't matter.
@@ -256,8 +256,9 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
// Lookup the StringPool for this package and make the reference there.
const xml::AaptAttribute& aapt_attr = xml_attr->compiled_attribute.value();
StringPool::Ref name_ref = package_pools[aapt_attr.id.value().package_id()].MakeRef(
xml_attr->name, StringPool::Context(aapt_attr.id.value().id));
android::StringPool::Ref name_ref =
package_pools[aapt_attr.id.value().package_id()].MakeRef(
xml_attr->name, android::StringPool::Context(aapt_attr.id.value().id));
// Add it to the list of strings to flatten.
AddString(name_ref, &flat_attr->name);
@@ -298,7 +299,7 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
AddString(xml_attr->value, kLowPriority, &flat_attr->rawValue);
}
flat_attr->typedValue.size = util::HostToDevice16(sizeof(flat_attr->typedValue));
flat_attr->typedValue.size = android::util::HostToDevice16(sizeof(flat_attr->typedValue));
flat_attr++;
}
}
@@ -313,7 +314,7 @@ class XmlFlattenerVisitor : public xml::ConstVisitor {
} // namespace
bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) {
BigBuffer node_buffer(1024);
android::BigBuffer node_buffer(1024);
XmlFlattenerVisitor visitor(&node_buffer, options_);
node->Accept(&visitor);
@@ -323,13 +324,14 @@ bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) {
}
// Sort the string pool so that attribute resource IDs show up first.
visitor.pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
return util::compare(a.priority, b.priority);
});
visitor.pool.Sort(
[](const android::StringPool::Context& a, const android::StringPool::Context& b) -> int {
return util::compare(a.priority, b.priority);
});
// Now we flatten the string pool references into the correct places.
for (const auto& ref_entry : visitor.string_refs) {
ref_entry.dest->index = util::HostToDevice32(ref_entry.ref.index());
ref_entry.dest->index = android::util::HostToDevice32(ref_entry.ref.index());
}
// Write the XML header.
@@ -338,9 +340,9 @@ bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) {
// Flatten the StringPool.
if (options_.use_utf16) {
StringPool::FlattenUtf16(buffer_, visitor.pool, context->GetDiagnostics());
android::StringPool::FlattenUtf16(buffer_, visitor.pool, context->GetDiagnostics());
} else {
StringPool::FlattenUtf8(buffer_, visitor.pool, context->GetDiagnostics());
android::StringPool::FlattenUtf8(buffer_, visitor.pool, context->GetDiagnostics());
}
{
@@ -353,7 +355,7 @@ bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) {
// When we see the first non-resource ID, we're done.
break;
}
*res_id_map_writer.NextBlock<uint32_t>() = util::HostToDevice32(id.id);
*res_id_map_writer.NextBlock<uint32_t>() = android::util::HostToDevice32(id.id);
}
res_id_map_writer.Finish();
}

View File

@@ -18,9 +18,8 @@
#define AAPT_FORMAT_BINARY_XMLFLATTENER_H
#include "android-base/macros.h"
#include "androidfw/BigBuffer.h"
#include "process/IResourceTableConsumer.h"
#include "util/BigBuffer.h"
#include "xml/XmlDom.h"
namespace aapt {
@@ -36,7 +35,7 @@ struct XmlFlattenerOptions {
class XmlFlattener {
public:
XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options)
XmlFlattener(android::BigBuffer* buffer, XmlFlattenerOptions options)
: buffer_(buffer), options_(options) {
}
@@ -47,7 +46,7 @@ class XmlFlattener {
bool Flatten(IAaptContext* context, const xml::Node* node);
BigBuffer* buffer_;
android::BigBuffer* buffer_;
XmlFlattenerOptions options_;
};

View File

@@ -16,11 +16,10 @@
#include "format/binary/XmlFlattener.h"
#include "androidfw/BigBuffer.h"
#include "androidfw/ResourceTypes.h"
#include "link/Linkers.h"
#include "test/Test.h"
#include "util/BigBuffer.h"
#include "util/Util.h"
using ::aapt::test::StrEq;
@@ -59,13 +58,13 @@ class XmlFlattenerTest : public ::testing::Test {
const XmlFlattenerOptions& options = {}) {
using namespace android; // For NO_ERROR on windows because it is a macro.
BigBuffer buffer(1024);
android::BigBuffer buffer(1024);
XmlFlattener flattener(&buffer, options);
if (!flattener.Consume(context_.get(), doc)) {
return ::testing::AssertionFailure() << "failed to flatten XML Tree";
}
std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
std::unique_ptr<uint8_t[]> data = android::util::Copy(buffer);
if (out_tree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
return ::testing::AssertionFailure() << "flattened XML is corrupt";
}

View File

@@ -16,15 +16,15 @@
#include "format/proto/ProtoDeserialize.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Locale.h"
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "androidfw/Locale.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
using ::android::ConfigDescription;
using ::android::LocaleValue;
@@ -358,8 +358,8 @@ bool DeserializeConfigFromPb(const pb::Configuration& pb_config, ConfigDescripti
}
static void DeserializeSourceFromPb(const pb::Source& pb_source, const ResStringPool& src_pool,
Source* out_source) {
out_source->path = util::GetString(src_pool, pb_source.path_idx());
android::Source* out_source) {
out_source->path = android::util::GetString(src_pool, pb_source.path_idx());
out_source->line = static_cast<size_t>(pb_source.position().line_number());
}
@@ -680,7 +680,7 @@ static bool DeserializeMacroFromPb(const pb::MacroBody& pb_ref, Macro* out_ref,
if (pb_ref.has_style_string()) {
out_ref->style_string.str = pb_ref.style_string().str();
for (const auto& span : pb_ref.style_string().spans()) {
out_ref->style_string.spans.emplace_back(Span{
out_ref->style_string.spans.emplace_back(android::Span{
.name = span.name(), .first_char = span.start_index(), .last_char = span.end_index()});
}
}
@@ -705,7 +705,7 @@ template <typename T>
static void DeserializeItemMetaDataFromPb(const T& pb_item, const android::ResStringPool& src_pool,
Value* out_value) {
if (pb_item.has_source()) {
Source source;
android::Source source;
DeserializeSourceFromPb(pb_item.source(), src_pool, &source);
out_value->SetSource(std::move(source));
}
@@ -733,8 +733,8 @@ static size_t DeserializePluralEnumFromPb(const pb::Plural_Arity& arity) {
std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
const android::ResStringPool& src_pool,
const ConfigDescription& config,
StringPool* value_pool, io::IFileCollection* files,
std::string* out_error) {
android::StringPool* value_pool,
io::IFileCollection* files, std::string* out_error) {
std::unique_ptr<Value> value;
if (pb_value.has_item()) {
value = DeserializeItemFromPb(pb_value.item(), src_pool, config, value_pool, files, out_error);
@@ -774,7 +774,7 @@ std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
}
if (pb_style.has_parent_source()) {
Source parent_source;
android::Source parent_source;
DeserializeSourceFromPb(pb_style.parent_source(), src_pool, &parent_source);
style->parent.value().SetSource(std::move(parent_source));
}
@@ -870,7 +870,8 @@ std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
const android::ResStringPool& src_pool,
const ConfigDescription& config, StringPool* value_pool,
const ConfigDescription& config,
android::StringPool* value_pool,
io::IFileCollection* files, std::string* out_error) {
switch (pb_item.value_case()) {
case pb::Item::kRef: {
@@ -960,29 +961,32 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
case pb::Item::kStr: {
return util::make_unique<String>(
value_pool->MakeRef(pb_item.str().value(), StringPool::Context(config)));
value_pool->MakeRef(pb_item.str().value(), android::StringPool::Context(config)));
} break;
case pb::Item::kRawStr: {
return util::make_unique<RawString>(
value_pool->MakeRef(pb_item.raw_str().value(), StringPool::Context(config)));
value_pool->MakeRef(pb_item.raw_str().value(), android::StringPool::Context(config)));
} break;
case pb::Item::kStyledStr: {
const pb::StyledString& pb_str = pb_item.styled_str();
StyleString style_str{pb_str.value()};
android::StyleString style_str{pb_str.value()};
for (const pb::StyledString::Span& pb_span : pb_str.span()) {
style_str.spans.push_back(Span{pb_span.tag(), pb_span.first_char(), pb_span.last_char()});
style_str.spans.push_back(
android::Span{pb_span.tag(), pb_span.first_char(), pb_span.last_char()});
}
return util::make_unique<StyledString>(value_pool->MakeRef(
style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
style_str,
android::StringPool::Context(android::StringPool::Context::kNormalPriority, config)));
} break;
case pb::Item::kFile: {
const pb::FileReference& pb_file = pb_item.file();
std::unique_ptr<FileReference> file_ref =
util::make_unique<FileReference>(value_pool->MakeRef(
pb_file.path(), StringPool::Context(StringPool::Context::kHighPriority, config)));
pb_file.path(),
android::StringPool::Context(android::StringPool::Context::kHighPriority, config)));
file_ref->type = DeserializeFileReferenceTypeFromPb(pb_file.type());
if (files != nullptr) {
file_ref->file = files->FindFile(*file_ref->path);
@@ -1011,8 +1015,8 @@ std::unique_ptr<xml::XmlResource> DeserializeXmlResourceFromPb(const pb::XmlNode
return resource;
}
bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el, StringPool* value_pool,
std::string* out_error) {
bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el,
android::StringPool* value_pool, std::string* out_error) {
const pb::XmlElement& pb_el = pb_node.element();
out_el->name = pb_el.name();
out_el->namespace_uri = pb_el.namespace_uri();
@@ -1042,7 +1046,7 @@ bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el, Stri
if (attr.compiled_value == nullptr) {
return {};
}
attr.compiled_value->SetSource(Source().WithLine(pb_attr.source().line_number()));
attr.compiled_value->SetSource(android::Source().WithLine(pb_attr.source().line_number()));
}
out_el->attributes.push_back(std::move(attr));
}

View File

@@ -17,16 +17,15 @@
#ifndef AAPT_FORMAT_PROTO_PROTODESERIALIZE_H
#define AAPT_FORMAT_PROTO_PROTODESERIALIZE_H
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "Configuration.pb.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "Resources.pb.h"
#include "ResourcesInternal.pb.h"
#include "StringPool.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPool.h"
#include "io/File.h"
#include "xml/XmlDom.h"
@@ -35,20 +34,20 @@ namespace aapt {
std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
const android::ResStringPool& src_pool,
const android::ConfigDescription& config,
StringPool* value_pool, io::IFileCollection* files,
std::string* out_error);
android::StringPool* value_pool,
io::IFileCollection* files, std::string* out_error);
std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
const android::ResStringPool& src_pool,
const android::ConfigDescription& config,
StringPool* value_pool, io::IFileCollection* files,
std::string* out_error);
android::StringPool* value_pool,
io::IFileCollection* files, std::string* out_error);
std::unique_ptr<xml::XmlResource> DeserializeXmlResourceFromPb(const pb::XmlNode& pb_node,
std::string* out_error);
bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el, StringPool* value_pool,
std::string* out_error);
bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el,
android::StringPool* value_pool, std::string* out_error);
bool DeserializeConfigFromPb(const pb::Configuration& pb_config,
android::ConfigDescription* out_config, std::string* out_error);

View File

@@ -17,7 +17,7 @@
#include "format/proto/ProtoSerialize.h"
#include "ValueVisitor.h"
#include "util/BigBuffer.h"
#include "androidfw/BigBuffer.h"
using android::ConfigDescription;
@@ -25,22 +25,24 @@ using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
namespace aapt {
void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag) {
BigBuffer buffer(1024);
StringPool::FlattenUtf8(&buffer, pool, diag);
void SerializeStringPoolToPb(const android::StringPool& pool, pb::StringPool* out_pb_pool,
android::IDiagnostics* diag) {
android::BigBuffer buffer(1024);
android::StringPool::FlattenUtf8(&buffer, pool, diag);
std::string* data = out_pb_pool->mutable_data();
data->reserve(buffer.size());
size_t offset = 0;
for (const BigBuffer::Block& block : buffer) {
for (const android::BigBuffer::Block& block : buffer) {
data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
offset += block.size;
}
}
void SerializeSourceToPb(const Source& source, StringPool* src_pool, pb::Source* out_pb_source) {
StringPool::Ref ref = src_pool->MakeRef(source.path);
void SerializeSourceToPb(const android::Source& source, android::StringPool* src_pool,
pb::Source* out_pb_source) {
android::StringPool::Ref ref = src_pool->MakeRef(source.path);
out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index()));
if (source.line) {
out_pb_source->mutable_position()->set_line_number(static_cast<uint32_t>(source.line.value()));
@@ -276,7 +278,7 @@ void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_
static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item,
std::vector<Overlayable*>& serialized_overlayables,
StringPool* source_pool, pb::Entry* pb_entry,
android::StringPool* source_pool, pb::Entry* pb_entry,
pb::ResourceTable* pb_table) {
// Retrieve the index of the overlayable in the list of groups that have already been serialized.
size_t i;
@@ -337,8 +339,8 @@ static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item
}
void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table,
IDiagnostics* diag, SerializeTableOptions options) {
auto source_pool = (options.exclude_sources) ? nullptr : util::make_unique<StringPool>();
android::IDiagnostics* diag, SerializeTableOptions options) {
auto source_pool = (options.exclude_sources) ? nullptr : util::make_unique<android::StringPool>();
pb::ToolFingerprint* pb_fingerprint = out_table->add_tool_fingerprint();
pb_fingerprint->set_tool(util::GetToolName());
@@ -482,7 +484,7 @@ static void SerializeMacroToPb(const Macro& ref, pb::MacroBody* pb_macro) {
}
template <typename T>
static void SerializeItemMetaDataToPb(const Item& item, T* pb_item, StringPool* src_pool) {
static void SerializeItemMetaDataToPb(const Item& item, T* pb_item, android::StringPool* src_pool) {
if (src_pool != nullptr) {
SerializeSourceToPb(item.GetSource(), src_pool, pb_item->mutable_source());
}
@@ -526,7 +528,7 @@ class ValueSerializer : public ConstValueVisitor {
public:
using ConstValueVisitor::Visit;
ValueSerializer(pb::Value* out_value, StringPool* src_pool)
ValueSerializer(pb::Value* out_value, android::StringPool* src_pool)
: out_value_(out_value), src_pool_(src_pool) {
}
@@ -545,7 +547,7 @@ class ValueSerializer : public ConstValueVisitor {
void Visit(const StyledString* str) override {
pb::StyledString* pb_str = out_value_->mutable_item()->mutable_styled_str();
pb_str->set_value(str->value->value);
for (const StringPool::Span& span : str->value->spans) {
for (const android::StringPool::Span& span : str->value->spans) {
pb::StyledString::Span* pb_span = pb_str->add_span();
pb_span->set_tag(*span.name);
pb_span->set_first_char(span.first_char);
@@ -693,12 +695,12 @@ class ValueSerializer : public ConstValueVisitor {
private:
pb::Value* out_value_;
StringPool* src_pool_;
android::StringPool* src_pool_;
};
} // namespace
void SerializeValueToPb(const Value& value, pb::Value* out_value, StringPool* src_pool) {
void SerializeValueToPb(const Value& value, pb::Value* out_value, android::StringPool* src_pool) {
ValueSerializer serializer(out_value, src_pool);
value.Accept(&serializer);

View File

@@ -17,15 +17,14 @@
#ifndef AAPT_FORMAT_PROTO_PROTOSERIALIZE_H
#define AAPT_FORMAT_PROTO_PROTOSERIALIZE_H
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "Configuration.pb.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "Resources.pb.h"
#include "ResourcesInternal.pb.h"
#include "StringPool.h"
#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPool.h"
#include "xml/XmlDom.h"
namespace aapt {
@@ -51,7 +50,8 @@ struct SerializeTableOptions {
// Serializes a Value to its protobuf representation. An optional StringPool will hold the
// source path string.
void SerializeValueToPb(const Value& value, pb::Value* out_value, StringPool* src_pool = nullptr);
void SerializeValueToPb(const Value& value, pb::Value* out_value,
android::StringPool* src_pool = nullptr);
// Serialize an Item into its protobuf representation. pb::Item does not store the source path nor
// comments of an Item.
@@ -67,14 +67,15 @@ void SerializeXmlResourceToPb(const xml::XmlResource& resource, pb::XmlNode* out
// Serializes a StringPool into its protobuf representation, which is really just the binary
// ResStringPool representation stuffed into a bytes field.
void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag);
void SerializeStringPoolToPb(const android::StringPool& pool, pb::StringPool* out_pb_pool,
android::IDiagnostics* diag);
// Serializes a ConfigDescription into its protobuf representation.
void SerializeConfig(const android::ConfigDescription& config, pb::Configuration* out_pb_config);
// Serializes a ResourceTable into its protobuf representation.
void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table,
IDiagnostics* diag, SerializeTableOptions options = {});
android::IDiagnostics* diag, SerializeTableOptions options = {});
// Serializes a ResourceFile into its protobuf representation.
void SerializeCompiledFileToPb(const ResourceFile& file, pb::internal::CompiledFile* out_file);

View File

@@ -127,9 +127,9 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
context->GetDiagnostics()));
// Make a styled string.
StyleString style_string;
android::StyleString style_string;
style_string.str = "hello";
style_string.spans.push_back(Span{"b", 0u, 4u});
style_string.spans.push_back(android::Span{"b", 0u, 4u});
ASSERT_TRUE(table->AddResource(
NewResourceBuilder(test::ParseNameOrDie("com.app.a:string/styled"))
.SetValue(util::make_unique<StyledString>(table->string_pool.MakeRef(style_string)))
@@ -164,8 +164,8 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
// Make an overlayable resource.
OverlayableItem overlayable_item(std::make_shared<Overlayable>(
"OverlayableName", "overlay://theme", Source("res/values/overlayable.xml", 40)));
overlayable_item.source = Source("res/values/overlayable.xml", 42);
"OverlayableName", "overlay://theme", android::Source("res/values/overlayable.xml", 40)));
overlayable_item.source = android::Source("res/values/overlayable.xml", 42);
ASSERT_TRUE(
table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.app.a:integer/overlayable"))
.SetOverlayable(overlayable_item)
@@ -271,7 +271,7 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
attr.compiled_attribute = xml::AaptAttribute(Attribute{}, ResourceId(0x01010000));
attr.compiled_value =
ResourceUtils::TryParseItemForAttribute(attr.value, android::ResTable_map::TYPE_DIMENSION);
attr.compiled_value->SetSource(Source().WithLine(25));
attr.compiled_value->SetSource(android::Source().WithLine(25));
element.attributes.push_back(std::move(attr));
std::unique_ptr<xml::Text> text = util::make_unique<xml::Text>();
@@ -292,7 +292,7 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
pb::XmlNode pb_xml;
SerializeXmlToPb(element, &pb_xml);
StringPool pool;
android::StringPool pool;
xml::Element actual_el;
std::string error;
ASSERT_TRUE(DeserializeXmlFromPb(pb_xml, &actual_el, &pool, &error));
@@ -365,7 +365,7 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXmlTrimEmptyWhitepsace) {
options.remove_empty_text_nodes = true;
SerializeXmlToPb(element, &pb_xml, options);
StringPool pool;
android::StringPool pool;
xml::Element actual_el;
std::string error;
ASSERT_TRUE(DeserializeXmlFromPb(pb_xml, &actual_el, &pool, &error));
@@ -898,7 +898,8 @@ TEST(ProtoSerializeTest, SerializeMacro) {
auto original = std::make_unique<Macro>();
original->raw_value = "\nThis being human is a guest house.";
original->style_string.str = " This being human is a guest house.";
original->style_string.spans.emplace_back(Span{.name = "b", .first_char = 12, .last_char = 16});
original->style_string.spans.emplace_back(
android::Span{.name = "b", .first_char = 12, .last_char = 16});
original->untranslatable_sections.emplace_back(UntranslatableSection{.start = 12, .end = 17});
original->alias_namespaces.emplace_back(
Macro::Namespace{.alias = "prefix", .package_name = "package.name", .is_private = true});

View File

@@ -17,15 +17,15 @@
#ifndef AAPT_IO_BIGBUFFERSTREAM_H
#define AAPT_IO_BIGBUFFERSTREAM_H
#include "androidfw/BigBuffer.h"
#include "io/Io.h"
#include "util/BigBuffer.h"
namespace aapt {
namespace io {
class BigBufferInputStream : public KnownSizeInputStream {
public:
inline explicit BigBufferInputStream(const BigBuffer* buffer)
inline explicit BigBufferInputStream(const android::BigBuffer* buffer)
: buffer_(buffer), iter_(buffer->begin()) {
}
virtual ~BigBufferInputStream() = default;
@@ -47,15 +47,15 @@ class BigBufferInputStream : public KnownSizeInputStream {
private:
DISALLOW_COPY_AND_ASSIGN(BigBufferInputStream);
const BigBuffer* buffer_;
BigBuffer::const_iterator iter_;
const android::BigBuffer* buffer_;
android::BigBuffer::const_iterator iter_;
size_t offset_ = 0;
size_t bytes_read_ = 0;
};
class BigBufferOutputStream : public OutputStream {
public:
inline explicit BigBufferOutputStream(BigBuffer* buffer) : buffer_(buffer) {
inline explicit BigBufferOutputStream(android::BigBuffer* buffer) : buffer_(buffer) {
}
virtual ~BigBufferOutputStream() = default;
@@ -70,7 +70,7 @@ class BigBufferOutputStream : public OutputStream {
private:
DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream);
BigBuffer* buffer_;
android::BigBuffer* buffer_;
};
} // namespace io

View File

@@ -22,8 +22,7 @@
#include <vector>
#include "android-base/macros.h"
#include "Source.h"
#include "androidfw/Source.h"
#include "io/Data.h"
#include "util/Files.h"
#include "util/Util.h"
@@ -49,7 +48,7 @@ class IFile {
// Returns the source of this file. This is for presentation to the user and
// may not be a valid file system path (for example, it may contain a '@' sign to separate
// the files within a ZIP archive from the path to the containing ZIP archive.
virtual const Source& GetSource() const = 0;
virtual const android::Source& GetSource() const = 0;
IFile* CreateFileSegment(size_t offset, size_t len);
@@ -76,7 +75,7 @@ class FileSegment : public IFile {
std::unique_ptr<IData> OpenAsData() override;
std::unique_ptr<io::InputStream> OpenInputStream() override;
const Source& GetSource() const override {
const android::Source& GetSource() const override {
return file_->GetSource();
}

View File

@@ -19,13 +19,12 @@
#include <dirent.h>
#include "android-base/errors.h"
#include "androidfw/Source.h"
#include "androidfw/StringPiece.h"
#include "utils/FileMap.h"
#include "Source.h"
#include "io/FileStream.h"
#include "util/Files.h"
#include "util/Util.h"
#include "utils/FileMap.h"
using ::android::StringPiece;
using ::android::base::SystemErrorCodeToString;
@@ -33,7 +32,8 @@ using ::android::base::SystemErrorCodeToString;
namespace aapt {
namespace io {
RegularFile::RegularFile(const Source& source) : source_(source) {}
RegularFile::RegularFile(const android::Source& source) : source_(source) {
}
std::unique_ptr<IData> RegularFile::OpenAsData() {
android::FileMap map;
@@ -50,7 +50,7 @@ std::unique_ptr<io::InputStream> RegularFile::OpenInputStream() {
return util::make_unique<FileInputStream>(source_.path);
}
const Source& RegularFile::GetSource() const {
const android::Source& RegularFile::GetSource() const {
return source_;
}
@@ -118,7 +118,7 @@ std::unique_ptr<FileCollection> FileCollection::Create(const android::StringPiec
}
IFile* FileCollection::InsertFile(const StringPiece& path) {
return (files_[path.to_string()] = util::make_unique<RegularFile>(Source(path))).get();
return (files_[path.to_string()] = util::make_unique<RegularFile>(android::Source(path))).get();
}
IFile* FileCollection::FindFile(const StringPiece& path) {

View File

@@ -27,16 +27,16 @@ namespace io {
// A regular file from the file system. Uses mmap to open the data.
class RegularFile : public IFile {
public:
explicit RegularFile(const Source& source);
explicit RegularFile(const android::Source& source);
std::unique_ptr<IData> OpenAsData() override;
std::unique_ptr<io::InputStream> OpenInputStream() override;
const Source& GetSource() const override;
const android::Source& GetSource() const override;
private:
DISALLOW_COPY_AND_ASSIGN(RegularFile);
Source source_;
android::Source source_;
};
class FileCollection;

View File

@@ -30,12 +30,14 @@ bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, const std:
uint32_t compression_flags, IArchiveWriter* writer) {
TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive");
context->GetDiagnostics()->Note(android::DiagMessage()
<< "writing " << out_path << " to archive");
}
if (!writer->WriteFile(out_path, compression_flags, in)) {
context->GetDiagnostics()->Error(DiagMessage() << "failed to write " << out_path
<< " to archive: " << writer->GetError());
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to write " << out_path
<< " to archive: " << writer->GetError());
return false;
}
return true;
@@ -46,7 +48,8 @@ bool CopyFileToArchive(IAaptContext* context, io::IFile* file, const std::string
TRACE_CALL();
std::unique_ptr<io::IData> data = file->OpenAsData();
if (!data) {
context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file");
context->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
<< "failed to open file");
return false;
}
return CopyInputStreamToArchive(context, data.get(), out_path, compression_flags, writer);
@@ -63,7 +66,8 @@ bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* prot
IArchiveWriter* writer) {
TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive");
context->GetDiagnostics()->Note(android::DiagMessage()
<< "writing " << out_path << " to archive");
}
if (writer->StartEntry(out_path, compression_flags)) {
@@ -72,8 +76,8 @@ bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* prot
// Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
::google::protobuf::io::CopyingOutputStreamAdaptor adaptor(writer);
if (!proto_msg->SerializeToZeroCopyStream(&adaptor)) {
context->GetDiagnostics()->Error(DiagMessage() << "failed to write " << out_path
<< " to archive");
context->GetDiagnostics()->Error(android::DiagMessage()
<< "failed to write " << out_path << " to archive");
return false;
}
}
@@ -82,8 +86,8 @@ bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* prot
return true;
}
}
context->GetDiagnostics()->Error(DiagMessage() << "failed to write " << out_path
<< " to archive: " << writer->GetError());
context->GetDiagnostics()->Error(android::DiagMessage() << "failed to write " << out_path
<< " to archive: " << writer->GetError());
return false;
}

View File

@@ -16,22 +16,21 @@
#include "io/ZipArchive.h"
#include "utils/FileMap.h"
#include "ziparchive/zip_archive.h"
#include "Source.h"
#include "androidfw/Source.h"
#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "util/Util.h"
#include "utils/FileMap.h"
#include "ziparchive/zip_archive.h"
using ::android::StringPiece;
namespace aapt {
namespace io {
ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry,
const Source& source)
: zip_handle_(handle), zip_entry_(entry), source_(source) {}
ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const android::Source& source)
: zip_handle_(handle), zip_entry_(entry), source_(source) {
}
std::unique_ptr<IData> ZipFile::OpenAsData() {
// The file will fail to be mmaped if it is empty
@@ -68,7 +67,7 @@ std::unique_ptr<io::InputStream> ZipFile::OpenInputStream() {
return OpenAsData();
}
const Source& ZipFile::GetSource() const {
const android::Source& ZipFile::GetSource() const {
return source_;
}
@@ -131,8 +130,8 @@ std::unique_ptr<ZipFileCollection> ZipFileCollection::Create(
continue;
}
std::unique_ptr<IFile> file = util::make_unique<ZipFile>(collection->handle_, zip_data,
Source(zip_entry_path, path.to_string()));
std::unique_ptr<IFile> file = util::make_unique<ZipFile>(
collection->handle_, zip_data, android::Source(zip_entry_path, path.to_string()));
collection->files_by_name_[zip_entry_path] = file.get();
collection->files_.push_back(std::move(file));
}

View File

@@ -32,17 +32,17 @@ namespace io {
// and copied into memory when opened. Otherwise it is mmapped from the ZIP archive.
class ZipFile : public IFile {
public:
ZipFile(::ZipArchiveHandle handle, const ::ZipEntry& entry, const Source& source);
ZipFile(::ZipArchiveHandle handle, const ::ZipEntry& entry, const android::Source& source);
std::unique_ptr<IData> OpenAsData() override;
std::unique_ptr<io::InputStream> OpenInputStream() override;
const Source& GetSource() const override;
const android::Source& GetSource() const override;
bool WasCompressed() override;
private:
::ZipArchiveHandle zip_handle_;
::ZipEntry zip_entry_;
Source source_;
android::Source source_;
};
class ZipFileCollection;

View File

@@ -18,7 +18,7 @@
#include <algorithm>
#include "Source.h"
#include "androidfw/Source.h"
#include "java/ClassDefinition.h"
#include "java/JavaClassGenerator.h"
#include "text/Unicode.h"
@@ -28,7 +28,8 @@ using ::aapt::text::IsJavaIdentifier;
namespace aapt {
static std::optional<std::string> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source,
static std::optional<std::string> ExtractJavaIdentifier(android::IDiagnostics* diag,
const android::Source& source,
const std::string& value) {
std::string result = value;
size_t pos = value.rfind('.');
@@ -42,22 +43,22 @@ static std::optional<std::string> ExtractJavaIdentifier(IDiagnostics* diag, cons
}
if (result.empty()) {
diag->Error(DiagMessage(source) << "empty symbol");
diag->Error(android::DiagMessage(source) << "empty symbol");
return {};
}
if (!IsJavaIdentifier(result)) {
diag->Error(DiagMessage(source) << "invalid Java identifier '" << result << "'");
diag->Error(android::DiagMessage(source) << "invalid Java identifier '" << result << "'");
return {};
}
return result;
}
static bool WriteSymbol(const Source& source, IDiagnostics* diag, xml::Element* el,
ClassDefinition* class_def) {
static bool WriteSymbol(const android::Source& source, android::IDiagnostics* diag,
xml::Element* el, ClassDefinition* class_def) {
xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name");
if (!attr) {
diag->Error(DiagMessage(source) << "<" << el->name << "> must define 'android:name'");
diag->Error(android::DiagMessage(source) << "<" << el->name << "> must define 'android:name'");
return false;
}
@@ -72,21 +73,22 @@ static bool WriteSymbol(const Source& source, IDiagnostics* diag, xml::Element*
string_member->GetCommentBuilder()->AppendComment(el->comment);
if (class_def->AddMember(std::move(string_member)) == ClassDefinition::Result::kOverridden) {
diag->Warn(DiagMessage(source.WithLine(el->line_number))
diag->Warn(android::DiagMessage(source.WithLine(el->line_number))
<< "duplicate definitions of '" << result.value() << "', overriding previous");
}
return true;
}
std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, xml::XmlResource* res) {
std::unique_ptr<ClassDefinition> GenerateManifestClass(android::IDiagnostics* diag,
xml::XmlResource* res) {
xml::Element* el = xml::FindRootElement(res->root.get());
if (!el) {
diag->Error(DiagMessage(res->file.source) << "no root tag defined");
diag->Error(android::DiagMessage(res->file.source) << "no root tag defined");
return {};
}
if (el->name != "manifest" && !el->namespace_uri.empty()) {
diag->Error(DiagMessage(res->file.source) << "no <manifest> root tag defined");
diag->Error(android::DiagMessage(res->file.source) << "no <manifest> root tag defined");
return {};
}

View File

@@ -17,13 +17,14 @@
#ifndef AAPT_JAVA_MANIFESTCLASSGENERATOR_H
#define AAPT_JAVA_MANIFESTCLASSGENERATOR_H
#include "Diagnostics.h"
#include "androidfw/IDiagnostics.h"
#include "java/ClassDefinition.h"
#include "xml/XmlDom.h"
namespace aapt {
std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, xml::XmlResource* res);
std::unique_ptr<ClassDefinition> GenerateManifestClass(android::IDiagnostics* diag,
xml::XmlResource* res);
} // namespace aapt

View File

@@ -22,12 +22,11 @@
#include <set>
#include <string>
#include "androidfw/StringPiece.h"
#include "Resource.h"
#include "ResourceTable.h"
#include "Source.h"
#include "ValueVisitor.h"
#include "androidfw/Source.h"
#include "androidfw/StringPiece.h"
#include "io/Io.h"
#include "process/IResourceTableConsumer.h"
#include "xml/XmlDom.h"
@@ -37,7 +36,7 @@ namespace proguard {
struct UsageLocation {
ResourceName name;
Source source;
android::Source source;
};
struct NameAndSignature {

View File

@@ -101,9 +101,10 @@ class ProductFilter : public IResourceTableConsumer {
explicit ProductFilter(std::unordered_set<std::string> products) : products_(products) {
}
ResourceConfigValueIter SelectProductToKeep(
const ResourceNameRef& name, const ResourceConfigValueIter begin,
const ResourceConfigValueIter end, IDiagnostics* diag);
ResourceConfigValueIter SelectProductToKeep(const ResourceNameRef& name,
const ResourceConfigValueIter begin,
const ResourceConfigValueIter end,
android::IDiagnostics* diag);
bool Consume(IAaptContext* context, ResourceTable* table) override;

Some files were not shown because too many files have changed in this diff Show More