VLC for Android updates on the Play Store
Published: 2024-03-26 08:37:51

We recently explained why VLC for Android has not been updated in months on the Play Store.

{% embed https://twitter.com/videolan/status/1771102415279763909 %}

In this post, I'll try to give some technical insights on why it's happening and what is our position.

## Signing Android apps

Since the first release of Android, any app has to be installed using an APK file. This file contains all of the code of the app as well as resources (icons, translations, ...) and any other data needed for the app to work.

To verify the authenticity of an APK file, it has to be signed. To do so, the developer has to generate a private key and use it to sign the APK. When done, anybody can verify the public key used to sign this file.

```
nicolas@Azabuntu:~/Downloads$ apksigner verify --print-certs -v VLC-Android-3.5.4-arm64-v8a.apk 
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Number of signers: 1
Signer #1 certificate DN: CN=Jean-Baptiste Kempf, O=VideoLAN Mobile, L=Paris, C=FR
Signer #1 certificate SHA-256 digest: c8768d2cea0c4b622e419b4b4715981946821e4ebc035fb41776cad395a7f68e
Signer #1 certificate SHA-1 digest: eefbc981428343bbddfff6b23b6bd8717351410c
Signer #1 certificate MD5 digest: 511fea1a22a7b62ebc01950c167c0406
Signer #1 key algorithm: RSA
Signer #1 key size (bits): 2048
Signer #1 public key SHA-256 digest: 0635a5fd15a4d1d70144357032506db52f5729440a597f1d492af3cd4b5d3990
Signer #1 public key SHA-1 digest: 7f98ab01f137803044707b8468c6a1747e0a396d
Signer #1 public key MD5 digest: e017420d81c24adf81ddbcafa67d7a11
```

When Android tries to update an already installed app, it will verify that the old and new signatures match before allowing the update and throw an error otherwise.

```
adb: failed to install VLC-Android-3.6.0-Beta-2-all.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package org.videolan.vlc signatures do not match newer version; ignoring!]
```

The application developers then have some obligations:
- avoid losing the signing certificate
- protect the certificate from any leak (by protecting it with a password, or storing it in a HSM, etc.)

If they lose their certificate or passwords, they won't be able to do any other release as Android will refuse to update their app with a different signature.

If they communicate their certificate and passwords to someone else, the third party will be able to sign their own version of the app and Android will consider it as legitimate.

## App bundles

A few years ago, Google announced a new way to package an Android app. It's called an [App Bundle](https://developer.android.com/guide/app-bundle). 

It's a compressed file also containing everything that is needed for the app to work, but that cannot be installed as is. To install it, the bundle has to be converted to an APK.

The goal is to be able to generate different APK files depending on the device specific features from the same App Bundle. That way, the release won't have the same content if you generate an APK for an Android 4.2 device with a x86 CPU versus if you do it for an Android 14 device with an arm64 CPU. The installation then uses less storage than before as the final APk file will only contain the needed parts.

## Release workflow on the Play Store

At VideoLAN, we already split our APK files depending on the device CPU arch. As we rely on pretty heavy native code (libvlc), it guarantees that the APK size will be as limited as possible. Currently, an APK containing all arch will be 125MB while its ARM64 only version will be only 45MB.

#### Release workflow using APKs

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd94lyurlnuwx4l81gm2.png)

#### Release workflow using App Bundle


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ssd0awe6okumv9vfczo.png)



#### Workflow differences

The huge difference here is the App Bundle workflow uses two signing keys. 

- The upload key allows the Play Store to verify that the uploader is legitimate. 
- the release key is then used and detained by the Play Store

#### Consequences

**The Play Store is signing the app on behalf of VideoLAN** in this workflow. 

**The Play Store has to detain VideoLAN's private key and passwords** to be able to do so.

#### Mitigations

Google is probably aware that asking the developers their signing private key is a bad practice, especially for already years old keys used for older apps.

To mitigate that, the Play Store proposes a mitigation called "dual release". Newest versions of Android (starting with Android 11) indeed allows updating an app with a different signature, as long as a proof of rotation is included.

The dual release workflow is then:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zrk2ws1lfzvu99ob8h6.png)



## Play Store rules

While all the above explanations are technical, the Play Store rules are a significant part of why we are now in a dead end.

In 2021, [Google announced](https://android-developers.googleblog.com/2021/06/the-future-of-android-app-bundles-is.html) that releasing using App Bundles will be mandatory for new apps starting from August 2021. 

Old apps were (and still are) able to use the old workflow to release, so it didn't affect us.

They then made [using App Bundles mandatory for any app including Android TV support](https://android-developers.googleblog.com/2022/11/app-bundles-for-google-tv-and-android-tv.html).

What seems to be a small change has a huge impact on VLC for Android.

## A dead end

As said before, the mitigation that makes sending our private key to Google is called dual release and will depend on the user's device Android version.

As App Bundles are mandatory for TV apps, dual release is not available anymore for apps supporting Android older than 11 and providing TV features.

#### History of Android TV support in VLC for Android

When Google provided some tools (called leanback) to let developer create TV apps, we decided not to do a dedicated app for Android TV. It had multiple advantages:

- Only one app to update
- Allow the user to switch to the TV interface even on non-TV devices

This latest point was (and still is) really important. A lot of manufacturers released devices that were meant to be used with a remote controller DPAD without being specifically Android TV devices. By allowing the user to directly switch to the TV interface, it made it much more easy to use for those devices.

#### The different alternatives we have

► Send our release private key to the Play Store

- Pros: we can release without disturbance of any kind
- Cons: Google detains our private key

► Remove the TV support in the APKs we send to the Play Store

- Pros: Google doesn't know our private key, we delegate the signature only for installation on Android 11 and newer
- Cons: no TV support under Android 11

► Start only sending App Bundles

- Pros: none
- Cons: makes the app technically only support Android 11 and later (About 30% of our users)

#### Our position

Sending Google our private signing key is a no-go. That's the first rule of security: your private key has to stay... private. 

The Play Store is not the only ecosystem using APKs. We also provide VLC for Android through other means (our website, Amazon AppStore, Huawei AppGalery) and giving our key to Google would compromise our entire release workflow.

Once that's said, there is unfortunately no solution left to provide TV support on Android 10 and less which is why we weren't able to release in the past months.