`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>
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>
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>
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>
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>
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>
* 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.
* 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>
- 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.
* 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.
* 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>
* 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.
* 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>
* 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>
* Add Google Tink dependency, replacing `androidx.security.crypto`
* Replace the `EncryptedFile` implementation too
* Extract constants, add some more docs
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."
* 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>