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

Strip unused code and resources from pwa-template.apk #7

Conversation

FluorescentHallucinogen
Copy link
Contributor

I've reduced the size of pwa-template.apk by 1000x, from 1.2 MB to 1.2 kB! 🤯

In fact, the only file in the APK that is used is AndroidManifest.xml.

Since AndroidManifest.xml doesn't contain any activities, all code can be deleted.

But to be installable, the APK must contain classes.dex file.

So I've prepared the minimal possible classes.dex file that the ART class loader loads without complaining (https://source.android.com/devices/tech/dalvik/dex-format). It defines 0 classes with 0 methods, and references 0 methods. It's only 116 bytes in size (uncompressed)!

Also I've removed from AndroidManifest.xml things that are not used or added later by ovr-platform-util:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    android:compileSdkVersion="23"
    android:compileSdkVersionCodename="6.0-2438415"
    package="com.oculus.pwa.templateapplication"
    platformBuildVersionCode="29"
    platformBuildVersionName="10">

    <uses-sdk
        android:minSdkVersion="23"
        android:targetSdkVersion="29" />

    <uses-feature
        android:name="android.hardware.vr.headtracking"
        android:required="false"
        android:version="1" />

    <uses-feature
        android:name="oculus.software.handtracking"
        android:required="false" />

    <uses-permission
        android:name="com.oculus.permission.HAND_TRACKING" />

    <application
-       android:theme="@style/AppTheme"
-       android:label="@string/app_name"
-       android:icon="@mipmap/ic_launcher"
        android:debuggable="false"
-       android:allowBackup="true"
        android:supportsRtl="true"
        android:extractNativeLibs="false"
-       android:roundIcon="@mipmap/ic_launcher_round"
        android:appComponentFactory="androidx.core.app.CoreComponentFactory">

-       <meta-data
-           android:name="web_manifest_url"
-           android:value="" />
-
-       <meta-data
-           android:name="com.oculus.pwa.START_URL"
-           android:value="" />
-
-       <meta-data
-           android:name="com.oculus.pwa.SCOPE"
-           android:value="" />
-
-       <meta-data
-           android:name="com.oculus.pwa.NAME"
-           android:value="" />
-
-       <meta-data
-           android:name="com.oculus.pwa.APPID"
-           android:value="" />
-
        <meta-data
            android:name="com.oculus.vrshell.supports_free_resizing"
            android:value="true"
            maxSizeX="1280"
            maxSizeY="1000"
            minSizeX="400"
            minSizeY="400" />
    </application>
</manifest>

This reduces the size of compiled uncompressed AndroidManifest.xml to just 2 564 bytes!

After that all resources (resources.arsc file and res folder) can be deleted from the APK as unused.

Also I've added an -s option to apktool:

- exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" "$@"
+ exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" -s "$@"

This helps to bypass an ovr-platform-util's error when trying to disassembly the classes.dex with no code and speeds up APK rebuilding.

@FluorescentHallucinogen
Copy link
Contributor Author

@JudahGabriel PTAL. 😉

@JudahGabriel
Copy link
Contributor

JudahGabriel commented Jun 9, 2022

Wow, awesome Alexey! @amrutha95 have a look?

@JudahGabriel
Copy link
Contributor

Also, @phosiaz can you have a look at this?

@phosiaz
Copy link
Collaborator

phosiaz commented Jun 10, 2022

Hey Alexey! This looks great! Thanks a bunch for suggestions, but we want to keep this tool aligned with that found at https://developer.oculus.com/documentation/web/pwa-packaging/ for the purposes of consistency and a standardized testing suite — as this hasn’t gone through all of our tests. However, you’ll note that the current version of pwa-template.apk is actually 8kB, not 1.2MB! This is because we’ve made the same changes to the classes.dex :)

@phosiaz phosiaz closed this Jun 10, 2022
@FluorescentHallucinogen
Copy link
Contributor Author

@phosiaz

as this hasn’t gone through all of our tests.

Could you please share more details, what exactly tests?

Have you tested only pwa-template.apk file without apktool file? They only work together.

but we want to keep this tool aligned with that found at https://developer.oculus.com/documentation/web/pwa-packaging/

The only changes are in two files: pwa-template.apk and apktool.

Here's the change in the apktool file:

- exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" "$@"
+ exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" -s "$@"

BTW, where did you find ovr-platform-util-pwa for Linux, if it's not a secret? The https://developer.oculus.com/documentation/web/pwa-packaging/#download-the-cli page contains only builds for Windows and MacOS. Do you have the source codes?

However, you’ll note that the current version of pwa-template.apk is actually 8kB, not 1.2MB!

