Skip to content

Update UnifiedPush library #4358

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

Merged
merged 13 commits into from
May 26, 2025
Merged

Update UnifiedPush library #4358

merged 13 commits into from
May 26, 2025

Conversation

bmarty
Copy link
Member

@bmarty bmarty commented Mar 4, 2025

Content

Update UnifiedPush library

Motivation and context

Be up to date and let Renovate handle this in the future.

We will also benefit from improvement from the library, in particular the support for RAISE_TO_FOREGROUND added in UnifiedPush/android-connector@7438c52 .

Screenshots / GIFs

Tests

  • Ensure that UnifiedPush notification are still working (still under test on my side)

Tested devices

  • Physical
  • Emulator
  • OS version(s):

Checklist

  • Changes have been tested on an Android device or Android emulator with API 24
  • UI change has been tested on both light and dark themes
  • Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility
  • Pull request is based on the develop branch
  • Pull request title will be used in the release note, it clearly define what will change for the user
  • Pull request includes screenshots or videos if containing UI changes
  • You've made a self review of your PR

@bmarty bmarty added the PR-Dependencies Pull requests that update a dependency file label Mar 4, 2025
Copy link
Contributor

github-actions bot commented Mar 4, 2025

📱 Scan the QR code below to install the build (arm64 only) for this PR.
QR code
If you can't scan the QR code you can install the build via this link: https://i.diawi.com/3qTYjg

Copy link

codecov bot commented Mar 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 80.40%. Comparing base (b926f5f) to head (beb7297).
Report is 4 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4358      +/-   ##
===========================================
- Coverage    80.40%   80.40%   -0.01%     
===========================================
  Files         2142     2142              
  Lines        56642    56642              
  Branches      7081     7081              
===========================================
- Hits         45545    45544       -1     
  Misses        8679     8679              
- Partials      2418     2419       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

// Duplicate classes between
// tink-1.16.0.jar -> tink-1.16.0 (com.google.crypto.tink:tink:1.16.0)
// tink-android-1.8.0.jar tink-android-1.8.0 (com.google.crypto.tink:tink-android:1.8.0)
exclude(group = "com.google.crypto.tink", module = "tink")
Copy link
Member Author

Choose a reason for hiding this comment

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

Hello @p1gp1g , do you know why I need to add this line?

It seems to be related to https://github.com/UnifiedPush/android-connector/blob/cf347ae931ea8b6e6c773cd566abea940d1297f1/connector/build.gradle#L58 and the related PR tink-crypto/tink-java-apps#5, but maybe I miss something?

Copy link

Choose a reason for hiding this comment

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

Since version 3.0.0, the lib is able to decrypt webpush messages:

  • When a new endpoint comes, you receive a PushEndpoint that contains p256dh and auth secrets that can be send to the server, so the server can encrypt your push notifications following RFC8291.
  • When a new message comes, you receive a PushMessage, if the library has correctly decrypted the push message with the webpush keys, content is the cleartext and decrypted is true.

At this moment, matrix doesn't officially support webpush messages. So for the moment, decrypted will always be false. There is a MSC to add webpush pusher. As mentioned in the MSC, some web clients have support for webpush with a gateway by hacking around the specifications. Once this MSC supported, you can even push to FCM servers without any gateway, because FCM servers can be requested with webpush requests (so Android won't need sygnal with servers supporting this MSC, this will probably help in some cases).

The library uses tink library to decrypt the push messages, and I think you have another library using it too. So you end up with duplicate classes. Maybe you should explicitly add tink as a dependency and exclude it from other library using it as well

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the fast and complete response. Maybe the unified push library should use tink-android and not tink and that would fix the conflicts? (even if I agree that we have another dependency (not checked which one yet) which has a dependency on an outdated version 1.8.0).

Copy link

Choose a reason for hiding this comment

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

You would have the same issue if 2 dependencies rely on tink-android, isn't it ?

I have opened an issue to migrate to tink-android, there are some pro/con to do the migration there

Copy link
Member

@jmartinesp jmartinesp Mar 12, 2025

Choose a reason for hiding this comment

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

(even if I agree that we have another dependency (not checked which one yet) which has a dependency on an outdated version 1.8.0)

I think it's this one:

androidx.security:security-crypto:1.1.0-alpha06
+--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
+--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
+--- androidx.collection:collection:1.1.0 -> 1.4.4 (*)
\--- com.google.crypto.tink:tink-android:1.8.0

... which is deprecated but we use to encrypted the session data. Yay 🥲 .

Copy link
Member Author

Choose a reason for hiding this comment

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

@bmarty
Copy link
Member Author

bmarty commented Mar 12, 2025

I am testing that the upgrade do not break anything, and sadly I do not receive anymore push from ntfy, even when not using a matrix.org account.

The troubleshoot fails at the "Test push loopback":

image

Logs:

