Commit graph

53 commits

Author SHA1 Message Date
Jorge Martin Espinosa
bba2e6df3f
Fix ForegroundServiceDidNotStartInTimeException (#6470)
* Start the `FetchPushForegroundService ` in foreground ASAP. This is a first step to mitigate `ForegroundServiceDidNotStartInTimeException` being thrown.

* Don't stop the service immediately if it's running but not in foreground. Try waiting up to 5s for it to be in foreground.
2026-03-27 06:54:27 +00:00
Jorge Martin Espinosa
8e46e68630
Add a foreground service with a wakelock for fetching push notifications (#6321)
* Create `PushHandlingWakeLock` to start a foreground service:

When receiving a push and scheduling the notification fetching, several problems can happen:

1. Some async operation is waiting for a timeout and it takes way longer than that to finish (i.e. timeout of 10s but it took 30s to advance).
2. The same, but when starting new coroutines. I've seen the time between scheduling a coroutine and it running sometimes take up to 1 minute.
3. Notification fetching can be scheduled immediately, but it can take a while to actually run because the OS understands the app is now in Doze.

Having a wakelock that runs as soon as the push handling starts fixes these: it continues the previous wakelock held by either Firebase or the UnifiedPush distributor.

* Acquire the wakelock as soon as we received the pushes in both receivers

* Also release the wakelock ahead of time if possible
2026-03-17 14:24:26 +01:00
Jorge Martin Espinosa
68023b5c74
Simplify push notification flow by using locally stored values for pending pushes (#6258)
* Create `PushRequest` in push history DB: this will be used to store requests for push notifications, either pending or completed ones.

* Rename `WorkManagerRequest` to `WorkManagerRequestBuilder`: make its `build` method return a list of `WorkManagerRequestWrapper`, which can be used to enqueue normal or unique workers.

* Rename `PerformDatabaseVacuumRequestBuilder` and adapt it to the new API.

* Adjust other components using `WorkManagerRequest`.

* Replace `SyncNotificationWorkManagerRequestBuilder` with `SyncPendingNotificationsRequestBuilder` and `FetchNotificationsWorker` with `FetchPendingNotificationsWorker`: this new pair of request builder and worker allow enqueuing requests for a session id and, once the worker runs, retrieve all the pending request data and use it to fetch the associated events. This simplifies quite a bit how this data had to be passed or grouped, since it's no longer necessary to do so

* Add new methods to `PushHistoryService` to modify the `PushDatabase`:

- insertOrUpdatePushRequest
- insertOrUpdatePushRequests
- getPendingPushRequests
- removeOldPushRequests

* Make `PushHandler` just handle incoming pushes: those will be inserted into the pending push request table in DB, then handled by the new worker. Once the process finished, a new `NotificationResultProcessor` will handle the results and what needs to be done with them (call ringing, displaying notifications, etc.)

* Add `requestType` optional parameter to `WorkManagerScheduler.cancel` so we can decide to only cancel some kinds of requests.

* Add migration to remove existing work manager requests for fetching notifications, since the previous worker class no longer exists.
2026-03-03 15:14:36 +00:00
Benoit Marty
6f13feed13 No need for an id, can use ordinal. 2025-11-14 09:38:31 +01:00
Benoit Marty
d3339872ff Ensure that disabling (resp. enabling) notification unregisters (resp. registers) the pusher 2025-11-13 17:50:21 +01:00
Benoit Marty
f9c0b9e8bb UnifiedPush: emit error when registration fails.
Note that I did not manage to have the method `onRegistrationFailed` invoked. If the network is not available for instance, unregistering the previous pusher will fail first.
2025-11-13 14:56:20 +01:00
Benoit Marty
573767aca1 Let notifications use avatar fallback.
Extract code which handles Matrix image to its own api / impl / test modules.
2025-11-12 11:28:42 +01:00
Benoit Marty
eb31505dc7 Copyright: Add Element Creations Ltd. copyright 2025-11-10 11:05:05 +01:00
Benoit Marty
f86431e663 Copyright: Add final period 2025-11-10 10:13:41 +01:00
Benoit Marty
c4e0370f41 Copyright: run command uv run license-editor --repository ../element-x-android 2025-11-10 10:09:26 +01:00
Jorge Martin Espinosa
eb08639776
Split notifications for messages in threads (#5595)
* Separate thread notifications into their own notifications when the feature flag is enabled.

Otherwise, set the `threadId` to null so it'll behave as usual. It's done this way to avoid having to inject `FeatureFlagService` in several places.

* Add permalink navigation to threads from notifications, focusing on the latest event in the list of messages of the notification tapped

* Fix redactions in threads

* Clear notifications for a thread when visiting it

* Fix opening a thread happening twice, first because of the `openThreadId` value, then because of the `focusedEventId` one

* Make opening a room through a notification also focus on the latest event

* Add helper `NotificationCreator.messageTag` function

* Remove unused `ROOM_CALL_NOTIFICATION_ID`: `FOREGROUND_SERVICE_NOTIFICATION_ID`+ `ForegroundServiceType` is used instead

* Simplify `DefaultDeepLinkCreator`

* Make sure the main timeline focuses on the thread root id too when navigating to a thread

* Handle "Mark as read" action for thread notification, using `timeline.markAsRead`

* Log failures to mark rooms as read using the notification action

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
2025-10-30 15:15:00 +00:00
Jorge Martin Espinosa
84d0338ed3
Fix issues with WorkManager on Android 12 and below (#5606)
* Add `getForegroundInfo` implementation to try to fix issues with WorkManager on Android 12 and below

This may be a MIUI-only issue as I couldn't reproduce it with several emulators on Android 11, 12 and 13.

* Use `setExpedited` only on Android 13 or higher, it's not needed on older versions

* Use an actual string resource, fix tests

* Fix review comments

* Fix broken test with Element Pro:

Instead of using Robolectric with API < 33 (since Pro uses minSdk 33) use a `BuildVersionSdkIntProvider`

* Remove `getForegroundInfo` and the associated permission, as we expect it to be dead code

* Fix lint issues

* Cleanup NotificationIdProvider

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
2025-10-28 20:06:57 +00:00
Benoit Marty
705b1b08f2 Remove dependency on AppNavigationStateService from DefaultGetCurrentPushProvider 2025-10-23 15:03:04 +02:00
Jorge Martin Espinosa
ebe94f873e
Sync notifications using WorkManager (#5545)
* Initial implementation of notification sync using `WorkManager`

* Use custom `MetroWorkerFactory` to allow assisted injection in WorkManager Workers

* Add tests for `FetchNotificationWorker`. Create `FakeNotificationResolverQueue` to help testing.

* Add more tests, fix Konsist checks

* Add tests for `SyncNotificationWorkManagerRequest`

* Simplify `FakeNotificationResolverQueue`
2025-10-17 09:51:27 +00:00
Benoit Marty
80750dcb39 Need to be a compose library for PushHistoryItem to be considered stable. 2025-10-09 18:22:28 +02:00
Jorge Martin Espinosa
9bc2c4a776
Add shortcut suggestions for rooms, remove then when leaving (#5180)
* Report shortcut usage for outgoing messages

This patch adds support for creating and pushing dynamic
long-lived shortcuts for outgoing messages. This together
with an existing reference to the roomId used by the
shortcuts as an identifer allows conversations to be
prioritized.

See https://developer.android.com/training/sharing/direct-share-targets#report-usage-outgoing

* Simplify how to get the other user in a DM room

* Add initial avatar icons to shortcuts

* Remove room shortcuts when they're no longer joined

* Try using API 33 for the new tests. They worked locally with API 30, so it's weird the CI asks for a higher API version.

* Add observers for the pin code and session logout states. With this we can prevent new shortcuts from being created and remove existing ones when needed.

* Wrap all calls to `ShortcutManagerCompat` with `runCatchingExceptions` to avoid crashes

* Make `DefaultNotificationConversationService` a singleton.

---------

Co-authored-by: networkException <git@nwex.de>
Co-authored-by: ElementBot <android@element.io>
2025-08-19 16:02:51 +02:00
Benoit Marty
017664f672 Ensure that the battery optimization banner is not displayed after an internal clear cache. 2025-06-17 16:31:35 +02:00
Benoit Marty
751f7e766c Rename DoAction to more specific RequestDisableOptimizations 2025-06-16 10:49:26 +02:00
Benoit Marty
6fbde3d407 Avoid using the Activity, and use eventSink instead of lambda in states. 2025-06-10 16:01:19 +02:00
Benoit Marty
7deed4cc86 Add a banner to ask the user to disable battery optimization when Event cannot be resolved from Push. 2025-06-09 15:09:00 +02:00
Benoit Marty
c7f0566dc1
Introduce PushHistoryService to store data about the received push (#4573)
* Introduce PushHistoryService to store data about the received push

Add a push database.

* Update screenshots

* Improve preview.

* Update screenshots

* Add missing test.

* Add test for PushHistoryView

* Fix configuration issue.

Was: w: /libraries/troubleshoot/impl/src/test/kotlin/io/element/android/libraries/troubleshoot/impl/history/PushHistoryPresenterTest.kt:35:27 Cannot access class 'PushProvider' in the expression type. While it may work, this case indicates a configuration mistake and can lead to avoidable compilation errors, so it may be forbidden soon. Check your module classpath for missing or conflicting dependencies.

---------

Co-authored-by: ElementBot <android@element.io>
2025-04-11 12:56:54 +02:00
Benoit Marty
a70249769d Migrate to coil3 2025-03-03 12:30:26 +01:00
Benoit Marty
97f3be3dc5 Apply dual licenses: AGPL + Element Commercial to file headers.
2 replace all actions have been performed:
- "SPDX-License-Identifier: AGPL-3.0-only" to "SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial"
- "Please see LICENSE in the repository root for full details." to "Please see LICENSE files in the repository root for full details."
2025-01-07 10:05:04 +01:00
Benoit Marty
500659d4e1 Change signature of selectPushProvider and add missing unit test. 2024-11-15 15:13:24 +01:00
Benoit Marty
f61df38e55 Migrate license to AGPL.
Run script `uv run license-editor --repository ../element-x-android`
2024-09-06 17:19:19 +02:00
Benoit Marty
6ea629a4d2 Rename interface NotificationDrawerManager to NotificationCleaner since it actually contains only method to remove notifications. 2024-07-16 11:24:41 +02:00
Benoit Marty
b4b407a69e Store the first provider even if no distributor is available, else error in troubleshoot test will not be accurate.
Also when registering for the first time, pick the fist available provider with at least one distributor.
2024-06-17 17:36:39 +02:00
Benoit Marty
f72fc36de8 Update PushProvider API, remove isAvailable(), but instead rely on getDistributors() to eventually return an empty list of Distributors. 2024-06-17 17:25:13 +02:00
Benoit Marty
64930e4435 Add ability to not show the pusher registration again. 2024-06-17 11:38:32 +02:00
Jorge Martin Espinosa
30a1367714
Element Call ringing notifications (#2978)
- Add `ActiveCallManager` to handle incoming and ongoing calls.
- Add ringing call notifications with full screen intents and missed call ones as part of the 'conversation' notifications.

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
2024-06-10 11:51:19 +02:00
Benoit Marty
61b3709970 Let NotificationBroadcastReceiver inject NotificationDrawerManager instead of implementation 2024-06-05 14:59:47 +02:00
Jorge Martin Espinosa
04e503177b
Notifications: simplify the flow by removing persistence (#2924)
* Notifications: simplify the flow by removing persistence. 
* Bump of minSdk to `24` (Android 7).
* Add migration to remove `notification.bin` file
2024-05-29 08:03:23 +00:00
Benoit Marty
b70c5915f7 Remove unused code notificationStyleChanged()
We may properly add it again later if necessary.
2024-05-22 11:31:56 +02:00
Benoit Marty
a65c290dd3 Improve API, to avoid ignoring errors 2024-05-21 14:45:16 +02:00
Benoit Marty
d2fbff09b8 Push distributor: ensure the current UnifiedPush distributor is stored 2024-05-21 14:45:15 +02:00
Benoit Marty
2bfe125a77 Troubleshoot notifications screen 2024-04-02 16:15:00 +02:00
Benoit Marty
7498c148f1 Ensure that a PushProvider is available on a device before using it.
It help to fallback to UnifiedPush (if available) if the PlayServices are not installed on the device.
2024-01-17 17:11:34 +01:00
Benoit Marty
1c56d95eab Do not render notification if the user has dismiss the notification.
It should not change anything, just avoid doing useless notification rendering.
2023-09-15 15:42:55 +02:00
Benoit Marty
7083abcf09 migrate object to data object (#1135) 2023-08-24 09:32:44 +02:00
Jorge Martin Espinosa
a0c1f2c18a
Display room invitation notification (#735)
* Notifications: Add some extra mappings so we keep the original contents and can pass it later to an UI layer

* Fix notifications not appearing for a room if the app was on that room when it went to background.

* Modernize how we create spannable strings for notifications, remove unneeded dependency

* Remove actions from invite notifications temporarily

* Add `NotificationDrawerManager` interface to be able to clear membership notifications when accepting or rejecting a room invite

* Fix tests

* Add comment to clarify some weird behaviours

* Address review comments

* Set circle shape for `largeBitmap` in message notifications

* Fix no avatar in DM rooms

* Fix rebase issues

* Add invite list pending intent:

- Refactor pending intents.
- Make `DeepLinkData` a sealed interface.
- Fix and add tests.

* Rename `navigate__` functions to `attach__`

* Add an extra test case for the `InviteList` deep link

* Address most review comments.

* Fix rebase issue

* Add fallback notification type, allow dismissing invite notifications.

Fallback notifications have a different underlying type and can be dismissed at will.

* Fix tests
2023-07-10 14:34:58 +02:00
Yoan Pintas
f534ecda96 Init analytics modules (#350) 2023-06-05 13:11:34 +00:00
Jorge Martin Espinosa
de010545fb Update Gradle to 8.1 and AGP to v8.0 (#329)
* Update AGP to 8.0.0.

* Set JAVA_HOME to JDK17

* Update lint version.

* Use right JDK for dependency analysis, replace deprecated env var.

* Upgrade to Gradle 8.1.

* Remove `@Supress(DSL_SCOPE_VIOLATION)` as it's no longer needed.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-17 08:49:52 +00:00
Benoit Marty
ce9ec1a066 Use Firebase by default and cleanup 2023-04-12 09:50:04 +02:00
Benoit Marty
dd71517abe Cleanup store. 2023-04-12 09:50:04 +02:00
Benoit Marty
287fca5438 UnifiedPush WIP 2023-04-12 09:49:23 +02:00
Benoit Marty
7333995630 Split push module into several modules: Firebase, UnifiedPush, store 2023-04-12 09:48:56 +02:00
Benoit Marty
7e7e798acf Making progress on notification for multi account. 2023-04-05 16:59:17 +02:00
Benoit Marty
6ecbe1f856 Cleanup + Add per user store. 2023-04-05 16:59:17 +02:00
Benoit Marty
6e4b1cd958 Create a LoggedInNode, used as a PermanentNode in LoggedInFlowNode 2023-04-05 16:59:17 +02:00
Benoit Marty
d41f4fc954 Retrieve notification - WIP 2023-04-05 16:32:28 +02:00