summaryrefslogtreecommitdiffstats
path: root/tools/aapt2/ResourceValues.cpp
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2014-11-14 14:48:12 -0800
committerAdam Lesinski <adamlesinski@google.com>2015-04-02 17:02:48 -0700
commit6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb (patch)
tree0a1f8e354c4714f162f849b09a5d5da757c6d5b8 /tools/aapt2/ResourceValues.cpp
parent041ca26d028ae314d416cb107721ea7267af6aca (diff)
downloadframeworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.zip
frameworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.tar.gz
frameworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.tar.bz2
AAPT2
First checking of AAPT2. The individual phases of AAPT2 work, but there are some missing pieces. For early testing we are missing: - Need to properly mark file references and include them in package - Need to package into zip Final AAPT for apps we are missing: - Need to crush PNGs - Need to parse 9-patches - Need to validate all of AndroidManifest.xml - Need to write align method to align resource tables for splits. Final AAPT for apps + system we are missing: - Need to handle overlays - Need to store comments for R file - Need to handle --shared-lib (dynamic references too). New AAPT features coming: - Need to import compiled libraries - Name mangling - R file generation for library code Change-Id: I95f8a63581b81a1f424ae6fb2c373c883b72c18d
Diffstat (limited to 'tools/aapt2/ResourceValues.cpp')
-rw-r--r--tools/aapt2/ResourceValues.cpp447
1 files changed, 447 insertions, 0 deletions
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
new file mode 100644
index 0000000..60ef1a8
--- /dev/null
+++ b/tools/aapt2/ResourceValues.cpp
@@ -0,0 +1,447 @@
+/*
+ * 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.
+ */
+
+#include "Resource.h"
+#include "ResourceTypeExtensions.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <limits>
+
+namespace aapt {
+
+bool Value::isItem() const {
+ return false;
+}
+
+bool Value::isWeak() const {
+ return false;
+}
+
+bool Item::isItem() const {
+ return true;
+}
+
+RawString::RawString(const StringPool::Ref& ref) : value(ref) {
+}
+
+RawString* RawString::clone() const {
+ return new RawString(value);
+}
+
+bool RawString::flatten(android::Res_value& outValue) const {
+ outValue.dataType = ExtendedTypes::TYPE_RAW_STRING;
+ outValue.data = static_cast<uint32_t>(value.getIndex());
+ return true;
+}
+
+void RawString::print(std::ostream& out) const {
+ out << "(raw string) " << *value;
+}
+
+Reference::Reference() : referenceType(Reference::Type::kResource) {
+}
+
+Reference::Reference(const ResourceNameRef& n, Type t) :
+ name(n.toResourceName()), referenceType(t) {
+}
+
+Reference::Reference(const ResourceId& i, Type type) : id(i), referenceType(type) {
+}
+
+bool Reference::flatten(android::Res_value& outValue) const {
+ outValue.dataType = (referenceType == Reference::Type::kResource)
+ ? android::Res_value::TYPE_REFERENCE
+ : android::Res_value::TYPE_ATTRIBUTE;
+ outValue.data = id.id;
+ return true;
+}
+
+Reference* Reference::clone() const {
+ Reference* ref = new Reference();
+ ref->referenceType = referenceType;
+ ref->name = name;
+ ref->id = id;
+ return ref;
+}
+
+void Reference::print(std::ostream& out) const {
+ out << "(reference) ";
+ if (referenceType == Reference::Type::kResource) {
+ out << "@";
+ } else {
+ out << "?";
+ }
+
+ if (name.isValid()) {
+ out << name;
+ }
+
+ if (id.isValid() || Res_INTERNALID(id.id)) {
+ out << " " << id;
+ }
+}
+
+bool Id::isWeak() const {
+ return true;
+}
+
+bool Id::flatten(android::Res_value& out) const {
+ out.dataType = android::Res_value::TYPE_NULL;
+ out.data = android::Res_value::DATA_NULL_UNDEFINED;
+ return true;
+}
+
+Id* Id::clone() const {
+ return new Id();
+}
+
+void Id::print(std::ostream& out) const {
+ out << "(id)";
+}
+
+String::String(const StringPool::Ref& ref) : value(ref) {
+}
+
+bool String::flatten(android::Res_value& outValue) const {
+ // Verify that our StringPool index is within encodeable limits.
+ if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+ return false;
+ }
+
+ outValue.dataType = android::Res_value::TYPE_STRING;
+ outValue.data = static_cast<uint32_t>(value.getIndex());
+ return true;
+}
+
+String* String::clone() const {
+ return new String(value);
+}
+
+void String::print(std::ostream& out) const {
+ out << "(string) \"" << *value << "\"";
+}
+
+StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {
+}
+
+bool StyledString::flatten(android::Res_value& outValue) const {
+ if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+ return false;
+ }
+
+ outValue.dataType = android::Res_value::TYPE_STRING;
+ outValue.data = static_cast<uint32_t>(value.getIndex());
+ return true;
+}
+
+StyledString* StyledString::clone() const {
+ return new StyledString(value);
+}
+
+void StyledString::print(std::ostream& out) const {
+ out << "(styled string) \"" << *value->str << "\"";
+}
+
+FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {
+}
+
+bool FileReference::flatten(android::Res_value& outValue) const {
+ if (path.getIndex() > std::numeric_limits<uint32_t>::max()) {
+ return false;
+ }
+
+ outValue.dataType = android::Res_value::TYPE_STRING;
+ outValue.data = static_cast<uint32_t>(path.getIndex());
+ return true;
+}
+
+FileReference* FileReference::clone() const {
+ return new FileReference(path);
+}
+
+void FileReference::print(std::ostream& out) const {
+ out << "(file) " << *path;
+}
+
+BinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {
+}
+
+bool BinaryPrimitive::flatten(android::Res_value& outValue) const {
+ outValue = value;
+ return true;
+}
+
+BinaryPrimitive* BinaryPrimitive::clone() const {
+ return new BinaryPrimitive(value);
+}
+
+void BinaryPrimitive::print(std::ostream& out) const {
+ switch (value.dataType) {
+ case android::Res_value::TYPE_NULL:
+ out << "(null)";
+ break;
+ case android::Res_value::TYPE_INT_DEC:
+ out << "(integer) " << value.data;
+ break;
+ case android::Res_value::TYPE_INT_HEX:
+ out << "(integer) " << std::hex << value.data << std::dec;
+ break;
+ case android::Res_value::TYPE_INT_BOOLEAN:
+ out << "(boolean) " << (value.data != 0 ? "true" : "false");
+ break;
+ case android::Res_value::TYPE_INT_COLOR_ARGB8:
+ case android::Res_value::TYPE_INT_COLOR_RGB8:
+ case android::Res_value::TYPE_INT_COLOR_ARGB4:
+ case android::Res_value::TYPE_INT_COLOR_RGB4:
+ out << "(color) #" << std::hex << value.data << std::dec;
+ break;
+ default:
+ out << "(unknown 0x" << std::hex << (int) value.dataType << ") 0x"
+ << std::hex << value.data << std::dec;
+ break;
+ }
+}
+
+bool Sentinel::isWeak() const {
+ return true;
+}
+
+bool Sentinel::flatten(android::Res_value& outValue) const {
+ outValue.dataType = ExtendedTypes::TYPE_SENTINEL;
+ outValue.data = 0;
+ return true;
+}
+
+Sentinel* Sentinel::clone() const {
+ return new Sentinel();
+}
+
+void Sentinel::print(std::ostream& out) const {
+ out << "(sentinel)";
+ return;
+}
+
+Attribute::Attribute(bool w, uint32_t t) : weak(w), typeMask(t) {
+}
+
+bool Attribute::isWeak() const {
+ return weak;
+}
+
+Attribute* Attribute::clone() const {
+ Attribute* attr = new Attribute(weak);
+ attr->typeMask = typeMask;
+ std::copy(symbols.begin(), symbols.end(), std::back_inserter(attr->symbols));
+ return attr;
+}
+
+void Attribute::print(std::ostream& out) const {
+ out << "(attr)";
+ if (typeMask == android::ResTable_map::TYPE_ANY) {
+ out << " any";
+ return;
+ }
+
+ bool set = false;
+ if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "reference";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "string";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "integer";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "boolean";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "color";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "float";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "dimension";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "fraction";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "enum";
+ }
+
+ if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) {
+ if (!set) {
+ out << " ";
+ set = true;
+ } else {
+ out << "|";
+ }
+ out << "flags";
+ }
+
+ out << " ["
+ << util::joiner(symbols.begin(), symbols.end(), ", ")
+ << "]";
+
+ if (weak) {
+ out << " [weak]";
+ }
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
+ return out << s.symbol.name.entry << "=" << s.value;
+}
+
+Style* Style::clone() const {
+ Style* style = new Style();
+ style->parent = parent;
+ for (auto& entry : entries) {
+ style->entries.push_back(Entry{
+ entry.key,
+ std::unique_ptr<Item>(entry.value->clone())
+ });
+ }
+ return style;
+}
+
+void Style::print(std::ostream& out) const {
+ out << "(style) ";
+ if (!parent.name.entry.empty()) {
+ out << parent.name;
+ }
+ out << " ["
+ << util::joiner(entries.begin(), entries.end(), ", ")
+ << "]";
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) {
+ out << value.key.name << " = ";
+ value.value->print(out);
+ return out;
+}
+
+Array* Array::clone() const {
+ Array* array = new Array();
+ for (auto& item : items) {
+ array->items.emplace_back(std::unique_ptr<Item>(item->clone()));
+ }
+ return array;
+}
+
+void Array::print(std::ostream& out) const {
+ out << "(array) ["
+ << util::joiner(items.begin(), items.end(), ", ")
+ << "]";
+}
+
+Plural* Plural::clone() const {
+ Plural* p = new Plural();
+ const size_t count = values.size();
+ for (size_t i = 0; i < count; i++) {
+ if (values[i]) {
+ p->values[i] = std::unique_ptr<Item>(values[i]->clone());
+ }
+ }
+ return p;
+}
+
+void Plural::print(std::ostream& out) const {
+ out << "(plural)";
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const std::unique_ptr<Item>& item) {
+ return out << *item;
+}
+
+Styleable* Styleable::clone() const {
+ Styleable* styleable = new Styleable();
+ std::copy(entries.begin(), entries.end(), std::back_inserter(styleable->entries));
+ return styleable;
+}
+
+void Styleable::print(std::ostream& out) const {
+ out << "(styleable) " << " ["
+ << util::joiner(entries.begin(), entries.end(), ", ")
+ << "]";
+}
+
+} // namespace aapt