POST https://ntfy.sh/_matrix/push/v1/notify 
{"notification":{"event_id":"$THIS_IS_A_FAKE_EVENT_ID","room_id":"!room:domain","devices":[{"app_id":"im.vector.app.android","pushkey":"https://ntfy.sh/upMQ1D9W3MlzAD?up=1"}]}}
<-- 507 https://ntfy.sh/_matrix/push/v1/notify
{"code":50701,"http":507,"error":"cannot publish to UnifiedPush topic without previously active subscriber"}

Seems related: binwiederhier/ntfy#649

@p1gp1g
Copy link

p1gp1g commented Mar 12, 2025

This may be because your ntfy didn't have any registration when it has received elemen-x request. And ntfy is a bit buggy during this state. This would be fixed with binwiederhier/ntfy-android#97

You can try Sunup, it will use the default gateway (matrix.gateway.unifiedpush.org) or create a first registration on ntfy before doing the tests

@bmarty
Copy link
Member Author

bmarty commented Mar 13, 2025

Testing again this morning, now the troubleshoot tests are OK, but I still do not receive push from the homeserver. When switching to Firebase it's working.

@p1gp1g
Copy link

p1gp1g commented Mar 13, 2025

MSC4173 would probably help here. The server may have rejected the push key due to the previous 507 error

You can try:

  • to remove the registration from ntfy (be sure to give it unrestricted background use, because of the bug quoted above) and try again
  • or try sunup

@Eskuero
Copy link

Eskuero commented Mar 13, 2025

I selfhost both ntfy and synapse

I built ntfy-android with binwiederhier/ntfy-android#97 and binwiederhier/ntfy-android#98
I built Element X with this patch based on the latest tag

  1. Upon installing I ran the the troubleshooting with my existing setup and it passed without issues as before
  2. Closed both apps from the foreground and sent a message, received instantly.
  3. Force closed Element X and cleared it's cache
  4. Sent another message, got the notification instantly too.
  5. Killed Element X and removed the topic from the ntfy android app
  6. Tried sending another message and obviously got nothing, but synapse logs still claimed to be trying to sending them to ntfy server (I guess this is a synapse/nfty server issue who are not communicating deletions and out of scope here)
  7. Opened Element X again and it automatically registered a new topic without any input.
  8. Run a troubleshoot without errores.
  9. Killed Element X again
  10. Sent another message, received without issues.

@Eskuero
Copy link

Eskuero commented Apr 9, 2025

Is there anything else missing or that I can test ? Been running the patch for a month without issues on notification receipts so on my clueless knowledge it seems ready to go.

@bmarty bmarty marked this pull request as ready for review April 9, 2025 14:59
@bmarty bmarty requested a review from a team as a code owner April 9, 2025 14:59
@bmarty bmarty requested review from jmartinesp and removed request for a team April 9, 2025 14:59
Comment on lines 46 to 50
// Exclude package com.google.crypto.tink
// Duplicate classes between
// tink-1.16.0.jar -> tink-1.16.0 (com.google.crypto.tink:tink:1.16.0)
// tink-android-1.8.0.jar tink-android-1.8.0 (com.google.crypto.tink:tink-android:1.8.0)
exclude(group = "com.google.crypto.tink", module = "tink")
Copy link
Member

Choose a reason for hiding this comment

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

I think this has to be removed now the dependency with the transitivity dependency to tink is gone.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in 57283a8

Copy link
Member Author

Choose a reason for hiding this comment

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

it seems to be still necessary

Copy link
Member

Choose a reason for hiding this comment

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

Weird, it wouldn't let me build the app locally with this exclusion 🫤 .

@jmartinesp
Copy link
Member

The current changes don't seem to work reliably on my end, sadly (element.io account).

  1. I switched Firebase to NTFY, it didn't seem to take effect until I restarted the app.
  2. Once restarted, I sent a few messages again from another account and I got one quite fast and the rest either were delayed a long time or didn't arrive at all.
  3. After a while no new notifications were received.

This device is charging and with the screen on, so Doze should not apply. The server is ntfy.sh, maybe I should change that.

The logs display a couple of timeouts, but otherwise just something like:

