Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version support #59

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Version support #59

wants to merge 8 commits into from

Conversation

garanj
Copy link
Collaborator

@garanj garanj commented Dec 19, 2024

What

Adds support for extracting WFF schema version from AndroidManifest.xml for use in validating the watch face package.

Why

The current version of the memory footprint evaluator relies on the --schema-version command-line argument in order to know which version of the schema to validate against.

However, the actual schema used in the watch face is specified in the AndroidManifest.xml file in the com.google.wear.watchface.format.version property.

A user could mistakenly be specifying a command-line value for the version, which is not the version of the schema in the manifest, and the resulting evaluation could therefore be incorrect.

How

Adds a getManifest() method to InputPackage which returns a new class AndroidManifest, containing useful details such as WFF version. AndroidManifest can be created from AAB, APK and plain file-based sources.

--schema-version is changed from a required to an optional argument, and where a mismatch is detected between CLI and manifest version, a warning is printed, but the CLI version is used.

implementation 'com.google.mug:mug-guava:6.6'
implementation 'commons-cli:commons-cli:1.5.0'
implementation 'com.android.tools.apkparser:binary-resources:31.4.0'
implementation 'com.android.tools.apkparser:binary-resources:31.7.3'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should move to toml in a follow up

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100%.

@@ -102,8 +103,9 @@ class EvaluationSettings(
var estimateOptimization: Boolean = false
private set

val isHoneyfaceMode
get() = schemaVersion == HONEYFACE_VERSION
@get:JvmName("isHoneyfaceMode")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is backwards compatible required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, I thought it safest to leave it as an option, @alexclarke-g will know best.

@@ -268,6 +267,9 @@ class EvaluationSettings(
if (line.hasOption(reportModeOption)) {
evaluationSettings.reportMode = true
}
if (line.hasOption(honeyfaceOption)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is honey face explained somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to my knowledge, it predates WFF.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, honeyface predates WFF. We keep support for it because we wanted to perform some estimations on older watch faces and we may need it in the future.

@garanj garanj requested a review from lucianbc January 7, 2025 13:51
@garanj
Copy link
Collaborator Author

garanj commented Jan 10, 2025

Thanks @lucianbc, I've addressed those comments, PTAL.

Comment on lines 63 to 64
val wffVersion =
getAttribute(doc, manifestProto, "//property/@android:value").toInt()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manifest may contain more than one , so you'll have to filter by name. Also, technically, there's no guarantee that such a property will be there and indeed that's not the case for honeyface watch faces. To fix this, I suggest this approach:

  • throw an IllegalArgumentException if no such property exists
  • only parse the AndroidManifest.xml if necessary (next comment).

To filter by name, you can use:

            val wffVersion = getAttribute(doc, "//property[@android:name=\"com.google.wear.watchface.format.version\"]/@android:value").toIntOrNull()
            requireNotNull(wffVersion) {
                "Watch Face Manifest must have a property with name \"com.google.wear.watchface.format.version\" that specifies the version of the Watch Face Format to be used."
            }

You may save the XPath in a constant and use it in the loadFromPlainXml method as well.

@@ -112,11 +112,25 @@ private static void evaluateInHumanReadableMode(EvaluationSettings settings) {
*/
static List<MemoryFootprint> evaluateMemoryFootprint(EvaluationSettings evaluationSettings) {
try (InputPackage inputPackage = InputPackage.open(evaluationSettings.getWatchFacePath())) {

AndroidManifest manifest = inputPackage.getManifest();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to line 122, so that it executes only if the --schema-version is not homeyface. If it is honeyface, then we won't throw in case the is not defined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants