1
0
mirror of https://github.com/element-hq/element-x-android.git synced 2026-10-23 18:49:00 +03:00

110 Commits

Author SHA1 Message Date
Benoit Marty
8912341439 Avoid database access on the main thread when opening the settings
`getUserProfile()` was storing the user profile (DB read, avatar Base64 encoding, DB write) on the caller
dispatcher, i.e. the main thread when called from a presenter, causing glitches in the screen transition.
- Run the whole `getUserProfile()` on the session dispatcher.
- Make `DatabaseSessionStore` main-safe by running the queries on the IO dispatcher.
- Do not refresh the profile twice from the settings screen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:42:19 +02:00
Benoit Marty
954eb731e7 Remove unused Gradle dependencies
Remove dependencies flagged as unused by the Dependency Analysis Gradle Plugin
(`./gradlew buildHealth`) and explicitly declared in module build files.

Removals were skipped when the dependency provides transitively something the
module (or a consumer of an `api` dependency) uses directly, as well as for
runtime-only dependencies (element-call-embedded, sentry-android,
rustls-platform-verifier). Dependencies added by the convention plugin helpers
(composeDependencies, testCommonDependencies) are left untouched.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 15:47:48 +02:00
Benoit Marty
db23023eda Store the user avatar thumbnail in the session database
Add a `userAvatarData` column to the session database, containing the base64 encoded
thumbnail of the user avatar. It will allow rendering the avatar of an account without
having to use its Matrix client, for instance on the signed out screen, or for other
accounts when the homeservers are not federated.

The thumbnail is downloaded when the user profile is retrieved or updated, and only if
the avatar URL has changed. The profile is now also persisted when received from the
own profile subscription.

Part of #5571

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 11:12:47 +02:00
Benoit Marty
e6116d5840 Move all binding containers to a di package and normalize their method names
Every @BindingContainer now lives in a di subpackage, in a file named after
it. Containers that were declared inside a shared file (SimplePlayer.kt,
LockScreenConfig.kt, VoiceMessagePresenter.kt, TimelineItemPresenterFactories.kt,
MediaItemPresenterFactories.kt) are extracted into their own file.

Method names are made consistent too:
- @Binds functions are named bind<ConcreteParameterType>, fixing three that
  named something else (notably RoomAliasResolverBindingContainer, whose
  provider was still called providesJoinRoomPresenterFactory).
- @Provides functions are named after what they provide, and all use the
  provides prefix rather than a mix of provide and provides.

ANDROID_KEYSTORE moves back to the cryptography impl package, next to
KeyStoreSecretKeyRepository which uses it; it is not DI specific and would
otherwise be unreachable from there.

No behaviour change: Metro discovers containers via @ContributesTo and does
not care about method names, so the only call site to follow was in
DefaultVoiceRecorderTest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 11:38:11 +02:00
Benoit Marty
1018d26211 Rename all @BindingContainer types with a BindingContainer suffix
Metro's @BindingContainer replaced Dagger's @Module, but the declarations
kept the old Module suffix. Rename them (and their dedicated files) so the
type name matches the annotation, matching UserStatusBindingContainer which
already followed this convention.

No behaviour change: Metro discovers containers via @ContributesTo, so there
were only two call sites to update, both in tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 10:08:54 +02:00
Benoit Marty
1ab401482a Fix formatting issues 2026-08-14 12:20:49 +02:00
Benoit Marty
012d43665f Add KDoc to the libraries/session-storage API interfaces
Document SessionStore, SessionObserver and SessionListener at the interface level
and add the missing @param entries.