[https://ntfy.sh/xxxxxxl] Connection is active (failed=false, callCanceled=false, jobActive=true, serviceStarted=true

When a timeout happens, the service reconnects but no new notifications arrive. I might try with the changes proposed by @Eskuero above.

@p1gp1g
Copy link

p1gp1g commented Apr 10, 2025

The current changes don't seem to work reliably on my end, sadly (element.io account).

Can you try with Sunup, or with another ntfy server (eg. https://ntfy.adminforge.de/), and double check that you have allowed background usage without restrictions for ntfy

@jmartinesp
Copy link
Member

With Sunup the notifications arrive, but they're severely delayed (30s) and for some reason they appear twice in the list of notifications 😓 .

With NTFY + the alternative server, I had the same problemas as before: some notifications being delayed, most not arriving at all. I also couldn't build a custom version of NTFY with the patches mentioned above, the versions are quite outdated and every time I fix a problem another one appears...

@Eskuero
Copy link

Eskuero commented Apr 10, 2025

I have the app already built with the patches in my fdroid repo
https://repo.fromshado.ws/repo/
https://repo.fromshado.ws/repo/ntfy-android-fdroidrelease-fdroid.apk

If you would rather give another try at building the clean patchfile to apply is also here:
https://github.com/Eskuero/nino_samples/tree/master/ntfy-android

And also is true that probably the ntfy.sh instance is putting some ratelimits which might harm testing. If you want I can give you access to my ntfy instance. Ping me at @Eskuero:matrix.fromshado.ws

@p1gp1g
Copy link

p1gp1g commented Apr 10, 2025

With Sunup the notifications arrive, but they're severely delayed (30s) and for some reason they appear twice in the list of notifications 😓 .

This is probably not the best place to debug setups. There are a lot of reasons why a notification could be delayed (depending on the load on the server, if the client have history to fetch, if it can get the decryption keys, etc.). It also depends on your OS configuration, if it is in doze mode etc. When doing tests, you may figure out that sometimes the web client get its notification after the android client, sometimes the opposite. You 'd see the same thing with FCM too

@bmarty bmarty force-pushed the feature/bma/upUpdate branch from 60a982b to 57283a8 Compare April 17, 2025 15:12
@p1gp1g
Copy link

p1gp1g commented Apr 24, 2025

Can you try with version 3.0.9 ?

@bmarty
Copy link
Member Author

bmarty commented May 2, 2025

Can you try with version 3.0.9 ?

Sure. Is there any bug fixed on the new version that may help with the encountered problem?

Copy link

sonarqubecloud bot commented May 2, 2025

@p1gp1g
Copy link

p1gp1g commented May 2, 2025

Can you try with version 3.0.9 ?

Sure. Is there any bug fixed on the new version that may help with the encountered problem?

There was a bug that doesn't apply here, sorry for the ping. For the details, PushService can be used to replace the MessagingReceiver, but isn't used here and it didn't work correctly with SDK<33

@p1gp1g
Copy link

p1gp1g commented May 8, 2025

By the way, what is the encountered problem ? Is it the 507 response ?

@p1gp1g
Copy link

p1gp1g commented May 20, 2025

It may be better to use a resolutionStrategy than to exclude the transient dependency.

something like

configurations.all {
    resolutionStrategy {
        force(libs.tink)
        dependencySubstitution {
            substitute module('com.google.crypto.tink:tink-android') using module(libs.tink)
        }
    }
}

@jmartinesp
Copy link
Member

jmartinesp commented May 23, 2025

Just for the record, I was able to get reliable push notifications working in NTFY by doing:

  1. Deleting every single topic in ntfy.
  2. Changing the push server to ntfy.adminforge.de.
  3. Switching to firebase, then back to ntfy in the notification settings.
  4. Checking the new server is used in ntfy (a new topic is created with the server name being part of it).

I have battery optimizations disabled on EXA, btw. With it enabled, notifications sometimes take some time to arrive.

@bmarty
Copy link
Member Author

bmarty commented May 26, 2025

Thanks for the commit @jmartinesp !

We have decided to merge this PR and let users play with the nightly (that can be joined at https://appdistribution.firebase.dev/i/7de2dbc61e7fb2a6) and report any issue with UnifiedPush / ntfy.

If we got issues, we will revert this PR before the next release.

@ElementBot
Copy link
Collaborator

Warnings
⚠️

gradle/libs.versions.toml#L23 - A newer version of androidx.compose:compose-bom than 2025.04.00 is available: 2025.05.01

⚠️

gradle/libs.versions.toml#L40 - A newer version of io.coil-kt.coil3:coil-test than 3.1.0 is available: 3.2.0

⚠️

gradle/libs.versions.toml#L42 - A newer version of com.bumble.appyx:testing-junit4 than 1.7.0 is available: 1.7.1

⚠️

gradle/libs.versions.toml#L43 - A newer version of app.cash.sqldelight:sqlite-driver than 2.0.2 is available: 2.1.0

⚠️

gradle/libs.versions.toml#L45 - A newer version of me.saket.telephoto:zoomable-image-coil than 0.15.1 is available: 0.16.0

⚠️

gradle/libs.versions.toml#L189 - The native library arm64-v8a/libopuscodec.so (from io.element.android:opusencoder:1.1.0) is not 16 KB aligned

⚠️

gradle/libs.versions.toml#L210 - A newer version of io.element.android:element-call-embedded than 0.9.0 is available: 0.11.1

Generated by 🚫 dangerJS against beb7297

@bmarty bmarty merged commit 61075c7 into develop May 26, 2025
30 of 31 checks passed
@bmarty bmarty deleted the feature/bma/upUpdate branch May 26, 2025 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR-Dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants