Watch face exceeds memory usage: let's clarify

You’re right, that’s correct. I tested it, and due to an animation, it exceeds 100 MB. It seems there is no way to make an animation take up less space.

I tried Image Sequence, Webp, Gif… without success.

Bye Bye Animated Watch Faces

Are you using compressed .png images You can reduce most .png files at over 50% and I’ve heard of results of 90% decrease in size.

There are GIF compressors that say they reduce them 60%

There are other ways to animate something using a single image that moves, but I guess ultimately it depends on your animations.

Ron
Samsung Developer Relations

Hi,

I compressed them from 20 MB to 500 kB.

The 20 MB asset, be it an image sequence, gif, or webp, consumes exactly the same RAM resources as the 500 kB one.

It exceeds 100 MB in active mode.

I’ve tried all possible variations.

In the end, I gave up on animations :frowning:

something is wrong in that system. why would the resource need to take up 200x more in memory than it takes in the storage. what is that if not bloating?

Google has a java tool to check what the memory usage will be. Again the memory usage is not the size of the file. Its how much ram the watch face will use in ambient and active modes.

Which has been posted before by Ron

However, I did some testing.

A blank brand new project compiled shows 0MB as expected.

If I add one gif file. That is 1MB in size. Only to active and nothing to AOD

I get this output from the tool

Number of supported layouts: 1
Total images memory footprint: 176.28 MB
Max memory footprint in active: 176.28 MB
Max memory footprint in ambient: 0.00 MB

Just one gif file causes this to bloat. This is the same if I use a webp or a image sequence for animation.

This tells me that there is some other issue going on.

With my full watchface that is being rejected this is the output for it

Number of supported layouts: 1
Total images memory footprint: 338.48 MB
Max memory footprint in active: 179.15 MB
Max memory footprint in ambient: 1.55 MB

Which ambient is below the threshold. My watchface has 2 selectable animations. Yet it seems like something is going wrong where the memory footprint is using both animations at the same time. And somehow inflating the usage way above what it should be.

@pigeoncraft @RECREATIVE

Wear App Quality Guidelines where the size restriction is list the added an appeals link earlier this month.

Managing Policy Violations and appeals

If you reported this it may help them improve their algorithm.

Ron
Samsung Developer Relations

I successfully published a new watch face today (link). However, I forgot to include something in the description (Store listing). When I submitted the missing sentence, it turned out to be too much for the Play Store :slight_smile: The update was rejected due to memory exceedance. :face_with_peeking_eye:

by @garan

Isn’t it that every frame counts?

The memory footprint of a drawable asset is defined as 4 times the number of pixels in the image times the number of frames in the asset (for GIF, WEBP). We typically need 4 bytes to represent a single pixel in memory (one for each of the RGBA channels).

More info:
watchface/play-validations at main · google/watchface (github.com)

So consider 450x450 gif with 90 frames,
it’s 4x450x450x90 = 72mb

1 Like

After reading more this is what they say

The memory footprint of a drawable asset is defined as 4 times the number of pixels in the image times the number of frames in the asset.

This means if a watch has a resolution of 480 x 480 (Galaxy watch 6) you could have max one animation with the max of 108 frames. Which at 30fps if you want a smooth animation and is recommended by google gives you a little over 3 seconds. My animation was 200 frames, However less resolution. This seems like a major inefficiency in the code for how animations are loaded and rendered. Basically they are taking the animation. Splitting it into each individual frame and loading all of that into ram. I wonder how the tool is handling it and if they are using Render.CanvasRenderer.render() correctly.

Instead of deomposing gifs and animations, I would think that using Glide or Fresco libraries would help a lot. Or at least let us do mp4 streaming, vector animation or object animation.

1 Like

I would like to add, that I have built, released, updated and live about 20 watch faces with WFS 1.5.7. I believe SDP team have successfully convinced Google to review their memory issues. I no longger face “Memory budget” issue. Thank you Ron and SDP team.

I do keep in mind to ensure my final build ).aab) does not exceed 7 MB and only 1/3 of it is for AOD. My dials are optimized at 640 x 640 px.

Thank you everyone for your support.

1 Like

In fact, reviewers were using old version of the watchface.xml Memory Footprint Validator. This was fixed just 3 weeks ago after issue report. I think @Matteo_Dini can confirm this too. So SDP team did not help fixing the root of issue (only helped changing memory limit which was not the cause). In the end, it was only necessary to test memory footprint validator and report that watch faces with no memory issues were rejected.

Tomas

2 Likes

Samsung Developer Program did not help, I just reported it to the Watch Face Studio team that informed Play Store team about the feedback on many occasions. :slight_smile:

So in reality the voice of the developer community was the biggest help.

Ron
Samsung Developer Relations

Hello.
Is someone able to provide detailed instructions on the building/usage of Memory Footprint Evaluator?
I have downloaded the source code, and installed Gradle (Also added his path to Ambient Variables in Windows, it is working), but i don’t understand what else to do, especially with provided commands in Github.
Yes, i have Java too.

PS: I’ve read this entire thread, and this one too → Update the status for memory budget limit

So i’m with you guys, i’m another person who is struggling with publications.
I’m tired of waiting for Google’s rejection and i want to check myself the bundle before uploading it.

Thank you in advance.

  1. Download source code and unzip it GitHub - google/watchface (Code, Download Zip)

  2. Make sure to have both Java and Gradle installed (Read the documentation on how to do it).

  3. Open CMD in play-validations folder and give the command: gradlew :memory-footprint:jar

  4. This will build the program.

  5. Now place your watchface apk, renamed in watchface.apk for convenience.

  6. Open the CMD in that folder again and give this command:

  7. java -jar memory-footprint.jar --watch-face watchface.apk --schema-version 1 --ambient-limit-mb 10 --active-limit-mb 100 --apply-v1-offload-limitations --estimate-optimization

  8. Pro Tip: Place your program in a defined folder, and create a txt file with this line, replacing the paths with yours:

  9. cmd /k "cd /d C:\Users\Me\Programs\whateveriscalledyourfolder\watchface-main\play-validations && java -jar memory-footprint.jar --watch-face watchface.apk --schema-version 1 --ambient-limit-mb 10 --active-limit-mb 100 --apply-v1-offload-limitations --estimate-optimization"

  10. Rename the .txt file in something like WF Memory Footprint Check.bat, place it wherever you want.

  11. Every time you want to check a WatchFace, just copy it in the play-validations folder and rename it to watchface.apk, then open the .bat to check it.

2 Likes

Yes, I confirm.
Sending watch faces to Google’s validation team is like a lottery. However, it seems they have finally updated their validation systems (it took months)

1 Like