Yes, I noticed it at the very last moment, only when I started doing a pull request, i.e. much later I started working on it independently.

But my pwa-template.apk is just 1.2 kB vs. current 8 kB.

Also I've found some issues in the current ovr-platform-util-pwa.zip and pwa-template.apk:

  1. ovr-platform-util-pwa.zip contains __MACOSX folder with files that contains some very interesting things like https://lookaside.internalfb.com/intern/tasks/attachment/?fbid=723687575426214&attachment_id=679066623167681. 🙈

  2. ovr-platform-util and apktool in ovr-platform-util-pwa.zip have incorrect permissions. They are not marked as executable i.e. 775 (-rwxr-xr-x).

  3. pwa-template.apk is for some reason is signed. The original pwa-template.apk from Meta is not signed. The size of META-INF folder is 2 096 bytes unpacked and 1 610 bytes packed.

  4. pwa-template.apk still contains resources.arsc. After ovr-platform-util's work all values are static strings in AndroidManifest.xml and are not links to resources anymore. App name is stored in AndroidManifest.xml itself. So resources.arsc can be deleted as unused. That's another 584 bytes unpacked and packed.

  5. classes.dex is 1 044 unpacked and 600 bytes packed. It still contains some code:

package com.oculus.pwa.templateapplication;

public class R {
   public static class string {
      public static final int app_name = 2130837504;
   }
}

Also it contains some interesting string:

{
  "compilation-mode": "debug",
  "min-api": 16,
  "sha-1": "engineering",
  "version": "1.5.20-dev"
}

My classes.dex defines 0 classes with 0 methods, and references 0 methods. It's only 116 bytes uncompressed and 48 bytes compressed.

The only downside of my classes.dex is that it requires an -s (--no-src) option for apktool because it doesn't contain any code and can't be disassembled to Smali code and assembled back to classes.dex.

But what is the point of disassembling and assembling back the code, if it's not used anyway? This just slows down rebuilding the APK.

  1. AndroidManifest.xml is 2 820 bytes uncompressed and 982 bytes compressed. It contains some very controversial changes:

Why the following was removed? Isn't that being used?

<meta-data
    android:name="com.oculus.vrshell.supports_free_resizing"
    android:value="true"
    maxSizeX="1280"
    maxSizeY="1000"
    minSizeX="400"
    minSizeY="400" />

Why the following was changed?

<manifest
-    android:compileSdkVersion="23"
+    android:compileSdkVersion="31"
-    android:compileSdkVersionCodename="6.0-2438415"
+    android:compileSdkVersionCodename="12"

-    platformBuildVersionCode="29"
+    platformBuildVersionCode="31"
-    platformBuildVersionName="10">
+    platformBuildVersionName="12">

    <uses-sdk
-        android:minSdkVersion="23"
+        android:minSdkVersion="28"

My AndroidManifest.xml is 2 564 bytes uncompressed and 934 bytes compressed.

I tried to keep AndroidManifest.xml as similar to the original as possible, I didn't change anything, just removed things that are not used or added later by ovr-platform-util anyway.

So please give my pull request another chance. 😉

@davehill00 @jacobrossi @cabanier cc.

P.S. I'm anyway working on a pull request for Bubblewrap, which adds a flag for generating universal APKs compatible with Quest that open Trusted Web Activity (TWA) on regular Android devices and Meta Quest Browser on Quest devices. This will allow to abandon ovr-platform-util in favor of Bubblewrap.

@FluorescentHallucinogen
Copy link
Contributor Author

See GoogleChromeLabs/bubblewrap#704. 😉

@phosiaz
Copy link
Collaborator

phosiaz commented Jun 20, 2022

Hey @FluorescentHallucinogen!! I just wanted to let you know this hasn't slipped through the cracks, thanks for the detailed (and really useful) set of notes -- just looking into how best to approach integration and I'll comment here once I have an update!

@phosiaz phosiaz reopened this Jul 12, 2022
@phosiaz
Copy link
Collaborator

phosiaz commented Jul 12, 2022

Hey @FluorescentHallucinogen ! Thanks a bunch for the improvements made here 😊 we were able to verify tests passed so going to merge this PR now!

@phosiaz phosiaz merged commit e0acd2d into pwa-builder:linuxdocker Jul 12, 2022
@FluorescentHallucinogen
Copy link
Contributor Author

@phosiaz 🎉

The good news is that soon all this will no longer be needed.

See https://twitter.com/alexey_rodionov/status/1544374516767285249, pwa-builder/PWABuilder#3162 and pwa-builder/CloudAPK#98. 😉

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