* feat: move to v0.37.0
* chore: maven publish is jdk 17+
* wip
* build: test on Java 25 as well
* chore: fix feedback from Copilot
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
* build: log test JVM path and version in doFirst to confirm toolchain selection
* build: add test summary and failed/skipped event logging to all Test tasks
* Some cleanup
---------
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: IgorEisberg <[email protected]>
* build: migrate to modern maven publish
* build: move to v0.36
* build: use v33 for Java 11 min
* build: skip maven on unsupported Java versions
* chore: configure codeql manually
* build: defer maven publishing till jdk11
* chore: move publising to own file
* refactor: Apktool Remastered
Refactor and reorganization of Apktool, especially resource decoding.
ARSC parsing and resource file decoding rewritten, obviously keeping
edge-case obfuscation handling intact.
Now it's a lot more congruent with AOSP source code, particularly
based on libs/androidfw and tools/aapt2.
The code is clean and much easier to follow.
Everything that can be perceived as confusing is documented to avoid
breaking changes later on.
Most of the changes are on the back end and won't be noticeable to
the average user.
User-end changes include:
* Support for 32-bit platforms is now over.
* Legacy aapt ("aapt1") is now resting in peace. It's about time.
It has limited the ability to evolve Apktool due to many compatibility
issues. aapt2 is a lot more robust.
* Supports decoding resource files not directly under res/r/R folders,
as long as you decode the APK with resources (without -r/--no-res or
--only-manifest).
* -api/--api-level option is no longer available or needed.
Apktool and baksmali take care of setting the correct API to use for
decoding/building dex files, you don't need to worry about it anymore.
* Advanced commands no longer occupy short options, and only get long
option. This is done for extensibility's sake, non-commonly used
options should not take up short options intended for core options.
* efd/empty-framework-dir command is replaced with cf/clean-frameworks.
Both cf/clean-frameworks and lf/list-frameworks have been extended:
the -t/--frame-tag option now lets you delete/list frameworks matching
a specific tag, as well as -a/--all option to delete/list all frameworks
regardless of tag (this also replaced the -f option for these commands).
* "packageInfo" in apktool.yml (along with "forcedPackageId" and
"renamedManifestPackage") is replaced with "resourcesInfo", where
all settings related to the transformation of resources.arsc is included:
"packageId", "packageName", "sparseResources", "compactEntries".
All future settings related to resources.arsc should be included here.
Note: "packageName" alters the app's package name in the resource table
only! To change the package name of the app itself, change it in
AndroidManifest.xml. If no "packageName" is defined in "resourcesInfo",
then the resource table inherits the app's package name.
* Many <item> tags are now replaced with tags corresponding to their
respective resource types, particularly for resource references,
that's the standard in AOSP source code and is perfectly supported by
aapt2. This used to be an issue with legacy aapt.
* Some <item> tags are still necessary, specifically when the value's
format doesn't match the resource type. This is especially common with
dimens, where some values are not of the "dimension" format.
e.g. "2.5" (without any unit suffix) is a "float" format, and has to
appear as an <item> tag, along with added "format" attribute. This
is commonly seen in AOSP source code.
* "dp" is used instead of "dip" as it's the Android development standard,
and more congruent with the other units: "px", "sp", "pt", "in", "mm".
Note: Both "dp" and "dip" are recognized when building and are encoded
identically.
* "match_parent" is preferred over "fill_parent" that has been deprecated
since API 8 (Android 2.2). It's also the standard in Android development
for over a decade.
Note: Both "match_parent" and "fill_parent" are recognized when building
and are encoded identically.
* Hex integer values are written in compact form (e.g. 0x20 rather than
0x00000020) to keep it clean and readable, and match original source
codes as much as possible. The only exception is for resource IDs in
public.xml. Those remain in the 0xPPTTEEEE format regardless of value.
* Colors values are written exactly as they were written in source code.
This respects the data in ARSC and doesn't reformat it. e.g. if the
source code had a color in the form #RRGGBB, than that's how it'll be
decoded. Previously, all colors were forced to #AARRGGBB format,
regardless of encoding data.
* Add an important comment
* Comment correction
* Fix aapt2 permissions
* Merge loop over entries
* Style, log and comments
* Minor log style
* refactor formatting according to aapt2 rules
Judging how to format values XMLs by looking at XMLs in AOSP is misleading
because the maintainers didn't update them according to aapt2 rules
(understandable, it'll require a lot of tedious work).
Some improvements to formatting:
* <id> tags are completely normal, <item type="id"> is redundant.
https://android.googlesource.com/platform/frameworks/base/+/main/tools/aapt2/ResourceParser.cpp#619
* Added support for references inside <id> tags, which is the only
allowed value type inside this tag. (empty string and @null are
allowed but are treated as empty body by aapt2 and discarded).
https://android.googlesource.com/platform/frameworks/base/+/main/tools/aapt2/ResourceParser.cpp#636https://android.googlesource.com/platform/frameworks/base/+/main/tools/aapt2/ResourceParser_test.cpp#1356
* No more hiding "synthesized" IDs generated for attribute items.
Although they are not strictly needed to be in ids.xml, removing them masks
the fact that they exist and are actual ID resources with an assigned entry
ID that can be clearly seen in public.xml anyway, which could have given
impression that those are missing resources.
Our aim is to fully and accurately display the data in resources.arsc,
not to alter it for cosmetic reasons.
So from the above - this is standard for aapt2:
<id name="foo2">@id/bar</id>
<id name="bar2"/>
<id name="baz2"></id>
And can also be seen in actual APKs:
[ResTable_entry_compact] id: 0x0006 name: add_phrase keyIndex: 1962 size: 8 flags: 0x120c
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
[ResTable_entry_compact] id: 0x0007 name: always_option keyIndex: 1963 size: 8 flags: 0x120c
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
[ResTable_entry_compact] id: 0x0008 name: android_alertTitle keyIndex: 1964 size: 8 flags: 0x0108
[Res_value] size: 8 dataType: 0x01 data: 0x010201e0 (@0x010201e0)
[ResTable_entry_compact] id: 0x0009 name: android_alwaysUse keyIndex: 1965 size: 8 flags: 0x0108
[Res_value] size: 8 dataType: 0x01 data: 0x010201ed (@0x010201ed)
Before this change, the IDs would lose their reference on rebuild:
[ResTable_entry_compact] id: 0x0006 name: add_phrase keyIndex: 1952 size: 8 flags: 0x120e
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
[ResTable_entry_compact] id: 0x0007 name: always_option keyIndex: 1953 size: 8 flags: 0x120e
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
[ResTable_entry_compact] id: 0x0008 name: android_alertTitle keyIndex: 1954 size: 8 flags: 0x120e
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
[ResTable_entry_compact] id: 0x0009 name: android_alwaysUse keyIndex: 1955 size: 8 flags: 0x120e
[Res_value] size: 8 dataType: 0x12 data: 0x00000000 ((id))
* formatted="false" for <string-array> is not a thing, aapt2 ignores it for
anything other than <string> tags.
https://android.googlesource.com/platform/frameworks/base/+/main/tools/aapt2/ResourceParser.cpp#855
* Specifying "format" attribute is a lot less common than what AOSP XMLs make
it appear. aapt2 code has a list of standard formats each resource type
supports (excluding references which are standard for all types except bags)
and aapt2 can understand them without needing explicit format:
https://android.googlesource.com/platform/frameworks/base/+/main/tools/aapt2/ResourceParser.cpp#510
As you can see, from the numeric types only integers are not directly supported
by dimen and fraction and need the format attribute if they appear in ARSC for
whatever reason, otherwise they'll be re-encoded as float by aapt2.
The map has been ported over for quick lookups:
protected static final Map<String, Set<String>> STANDARD_TYPE_FORMATS = new HashMap<>();
static {
STANDARD_TYPE_FORMATS.put("bool", Sets.newHashSet("boolean"));
STANDARD_TYPE_FORMATS.put("color", Sets.newHashSet("color"));
STANDARD_TYPE_FORMATS.put("dimen", Sets.newHashSet("float", "fraction", "dimension"));
STANDARD_TYPE_FORMATS.put("drawable", Sets.newHashSet("color"));
STANDARD_TYPE_FORMATS.put("fraction", Sets.newHashSet("float", "fraction", "dimension"));
STANDARD_TYPE_FORMATS.put("integer", Sets.newHashSet("integer"));
STANDARD_TYPE_FORMATS.put("string", Sets.newHashSet("string"));
}
* Add support for res/values/overlayable.xml
* style
* whoops