The store doc records that sessions are ordered by last usage, which is what makes
"the latest session" meaningful across the rest of the interface, and the listener
doc explains that wasLastSession is the signal to clean up app-wide data too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 11:24:04 +02:00
Jorge Martin Espinosa
1e00353f29 Avoid SQLCipher key derivation (#6774)
* Avoid SQLCipher key derivation by manually providing the generated as a raw key: this needs a series of DB re-key operations, performed as part of a 'dummy' DB migration

* Set key generation length to 32 bytes in `RandomSecretPassphraseProvider`.

* Use `ClientSecret` for handling the keys for SQLCipher. Move `ClientSecret` to `:libraries:androidutils` so it's shared.
2026-05-27 17:25:51 +02:00
ganfra
e49e183178 Feature : share live location (#6741)
* First live location sharing sending implementation

* Simplify logic around canStop sharing

* Add some debug logs around LiveLocationSharingService

* Add LiveLocationException

* Expose beaconId to identify the current share

* Throttle live location instead of debouncing

* Keep sync alive when sharing live location

* Improve LiveLocation sharing

* Show LiveLocationDisclaimer

* Read minDistanceUpdate in LiveLocationSharingService

* Set minDistanceUpdate in AdvancedSettings

* Display banner in room when sharing live location

* Fix tests around LiveLocationSharing

* Ensure shares are properly restarted/stopped when app is re-launched

* Ensure LLS data is cleared when session is removed

* Update and fix LLS tests

* Handle Start LLS in ui

* Add check LLS permissions

* Remove hardcoded strings

* Fix quality and format

* Create DeviceLocationProvider so we can share location data between sources (presenter/live location service)

* Update screenshots

* Fix warning

* Do not try to stop if it was not sharing

* Revert "Create DeviceLocationProvider so we can share location data between sources (presenter/live location service)"

This reverts commit ba12bd968e.

* Tweak location provider config values

* Address PR review remarks

* Fix ktlint

* Update screenshots

* Fix some tests after merging develop

* Adjust TimelineItemLocationView ui to match figma

* Update screenshots

* Documentation and cleanup

* Remove temporary resource

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: Benoit Marty <benoitm@matrix.org>
2026-05-11 08:19:28 +00:00
Benoit Marty
4d0be69b4c In the module :libraries:matrix.api, change the dependencies to:
- libraries.sessionStorage.api
- projects.libraries.architecture
from `api` to `implementation`.

Modules who need `:libraries:matrix.api` do not necessarily need to use the session storage api.
2026-04-30 09:52:10 +02:00
Jorge Martin Espinosa
367995303d Rename OIDC components and variables to OAuth (#6686)
* Rename `OIDC` components and variables to `OAuth`. This matches the new behavior in the SDK.
2026-04-29 11:41:47 +02:00
Benoit Marty
9dfd0aad3b It seems that SqlDelight v2.3.1 does not like unnecessary file 2026-03-13 18:53:08 +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
Jorge Martín
6ef86cdda9 Test DefaultWorkManagerScheduler 2025-12-05 17:42:57 +01:00
Benoit Marty
a9ae55703a Remove unused slidingSyncProxy from DB. 2025-11-18 15:58:22 +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
Benoit Marty
85c9fd916b Session database: add count query. 2025-11-04 15:25:13 +01:00
Benoit Marty
752a4ea846 Fix detekt issue. 2025-10-23 18:03:22 +02:00
Benoit Marty
85035da028 Add unit test on DefaultLockScreenService 2025-10-23 17:20:36 +02:00
Benoit Marty
34a5785f38 Use TestScope.backgroundScope 2025-10-23 16:48:24 +02:00
Benoit Marty
11a808a2e0 Add test on wasLastSession value. 2025-10-23 16:48:23 +02:00
Benoit Marty
e23f9c31c5 Rename fixture fun for clarity. 2025-10-23 16:48:22 +02:00
Benoit Marty
a18eb6eb5e Add default implementation to SessionListener 2025-10-23 16:48:20 +02:00
Benoit Marty
9ca5fbdc08 Add parameter wasLastSession to SessionListener.onSessionDeleted 2025-10-23 16:20:15 +02:00
Benoit Marty
263e761907 Remove @Inject, not necessary anymore when class is annotated with @ContributesBinding 2025-10-22 18:52:37 +02:00
Benoit Marty
c5da479065 Improve API and documentation 2025-10-21 11:53:36 +02:00
Benoit Marty
7b00a12529 Avoid emitted a new value each time the token is refreshed (for instance) 2025-10-20 16:33:48 +02:00
Benoit Marty
38908a42a2 Update API around brandColor. 2025-10-20 16:33:46 +02:00
Benoit Marty
97f1bbd66a Add missing @Immutable annotation 2025-10-09 18:22:17 +02:00
Benoit Marty
1e546335df Multi accounts - experimental first implementation (#5285)
* Multi account - Do not reset analytics store on sign out.

Else when 1 of many accounts is removed, the analytics opt in screen is displayed again.

* Multi accounts - first implementation.

* Multi accounts - Prevent user from logging twice with the same account

* Multi accounts - ignore automatic GoBack in case of error.

* Multi accounts - update first view when adding an account.

* Rename method storeData to addSession.

* Multi accounts - handle account switch when coming from a notification

* Multi accounts - handle login link when there is already an account.

* Multi accounts - handle click on push history for not current account.

* Multi accounts - improve layout and add preview.

* Add accountselect modules

* Multi accounts - incoming share with account selection

* Multi accounts - check the feature flag before allowing login using login link.

* Multi accounts - swipe on account icon

* Cleanup

* Multi accounts - fix other implementation of SessionStore

* Multi accounts - fix PreferencesRootPresenterTest

* Multi accounts - Add test on AccountSelectPresenter

* Multi accounts - Fix test on HomePresenter - WIP

* Update database to be able to sort accounts by creation date.

* Add unit test on takeCurrentUserWithNeighbors

* Fix test and improve code.

* Add exception

* Multi accounts - handle permalink

* Code quality

* Multi accounts - localization

* Fix issue after rebase on develop

* Fix issue after rebase on develop

* Fix tests

* Fix tests

* Fix tests

* Fix tests

* Update Multi accounts flag details.

* Add missing test on DatabaseSessionStore

* Add missing preview on LoginModeView

* Remove dead code.

* Add missing preview on PushHistoryView

* Document API.

* Rename API and update test.

* Remove MatrixAuthenticationService.loggedInStateFlow()

* Update screenshots

* Remove unused import

* Add exception

* Fix compilation issue after rebase on develop.

* Update screenshots

* Fix test

* Avoid calling getLatestSession() twice

* Rename `matrixUserAndNeighbors` to `currentUserAndNeighbors`

* Extract code to its own class.

* Add comment to clarify the code.

* Init current user profile with what we now have in the database.

It allows having the cached data (user display name and avatar) when starting the application when no network is available.

* Let the RustMatrixClient update the profile in the session database

* Fix test.

* When logging out from Pin code screen, logout from all the sessions.

tom

* Make PushData.clientSecret mandatory.
Also do not restore the last session as a fallback, it can lead to error in a multi account context, or even when a ghost pusher send a Push.

* Change test in RustMatrixAuthenticationServiceTest

* Do not use MatrixAuthenticationService in RootFlowNode, only use SessionStore

* Remove MatrixAuthenticationService.getLatestSessionId()

* Fix compilation issue after merging develop

* Add test on DefaultAccountSelectEntryPoint

* Fix compilation issue after merging develop

* Introduce LoggedInAccountSwitcherNode, to improve animation when switching between accounts.

* Rename Node to follow naming convention.

* Fix navigation issue after login.

* Remove unused import

* Revert "Fix navigation issue after login."

This reverts commit e409630856.

* Revert "Rename Node to follow naming convention."

This reverts commit 883b1f37c7.

* Revert "Introduce LoggedInAccountSwitcherNode, to improve animation when switching between accounts."

This reverts commit 9c698ff815.

* Metro now have `@AssistedInject`.

* Update screenshots

* Introduce DelegateTransitionHandler and use it in RootFlowNode

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: ganfra <francoisg@element.io>
2025-09-26 15:45:06 +02:00
Benoit Marty
80fa442b64 Rename API and update test. 2025-09-19 10:57:18 +02:00
Benoit Marty
65d682f8ca Rename method storeData to addSession. 2025-09-19 10:57:17 +02:00
Benoit Marty
a575019760 Use DependencyHandlerScope.testCommonDependencies() 2025-09-16 14:38:31 +02:00
Jorge Martín
de8de61b2e Remove dagger and anvil dependencies, try to simplify gradle build scripts a bit 2025-09-04 16:49:21 +02:00
Jorge Martín
4ab62a6a38 Redo DI gradle setup code 2025-09-04 16:49:20 +02:00
Jorge Martín
29a97fc0d9 Fix lint issues and restore commented out code 2025-09-04 16:49:18 +02:00
Jorge Martín
b76a71ebf5 Start migrating Anvil KSP to Metro 2025-09-04 16:48:34 +02:00
Benoit Marty
58696780c8 Fix error. 2025-09-01 16:41:12 +02:00
Benoit Marty
025131841b Cleanup tests. 2025-09-01 15:03:41 +02:00
Benoit Marty
75a640b986 Refactor: Move InMemorySessionStore to test module
- Delete `libraries/session-storage/impl-memory` module
- Move `InMemorySessionStore.kt` to `libraries/session-storage/test`
2025-09-01 14:47:42 +02:00
Benoit Marty
5f191d9f9c Fix coroutine scope (#4820)
* Inject the session scope instead of the application scope where it's possible.

* Create AppCoroutineScope annotation to let developers explicitly choose the appropriate CoroutineScope when injecting one.
2025-06-04 15:33:51 +00:00
renovate[bot]
f0c9f8294a fix(deps): update sqldelight to v2.1.0 (#4735)
* fix(deps): update sqldelight to v2.1.0

* Ignore new returned value from database query which know have type QueryResult<Long>.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
2025-05-26 14:58:57 +02:00
renovate[bot]
1dcd6088d3 fix(deps): update kotlin (#4552)
* fix(deps): update kotlin

* Fix deprecation warning

* Remove this workaround, it's not needed anymore, and was causing a compilation error:

* What went wrong:
A problem occurred configuring project ':libraries:session-storage:impl'.
> Failed to notify project evaluation listener.
   > Element 'kspDebugKotlin' of type 'com.google.devtools.ksp.gradle.KspAATask_Decorated' from container 'task set' cannot be cast to 'org.jetbrains.kotlin.gradle.tasks.KotlinCompile'.
   > Element 'kspReleaseKotlin' of type 'com.google.devtools.ksp.gradle.KspAATask_Decorated' from container 'task set' cannot be cast to 'org.jetbrains.kotlin.gradle.tasks.KotlinCompile'.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
2025-04-09 16:45:48 +02:00
Jorge Martin Espinosa
715d75c5c4 Add Google Tink dependency, replacing androidx.security.crypto (#4405)
* Add Google Tink dependency, replacing `androidx.security.crypto`

* Replace the `EncryptedFile` implementation too

* Extract constants, add some more docs
2025-03-17 10:04:21 +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
Jorge Martin Espinosa
79c17f714f Use Anvil KSP instead of the Square KAPT one (#3564)
* Use Anvil KSP instead of the Square KAPT one

* Fix several configuration cache, lint and test issues

* Allow incremental kotlin compilation in the CI

* Workaround Robolectric + Compose issue that caused `AppNotIdleException`

* Update the `enterprise` commit hash

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2024-10-02 11:52:17 +00:00
Jorge Martin Espinosa
eeec7cc785 Centralise the DI code generation logic (#3562)
* Create Anvil extension helper

* Use the helper everywhere
2024-09-30 12:20:28 +00:00
Benoit Marty
86844e0b27 Add test on RustClientSessionDelegate 2024-09-19 12:30:40 +02:00