Adam Lesinski 5924d8c9ab AAPT2: Allow merging of Style attributes from overlays
Previously style overlays would completely override an existing style.
To be compatible with AAPT, styles now merge with the overlay, allowing
the overlay's attributes and parent to take precedence.

Bug: 38355988
Test: make aapt2_tests
Change-Id: Id25c7240050a43e6a4a177c6e3d51e048d0cceb5
2017-05-31 10:09:06 -07:00

219 lines
7.2 KiB
C++

/*
* 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 AAPT_RESOURCEUTILS_H
#define AAPT_RESOURCEUTILS_H
#include <functional>
#include <memory>
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "NameMangler.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "StringPool.h"
namespace aapt {
namespace ResourceUtils {
/**
* Returns true if the string was parsed as a resource name
* ([*][package:]type/name), with
* `out_resource` set to the parsed resource name and `out_private` set to true
* if a '*' prefix was present.
*/
bool ParseResourceName(const android::StringPiece& str, ResourceNameRef* out_resource,
bool* out_private = nullptr);
/*
* Returns true if the string was parsed as a reference
* (@[+][package:]type/name), with
* `out_reference` set to the parsed reference.
*
* If '+' was present in the reference, `out_create` is set to true.
* If '*' was present in the reference, `out_private` is set to true.
*/
bool ParseReference(const android::StringPiece& str, ResourceNameRef* out_reference,
bool* out_create = nullptr, bool* out_private = nullptr);
/*
* Returns true if the string is in the form of a resource reference
* (@[+][package:]type/name).
*/
bool IsReference(const android::StringPiece& str);
/*
* Returns true if the string was parsed as an attribute reference
* (?[package:][type/]name),
* with `out_reference` set to the parsed reference.
*/
bool ParseAttributeReference(const android::StringPiece& str, ResourceNameRef* out_reference);
/**
* Returns true if the string is in the form of an attribute
* reference(?[package:][type/]name).
*/
bool IsAttributeReference(const android::StringPiece& str);
/**
* Convert an android::ResTable::resource_name to an aapt::ResourceName struct.
*/
Maybe<ResourceName> ToResourceName(
const android::ResTable::resource_name& name);
/**
* Returns a boolean value if the string is equal to TRUE, true, True, FALSE,
* false, or False.
*/
Maybe<bool> ParseBool(const android::StringPiece& str);
/**
* Returns a uint32_t if the string is an integer.
*/
Maybe<uint32_t> ParseInt(const android::StringPiece& str);
/**
* Returns an ID if it the string represented a valid ID.
*/
Maybe<ResourceId> ParseResourceId(const android::StringPiece& str);
/**
* Parses an SDK version, which can be an integer, or a letter from A-Z.
*/
Maybe<int> ParseSdkVersion(const android::StringPiece& str);
/*
* Returns a Reference, or None Maybe instance if the string `str` was parsed as
* a
* valid reference to a style.
* The format for a style parent is slightly more flexible than a normal
* reference:
*
* @[package:]style/<entry> or
* ?[package:]style/<entry> or
* <package>:[style/]<entry>
*/
Maybe<Reference> ParseStyleParentReference(const android::StringPiece& str, std::string* out_error);
/*
* Returns a Reference if the string `str` was parsed as a valid XML attribute
* name.
* The valid format for an XML attribute name is:
*
* package:entry
*/
Maybe<Reference> ParseXmlAttributeName(const android::StringPiece& str);
/*
* Returns a Reference object if the string was parsed as a resource or
* attribute reference,
* ( @[+][package:]type/name | ?[package:]type/name ) setting outCreate to true
* if
* the '+' was present in the string.
*/
std::unique_ptr<Reference> TryParseReference(const android::StringPiece& str,
bool* out_create = nullptr);
/*
* Returns a BinaryPrimitve object representing @null or @empty if the string
* was parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseNullOrEmpty(const android::StringPiece& str);
/*
* Returns a BinaryPrimitve object representing a color if the string was parsed
* as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseColor(const android::StringPiece& str);
/*
* Returns a BinaryPrimitve object representing a boolean if the string was
* parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseBool(const android::StringPiece& str);
// Returns a boolean BinaryPrimitive.
std::unique_ptr<BinaryPrimitive> MakeBool(bool val);
/*
* Returns a BinaryPrimitve object representing an integer if the string was
* parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseInt(const android::StringPiece& str);
/*
* Returns a BinaryPrimitve object representing a floating point number
* (float, dimension, etc) if the string was parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseFloat(const android::StringPiece& str);
/*
* Returns a BinaryPrimitve object representing an enum symbol if the string was
* parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr,
const android::StringPiece& str);
/*
* Returns a BinaryPrimitve object representing a flag symbol if the string was
* parsed as one.
*/
std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* enum_attr,
const android::StringPiece& str);
/*
* Try to convert a string to an Item for the given attribute. The attribute
* will
* restrict what values the string can be converted to.
* The callback function on_create_reference is called when the parsed item is a
* reference to an ID that must be created (@+id/foo).
*/
std::unique_ptr<Item> TryParseItemForAttribute(
const android::StringPiece& value, const Attribute* attr,
const std::function<void(const ResourceName&)>& on_create_reference = {});
std::unique_ptr<Item> TryParseItemForAttribute(
const android::StringPiece& value, uint32_t type_mask,
const std::function<void(const ResourceName&)>& on_create_reference = {});
uint32_t AndroidTypeToAttributeTypeMask(uint16_t type);
/**
* Returns a string path suitable for use within an APK. The path will look
* like:
*
* res/type[-config]/<name>.<ext>
*
* Then name may be mangled if a NameMangler is supplied (can be nullptr) and
* the package
* requires mangling.
*/
std::string BuildResourceFileName(const ResourceFile& res_file,
const NameMangler* mangler = nullptr);
// Parses the binary form of a resource value. `type` is used as a hint to know when a value is
// an ID versus a False boolean value, etc. `config` is for sorting strings in the string pool.
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);
} // namespace ResourceUtils
} // namespace aapt
#endif /* AAPT_RESOURCEUTILS_H */