Skip to content

Commit

Permalink
Improve booster-aapt2 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsonlee committed Aug 22, 2022
1 parent 706e94e commit 6bc3266
Show file tree
Hide file tree
Showing 1,223 changed files with 168 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class Aapt2Container(val header: Header, private vararg val _entries: Entry<*>)

open class Png(header: ResourcesInternal.CompiledFile, val image: ByteBuffer) : ResFile(header)

open class WebP(header: ResourcesInternal.CompiledFile, val image: ByteBuffer) : ResFile(header)

open class Xml(file: ResourcesInternal.CompiledFile, val root: Resources.XmlNode) : ResFile(file)

val entries: List<Entry<*>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.didiglobal.booster.aapt2.Aapt2Container.Metadata
import com.didiglobal.booster.aapt2.Aapt2Container.Png
import com.didiglobal.booster.aapt2.Aapt2Container.ResFile
import com.didiglobal.booster.aapt2.Aapt2Container.ResTable
import com.didiglobal.booster.aapt2.Aapt2Container.WebP
import com.didiglobal.booster.aapt2.Aapt2Container.Xml
import com.didiglobal.booster.aapt2.legacy.ResourcesInternalLegacy
import java.io.File
Expand All @@ -25,6 +26,7 @@ val File.metadata: Metadata
MAGIC -> {
parser.parseHeader()
val type = parser.readInt()
@Suppress("UNUSED_VARIABLE")
val length = parser.readLong()

when (type) {
Expand All @@ -39,6 +41,7 @@ val File.metadata: Metadata

private fun BinaryParser.parseResFileMetadata(): Metadata {
val headerSize = readInt()
@Suppress("UNUSED_VARIABLE")
val dataSize = readLong()

return parse {
Expand Down Expand Up @@ -86,11 +89,7 @@ private fun BinaryParser.parseResFileMetadata(): Metadata {
height = it.config.screenHeightDp.toShort()
}
// TODO localScript = ...
it.config.localeBytes.takeIf { l ->
l.size() > 0
}?.let { l ->
l.copyTo(localeVariant, 0, 0, l.size())
}
it.config.localeBytes.takeIf { l -> l.size() > 0 }?.copyTo(localeScript, 0)
screenConfig2.apply {
layout = it.config.screenRoundValue.toByte()
colorMode = (it.config.hdrValue shl 2 and it.config.wideColorGamutValue).toByte()
Expand All @@ -100,6 +99,7 @@ private fun BinaryParser.parseResFileMetadata(): Metadata {
}

private fun BinaryParser.parseLegacyMetadata(): Metadata {
@Suppress("UNUSED_VARIABLE")
val entryType = readInt()
val entryLength = readLong()
return parse {
Expand Down Expand Up @@ -156,6 +156,7 @@ fun BinaryParser.parseHeader(): Header {
fun BinaryParser.parseResEntry(): Entry<*> {
val p = tell()
val type = readInt()
@Suppress("UNUSED_VARIABLE")
val length = readLong()

try {
Expand All @@ -164,7 +165,7 @@ fun BinaryParser.parseResEntry(): Entry<*> {
RES_TABLE -> ResTable(parse {
Resources.ResourceTable.parseFrom(it)
})
else -> TODO("Unknown type 0x`${type.toString(16)}`")
else -> TODO("Unknown type 0x${type.toString(16)} at 0x${p.toString(16)}: $file")
}
} finally {
//seek(p + length.toInt())
Expand Down Expand Up @@ -234,17 +235,24 @@ private fun BinaryParser.parseResFile(): ResFile {
val header = parse {
ResourcesInternal.CompiledFile.parseFrom(readBytes(headerSize))
}
val padding = readBytes((4 - tell() % 4) % 4)

return when (header.type) {
Resources.FileReference.Type.PNG -> parsePng(header)
Resources.FileReference.Type.BINARY_XML -> TODO("binary XML")
Resources.FileReference.Type.PROTO_XML -> Xml(header, Resources.XmlNode.parseFrom(readBytes(dataSize.toInt())))
Resources.FileReference.Type.UNKNOWN -> when (header.resourcePath.substringAfter('.')) {
"png", "9.png" -> parsePng(header)
else -> TODO("Unknown RES_FILE `$file`")

readBytes((4 - tell() % 4) % 4) // header padding

try {
@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
return when (header.type) {
Resources.FileReference.Type.PNG -> parsePng(header)
Resources.FileReference.Type.BINARY_XML -> TODO("binary XML")
Resources.FileReference.Type.PROTO_XML -> Xml(header, Resources.XmlNode.parseFrom(readBytes(dataSize.toInt())))
Resources.FileReference.Type.UNKNOWN -> when (header.resourcePath.substringAfter('.')) {
"png", "9.png" -> parsePng(header)
"webp" -> parseWebP(header)
else -> TODO("Unknown RES_FILE `$file`")
}
Resources.FileReference.Type.UNRECOGNIZED -> TODO("Unrecognized resource file `${header.sourcePath}`")
}
Resources.FileReference.Type.UNRECOGNIZED -> TODO("Unrecognized resource file `${header.sourcePath}`")
} finally {
readBytes((4 - tell() % 4) % 4) // data padding
}
}

Expand All @@ -260,6 +268,23 @@ private fun BinaryParser.parsePng(header: ResourcesInternal.CompiledFile): Png {
})
}

/**
* @see <a href="https://developers.google.com/speed/webp/docs/riff_container">WebP Container Specification</a>
*/
private fun BinaryParser.parseWebP(header: ResourcesInternal.CompiledFile): WebP {
return WebP(header, parse {
val p = tell()
val riff = readInt() // 'RIFF'
val size = readUInt() // size of the file in bytes starting at offset 8
val webp = readInt() // 'WEBP'
if (0x46464952 != riff || size <= 0 || 0x50424557 != webp) {
throw Aapt2ParseException("Not a WebP entry `$file`")
}
seek(p)
it
})
}

val ResourcesInternal.CompiledFile.resourcePath: String
get() = File(this.sourcePath).resourcePath

Expand Down
107 changes: 103 additions & 4 deletions booster-aapt2/src/main/proto/Resources.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ message Source {
SourcePosition position = 2;
}

// The name and version fingerprint of a build tool.
message ToolFingerprint {
string tool = 1;
string version = 2;
}

// Top level message representing a resource table.
message ResourceTable {
// The string pool containing source paths referenced throughout the resource table. This does
Expand All @@ -49,6 +55,10 @@ message ResourceTable {

// Resource definitions corresponding to an Android package.
repeated Package package = 2;
// The <overlayable> declarations within the resource table.
repeated Overlayable overlayable = 3;
// The version fingerprints of the tools that built the resource table.
repeated ToolFingerprint tool_fingerprint = 4;
}

// A package ID in the range [0x00, 0xff].
Expand Down Expand Up @@ -121,6 +131,11 @@ message Visibility {

// The comment associated with the <public> tag.
string comment = 3;

// Indicates that the resource id may change across builds and that the public R.java identifier
// for this resource should not be final. This is set to `true` for resources in `staging-group`
// tags.
bool staged_api = 4;
}

// Whether a resource comes from a compile-time overlay and is explicitly allowed to not overlay an
Expand All @@ -133,15 +148,49 @@ message AllowNew {
string comment = 2;
}

// Whether a resource is overlayable by runtime resource overlays (RRO).
// Represents a set of overlayable resources.
message Overlayable {
// Where this declaration was defined in source.
// The name of the <overlayable>.
string name = 1;
// The location of the <overlayable> declaration in the source.
Source source = 2;
// The component responsible for enabling and disabling overlays targeting this <overlayable>.
string actor = 3;
}

// Represents an overlayable <item> declaration within an <overlayable> tag.
message OverlayableItem {
enum Policy {
NONE = 0;
PUBLIC = 1;
SYSTEM = 2;
VENDOR = 3;
PRODUCT = 4;
SIGNATURE = 5;
ODM = 6;
OEM = 7;
ACTOR = 8;
CONFIG_SIGNATURE = 9;
}
// The location of the <item> declaration in source.
Source source = 1;

// Any comment associated with the declaration.
string comment = 2;

// The policy defined by the enclosing <policy> tag of this <item>.
repeated Policy policy = 3;

// The index into overlayable list that points to the <overlayable> tag that contains
// this <item>.
uint32 overlayable_idx = 4;
}

// The staged resource ID definition of a finalized resource.
message StagedId {
Source source = 1;
uint32 staged_id = 2;
}
// An entry ID in the range [0x0000, 0xffff].
message EntryId {
uint32 id = 1;
Expand Down Expand Up @@ -169,11 +218,13 @@ message Entry {
AllowNew allow_new = 4;

// Whether this resource can be overlaid by a runtime resource overlay (RRO).
Overlayable overlayable = 5;

OverlayableItem overlayable_item = 5;
// The set of values defined for this entry, each corresponding to a different
// configuration/variant.
repeated ConfigValue config_value = 6;

// The staged resource ID of this finalized resource.
StagedId staged_id = 7;
}

// A Configuration/Value pair.
Expand Down Expand Up @@ -225,9 +276,15 @@ message CompoundValue {
Styleable styleable = 3;
Array array = 4;
Plural plural = 5;
MacroBody macro = 6;
}
}

// Message holding a boolean, so it can be optionally encoded.
message Boolean {
bool value = 1;
}

// A value that is a reference to another resource. This reference can be by name or resource ID.
message Reference {
enum Type {
Expand All @@ -248,6 +305,16 @@ message Reference {

// Whether this reference is referencing a private resource (@*package:type/entry).
bool private = 4;

// Whether this reference is dynamic.
Boolean is_dynamic = 5;

// The type flags used when compiling the reference. Used for substituting the contents of macros.
uint32 type_flags = 6;

// Whether raw string values would have been accepted in place of this reference definition. Used
// for substituting the contents of macros.
bool allow_raw = 7;
}

// A value that represents an ID. This is just a placeholder, as ID values are used to occupy a
Expand Down Expand Up @@ -346,6 +413,9 @@ message Attribute {

// The value of the enum/flag.
uint32 value = 4;

// The data type of the enum/flag as defined in android::Res_value.
uint32 type = 5;
}

// Bitmask of formats allowed for an attribute.
Expand Down Expand Up @@ -532,3 +602,32 @@ message XmlAttribute {
// The optional interpreted/compiled version of the `value` string.
Item compiled_item = 6;
}

message MacroBody {
string raw_string = 1;
StyleString style_string = 2;
repeated UntranslatableSection untranslatable_sections = 3;
repeated NamespaceAlias namespace_stack = 4;
SourcePosition source = 5;
}

message NamespaceAlias {
string prefix = 1;
string package_name = 2;
bool is_private = 3;
}

message StyleString {
message Span {
string name = 1;
uint32 start_index = 2;
uint32 end_index = 3;
}
string str = 1;
repeated Span spans = 2;
}

message UntranslatableSection {
uint64 start_index = 1;
uint64 end_index = 2;
}
Loading

0 comments on commit 6bc3266

Please sign in to comment.