diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md
new file mode 100644
index 0000000000..154e93286c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/release.md
@@ -0,0 +1,84 @@
+---
+name: Release
+about: Checklist for each release. To be used by the core team only.
+title: "[Release] Element Android v"
+labels: "\U0001F680 Release"
+assignees: bmarty
+
+---
+
+For the example, we are releasing the version 1.1.10. Delete this line and replace 1.1.10 with the version in the issue content.
+
+### Before the release
+
+- [ ] Weblate sync, fix lint issue if any (in a dedicated PR)
+- [ ] Check the update of the store descriptions (using Google Translate if necessary) to ensure that the changes are acceptable to be published to the stores.
+- [ ] Run the script `./tools/release/pushPlayStoreMetaData.sh`. You can check in the GooglePlay console the Activity log to check the effect.
+
+### Do the release
+
+- [ ] Create release with gitflow, branch name `release/1.1.10`
+- [ ] Run `./tools/import_emojis.py` and commit the change if any.
+- [ ] Run `./tools/import_sas_strings.py` and commit the change if any. If there is no change since a while, ping Travis
+- [ ] Check the crashes from the PlayStore
+- [ ] Check the rageshake with the current dev version: https://github.com/matrix-org/element-android-rageshakes/labels/1.1.10-dev
+- [ ] Run the integration test, and especially `UiAllScreensSanityTest.allScreensTest()`
+- [ ] Create an account on matrix.org
+- [ ] Run towncrier: `towncrier --version v1.1.10 --draft` (remove `--draft` do write the file CHANGES.md)
+- [ ] Add file for fastlane under ./fastlane/metadata/android/en-US/changelogs
+- [ ] Push the branch and start a draft PR (will not be merged), to check that the CI is happy with all the changes.
+- [ ] Finish release with gitflow, delete the draft PR
+- [ ] Push `main` and the new tag `v1.1.10` to origin
+- [ ] Checkout `develop`
+- [ ] Increase version in `./vector/build.gradle`
+- [ ] Commit and push `develop`
+- [ ] Wait for [Buildkite](https://buildkite.com/matrix-dot-org/element-android/builds?branch=main) to build the `main` branch.
+- [ ] Run the script `~/scripts/releaseElement.sh`. It will download the APKs from Buildkite check them and sign them.
+- [ ] Install the APK on your phone to check that the upgrade went well (no init sync, etc.)
+- [ ] Create a new beta release on the GooglePlay console and upload the 4 signed Apks.
+- [ ] Check that the version codes are correct
+- [ ] Copy the fastlane change to the GooglePlay console in the section en-GB.
+- [ ] Push to beta release to 100% of the users
+- [ ] Create the release on gitHub [from the tag](https://github.com/vector-im/element-android/tags), copy paste the block from the file CHANGES.md
+- [ ] Add the 4 signed APKs to the GitHub release
+- [ ] Ping the Android Internal room
+- [ ] Add an entry in the internal diary
+
+### Once Live on PlayStore
+
+- [ ] Ping the Android public room and update its topic
+
+### After at least 2 days
+
+- [ ] Check the [rageshakes](https://github.com/matrix-org/element-android-rageshakes/issues)
+- [ ] Check the crash reports on the GooglePlay console
+- [ ] Check the Android Element room for any reported issues on the new version
+- [ ] If all is OK, push to production and notify Markus (Bubu) to release the F-Droid version
+- [ ] Ping the Android public room and update its topic with the new available version
+
+### Android SDK2
+
+- [ ] Checkout the `main` branch on Element Android project
+
+#### On the SDK2 project
+
+https://github.com/matrix-org/matrix-android-sdk2
+
+- [ ] Create a release with GitFlow
+- [ ] Update the files `./build.gradle` and `./gradle/gradle-wrapper.properties` manually, to use the latest version for the dependency. You can get inspired by the same files on Element Android project.
+- [ ] Run the script `./tools/import_from_element.sh`
+- [ ] Update the version in `./matrix-sdk-android/build.gradle` and let the script finish to build the library
+- [ ] Update the file `CHANGES.md`
+- [ ] Finish the release using GitFlow
+- [ ] Create the release on GitHub from [the tag](https://github.com/matrix-org/matrix-android-sdk2/tags)
+- [ ] Upload the AAR on the GitHub release
+
+### Android SDK2 sample
+
+https://github.com/matrix-org/matrix-android-sdk2-sample
+
+- [ ] Update the dependency to the new version of the SDK2. Jitpack will have to build the AAR, it can take a few minutes. You can check status on https://jitpack.io/#matrix-org/matrix-android-sdk2
+- [ ] Build and run the sample, you may have to fix some API break
+- [ ] Commit and push directly on `main`
+
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 34d7b40a88..8fbc5602fe 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -5,6 +5,6 @@
- [ ] Changes has been tested on an Android device or Android emulator with API 21
- [ ] UI change has been tested on both light and dark themes
- [ ] Pull request is based on the develop branch
-- [ ] Pull request updates [CHANGES.md](https://github.com/vector-im/element-android/blob/develop/CHANGES.md)
+- [ ] Pull request includes a new file under ./changelog.d. See https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog
- [ ] Pull request includes screenshots or videos if containing UI changes
- [ ] Pull request includes a [sign off](https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md#sign-off)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000000..85148a2632
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,59 @@
+name: APK Build
+
+on:
+ pull_request: { }
+ push:
+ branches: [ main, develop ]
+
+jobs:
+ debug:
+ name: Build debug APKs (${{ matrix.target }})
+ runs-on: ubuntu-latest
+ if: github.ref != 'refs/heads/main'
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [ Gplay, Fdroid ]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Assemble ${{ matrix.target }} debug apk
+ run: ./gradlew assemble${{ matrix.target }}Debug --stacktrace
+ - name: Upload ${{ matrix.target }} debug APKs
+ uses: actions/upload-artifact@v2
+ with:
+ name: vector-${{ matrix.target }}-debug
+ path: |
+ vector/build/outputs/apk/*/debug/*.apk
+
+ release:
+ name: Build unsigned GPlay APKs
+ runs-on: ubuntu-latest
+ if: github.ref == 'refs/heads/main'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Assemble GPlay unsigned apk
+ run: ./gradlew clean assembleGplayRelease --stacktrace
+ - name: Upload Gplay unsigned APKs
+ uses: actions/upload-artifact@v2
+ with:
+ name: vector-gplay-release-unsigned
+ path: |
+ vector/build/outputs/apk/*/release/*.apk
+
+# TODO: add exodus checks
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
new file mode 100644
index 0000000000..cb6f1b0e48
--- /dev/null
+++ b/.github/workflows/integration.yml
@@ -0,0 +1,49 @@
+name: Integration Test
+
+on:
+ pull_request: { }
+ push:
+ branches: [ main, develop ]
+
+jobs:
+ integration-tests:
+ name: Integration Tests (Synapse)
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ api-level: [21, 30]
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.8
+ - name: Cache pip
+ uses: actions/cache@v2
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip
+ restore-keys: |
+ ${{ runner.os }}-pip-
+ ${{ runner.os }}-
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Start synapse server
+ run: |
+ python3 -m venv .synapse
+ source .synapse/bin/activate
+ pip install synapse matrix-synapse
+ curl -sL https://raw.githubusercontent.com/matrix-org/synapse/develop/demo/start.sh --no-rate-limit \
+ | sed s/127.0.0.1/0.0.0.0/g | bash
+ - name: Run integration tests on API ${{ matrix.api-level }}
+ uses: reactivecircus/android-emulator-runner@v2
+ with:
+ api-level: ${{ matrix.api-level }}
+ # script: ./gradlew -PallWarningsAsErrors=false vector:connectedAndroidTest matrix-sdk-android:connectedAndroidTest
+ script: ./gradlew -PallWarningsAsErrors=false connectedCheck
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
new file mode 100644
index 0000000000..a65e6b5dee
--- /dev/null
+++ b/.github/workflows/quality.yml
@@ -0,0 +1,74 @@
+name: Code Quality Checks
+
+on:
+ pull_request: { }
+ push:
+ branches: [ main, develop ]
+
+jobs:
+ check:
+ name: Project Check Suite
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Run code quality check suite
+ run: ./tools/check/check_code_quality.sh
+
+ klint:
+ name: Kotlin Linter
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Run klint
+ run: |
+ curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.36.0/ktlint && chmod a+x ktlint
+ ./ktlint --android --experimental -v
+
+ android-lint:
+ name: Android Linter
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Lint analysis of the SDK
+ run: ./gradlew clean :matrix-sdk-android:lintRelease --stacktrace
+ - name: Upload reports
+ uses: actions/upload-artifact@v2
+ with:
+ name: linting-report-android-sdk
+ path: matrix-sdk-android/build/reports/*.*
+
+ apk-lint:
+ name: Lint APK (${{ matrix.target }})
+ runs-on: ubuntu-latest
+ if: github.ref != 'refs/heads/main'
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [ Gplay, Fdroid ]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Lint ${{ matrix.target }} release
+ run: ./gradlew clean lint${{ matrix.target }}Release --stacktrace
+ - name: Upload ${{ matrix.target }} linting report
+ uses: actions/upload-artifact@v2
+ if: always()
+ with:
+ name: release-debug-linting-report-${{ matrix.target }}
+ path: |
+ vector/build/reports/*.*
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000000..6e51368ce5
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,23 @@
+name: Test
+
+on:
+ pull_request: {}
+ push:
+ branches: [main, develop]
+
+jobs:
+ unit-tests:
+ name: Run Unit Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Run unit tests
+ run: ./gradlew clean test --stacktrace -PallWarningsAsErrors=false
diff --git a/.gitignore b/.gitignore
index 4a264a28d8..04d1b6fe06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,5 +12,7 @@
.externalNativeBuild
/tmp
+/fastlane/private
+/fastlane/report.xml
ktlint
diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index 4585842153..e143720aa9 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -37,6 +37,8 @@
threepidunpublishunwedging
+ vctr
+ wellknown
\ No newline at end of file
diff --git a/CHANGES.md b/CHANGES.md
index 3dda2fcb18..1d1e179426 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,33 +1,197 @@
-Changes in Element 1.1.8 (2021-XX-XX)
-===================================================
+Changes in Element v1.2.0 (2021-08-12)
+======================================
+
+Features ✨
+----------
+ - Reorganise Advanced Notifications in to Default Notifications, Keywords and Mentions, Other (This feature is hidden in the release ui until a future release date.) ([#3646](https://github.com/vector-im/element-android/issues/3646))
+ - Voice Message - Enable by default, remove from labs ([#3817](https://github.com/vector-im/element-android/issues/3817))
+
+Bugfixes 🐛
+----------
+ - Voice Message - UI Improvements ([#3798](https://github.com/vector-im/element-android/issues/3798))
+ - Stop VMs playing in the timeline if a new VM recording is started ([#3802](https://github.com/vector-im/element-android/issues/3802))
+
+
+Changes in Element v1.1.16 (2021-08-09)
+=======================================
+
+Features ✨
+----------
+ - Spaces - Support Restricted Room via room capabilities API ([#3509](https://github.com/vector-im/element-android/issues/3509))
+ - Spaces | Support restricted room access in room settings ([#3665](https://github.com/vector-im/element-android/issues/3665))
+
+Bugfixes 🐛
+----------
+ - Fix crash when opening Troubleshoot Notifications ([#3778](https://github.com/vector-im/element-android/issues/3778))
+ - Fix error when sending encrypted message if someone in the room logs out. ([#3792](https://github.com/vector-im/element-android/issues/3792))
+ - Voice Message - Amplitude update java.util.ConcurrentModificationException ([#3796](https://github.com/vector-im/element-android/issues/3796))
+
+
+Changes in Element v1.1.15 (2021-07-30)
+=======================================
+
+Features ✨
+----------
+ - Voice Message implementation (Currently under Labs Settings and disabled by default). ([#3598](https://github.com/vector-im/element-android/issues/3598))
+
+SDK API changes ⚠️
+------------------
+ - updatePushRuleActions signature has been updated to more explicitly enabled/disable the rule and update the actions. It's behaviour has also been changed to match the web with the enable/disable requests being sent on every invocation and actions sent when needed(not null). ([#3681](https://github.com/vector-im/element-android/issues/3681))
+
+
+Changes in Element 1.1.14 (2021-07-23)
+======================================
+
+Features ✨
+----------
+ - Add low priority section in DM tab ([#3463](https://github.com/vector-im/element-android/issues/3463))
+ - Show missed call notification. ([#3710](https://github.com/vector-im/element-android/issues/3710))
+
+Bugfixes 🐛
+----------
+ - Don't use the transaction ID of the verification for the request ([#3589](https://github.com/vector-im/element-android/issues/3589))
+ - Avoid incomplete downloads in cache ([#3656](https://github.com/vector-im/element-android/issues/3656))
+ - Fix a crash which can happen when user signs out ([#3720](https://github.com/vector-im/element-android/issues/3720))
+ - Ensure OTKs are uploaded when the session is created ([#3724](https://github.com/vector-im/element-android/issues/3724))
+
+SDK API changes ⚠️
+------------------
+ - Add initialState support to CreateRoomParams (#3713) ([#3713](https://github.com/vector-im/element-android/issues/3713))
+
+Other changes
+-------------
+ - Apply grammatical fixes to the Server ACL timeline messages. ([#3721](https://github.com/vector-im/element-android/issues/3721))
+ - Add tags in the log, especially for VoIP, but can be used for other features in the future ([#3723](https://github.com/vector-im/element-android/issues/3723))
+
+
+Changes in Element v1.1.13 (2021-07-19)
+=======================================
+
+Features ✨
+----------
+ - Remove redundant mimetype (vector-im/element-web#2547) ([#3273](https://github.com/vector-im/element-android/issues/3273))
+ - Room version capabilities and room upgrade support, better error feedback ([#3551](https://github.com/vector-im/element-android/issues/3551))
+ - Add retry support in room addresses screen ([#3635](https://github.com/vector-im/element-android/issues/3635))
+ - Better management of permission requests ([#3667](https://github.com/vector-im/element-android/issues/3667))
+
+Bugfixes 🐛
+----------
+ - Standardise spelling and casing of homeserver, identity server, and integration manager. ([#491](https://github.com/vector-im/element-android/issues/491))
+ - Perform .well-known request first, even if the entered URL is a valid homeserver base url ([#2843](https://github.com/vector-im/element-android/issues/2843))
+ - Use different copy for self verification. ([#3624](https://github.com/vector-im/element-android/issues/3624))
+ - Crash when opening room addresses screen with no internet connection ([#3634](https://github.com/vector-im/element-android/issues/3634))
+ - Fix unread messages marker being hidden in collapsed membership item ([#3655](https://github.com/vector-im/element-android/issues/3655))
+ - Ensure reaction emoji picker tabs look fine on small displays ([#3661](https://github.com/vector-im/element-android/issues/3661))
+
+SDK API changes ⚠️
+------------------
+ - RawService.getWellknown() now takes a domain instead of a matrixId as parameter ([#3572](https://github.com/vector-im/element-android/issues/3572))
+
+
+Changes in Element 1.1.12 (2021-07-05)
+======================================
+
+Features ✨
+----------
+ - Reveal password: use facility from com.google.android.material.textfield.TextInputLayout instead of manual handling. ([#3545](https://github.com/vector-im/element-android/issues/3545))
+ - Implements new design for Jump to unread and quick fix visibility issues. ([#3547](https://github.com/vector-im/element-android/issues/3547))
+
+Bugfixes 🐛
+----------
+ - Fix some issues with timeline cache invalidation and visibility. ([#3542](https://github.com/vector-im/element-android/issues/3542))
+ - Fix call invite processed after call is ended because of fastlane mode. ([#3564](https://github.com/vector-im/element-android/issues/3564))
+ - Fix crash after video call. ([#3577](https://github.com/vector-im/element-android/issues/3577))
+ - Fix crash out of memory ([#3583](https://github.com/vector-im/element-android/issues/3583))
+ - CryptoStore migration has to be object to avoid crash ([#3605](https://github.com/vector-im/element-android/issues/3605))
+
+
+Changes in Element v1.1.11 (2021-06-22)
+=======================================
+
+Bugfixes 🐛
+----------
+ - Send button does not show up half of the time ([#3535](https://github.com/vector-im/element-android/issues/3535))
+ - Fix crash on signout: release session at the end of clean up. ([#3538](https://github.com/vector-im/element-android/issues/3538))
+
+
+Changes in Element v1.1.10 (2021-06-18)
+=======================================
+
+Features ✨
+----------
+ - Migrate DefaultTypingService, KeysImporter and KeysExporter to coroutines ([#2449](https://github.com/vector-im/element-android/issues/2449))
+ - Update Message Composer design ([#3182](https://github.com/vector-im/element-android/issues/3182))
+ - Cleanup Epoxy items, and debounce all the clicks ([#3435](https://github.com/vector-im/element-android/issues/3435))
+ - Adds support for receiving MSC3086 Asserted Identity events. ([#3451](https://github.com/vector-im/element-android/issues/3451))
+ - Migrate to new colors and cleanup the style and theme. Now exported in module :library:ui-styles
+ Ref: https://material.io/blog/migrate-android-material-components ([#3459](https://github.com/vector-im/element-android/issues/3459))
+ - Add option to set aliases for public spaces ([#3483](https://github.com/vector-im/element-android/issues/3483))
+ - Add beta warning to private space creation flow ([#3485](https://github.com/vector-im/element-android/issues/3485))
+ - User defined top level spaces ordering ([#3501](https://github.com/vector-im/element-android/issues/3501))
+
+Bugfixes 🐛
+----------
+ - Fix new DMs not always marked as such ([#3333](https://github.com/vector-im/element-android/issues/3333))
+
+SDK API changes ⚠️
+------------------
+ - Splits SessionAccountDataService and RoomAccountDataService and offers to query RoomAccountDataEvent at the session level. ([#3479](https://github.com/vector-im/element-android/issues/3479))
+
+Other changes
+-------------
+ - Move the ability to start a call from dialpad directly to a dedicated tab in the home screen. ([#3457](https://github.com/vector-im/element-android/issues/3457))
+ - VoIP: Change hold direction to send-only. ([#3467](https://github.com/vector-im/element-android/issues/3467))
+ - Some improvements on DialPad (cursor edition, paste number, small fixes). ([#3516](https://github.com/vector-im/element-android/issues/3516))
+
+
+Changes in Element v1.1.9 (2021-06-02)
+======================================
Features ✨:
- -
+ - Upgrade Olm dependency to 3.2.4
+ - Allow user to add custom "network" in room search (#1458)
+ - Add Gitter.im as a default in the Change Network menu (#3196)
+ - VoIP: support for virtual rooms (#3355)
+ - Compress thumbnail: change Jpeg quality from 100 to 80 (#3396)
+ - Inconsistent usage of the term homeserver in Settings (#3404)
+ - VoIP: support attended transfer (#3420)
+ - /snow -> /snowfall and update wording (iso Element Web) (#3430)
+
+Bugfixes 🐛:
+ - Fix | On Android it seems to be impossible to view the complete description of a Space (without dev tools) (#3401)
+ - Fix | Suggest Rooms, Show a detailed view of the room on click (#3406)
+ - Fix app crashing when signing out (#3424)
+ - Switch to stable endpoint/fields for MSC2858 (#3442)
+
+Changes in Element 1.1.8 (2021-05-25)
+===================================================
Improvements 🙌:
- -
+ - Support Jitsi authentication (#3379)
Bugfix 🐛:
- Space Invite by link not always displayed for public space (#3345)
- Wrong copy in share space bottom sheet (#3346)
- Fix a problem with database migration on nightly builds (#3335)
-
-Translations 🗣:
- -
-
-SDK API changes ⚠️:
- -
+ - Implement a workaround to render <del> and <u> in the timeline (#1817)
+ - Make sure the SDK can retrieve the secret storage if the system is upgraded (#3304)
+ - Spaces | Explore room list: the RoomId is displayed instead of name (#3371)
+ - Spaces | Personal spaces add DM - Web Parity (#3271)
+ - Spaces | Improve 'Leave Space' UX/UI (#3359)
+ - Don't create private spaces with encryption enabled (#3363)
+ - #+ button on lower right when looking at an empty space goes to an empty 'Explore rooms' (#3327)
Build 🧱:
- - Compile with Kotlin 1.5.
+ - Compile with Kotlin 1.5.10.
- Upgrade some dependencies: gradle wrapper, third party lib, etc.
- Sign APK with build tools 30.0.3
-Test:
- -
-
Other changes:
- Add documentation on LoginWizard and RegistrationWizard (#3303)
+ - Setup towncrier tool (#3293)
+
+ Security:
+ - Element Android shares name of E2EE files with homeserver (#3387)
Changes in Element 1.1.7 (2021-05-12)
===================================================
@@ -1378,36 +1542,3 @@ Changes in RiotX 0.1.0 (2019-07-11)
First release!
Mode details here: https://medium.com/@RiotChat/introducing-the-riotx-beta-for-android-b17952e8f771
-
-
-=======================================================
-+ TEMPLATE WHEN PREPARING A NEW RELEASE +
-=======================================================
-
-
-Changes in Element 1.1.X (2021-XX-XX)
-===================================================
-
-Features ✨:
- -
-
-Improvements 🙌:
- -
-
-Bugfix 🐛:
- -
-
-Translations 🗣:
- -
-
-SDK API changes ⚠️:
- -
-
-Build 🧱:
- -
-
-Test:
- -
-
-Other changes:
- -
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dd32991051..5151a618f6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,7 +26,7 @@ To install the template (to be done only once):
To create a new screen:
- First create a new package in your code.
-- Then right click on the package, and select `New/New Vector/RiotX Feature`.
+- Then right click on the package, and select `New/New Vector/Element Feature`.
- Follow the Wizard, especially replace `Main` by something more relevant to your feature.
- Click on `Finish`.
- Remaining steps are described as TODO in the generated files, or will be pointed out by the compiler, or at runtime :)
@@ -51,9 +51,21 @@ If an issue does not exist yet, it may be relevant to open a new issue and let u
This project is full Kotlin. Please do not write Java classes.
-### CHANGES.md
+### Changelog
-Please add a line to the top of the file `CHANGES.md` describing your change.
+Please create at least one file under ./changelog.d containing details about your change. Towncrier will be used when preparing the release.
+
+Towncrier says to use the PR number for the filename, but the issue number is also fine.
+
+Supported filename extensions are:
+
+- ``.feature``: Signifying a new feature in Element Android or in the Matrix SDK.
+- ``.bugfix``: Signifying a bug fix.
+- ``.doc``: Signifying a documentation improvement.
+- ``.removal``: Signifying a deprecation or removal of public API. Can be used to notifying about API change in the Matrix SDK
+- ``.misc``: Any other changes.
+
+See https://github.com/twisted/towncrier#news-fragments if you need more details.
### Code quality
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000000..7a118b49be
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem "fastlane"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000000..345b4c1502
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,209 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.3)
+ addressable (2.8.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ artifactory (3.0.15)
+ atomos (0.1.3)
+ aws-eventstream (1.1.1)
+ aws-partitions (1.479.0)
+ aws-sdk-core (3.117.0)
+ aws-eventstream (~> 1, >= 1.0.2)
+ aws-partitions (~> 1, >= 1.239.0)
+ aws-sigv4 (~> 1.1)
+ jmespath (~> 1.0)
+ aws-sdk-kms (1.44.0)
+ aws-sdk-core (~> 3, >= 3.112.0)
+ aws-sigv4 (~> 1.1)
+ aws-sdk-s3 (1.96.1)
+ aws-sdk-core (~> 3, >= 3.112.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.1)
+ aws-sigv4 (1.2.4)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.4)
+ claide (1.0.3)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander (4.6.0)
+ highline (~> 2.0.0)
+ declarative (0.0.20)
+ digest-crc (0.6.3)
+ rake (>= 12.0.0, < 14.0.0)
+ domain_name (0.5.20190701)
+ unf (>= 0.0.5, < 1.0.0)
+ dotenv (2.7.6)
+ emoji_regex (3.2.2)
+ excon (0.85.0)
+ faraday (1.5.1)
+ faraday-em_http (~> 1.0)
+ faraday-em_synchrony (~> 1.0)
+ faraday-excon (~> 1.1)
+ faraday-httpclient (~> 1.0.1)
+ faraday-net_http (~> 1.0)
+ faraday-net_http_persistent (~> 1.1)
+ faraday-patron (~> 1.0)
+ multipart-post (>= 1.2, < 3)
+ ruby2_keywords (>= 0.0.4)
+ faraday-cookie_jar (0.0.7)
+ faraday (>= 0.8.0)
+ http-cookie (~> 1.0.0)
+ faraday-em_http (1.0.0)
+ faraday-em_synchrony (1.0.0)
+ faraday-excon (1.1.0)
+ faraday-httpclient (1.0.1)
+ faraday-net_http (1.0.1)
+ faraday-net_http_persistent (1.2.0)
+ faraday-patron (1.0.0)
+ faraday_middleware (1.0.0)
+ faraday (~> 1.0)
+ fastimage (2.2.4)
+ fastlane (2.187.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.3, < 3.0.0)
+ artifactory (~> 3.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored
+ commander (~> 4.6)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 1.0)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-apis-androidpublisher_v3 (~> 0.1)
+ google-apis-playcustomapp_v1 (~> 0.1)
+ google-cloud-storage (~> 1.31)
+ highline (~> 2.0)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (~> 2.0.0)
+ naturally (~> 2.2)
+ plist (>= 3.1.0, < 4.0.0)
+ rubyzip (>= 2.0.0, < 3.0.0)
+ security (= 0.1.3)
+ simctl (~> 1.6.3)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (>= 1.4.5, < 2.0.0)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3)
+ gh_inspector (1.1.3)
+ google-apis-androidpublisher_v3 (0.8.0)
+ google-apis-core (>= 0.4, < 2.a)
+ google-apis-core (0.4.0)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.16.2, < 2.a)
+ httpclient (>= 2.8.1, < 3.a)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.a)
+ rexml
+ webrick
+ google-apis-iamcredentials_v1 (0.6.0)
+ google-apis-core (>= 0.4, < 2.a)
+ google-apis-playcustomapp_v1 (0.5.0)
+ google-apis-core (>= 0.4, < 2.a)
+ google-apis-storage_v1 (0.6.0)
+ google-apis-core (>= 0.4, < 2.a)
+ google-cloud-core (1.6.0)
+ google-cloud-env (~> 1.0)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.5.0)
+ faraday (>= 0.17.3, < 2.0)
+ google-cloud-errors (1.1.0)
+ google-cloud-storage (1.34.1)
+ addressable (~> 2.5)
+ digest-crc (~> 0.4)
+ google-apis-iamcredentials_v1 (~> 0.1)
+ google-apis-storage_v1 (~> 0.1)
+ google-cloud-core (~> 1.6)
+ googleauth (>= 0.16.2, < 2.a)
+ mini_mime (~> 1.0)
+ googleauth (0.16.2)
+ faraday (>= 0.17.3, < 2.0)
+ jwt (>= 1.4, < 3.0)
+ memoist (~> 0.16)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (~> 0.14)
+ highline (2.0.3)
+ http-cookie (1.0.4)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ jmespath (1.4.0)
+ json (2.5.1)
+ jwt (2.2.3)
+ memoist (0.16.2)
+ mini_magick (4.11.0)
+ mini_mime (1.1.0)
+ multi_json (1.15.0)
+ multipart-post (2.0.0)
+ nanaimo (0.3.0)
+ naturally (2.2.1)
+ os (1.1.1)
+ plist (3.6.0)
+ public_suffix (4.0.6)
+ rake (13.0.6)
+ representable (3.1.1)
+ declarative (< 0.1.0)
+ trailblazer-option (>= 0.1.1, < 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rexml (3.2.5)
+ rouge (2.0.7)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ security (0.1.3)
+ signet (0.15.0)
+ addressable (~> 2.3)
+ faraday (>= 0.17.3, < 2.0)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.8)
+ CFPropertyList
+ naturally
+ terminal-notifier (2.0.0)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ trailblazer-option (0.1.1)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.1)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.7)
+ unicode-display_width (1.7.0)
+ webrick (1.7.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.20.0)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.3.0)
+ rexml (~> 3.2.4)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.1)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ x86_64-darwin-20
+
+DEPENDENCIES
+ fastlane
+
+BUNDLED WITH
+ 2.2.15
diff --git a/attachment-viewer/build.gradle b/attachment-viewer/build.gradle
index aa35f06767..c393c5f483 100644
--- a/attachment-viewer/build.gradle
+++ b/attachment-viewer/build.gradle
@@ -47,15 +47,17 @@ android {
}
dependencies {
+ implementation project(":library:ui-styles")
+
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'androidx.core:core-ktx:1.3.2'
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation "androidx.recyclerview:recyclerview:1.2.0"
+ implementation 'androidx.core:core-ktx:1.6.0'
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation "androidx.recyclerview:recyclerview:1.2.1"
- implementation 'com.google.android.material:material:1.3.0'
+ implementation 'com.google.android.material:material:1.4.0'
}
\ No newline at end of file
diff --git a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
index 418b5b5cbb..f909418d6f 100644
--- a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
+++ b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt
@@ -33,6 +33,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.transition.TransitionManager
@@ -124,9 +125,11 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
scaleDetector = createScaleGestureDetector()
ViewCompat.setOnApplyWindowInsetsListener(views.rootContainer) { _, insets ->
- overlayView?.updatePadding(top = insets.systemWindowInsetTop, bottom = insets.systemWindowInsetBottom)
- topInset = insets.systemWindowInsetTop
- bottomInset = insets.systemWindowInsetBottom
+ val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
+
+ overlayView?.updatePadding(top = systemBarsInsets.top, bottom = systemBarsInsets.bottom)
+ topInset = systemBarsInsets.top
+ bottomInset = systemBarsInsets.bottom
insets
}
}
diff --git a/attachment-viewer/src/main/res/layout/item_image_attachment.xml b/attachment-viewer/src/main/res/layout/item_image_attachment.xml
index 91a009df2a..0f9a90e91c 100644
--- a/attachment-viewer/src/main/res/layout/item_image_attachment.xml
+++ b/attachment-viewer/src/main/res/layout/item_image_attachment.xml
@@ -1,22 +1,18 @@
+ android:layout_height="match_parent">
+ android:layout_height="match_parent" />
+ android:layout_centerInParent="true" />
\ No newline at end of file
diff --git a/attachment-viewer/src/main/res/layout/item_video_attachment.xml b/attachment-viewer/src/main/res/layout/item_video_attachment.xml
index 29f01650fd..7dd13ea460 100644
--- a/attachment-viewer/src/main/res/layout/item_video_attachment.xml
+++ b/attachment-viewer/src/main/res/layout/item_video_attachment.xml
@@ -1,8 +1,8 @@
+ android:layout_height="match_parent">
+ android:layout_centerInParent="true"
+ android:visibility="gone"
+ tools:visibility="visible" />
diff --git a/attachment-viewer/src/main/res/values/colors.xml b/attachment-viewer/src/main/res/values/colors.xml
deleted file mode 100644
index 7ceef40881..0000000000
--- a/attachment-viewer/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- #80000000
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 470e9a06b4..d7ba0168dd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,8 +2,8 @@
buildscript {
// Ref: https://kotlinlang.org/releases.html
- ext.kotlin_version = '1.5.0'
- ext.kotlin_coroutines_version = "1.5.0-RC"
+ ext.kotlin_version = '1.5.21'
+ ext.kotlin_coroutines_version = "1.5.0"
repositories {
google()
jcenter()
@@ -12,10 +12,10 @@ buildscript {
}
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.2.1'
+ classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.google.gms:google-services:4.3.8'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.2.0'
+ classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.4'
classpath "com.likethesalad.android:string-reference:1.2.2"
@@ -48,6 +48,9 @@ allprojects {
// Chat effects
includeGroupByRegex 'com\\.github\\.jetradarmobile'
includeGroupByRegex 'nl\\.dionsegijn'
+
+ // Voice RecordView
+ includeGroupByRegex 'com\\.github\\.Armen101'
}
}
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
diff --git a/changelog.d/.gitignore b/changelog.d/.gitignore
new file mode 100644
index 0000000000..b722e9e13e
--- /dev/null
+++ b/changelog.d/.gitignore
@@ -0,0 +1 @@
+!.gitignore
\ No newline at end of file
diff --git a/docs/color_migration_guide.md b/docs/color_migration_guide.md
new file mode 100644
index 0000000000..31a531d124
--- /dev/null
+++ b/docs/color_migration_guide.md
@@ -0,0 +1,85 @@
+# Color migration
+
+### Changes
+
+- use colors defined in https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=557%3A0
+- remove unused resources and code (ex: PercentView)
+- split some resource files into smaller file
+- rework the theme files
+- ensure material theme is used everywhere in the theme and in the layout
+- add default style for some views in the theme (ex: Toolbar, etc.)
+- add some debug screen in the debug menu, to test the themes and the button style
+- rework the button style to use `materialThemeOverlay` attribute
+- custom tint icon for menu management has been removed
+- comment with `riotx` has been updated
+
+### Main change for developers
+
+- Read migration guide: https://github.com/vector-im/element-android/pull/3459/files#diff-f0e52729d5e4f6eccbcf72246807aa34ed19c4ef5625ca669df998cd1022874b
+- Use MaterialAlertDialogBuilder instead of AlertDialog.Builder
+- some Epoxy Item included a divider. This has been removed. Use a `dividerItem` or `bottomSheetDividerItem` Epoxy items to add a divider
+- RecyclerView.configureWith now take a divider drawable instead of a divider color
+
+### Remaining work
+
+- Cleanup some vector drawables and ensure a tint is always used instead of hard coded color.
+
+### Migration guide
+
+Some colors and color attribute has been removed, here is the list and what has to be used now.
+
+It can help Element Android forks maintainers to migrate their code.
+
+- riotx_text_primary -> ?vctr_content_primary
+- riotx_text_secondary -> ?vctr_content_secondary
+- riotx_text_tertiary -> ?vctr_content_tertiary
+
+- ?riotx_background -> ?android:colorBackground
+- riotx_background_light -> element_background_light
+- riotx_background_dark -> element_background_dark
+- riotx_background_black -> element_background_black
+
+- riotx_accent -> ?colorPrimary
+- riotx_positive_accent -> ?colorPrimary
+- riotx_accent_alpha25 -> color_primary_alpha25
+- riotx_notice -> ?colorError
+- riotx_destructive_accent -> ?colorError
+- vector_error_color -> ?colorError
+- vector_warning_color -> ?colorError
+
+- riotx_bottom_sheet_background -> ?colorSurface
+- riotx_alerter_background -> ?colorSurface
+
+- riotx_username_1 -> element_name_01
+- riotx_username_2 -> element_name_02
+- riotx_username_3 -> element_name_03
+- riotx_username_4 -> element_name_04
+- riotx_username_5 -> element_name_05
+- riotx_username_6 -> element_name_06
+- riotx_username_7 -> element_name_07
+- riotx_username_8 -> element_name_08
+
+- riotx_avatar_fill_1 -> element_room_01
+- riotx_avatar_fill_2 -> element_room_02
+- riotx_avatar_fill_3 -> element_room_03
+
+- white -> @android:color/white
+- black -> @android:color/black or emoji_color
+
+- riotx_list_header_background_color -> ?vctr_header_background
+- riotx_header_panel_background -> ?vctr_header_background
+- riotx_list_bottom_sheet_divider_color -> ?vctr_list_separator_on_surface
+- riotx_list_divider_color -> ?vctr_list_separator
+- list_divider_color -> ?vctr_list_separator
+- riotx_header_panel_border_mobile -> ?vctr_list_separator
+- riotx_bottom_nav_background_border_color -> ?vctr_list_separator
+- riotx_header_panel_text_secondary -> ?vctr_content_primary
+
+- link_color_light -> element_link_light
+- link_color_dark -> element_link_dark
+
+- riotx_toolbar_primary_text_color -> vctr_content_primary
+- riotx_toolbar_secondary_text_color -> vctr_content_primary
+- riot_primary_text_color -> vctr_content_primary
+
+- riotx_android_secondary -> vctr_content_secondary
diff --git a/docs/identity_server.md b/docs/identity_server.md
index 0d75108dd3..e765ae3949 100644
--- a/docs/identity_server.md
+++ b/docs/identity_server.md
@@ -4,7 +4,7 @@ Issue: #607
PR: #1354
## Introduction
-Identity Servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
+Identity servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
## Implementation
@@ -87,6 +87,6 @@ This screen displays the identity server configuration and the binding of the us
This screen is a form to set a new identity server URL
## Ref:
-- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an Identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
+- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
- API documentation: https://matrix.org/docs/spec/identity_service/latest
- vector.im TOS: https://vector.im/identity-server-privacy-notice
diff --git a/docs/notifications.md b/docs/notifications.md
index a00fef8fae..b44984785a 100644
--- a/docs/notifications.md
+++ b/docs/notifications.md
@@ -2,11 +2,11 @@ This document aims to describe how Element android displays notifications to the
# Table of Contents
1. [Prerequisites Knowledge](#prerequisites-knowledge)
- * [How does a matrix client get a message from a Home Server?](#how-does-a-matrix-client-get-a-message-from-a-home-server)
+ * [How does a matrix client get a message from a homeserver?](#how-does-a-matrix-client-get-a-message-from-a-homeserver)
* [How does a mobile app receives push notification?](#how-does-a-mobile-app-receives-push-notification)
* [Push VS Notification](#push-vs-notification)
* [Push in the matrix federated world](#push-in-the-matrix-federated-world)
- * [How does the Home Server knows when to notify a client?](#how-does-the-home-server-knows-when-to-notify-a-client)
+ * [How does the homeserver know when to notify a client?](#how-does-the-homeserver-know-when-to-notify-a-client)
* [Push vs privacy, and mitigation](#push-vs-privacy-and-mitigation)
* [Background processing limitations](#background-processing-limitations)
2. [Element Notification implementations](#element-notification-implementations)
@@ -22,9 +22,9 @@ First let's start with some prerequisite knowledge
# Prerequisites Knowledge
-## How does a matrix client get a message from a Home Server?
+## How does a matrix client get a message from a homeserver?
-In order to get messages from a home server, a matrix client need to perform a ``sync`` operation.
+In order to get messages from a homeserver, a matrix client need to perform a ``sync`` operation.
`To read events, the intended flow of operation is for clients to first call the /sync API without a since parameter. This returns the most recent message events for each room, as well as the state of the room at the start of the returned timeline. `
@@ -90,7 +90,7 @@ That means that Element Android, a matrix client created by New Vector, is using
If you create your own matrix client, you will also need to deploy an instance of a **Push Gateway** with the credentials needed to use FCM for your app.
-On registration, a matrix client must tell to it's Home Server what Push Gateway to use.
+On registration, a matrix client must tell its homeserver what Push Gateway to use.
See [Sygnal](https://github.com/matrix-org/sygnal/) for a reference implementation.
```
@@ -122,13 +122,13 @@ Recommended reading:
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id128
-## How does the Home Server knows when to notify a client?
+## How does the homeserver know when to notify a client?
This is defined by [**push rules**](https://matrix.org/docs/spec/client_server/r0.4.0.html#push-rules-).
`A push rule is a single rule that states under what conditions an event should be passed onto a push gateway and how the notification should be presented (sound / importance).`
-A Home Server can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
+A homeserver can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
There are different kind of push rules, it can be per room (each new message on this room should be notified), it can also define a pattern that a message should match (when you are mentioned, or key word based).
@@ -187,7 +187,7 @@ In background, and depending on wether push is available or not, Element will us
## Push (FCM) received in background
-In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the HomeServer.
+In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the homeserver.
When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for Element, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org.
@@ -199,7 +199,7 @@ Homeserver ----> Sygnal (configured for Element) ----> FCM ----> Element
The push gateway is configured to only send `(eventId,roomId)` in the push payload (for better [privacy](#push-vs-privacy-and-mitigation)).
-Element needs then to synchronise with the user's HomeServer, in order to resolve the event and create a notification.
+Element needs then to synchronise with the user's homeserver, in order to resolve the event and create a notification.
As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), Element will then use the WorkManager API in order to trigger a background sync.
@@ -217,7 +217,7 @@ Homeserver ----> Sygnal ----> FCM ----> Element
**Possible outcomes**
-Upon reception of the FCM push, Element will perform a sync call to the Home Server, during this process it is possible that:
+Upon reception of the FCM push, Element will perform a sync call to the homeserver, during this process it is possible that:
* Happy path, the sync is performed, the message resolved and displayed in the notification drawer
* The notified message is not in the sync. Can happen if a lot of things did happen since the push (`gappy sync`)
* The sync generates additional notifications (e.g an encrypted message where the user is mentioned detected locally)
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 0000000000..25273b0b09
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1,2 @@
+json_key_file("./fastlane/private/api-8525453667099313774-565354-aca0e6153603.json")
+package_name("im.vector.app")
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
new file mode 100644
index 0000000000..85e3d777ac
--- /dev/null
+++ b/fastlane/Fastfile
@@ -0,0 +1,60 @@
+# This file contains the fastlane.tools configuration
+# You can find the documentation at https://docs.fastlane.tools
+#
+# For a list of all available actions, check out
+#
+# https://docs.fastlane.tools/actions
+#
+# For a list of all available plugins, check out
+#
+# https://docs.fastlane.tools/plugins/available-plugins
+#
+
+# Uncomment the line if you want fastlane to automatically update itself
+# update_fastlane
+
+default_platform(:android)
+
+platform :android do
+ desc "Runs all the tests"
+ lane :test do
+ gradle(task: "test")
+ end
+
+ desc "Submit a new Beta Build to Crashlytics Beta"
+ lane :beta do
+ gradle(task: "clean assembleRelease")
+ crashlytics
+
+ # sh "your_script.sh"
+ # You can also use other beta testing services here
+ end
+
+ desc "Deploy a new version to the Google Play"
+ lane :deploy do
+ gradle(task: "clean assembleRelease")
+ upload_to_play_store
+ end
+
+ desc "Deploy Google Play metadata"
+ lane :deployMeta do
+ # Doc: https://docs.fastlane.tools/actions/upload_to_play_store/
+ upload_to_play_store(
+ skip_upload_apk: true,
+ skip_upload_aab: true,
+ skip_upload_images: true,
+ skip_upload_screenshots: true,
+ skip_upload_changelogs: true,
+ # Set to true to not update the PlayStore
+ validate_only: false
+ )
+ end
+
+ desc "Get version code"
+ lane :getVersionCode do
+ versions = google_play_track_version_codes(track: "production")
+ puts(versions)
+ version_code = versions[0]
+ puts(version_code)
+ end
+end
diff --git a/fastlane/README.md b/fastlane/README.md
new file mode 100644
index 0000000000..54d3a005a6
--- /dev/null
+++ b/fastlane/README.md
@@ -0,0 +1,49 @@
+fastlane documentation
+================
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```
+xcode-select --install
+```
+
+Install _fastlane_ using
+```
+[sudo] gem install fastlane -NV
+```
+or alternatively using `brew install fastlane`
+
+# Available Actions
+## Android
+### android test
+```
+fastlane android test
+```
+Runs all the tests
+### android beta
+```
+fastlane android beta
+```
+Submit a new Beta Build to Crashlytics Beta
+### android deploy
+```
+fastlane android deploy
+```
+Deploy a new version to the Google Play
+### android deployMeta
+```
+fastlane android deployMeta
+```
+Deploy Google Play metadata
+### android getVersionCode
+```
+fastlane android getVersionCode
+```
+Get version code
+
+----
+
+This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
+More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
+The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/fastlane/metadata/android/cs/changelogs/40100100.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100100.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100110.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100110.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100120.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100120.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100130.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100130.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100140.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100140.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100150.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100150.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100160.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100160.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40100170.txt b/fastlane/metadata/android/cs-CZ/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40100170.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101000.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101000.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101010.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101010.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101020.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101020.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101030.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101030.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101040.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101040.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101050.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101050.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/cs/changelogs/40101060.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/cs/changelogs/40101060.txt
rename to fastlane/metadata/android/cs-CZ/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101070.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101070.txt
new file mode 100644
index 0000000000..2a6afb21a5
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: beta podpora pro Spaces. Komprimace videa před odesláním.
+Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101080.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101080.txt
new file mode 100644
index 0000000000..5ec173ebea
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: vylepšení pro Spaces
+Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101090.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101090.txt
new file mode 100644
index 0000000000..782a2fa8c5
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: doplněna podpora pro síť gitter.im
+Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101100.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101100.txt
new file mode 100644
index 0000000000..de73b6f382
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: aktualizace vzhledu a stylu a nové funkce prostorů.
+Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101110.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101110.txt
new file mode 100644
index 0000000000..c4bfee0779
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: aktualizace vzhledu a stylu a nové funkce prostorů (bugfix pro 1.1.10)
+Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101120.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101120.txt
new file mode 100644
index 0000000000..3a10c20c0a
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: aktualizace motivu a stylu a oprava pádu aplikace po videohovoru
+Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101130.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101130.txt
new file mode 100644
index 0000000000..1ea00cbbb9
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: aktualizace hlavně kvůli stabilitě a opravám chyb
+Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101140.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101140.txt
new file mode 100644
index 0000000000..09f0da7763
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: oprava chyby ohledně šifrovaných zpráv
+Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40101150.txt b/fastlane/metadata/android/cs-CZ/changelogs/40101150.txt
new file mode 100644
index 0000000000..e82655d352
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: implementace hlasových zpráv dosupných v rámci laboratoře.
+Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/cs-CZ/full_description.txt b/fastlane/metadata/android/cs-CZ/full_description.txt
new file mode 100644
index 0000000000..d169c077e1
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/full_description.txt
@@ -0,0 +1,39 @@
+Element je zabezpečený komunikátor a zároveň aplikace pro týmovou spolupráci, která je ideální pro skupinové chaty při práci na dálku. Tato chatovací aplikace využívá end-to-end šifrování a poskytuje výkonné videokonference, sdílení souborů a hlasové hovory.
+
+Mezi funkce aplikace Element patří:
+- Pokročilé nástroje pro online komunikaci
+- Plně šifrované zprávy umožňující bezpečnější firemní komunikaci i pro pracovníky na dálku
+- Decentralizovaný chat založený na open source frameworku Matrix
+- Bezpečné sdílení souborů se šifrovanými daty při správě projektů
+- Videochaty s funkcí Voice over IP a sdílením obrazovky
+- Snadná integrace s oblíbenými nástroji pro online spolupráci, nástroji pro správu projektů, službami VoIP a dalšími aplikacemi pro týmovou komunikaci
+
+Element se zcela liší od ostatních aplikací pro zasílání zpráv a spolupráci. Funguje na platformě Matrix, otevřené síti pro bezpečné zasílání zpráv a decentralizovanou komunikaci. Umožňuje vlastní hostování, aby uživatelé měli maximální vlastnictví a kontrolu nad svými daty a zprávami.
+
+Soukromí a šifrované zprávy
+Element vás chrání před nežádoucími reklamami, vytěžováním dat a tzv. walled gardens. Zabezpečuje také všechna vaše data, video a hlasovou komunikaci jeden na jednoho prostřednictvím šifrování end-to-end a křížového ověřování zařízení.
+
+Element vám dává kontrolu nad vaším soukromím a zároveň vám umožňuje bezpečně komunikovat s kýmkoli v síti Matrix nebo s dalšími nástroji pro firemní spolupráci díky integraci s aplikacemi, jako je Slack.
+
+Element lze hostovat samostatně
+Abyste měli větší kontrolu nad svými citlivými daty a konverzacemi, může být Element hostován na vlastním hardwaru nebo si můžete vybrat libovolného hostitele založeného na systému Matrix - standardu pro decentralizovanou komunikaci s otevřeným zdrojovým kódem. Element vám poskytuje soukromí, soulad se zásadami bezpečnosti a flexibilitu integrace.
+
+Vlastněte svá data
+Sami rozhodujete, kde budou vaše data a zprávy uloženy. Bez rizika vytěžování dat nebo přístupu třetích stran.
+
+Element vám dává kontrolu různými způsoby:
+1. Získejte bezplatný účet na veřejném serveru matrix.org, který hostují vývojáři Matrixu, nebo si vyberte z tisíců veřejných serverů hostovaných dobrovolníky.
+2. Vlastní hostování účtu spuštěním serveru na vlastní IT infrastruktuře.
+3. Zaregistrujte si účet na vlastním serveru tak, že si jednoduše předplatíte hostingovou platformu Element Matrix Services.
+
+Otevřené zasílání zpráv a spolupráce
+Můžete chatovat s kýmkoli v síti Matrix, ať už používá aplikaci Element, jinou aplikaci podporující protokol Matrix nebo dokonce i když používá jinou aplikaci pro zasílání zpráv.
+
+Superbezpečné
+Skutečné end-to-end šifrování (zprávy mohou dešifrovat pouze účastníci konverzace) a křížové ověřování zařízení.
+
+Kompletní komunikace a integrace
+Zprávy, hlasové a videohovory, sdílení souborů, sdílení obrazovky a celá řada integrací, botů a widgetů. Vytvářejte místnosti, komunity, zůstaňte v kontaktu a spolupracujte.
+
+Navažte tam, kde jste skončili
+Zůstaňte v kontaktu, ať jste kdekoli, díky plně synchronizované historii zpráv ve všech zařízeních a na webu https://app.element.io
diff --git a/fastlane/metadata/android/cs/short_description.txt b/fastlane/metadata/android/cs-CZ/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/cs/short_description.txt
rename to fastlane/metadata/android/cs-CZ/short_description.txt
diff --git a/fastlane/metadata/android/cs/title.txt b/fastlane/metadata/android/cs-CZ/title.txt
similarity index 100%
rename from fastlane/metadata/android/cs/title.txt
rename to fastlane/metadata/android/cs-CZ/title.txt
diff --git a/fastlane/metadata/android/cs/full_description.txt b/fastlane/metadata/android/cs/full_description.txt
deleted file mode 100644
index f9c1f2ad0c..0000000000
--- a/fastlane/metadata/android/cs/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Element je nový typ aplikace pro výměnu zpráv a spolupráci, která:
-
-1. Vám dá kontrolu nad ochranou vašeho soukromí
-2. Umožní vám komunikovat s kýmkoli v síti Matrix a dokonce i mimo ni pomocí integrací s aplikacemi, jako je Slack
-3. Ochrání vás před inzercí, dataminingem a uzavřenými zahradami
-4. Zabezpečí vás end-to-end šifrováním s křížovým podpisem pro ověření ostatních
-
-Element je zcela odlišný od ostatních aplikací pro zasílání zpráv a spolupráci, protože je decentralizovaný a otevřený.
-
-Element vám umožňuje použít vlastní domovský server - nebo si vybrat hostitele - abyste měli soukromí, vlastnictví a kontrolu nad svými daty a konverzacemi. Poskytuje vám přístup k otevřené síti; takže nejste zaseknuti jen při konverzaci s ostatními uživateli Elementu. A je velmi bezpečný.
-
-Element je toho všeho schopen, protože pracuje na Matrixu - standardu otevřené, decentralizované komunikace.
-
-Element vám dává kontrolu nad tím, že si můžete vybrat, kdo bude hostovat vaše konverzace. Z aplikace Element si můžete vybrat hostování různými způsoby:
-
-1. Získejte zdarma účet na veřejném serveru matrix.org hostovaném vývojáři Matrixu, nebo si vyberte z tisíců veřejných serverů hostovaných dobrovolníky
-2. Hostujte svůj účet spuštěním serveru na svém vlastním hardwaru
-3. Zaregistrujte si účet na vlastním serveru jednoduchým přihlášením k hostitelské platformě Element Matrix Services
-
-Proč zvolit Element?
-
-VLASTNĚTE SVÁ DATA: Vy rozhodnete, kde svá data a zprávy ponecháte. Vlastníte je a jsou pod vaší kontrolou, ne nějaký MEGACORP, který těží vaše data nebo poskytuje přístup třetím stranám.
-
-ZPRÁVY A SPOLUPRÁCE: Můžete chatovat s kýmkoli v síti Matrix, ať už používá Element nebo jinou aplikaci, a to i v případě, že používají jiný systém zasílání zpráv, jako je Slack, IRC nebo XMPP.
-
-MAXIMÁLNĚ BEZPEČNÉ: Skutečné šifrování typu end-to-end (pouze ti v konverzaci mohou dešifrovat zprávy) a křížové podepisování k ověření zařízení účastníků konverzace.
-
-KOMPLETNÍ KOMUNIKACE: Zprávy, hlasové hovory a videohovory, sdílení souborů, sdílení obrazovky a celá řada integrací, robotů a widgetů. Budujte místnosti, komunity, zůstaňte v kontaktu a spolupracujte.
-
-KDEKOLIV JSTE: Zůstaňte v kontaktu, ať jste kdekoli, s plně synchronizovanou historií zpráv na všech vašich zařízeních a na webu na adrese https://app.element.io.
diff --git a/fastlane/metadata/android/de/changelogs/40100100.txt b/fastlane/metadata/android/de-DE/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100100.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100110.txt b/fastlane/metadata/android/de-DE/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100110.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100120.txt b/fastlane/metadata/android/de-DE/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100120.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100130.txt b/fastlane/metadata/android/de-DE/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100130.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100140.txt b/fastlane/metadata/android/de-DE/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100140.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100150.txt b/fastlane/metadata/android/de-DE/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100150.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100160.txt b/fastlane/metadata/android/de-DE/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100160.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/de/changelogs/40100170.txt b/fastlane/metadata/android/de-DE/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40100170.txt
rename to fastlane/metadata/android/de-DE/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101000.txt b/fastlane/metadata/android/de-DE/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101000.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101010.txt b/fastlane/metadata/android/de-DE/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101010.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101020.txt b/fastlane/metadata/android/de-DE/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101020.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101030.txt b/fastlane/metadata/android/de-DE/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101030.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101040.txt b/fastlane/metadata/android/de-DE/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101040.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101050.txt b/fastlane/metadata/android/de-DE/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101050.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/de/changelogs/40101060.txt b/fastlane/metadata/android/de-DE/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/de/changelogs/40101060.txt
rename to fastlane/metadata/android/de-DE/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101070.txt b/fastlane/metadata/android/de-DE/changelogs/40101070.txt
new file mode 100644
index 0000000000..757475a44d
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Hauptänderungen in dieser Version: Mit Spaces kannst du deine Räume gruppieren (Beta). Videos können vor dem Senden komprimiert werden.
+Die vollständige Änderungsliste gibt es hier: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101080.txt b/fastlane/metadata/android/de-DE/changelogs/40101080.txt
new file mode 100644
index 0000000000..3609fb7078
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Hauptänderung: Verbesserung für Spaces.
+Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101090.txt b/fastlane/metadata/android/de-DE/changelogs/40101090.txt
new file mode 100644
index 0000000000..1a957862ab
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Hauptänderung in dieser Version: Füge Unterstützung für gitter.im-Netzwerk hinzu
+Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101100.txt b/fastlane/metadata/android/de-DE/changelogs/40101100.txt
new file mode 100644
index 0000000000..04f944cdcf
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Hauptänderungen: Design-Update und neue Features für Spaces
+Vollständige Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101110.txt b/fastlane/metadata/android/de-DE/changelogs/40101110.txt
new file mode 100644
index 0000000000..8e115469e1
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Hauptänderungen: Design-Update und neue Features für Spaces (Bugfix für 1.1.10)
+Vollständige Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/de-DE/changelogs/40101140.txt b/fastlane/metadata/android/de-DE/changelogs/40101140.txt
new file mode 100644
index 0000000000..75732a5364
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Hauptänderung dieser Version: Beheben eines Problems mit verschlüsselten Nachrichten.
+Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt
new file mode 100644
index 0000000000..30eb153ee9
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/full_description.txt
@@ -0,0 +1,39 @@
+Element ist ein sicherer Messenger und ideal für die produktive Zusammenarbeit mit Ihrem Team im Homeoffice. Mit eingebauter Ende-zu-Ende-Verschlüsselung ermöglicht Element auch umfangreiche und sichere Videokonferenzen, das Teilen von Dateien, Sprachanrufe und vieles mehr.
+
+Element bietet folgende Funktionen:
+- Fortschrittliche Werkzeuge für die Online-Kommunikation
+- Vollständig verschlüsselte Nachrichten, um eine sichere Kommunikation innerhalb und außerhalb von Unternehmen zu ermöglichen
+- Dezentralisierte Chats, basierend auf dem quelloffenen Matrix-Protokoll
+- Sichere und kontrollierte Dateifreigabe durch verschlüsselte Daten beim Verwalten von Projekten
+- Videochats mit VoIP und Bildschirmübertragung
+- Einfache Einbindung in Ihre bevorzugten Online-Kollaborations- und Projektverwaltungswerkzeuge, VoIP-Dienste und andere Kommunikationsapps für Ihr Team
+
+Element unterscheidet sich grundlegend von anderen Kommunikations- und Kollaborationsapps. Es läuft auf Matrix, einem offenen Netzwerk für sichere und dezentralisierte Kommunikation. Es erlaubt Nutzern ihre eigene Infrastruktur zu betreiben und gibt ihnen damit vollständige Kontrolle und Besitz über ihre eigenen Daten und Nachrichten.
+
+Privatsphäre/Datenschutz und verschlüsselte Kommunikation
+Element schützt Sie vor unerwünschter Werbung, dem Datensammeln und geschlossenen Plattformen. Auch schützt es all Ihre Daten, Ihre Video- und Sprachkommunikation mittels Ende-zu-Ende-Verschlüsselung und durch das Quersignieren von Geräten zur Verifizierung.
+
+Element gibt Ihnen volle Kontrolle über Ihre Privatsphäre und ermöglicht es Ihnen zugleich, mit jedem im Matrix-Netzwerk sicher zu kommunizieren - oder auch auf anderen geschäftlichen Kollaborationswerkzeugen, zum Beispiel durch das Einbinden von Apps wie Slack.
+
+Element kann man selber betreiben
+Um mehr Kontrolle über Ihre sensiblen Daten und Konversationen zu ermöglichen, kann man Element selbst betreiben, oder Sie wählen irgendeinen Matrix-basierten Dienst - der Standard für quelloffene, dezentralisierte Kommunikation. Element gibt Ihnen Privatsphäre, Sicherheitskonformität und Flexibilität für Integrationen.
+
+Besitzen Sie Ihre Daten
+Sie entscheiden, wo Sie Ihre Daten und Nachrichten aufbewahren - ohne das Datensammeln oder den Zugriff Dritter zu riskieren.
+
+Element gibt Ihnen auf verschiedene Arten Kontrolle:
+1. Sie können sich kostenlos auf dem öffentlichen matrix.org-Server registrieren, der von den Matrix-Entwicklern gehostet wird, oder einen von Tausenden öffentlichen Servern, die von Freiwilligen betrieben werden, auswählen
+2. Sie haben die Möglichkeit, ein Konto auf einem eigenen Server in der eigenen IT-Infrastruktur betreiben
+3. Außerdem können Sie durch ein Abonnement der Element Matrix Services ein Konto auf einem für Sie maßgeschneiderten Server erstellen
+
+Offene Kommunikation und Zusammenarbeit
+Sie können mit jedem im Matrix-Netzwerk chatten, egal ob ihr Kontakt Element, eine andere Matrix-App oder sogar eine völlig andere Anwendung nutzt.
+
+Super sicher
+Durch Ende-zu-Ende-Verschlüsselung können nur die Personen, die in der Unterhaltung sind, die Nachrichten lesen. Außerdem stellt die Verifizierung mittels Quersignierung sicher, dass Sie wirklich mit dem Chatten, mit dem Sie glauben - und niemand Anderem.
+
+Vollständige Kommunikation und Integration
+Kurznachrichten, Sprach- und Videoanrufe, Dateifreigaben, Bildschirmübertragungen und einer Menge an Integrationen, Bots und Widgets. Schaffen Sie Räume und Communities, bleiben Sie auf dem Laufenden und erledigen Sie Sachen.
+
+Da Weitermachen, wo Sie aufgehört haben
+Bleiben Sie in Kontakt, egal wo Sie sind, mit vollständig synchronisiertem Nachrichtenverlauf quer über all Ihre Geräte und im Netz auf https://app.element.io
diff --git a/fastlane/metadata/android/de/short_description.txt b/fastlane/metadata/android/de-DE/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/de/short_description.txt
rename to fastlane/metadata/android/de-DE/short_description.txt
diff --git a/fastlane/metadata/android/de/title.txt b/fastlane/metadata/android/de-DE/title.txt
similarity index 100%
rename from fastlane/metadata/android/de/title.txt
rename to fastlane/metadata/android/de-DE/title.txt
diff --git a/fastlane/metadata/android/de/full_description.txt b/fastlane/metadata/android/de/full_description.txt
deleted file mode 100644
index 69343cf0e3..0000000000
--- a/fastlane/metadata/android/de/full_description.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Element ist mehr als ein sicherer Messenger. Es ist ein produktives Kolaborationsapp für das Team und eignet sich ideal für den Gruppenchat beim Arbeiten von zuhause aus. Mit eingebauter Ende-zu-Ende-Verschlüsselung ermöglicht Element umfangreiche und sichere Videokonferenzen, das Teilen von Dokumenten/Dateien und Videoanrufe.
-
-Element enthält folgende Funktionen:
-- Fortgeschrittene Werkzeuge für die Online-Kommunikation
-- Vollverschlüsselte Nachrichten um eine sichere Kommunikation innerhalb und außerhalb des Unternehmens zu ermöglichen
-- Dezentralisierte Chats basierend auf das quelloffene Matrix-Framework
-- Sichere und kontrollierte Dateienfreigabe durch verschlüsselte Daten beim verwalten von Projekten
-- Videochats über VoIP und Bildschirmübertragung
-- Einfache Einbindungen mit Ihren favorisierten Online-Kolaborationswerkzeugen, Projektverwaltungswerkzeugen, VoIP-Diensten und andere Kommunikationsapps für Ihren Team
-
-Element unterscheidet sich deutlich von anderen Kommunikations- und Kollaborationsapps. Es läuft auf Matrix, ein offenes Netzwerk für eine sichere und dezentralisierte Kommunikation. Es erlaubt den Nutzern ihre eigenen Matrix-Dienste zu betreiben und gibt ihnen damit die vollständige Kontrolle und Besitz über ihre eigenen Daten und Nachrichten.
-
-Privatsphäre/Datenschutz und verschlüsselte Kommunikation
-Element schützt Ihnen vor unerwünschte Werbung, das Datenschürfen und geschlossene unentkommbare Dienste. Auch schützt es all Ihre Daten, Video und Sprachkommunikation unter vier Augen durch Ende-zu-Ende-Verschlüsselung und das Quersignieren von Geräten zur Verifizierung.
-
-Element gibt Ihnen die Kontrolle über Ihre Privatsphäre, während es Ihnen ermöglicht mit jeden auf dem Matrix-Netzwerk oder andere geschäftliche Kollaborationswerkzeuge durch das Einbinden von Apps wie Slack sicher zu kommunizieren.
-
-Element kann man selber betreiben
-Um mehr Kontrolle über Ihre sensiblen Daten und Konversationen zu ermöglichen, kann man Element selbst betreiben oder Sie wählen irgendeinen Matrix-basierten Dienst - der standard für quelloffene, dezentralisierte Kommunikation. Element gibt Ihnen Privatsphäre, Sicherheitskonformität und die Flexibilität zum Integrieren.
-
-Besitzen Sie Ihre Daten
-Sie entscheiden wo Sie Ihre Daten und Nachrichten aufbewahren, ohne das Risiko des Datenschürfens oder des Zugriffes Dritter.
-
-Element gibt Ihnen die Kontrolle durch verschiedene Wege:
-1. Kostenlos auf dem öffentlichen matrix.org Server registrieren, der von den Matrix-Entwicklern gehostet wird, oder wähle aus Tausenden von öffentlichen Servern, die von Freiwilligen gehostet werden
-2. Einen Konto auf einem eigenen Server in der eigenen IT-Infrastruktur betreiben
-3. Einen Konto auf einem benutzerdefinierten Server erstellen, zum Beispiel durch ein Abonnement bei Element Matrix Services (kurz EMS)
-
-Offene Kommunikation und Zusammenarbeit
-Sie können mit jeden auf dem Matrix-Netzwerk chatten, egal ob sie Element, eine Matrix-App oder sogar eine andere Kommunikationsapp nutzen.
-
-Super sicher
-Reale Ende-zu-Ende-Verschlüsselung (nur die Personen in der Konversation können die Nachricht entschüsseln) und Quersignierung von Geräten zur Verifizierung.
-
-Vollständige Kommunikation und Integration
-Kurznachrichten, Sprach- und Videoanrufe, kontrollierte Dateifreigaben, Bildschirmübertragungen und eine ganze Reihe an Integrationen, Bots and Widgets. Schaffe Räume, Gemeinschaften, bleibe auf dem Laufenden und erledige Sachen.
-
-Das Stehengelassene später wieder aufgreifen
-Bleibe auf dem Laufenden, egal wo Sie sind, mit vollständig synchronisierter Nachrichtenverlauf quer über all Ihrer Geräte und im Netz auf https://app.element.io
diff --git a/fastlane/metadata/android/en-US/changelogs/40101080.txt b/fastlane/metadata/android/en-US/changelogs/40101080.txt
new file mode 100644
index 0000000000..f94a332ec3
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Main changes in this version: improvement for Spaces.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.8
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101090.txt b/fastlane/metadata/android/en-US/changelogs/40101090.txt
new file mode 100644
index 0000000000..a5a4e14a29
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Main changes in this version: add support for gitter.im network.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.9
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101100.txt b/fastlane/metadata/android/en-US/changelogs/40101100.txt
new file mode 100644
index 0000000000..30543cb102
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Main changes in this version: theme and style update and new features for spaces.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.10
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101110.txt b/fastlane/metadata/android/en-US/changelogs/40101110.txt
new file mode 100644
index 0000000000..cb3e85d6c0
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Main changes in this version: theme and style update and new features for spaces (bugfix for 1.1.10)
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.11
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101120.txt b/fastlane/metadata/android/en-US/changelogs/40101120.txt
new file mode 100644
index 0000000000..6118974777
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Main changes in this version: theme and style update and fix a crash after video call
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.12
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101130.txt b/fastlane/metadata/android/en-US/changelogs/40101130.txt
new file mode 100644
index 0000000000..9fc3f23b3e
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Main changes in this version: mainly stability and bugfixes update.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.13
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101140.txt b/fastlane/metadata/android/en-US/changelogs/40101140.txt
new file mode 100644
index 0000000000..ee04069968
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Main changes in this version: fix an issue about encrypted messages.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.14
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101150.txt b/fastlane/metadata/android/en-US/changelogs/40101150.txt
new file mode 100644
index 0000000000..321d78b21d
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Main changes in this version: voice message implementation under labs settings.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.15
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40101160.txt b/fastlane/metadata/android/en-US/changelogs/40101160.txt
new file mode 100644
index 0000000000..54b6cbee97
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40101160.txt
@@ -0,0 +1,2 @@
+Main changes in this version: Fix error when sending encrypted message if someone in the room logs out.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.16
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/40102000.txt b/fastlane/metadata/android/en-US/changelogs/40102000.txt
new file mode 100644
index 0000000000..46d9b07809
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40102000.txt
@@ -0,0 +1,2 @@
+Main changes in this version: Voice Message is enabled by default.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.16
\ No newline at end of file
diff --git a/fastlane/metadata/android/es/changelogs/40100100.txt b/fastlane/metadata/android/es-ES/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/es/changelogs/40100100.txt
rename to fastlane/metadata/android/es-ES/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/es/full_description.txt b/fastlane/metadata/android/es-ES/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/es/full_description.txt
rename to fastlane/metadata/android/es-ES/full_description.txt
diff --git a/fastlane/metadata/android/es/short_description.txt b/fastlane/metadata/android/es-ES/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/es/short_description.txt
rename to fastlane/metadata/android/es-ES/short_description.txt
diff --git a/fastlane/metadata/android/es/title.txt b/fastlane/metadata/android/es-ES/title.txt
similarity index 100%
rename from fastlane/metadata/android/es/title.txt
rename to fastlane/metadata/android/es-ES/title.txt
diff --git a/fastlane/metadata/android/et/changelogs/40101070.txt b/fastlane/metadata/android/et/changelogs/40101070.txt
new file mode 100644
index 0000000000..8ef65a7396
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Põhilised muudatused selles versioonis: beeta-versioon kogukonnakeskustest ja videofailide pakkimine enne üleslaadimist.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/et/changelogs/40101080.txt b/fastlane/metadata/android/et/changelogs/40101080.txt
new file mode 100644
index 0000000000..6fa09b30a7
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: kogukonnakeskuste täiendused
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/et/changelogs/40101090.txt b/fastlane/metadata/android/et/changelogs/40101090.txt
new file mode 100644
index 0000000000..f354f7f320
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: liidestus gitter.im võrguga.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/et/changelogs/40101100.txt b/fastlane/metadata/android/et/changelogs/40101100.txt
new file mode 100644
index 0000000000..e00e6de393
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: teemade ja välimuse uuendused ning mõned kogukondade uuendused
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/et/changelogs/40101110.txt b/fastlane/metadata/android/et/changelogs/40101110.txt
new file mode 100644
index 0000000000..a4629c92d0
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: teemade ja välimuse uuendused ning mõned kogukondade uuendused (1.1.10 veaparandus)
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/et/changelogs/40101120.txt b/fastlane/metadata/android/et/changelogs/40101120.txt
new file mode 100644
index 0000000000..c43e8f47b5
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: teemade ja välimuse uuendused ning videokõne-järgse kokkujooksmise parandused
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/et/changelogs/40101130.txt b/fastlane/metadata/android/et/changelogs/40101130.txt
new file mode 100644
index 0000000000..4305a66770
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: üldiste vigade parandus.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/et/changelogs/40101140.txt b/fastlane/metadata/android/et/changelogs/40101140.txt
new file mode 100644
index 0000000000..5e16cad97b
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: krüptitud sõnumitega seotud vigade parandus
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/et/changelogs/40101150.txt b/fastlane/metadata/android/et/changelogs/40101150.txt
new file mode 100644
index 0000000000..caab68c89f
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: häälsõnumid katsete all.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/fa/changelogs/40101150.txt b/fastlane/metadata/android/fa/changelogs/40101150.txt
new file mode 100644
index 0000000000..46677551ef
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+تغییرات اصلی در این نگارش: پیادهسازی پیام صوتی در تنظیمات آزمایشگاهها.
+گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/fa/full_description.txt b/fastlane/metadata/android/fa/full_description.txt
index 0a93676bbf..3051f491ba 100644
--- a/fastlane/metadata/android/fa/full_description.txt
+++ b/fastlane/metadata/android/fa/full_description.txt
@@ -23,7 +23,7 @@
پیامرسانی و همکاری باز: میتوانید با هرکسی در شبکهٔ ماتریکس گپ بزنید، چه از المنت استفاده کنند و چه از هر کارهٔ ماتریکس دیگری؛ و حتا اگر از سامانهٔ پیامرسانی متفاوتی مثل اسلک، آیآرسی یا جبر استفاده کنند.
-فوق امن: رمزنگاری سرتاسری واقعی (فقط کسانی که در گفتوگو هستند،میتوانند پیامها را رمزگشایی کنند) و ورود چندگانه برای تأیید هویت افزارههای شرکتکنندگان در گفتوگو.
+b>فوق امن: رمزنگاری سرتاسری واقعی (فقط کسانی که در گفتوگو هستند،میتوانند پیامها را رمزگشایی کنند) و ورود چندگانه برای تأیید هویت افزارههای شرکتکنندگان در گفتوگو.
ارتباط کامل: پیامرسانی، تماسهای صوتی و تصویری،همرسانی پرونده، همرسانی صفحه و یه عالمه یکپارچگی، بات و ابزارک. اتاق و اجتماع ساخته، در دسترس بوده و کارها را انجام دهید.
diff --git a/fastlane/metadata/android/fa/short_description.txt b/fastlane/metadata/android/fa/short_description.txt
index aba229f959..2925db47b7 100644
--- a/fastlane/metadata/android/fa/short_description.txt
+++ b/fastlane/metadata/android/fa/short_description.txt
@@ -1 +1 @@
-گپ و تماس نامتمرکز امن. دادههایتان را از اشخاص سوم امن نگه دارید.
+پیامرسان گروهی - پیامرسانی رمزنگاشته، گپ گروهی و تماسهای ویدیویی
diff --git a/fastlane/metadata/android/fa/title.txt b/fastlane/metadata/android/fa/title.txt
index fb4ea4125e..96f2f9a9df 100644
--- a/fastlane/metadata/android/fa/title.txt
+++ b/fastlane/metadata/android/fa/title.txt
@@ -1 +1 @@
-المنت (ریوت سابق)
+المنت - پیامرسان امن
diff --git a/fastlane/metadata/android/fi/changelogs/40100100.txt b/fastlane/metadata/android/fi-FI/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100100.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100110.txt b/fastlane/metadata/android/fi-FI/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100110.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100120.txt b/fastlane/metadata/android/fi-FI/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100120.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100130.txt b/fastlane/metadata/android/fi-FI/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100130.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100140.txt b/fastlane/metadata/android/fi-FI/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100140.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100150.txt b/fastlane/metadata/android/fi-FI/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100150.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100160.txt b/fastlane/metadata/android/fi-FI/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100160.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40100170.txt b/fastlane/metadata/android/fi-FI/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40100170.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40101000.txt b/fastlane/metadata/android/fi-FI/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40101000.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/fi/changelogs/40101010.txt b/fastlane/metadata/android/fi-FI/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/fi/changelogs/40101010.txt
rename to fastlane/metadata/android/fi-FI/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/fi-FI/full_description.txt b/fastlane/metadata/android/fi-FI/full_description.txt
new file mode 100644
index 0000000000..ac02bc3b42
--- /dev/null
+++ b/fastlane/metadata/android/fi-FI/full_description.txt
@@ -0,0 +1,39 @@
+Element on turvallinen pikaviesti- ja tiimityösovellus joka sopii mainiosti ryhmäkeskusteluihin etätöissä. Sovellus käyttää päästä päähän -salausta ja tarjoaa videoneuvottelun, tiedostojen jakamisen ja äänipuhelut.
+
+Elementin ominaisuuksia:
+- Edistyneet viestintätyökalut
+- Turvallisempaa yritysviestintää täysin salatuilla viesteillä, myös etätyöntekijöille
+- Hajautettu keskustelu, joka perustuu avoimen lähdekoodin Matrix-teknologiaan
+- Turvallinen tiedostojen jakaminen datan salauksella
+- Videoneuvottelut VoIP:lla ja näytön jakamisella
+- Helppo integraatio tiimityövälineisiin, projektinhallintatyökaluihin, VoIP-palveluihin ja muihin ryhmäviestimiin
+
+Element on täysin erilainen kuin muut viestintä- ja yhteistyösovellukset. Se toimii Matrixilla, avoimella turvallisen ja hajautetun viestinnän verkostolla. Palvelimen ylläpitäminen itse on mahdollista, jos haluaa tietonsa ja viestinsä täysin hallintaansa.
+
+Yksityisyys ja salattu viestintä
+Element protects you from unwanted ads, data mining and walled gardens. It also secures all your data, one-to-one video and voice communication through end-to-end encryption and cross-signed device verification.
+
+Element gives you control over your privacy while allowing you to communicate securely with anyone on the Matrix network, or other business collaboration tools by integrating with apps such as Slack.
+
+Voit ylläpitää omaa palvelinta
+To allow more control of your sensitive data and conversations, Element can be self-hosted or you can choose any Matrix-based host - the standard for open source, decentralized communication. Element gives you privacy, security compliance and integration flexibility.
+
+Hallitse omia tietojasi
+You decide where to keep your data and messages. Without the risk of data mining or access from third parties.
+
+Element puts you in control in different ways:
+1. Get a free account on the matrix.org public server hosted by the Matrix developers, or choose from thousands of public servers hosted by volunteers
+2. Self-host your account by running a server on your own IT infrastructure
+3. Sign up for an account on a custom server by simply subscribing to the Element Matrix Services hosting platform
+
+Avointa viestintää ja yhteistyötä
+Voit keskustella kenen tahansa kanssa Matrix-verkossa, riippumatta siitä käyttääkö tämä Elementiä, jotain muuta Matrix-sovellusta tai jopa muuta viestintäsovellusta.
+
+Todella turvallinen
+Real end-to-end encryption (only those in the conversation can decrypt messages), and cross-signed device verification.
+
+Kattavaa viestintää ja integraatioita
+Viestit, ääni- ja videopuhelut, tiedostojen jakaminen, näytön jakaminen ja koko joukko integraatioita, botteja ja sovelmia. Luo huoneita ja yhteisöjä, pidä yhteyttä ja hoida asiasi.
+
+Jatka siitä mihin jäit
+Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://app.element.io
diff --git a/fastlane/metadata/android/fi-FI/short_description.txt b/fastlane/metadata/android/fi-FI/short_description.txt
new file mode 100644
index 0000000000..0f5314071d
--- /dev/null
+++ b/fastlane/metadata/android/fi-FI/short_description.txt
@@ -0,0 +1 @@
+Ryhmäviestin - salattua viestintää, ryhmäkeskusteluja ja videopuheluita
diff --git a/fastlane/metadata/android/fi-FI/title.txt b/fastlane/metadata/android/fi-FI/title.txt
new file mode 100644
index 0000000000..080d4020d0
--- /dev/null
+++ b/fastlane/metadata/android/fi-FI/title.txt
@@ -0,0 +1 @@
+Element - Turvallinen viestin
diff --git a/fastlane/metadata/android/fi/full_description.txt b/fastlane/metadata/android/fi/full_description.txt
deleted file mode 100644
index 947d19ce3d..0000000000
--- a/fastlane/metadata/android/fi/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Element on uudenlainen viestinsovellus, joka:
-
-1. Antaa sinun päättää yksityisyydestäsi
-2. Antaa sinun kommunikoida kenen tahansa kanssa Matrix-verkossa ja jopa sen ulkopuolella siltaamalla sovelluksiin, kuten Slack
-3. Suojaa sinua mainonnalta, tietojen keräämiseltä ja suljetuilta alustoilta
-4. Suojaa sinut päästä päähän -salauksella sekä ristiin varmentamisella muiden todentamiseksi
-
-Element eroaa täysin muista viestintäsovelluksista, koska se on hajautettu ja avointa lähdekoodia.
-
-Element antaa sinun isännöidä itse - tai valita palveluntarjoajan - jotta sinulla on yksityisyys ja voit hallita tietojasi sekä keskustelujasi. Se antaa sinulle pääsyn avoimeen verkkoon, joten et jää juttelemaan vain toisten Elementin käyttäjien kanssa. Se on myös hyvin turvallinen.
-
-Element pystyy tekemään kaiken tämän, koska se toimii Matrixilla - avoimella, hajautetun viestinnän standardilla.
-
-Element antaa sinulle päätösvallan antamalla sinun valita, kuka isännöi keskustelujasi. Element-sovelluksessa voit valita isännän eri tavoin:
-
-1. Hanki ilmainen tili Matrix-kehittäjien ylläpitämällä matrix.org-palvelimella tai valitse tuhansista vapaaehtoisten ylläpitämistä julkisista palvelimista.
-2. Isännöi tiliäsi itse ylläpitämällä palvelinta omalla laitteellasi
-3. Luo tili sinua varten tehdyllä palvelimella tilaamalla Element Matrix Services -palvelu
-
-Miksi valita Element?
-
-OMAT TIEDOT: Sinä päätät, missä tietosi ja viestisi säilytetään. Sinä määräät, ei jokin jättiyhtiö, joka tutkii tietojasi tai antaa niitä kolmansille osapuolille.
-
-AVOINTA VIESTINTÄÄ JA YHTEISTYÖTÄ: Voit keskustella kaikkien muiden Matrix-verkon käyttäjien kanssa, riippumatta siitä käyttävätkö he Elementiä tai muuta Matrix-sovellusta, ja vaikka he käyttäisivät eri viestijärjestelmiä, kuten Slack, IRC tai XMPP.
-
-ERITTÄIN TURVALLINEN: Vahva päästä päähän -salaus (vain keskustelussa olevat voivat purkaa viestien salauksen), ja ristiin varmentaminen keskustelun osallistujien laitteiden tarkistamiseksi.
-
-KATTAVAA VIESTINTÄÄ: Viestit, ääni- ja videopuhelut, tiedostojen jakaminen, näytön jakaminen ja koko joukko integraatioita, botteja ja sovelmia. Rakenna huoneita ja yhteisöjä, pidä yhteyttä ja hoida asiasi.
-
-MISSÄ TAHANSA OLETKIN: Pidä yhteyttä missä tahansa, täysin synkronoidun viestihistorian kautta kaikilla laitteillasi ja verkossa osoitteessa https://app.element.io.
diff --git a/fastlane/metadata/android/fi/short_description.txt b/fastlane/metadata/android/fi/short_description.txt
deleted file mode 100644
index 64f35a7dff..0000000000
--- a/fastlane/metadata/android/fi/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-Turvallista, hajautettua keskustelua ja VoIP-puheluita. Pidä tietosi turvassa.
diff --git a/fastlane/metadata/android/fi/title.txt b/fastlane/metadata/android/fi/title.txt
deleted file mode 100644
index 8cda14e3c8..0000000000
--- a/fastlane/metadata/android/fi/title.txt
+++ /dev/null
@@ -1 +0,0 @@
-Element (aiemmin Riot.im)
diff --git a/fastlane/metadata/android/fr/changelogs/40100100.txt b/fastlane/metadata/android/fr-FR/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100100.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100110.txt b/fastlane/metadata/android/fr-FR/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100110.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100120.txt b/fastlane/metadata/android/fr-FR/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100120.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100130.txt b/fastlane/metadata/android/fr-FR/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100130.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100140.txt b/fastlane/metadata/android/fr-FR/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100140.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100150.txt b/fastlane/metadata/android/fr-FR/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100150.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100160.txt b/fastlane/metadata/android/fr-FR/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100160.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40100170.txt b/fastlane/metadata/android/fr-FR/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40100170.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101000.txt b/fastlane/metadata/android/fr-FR/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101000.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101010.txt b/fastlane/metadata/android/fr-FR/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101010.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101020.txt b/fastlane/metadata/android/fr-FR/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101020.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101030.txt b/fastlane/metadata/android/fr-FR/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101030.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101040.txt b/fastlane/metadata/android/fr-FR/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101040.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101050.txt b/fastlane/metadata/android/fr-FR/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101050.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/fr/changelogs/40101060.txt b/fastlane/metadata/android/fr-FR/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/fr/changelogs/40101060.txt
rename to fastlane/metadata/android/fr-FR/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101070.txt b/fastlane/metadata/android/fr-FR/changelogs/40101070.txt
new file mode 100644
index 0000000000..66cc5d1671
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : prise en charge des espaces en bêta. Compression des vidéos avant envoi.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101080.txt b/fastlane/metadata/android/fr-FR/changelogs/40101080.txt
new file mode 100644
index 0000000000..31a4b72363
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : amélioration des espaces.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101090.txt b/fastlane/metadata/android/fr-FR/changelogs/40101090.txt
new file mode 100644
index 0000000000..99f02f1bb2
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : ajout de la prise en charge de gitter.im
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101100.txt b/fastlane/metadata/android/fr-FR/changelogs/40101100.txt
new file mode 100644
index 0000000000..610f7765d6
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : rafraîchissement des styles et des thèmes, et nouvelles fonctionnalités pour les espaces.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101110.txt b/fastlane/metadata/android/fr-FR/changelogs/40101110.txt
new file mode 100644
index 0000000000..5a5db82f07
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : rafraîchissement des styles et des thèmes, et nouvelles fonctionnalités pour les espaces (correction for 1.1.10).
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101120.txt b/fastlane/metadata/android/fr-FR/changelogs/40101120.txt
new file mode 100644
index 0000000000..b75ec7d3fe
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : rafraîchissement des styles et des thèmes, et correction d’un plantage après un appel vidéo.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101130.txt b/fastlane/metadata/android/fr-FR/changelogs/40101130.txt
new file mode 100644
index 0000000000..7190eede74
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : principalement des corrections de bogues et de stabilité.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101140.txt b/fastlane/metadata/android/fr-FR/changelogs/40101140.txt
new file mode 100644
index 0000000000..ba1784b5fd
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : correction d’un problème concernant les messages chiffrés.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40101150.txt b/fastlane/metadata/android/fr-FR/changelogs/40101150.txt
new file mode 100644
index 0000000000..559dcc1f6a
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : ajout des messages vocaux dans les expérimentations.
+Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt
new file mode 100644
index 0000000000..78fcdf5617
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/full_description.txt
@@ -0,0 +1,39 @@
+Element est à la fois une messagerie sécurisée et une application de collaboration en équipe, idéale pour les conversations de groupe en télétravail. Cette application utilise le chiffrement de bout en bout. Elle permet de mettre en place des téléconférences vidéo, du partage de fichier et des appels vocaux.
+
+Les fonctionnalités d’Element incluent :
+- Outils de communication en ligne avancés
+- Communication d’entreprise sécurisée par le chiffrement de bout en bout des messages, même pour les travailleurs à distance
+- Messagerie décentralisée basée sur le framework open source Matrix
+- Partage sécurisé de fichiers avec chiffrement des données lors de la gestion de projet
+- Conversations vidéo par voix sur IP et partage d’écran
+- Intégration facile avec vos outils de collaboration, de gestion de projet, services de VoIP et autres applications de messagerie
+
+Element est complètement différente des autres applications de messagerie et de collaboration. Elle s’appuie sur Matrix, un réseau ouvert de communication décentralisée. Elle permet l’auto-hébergement pour que ses utilisateurs restent le plus en contrôle possible de leurs données et leurs messages.
+
+Confidentialité et messagerie chiffrée
+Element vous protège des publicités non désirées, du minage de données et des prisons dorées. Elle protègé vos données et vos communications vocales grâce au chiffrement de bout en bout et à la vérification de signature croisée entre appareils.
+
+Element vous donne la main sur votre confidentialité en vous permettant de communiquer de manière sécurisée avec tout le réseau Matrix ou d’autres applications de communication d’entreprise au travers d’intégrations d’applications comme Slack.
+
+Element peut être auto-hébergé
+Pour une meilleure souveraineté sur vos données et conversations, Element peut être auto-hébergé ou vous pouvez choisir votre hôte Matrix - la norme open source pour les communications décentralisées. Element garantit votre confidentialité, conformité aux normes de sécurité, tout en proposant une intégration souple.
+
+Vos données vous appartiennent
+Vous décidez où stocker vos données et messages. Aucun risque de minage de données où d’accès par des tierce parties.
+
+Element vous place aux commandes de différente manières :
+1. Inscrivez vous sur le serveur public matrix.org hébergé par les développeurs de Matrix ou choisissez parmi des milliers de serveurs publics hébergés par des bénévoles
+2. Auto-hébergez votre compte sur un serveur de votre proper infrastructure informatique
+3. Inscrivez vous à la plateforme d’hébergement Element Matrix Services
+
+Messagerie et collaboration ouvertes
+Vous pouvez discuter avec tout le réseau Matrix, que vos interlocuteurs utilisent Element, une autre application Matrix, ou même s’ils utilisent une application complètement différente.
+
+Ultra sécurisé
+Chiffrement de bout en bout (seules les personnes dans la conversation peuvent déchiffrer les messages) et vérification de signature croisée entre appareils.
+
+Communication et intégration parfaites
+Messagerie instantannée, appels audio et vidéo, partage de fichier, partage d’écran et bien d’autres intégrations, bots et widgets. Lancez des salons, des communautés, restez en contact et menez vos projets à bien.
+
+Reprenez où vous vous êtes arrêté
+Restez en contact où que vous soyez grâce à l’historique des messages synchronisé entre tous vos appareils et sur le web sur https://app.element.io
diff --git a/fastlane/metadata/android/fr-FR/short_description.txt b/fastlane/metadata/android/fr-FR/short_description.txt
new file mode 100644
index 0000000000..f9d18863ce
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/short_description.txt
@@ -0,0 +1 @@
+Messagerie de groupe - messages chiffrés, groupes et appels vidéos
diff --git a/fastlane/metadata/android/fr/title.txt b/fastlane/metadata/android/fr-FR/title.txt
similarity index 100%
rename from fastlane/metadata/android/fr/title.txt
rename to fastlane/metadata/android/fr-FR/title.txt
diff --git a/fastlane/metadata/android/fr/full_description.txt b/fastlane/metadata/android/fr/full_description.txt
deleted file mode 100644
index 066b94868b..0000000000
--- a/fastlane/metadata/android/fr/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Element est une nouvelle application de messagerie et de collaboration qui :
-
-1. Vous permet de préserver votre vie privée
-2. Vous permet de communiquer avec n’importe qui sur réseau Matrix, et plus encore grâce aux intégrations d’autres applications telles que Slack ou Discord
-3. Vous protège de la publicité et de la collecte de données
-4. Vous protège grâce au chiffrement de bout-à-bout et à la signature croisée pour authentifier les autres utilisateurs
-
-Element est complètement différente des autres applications de messagerie et de collaboration puisque l’application est décentralisée et open-source.
-
-Element vous permet d’héberger vous-même ou de choisir un hôte vous permettant d’assurer votre vie privée, la propriété et le contrôle de vos données et de vos conversations. Cela vous donne accès à un réseau ouvert. Vous n’êtes donc pas condamné à parler à d’autres utilisateurs d’Element seulement. Et c'est très sécurisé.
-
-Element peut faire tout ça car elle est basée sur Matrix, le protocole standard pour la communication ouverte et décentralisée.
-
-Element vous donne le contrôle en vous laissant choisir qui héberge vos conversations. Depuis l'application Element, vous pouvez choisir votre hôte de différentes manières :
-
-1. Créer un compte gratuit sur le serveur public matrix.org hébergé par les développeurs de Matrix, ou choisir parmi les milliers de serveurs public hébergés par des bénévoles
-2. Héberger vous-même votre compte en installant un serveur sur votre propre machine
-3. Créer un compte sur un serveur personnalisé en souscrivant sur la plateforme d'hébergement « Element Matrix Services » (EMS)
-
-Pourquoi choisir Element ?
-
-VOS DONNÉES VOUS APPARTIENNENT : vous décidez où stocker vos données et messages. Ils vous appartiennent et vous les maîtrisez. Aucune multinationale ne viendra extraire vos données pour les envoyer au plus offrant.
-
-MESSAGERIE ET COLLABORATION OUVERTES : vous pouvez discuter avec tout le réseau Matrix, qu’ils utilisent Element ou une autre application Matrix, même s’ils utilisent une autre plateforme de messagerie telle que Slack, IRC ou XMPP.
-
-ULTRA SÉCURISÉ : chiffrement de bout en bout (seuls les membres d’une conversation peuvent déchiffrer les messages), et signature croisée pour vérifier les appareils de vos interlocuteurs.
-
-TOUTES VOS COMMUNICATIONS : messagerie, appels audio et vidéo, partage de fichier, partage d’écran et un grand nombre d’intégrations, robots et widgets. Participez à des salons, des communautés, restez en contact et faites avancer vos projets.
-
-PARTOUT AVEC VOUS : votre historique reste synchronisé entre tous vos appareils et sur le web sur https://element.io/app.
diff --git a/fastlane/metadata/android/fr/short_description.txt b/fastlane/metadata/android/fr/short_description.txt
deleted file mode 100644
index 6d86b77a6b..0000000000
--- a/fastlane/metadata/android/fr/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-Messagerie de groupes - messages chiffrés, groupés et appels vidéos
diff --git a/fastlane/metadata/android/hu/changelogs/40100100.txt b/fastlane/metadata/android/hu-HU/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/hu/changelogs/40100100.txt
rename to fastlane/metadata/android/hu-HU/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/hu/changelogs/40100110.txt b/fastlane/metadata/android/hu-HU/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/hu/changelogs/40100110.txt
rename to fastlane/metadata/android/hu-HU/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/hu/changelogs/40100120.txt b/fastlane/metadata/android/hu-HU/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/hu/changelogs/40100120.txt
rename to fastlane/metadata/android/hu-HU/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/hu/changelogs/40100130.txt b/fastlane/metadata/android/hu-HU/changelogs/40100130.txt
similarity index 88%
rename from fastlane/metadata/android/hu/changelogs/40100130.txt
rename to fastlane/metadata/android/hu-HU/changelogs/40100130.txt
index e1b044f4e5..47ce2690f4 100644
--- a/fastlane/metadata/android/hu/changelogs/40100130.txt
+++ b/fastlane/metadata/android/hu-HU/changelogs/40100130.txt
@@ -1,2 +1,2 @@
Főbb változtatások ebben a verzióban: URL előnézet, új emoji billentyűzet, új szoba beállitási lehetőségek, és hó karácsonyra!
-Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.12
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.13
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40100140.txt b/fastlane/metadata/android/hu-HU/changelogs/40100140.txt
new file mode 100644
index 0000000000..1b86da9ab1
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40100140.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: Szoba jogosultságok szerkesztése, automatikus sötét/világos téma és sok hibajavítás.
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.14
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40100150.txt b/fastlane/metadata/android/hu-HU/changelogs/40100150.txt
new file mode 100644
index 0000000000..b48fd6a0d7
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40100150.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: Közösségi hálózatos bejelentkezés támogatása
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.15
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40100160.txt b/fastlane/metadata/android/hu-HU/changelogs/40100160.txt
new file mode 100644
index 0000000000..bb983ed5e8
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40100160.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: Közösségi hálózatos bejelentkezés
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40100170.txt b/fastlane/metadata/android/hu-HU/changelogs/40100170.txt
new file mode 100644
index 0000000000..806470d74e
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40100170.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: Hibajavítás!
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.17
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101000.txt b/fastlane/metadata/android/hu-HU/changelogs/40101000.txt
new file mode 100644
index 0000000000..0bc4f5d49f
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101000.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: VoIP (hang és videóhívás közvetlen beszélgetésekben) fejlesztés és hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.0
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101010.txt b/fastlane/metadata/android/hu-HU/changelogs/40101010.txt
new file mode 100644
index 0000000000..503fc0ab2f
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101010.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: sebesség javítás és hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.1
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101020.txt b/fastlane/metadata/android/hu-HU/changelogs/40101020.txt
new file mode 100644
index 0000000000..04d67ac5ae
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101020.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: sebesség javítás és hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.2
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101030.txt b/fastlane/metadata/android/hu-HU/changelogs/40101030.txt
new file mode 100644
index 0000000000..4d0e46739e
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101030.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: sebesség javítás és hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.3
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101040.txt b/fastlane/metadata/android/hu-HU/changelogs/40101040.txt
new file mode 100644
index 0000000000..1c6921f0d5
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: sebesség javítás és hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101050.txt b/fastlane/metadata/android/hu-HU/changelogs/40101050.txt
new file mode 100644
index 0000000000..c937bb9215
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: javítás az 1.1.4 verzióhoz
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101060.txt b/fastlane/metadata/android/hu-HU/changelogs/40101060.txt
new file mode 100644
index 0000000000..a9b37e66a9
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: javítás az 1.1.5 verzióhoz
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101070.txt b/fastlane/metadata/android/hu-HU/changelogs/40101070.txt
new file mode 100644
index 0000000000..4acfbea1ea
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: béta állapotú Tér támogatás. Videó tömörítés küldés előtt.
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101080.txt b/fastlane/metadata/android/hu-HU/changelogs/40101080.txt
new file mode 100644
index 0000000000..e0f45f09b5
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: javítások a Terekhez
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101090.txt b/fastlane/metadata/android/hu-HU/changelogs/40101090.txt
new file mode 100644
index 0000000000..b3f3369ed7
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: támogatás a gitter.im hálózathoz
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101100.txt b/fastlane/metadata/android/hu-HU/changelogs/40101100.txt
new file mode 100644
index 0000000000..34171b2221
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Főbb változtatások ebben a verzióban: kinézet és stílus frissítések és új funkciók a terekhez
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101110.txt b/fastlane/metadata/android/hu-HU/changelogs/40101110.txt
new file mode 100644
index 0000000000..1550736f36
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Főbb változtatások ebben a verzióban: kinézet és stílus frissítések és új funkciók a terekhez (hibajavítás az 1.1.10-hez)
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101120.txt b/fastlane/metadata/android/hu-HU/changelogs/40101120.txt
new file mode 100644
index 0000000000..d3ca6a935f
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Főbb változtatások ebben a verzióban: kinézet és stílus frissítések és a videóhívás utáni összeomlás javítása
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101130.txt b/fastlane/metadata/android/hu-HU/changelogs/40101130.txt
new file mode 100644
index 0000000000..c90cefeeda
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: leginkább hibajavító és stabilitást növelő frissítés
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40101140.txt b/fastlane/metadata/android/hu-HU/changelogs/40101140.txt
new file mode 100644
index 0000000000..55d57c4515
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: titkosított üzenetekkel kapcsolatos hibajavítás
+Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/hu-HU/full_description.txt b/fastlane/metadata/android/hu-HU/full_description.txt
new file mode 100644
index 0000000000..032346ccb8
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/full_description.txt
@@ -0,0 +1,40 @@
+Element egy biztonságos üzenetküldő és csapatmunka támogató alkalmazás ami ideális távoli munkavégzés közben csoportos csevegéshez. Az alkalmazás végpontok közötti titkosítást használ videó konferenciához, fájl megosztáshoz és videó hivásokhoz.
+
+Element tulajdonságai:
+- Fejlett online kommunikációs eszköz
+- Teljesen titkosított üzenetküldés biztonságos céges kommunikációt kínál még a távdolgozóknak is
+- Elosztott csevegés a Matrix nyílt forráskódú keretrendszer felhasználásával
+- Bizontságos fájl megosztás titkosítottan projektek kezeléséhez
+- Videó hívás VoIP-pal és képernyőmegosztással
+- Könnyen integrálható a kedvenc online kollaborációs eszközöddel, projekt menedzsment eszközzel, VoIP szolgáltatással vagy más csoport üzenetküldő alkalmazással
+
+Element teljesen más mint a többi üzenetküldő alkalmazás. Matrixot használ, egy nyílt hálózatot a decentralizált biztonságos kommunikációhoz. Lehetőséget ad saját szerver üzemeltetésére ami maximális tulajdont és kontrollt biztosít az adatok fölött.
+
+Magánélet védelme és titkosított üzenetküldés
+Element megóv a kéretlen hirdetésektől, adatbányászattól és a különböző szigetszerű megoldásoktól. Minden adatot biztonságba helyez, egy az egybe videó és hang kommunikáció végpontok között titkosítva ahol az eszközök hitelesítve vannak.
+
+Element a kezedbe adja az adatvédelmi irányítást miközben bárkivel kommunikálhatsz a Matrix hálózatban vagy más üzleti kollaborációs eszközzel ami integrálva van, mint amilyen a Slack.
+
+Element futtatható saját szerveren
+
+Azért, hogy az érzékeny adatok és beszélgetések minnél inkább az irányításod alatt lehessen az Elementet saját magadnak üzemeltetheted vagy választhatsz bármely Matrixon alapuló - szabványos nyílt forráskódú és decentralizált kommunikáció - szoláltató közül. Element adatvédelmet, biztonságot és rugalmas integrációkat biztosít.
+
+A te adatod a tiéd
+Te döntöd el, hogy hol tárolod az adataidat és üzeneteidet. Adatbányászat vagy harmadik fél hozzáférésének kockázata nélkül.
+
+Element többféle képpen adja vissza az irányítást:
+1. Szerezz egy ingyenes hozzáférést a matrix.org nyilvános szerverre amit a Matrix fejlesztők üzemeltetnek vagy válassz a több ezer önkéntesek által üzemeltetett nyilvános szerverből
+2. Üzemeltess szerver magadnak a saját infrastruktúrádon
+3. Iratkozz fel egy egyedi szerverre az Element Matrix Services platformon
+
+Nyílt üzenetküldés és kollaboráció
+Bárkivel beszélgethetsz a Matrix hálózaton, akár az Elementet használja akár egy másik Matrix alkalmazást használ vagy akár egy eltérő üzenetküldőt.
+
+Fantasztikusan biztonságos
+Igazi végpontok között titkosítás (csak a beszélgetésben résztvevők tudják visszafejteni) és hitelesítés eszközök közötti aláírásokkal.
+
+Teljes kommunikáció és integráció
+Üzenetküldés, hang és videóhívás, fájl megosztás, képernyő megosztás és egy csomó integráció, botok és kisalkalmazások. Építs szobákat, közösségeket, maradj kapcsolatban és végezz el dolgokat.
+
+Vedd fel a fonalat
+Maradj kapcsolatban bárhol minden eszközödön a szinkronizált üzenetekkel és a weben a https://app.element.io oldallal
diff --git a/fastlane/metadata/android/hu-HU/short_description.txt b/fastlane/metadata/android/hu-HU/short_description.txt
new file mode 100644
index 0000000000..2dfe14c516
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/short_description.txt
@@ -0,0 +1 @@
+Csoportos üzenetküldő - titkosított üzenetek, videó hívások
diff --git a/fastlane/metadata/android/hu-HU/title.txt b/fastlane/metadata/android/hu-HU/title.txt
new file mode 100644
index 0000000000..c463dea393
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/title.txt
@@ -0,0 +1 @@
+Element - Biztonságos üzenetküldő
diff --git a/fastlane/metadata/android/hu/full_description.txt b/fastlane/metadata/android/hu/full_description.txt
deleted file mode 100644
index b75f259d02..0000000000
--- a/fastlane/metadata/android/hu/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Az Element egy új üzenetküldő, és csapatmunka alkalmazás, amivel
-
-1. A te kezedben van az irányítás a saját adataid fölött, hogy megőrizhesd a magánszférádat
-2. Akárkivel beszélgethetsz a Matrix hálózatban, sőt még azon kívül is, például olyan alkalmazások integrálásával, mint a Slack
-3. Megvédheted magad a hirdetésektől, adatbányászattól, és a nagy cégek megoldásaiba való bezártságtól
-4. Biztonságosan beszélgethetsz, a végpontok közötti titkosításnak köszönhetően, az eszközök megbízhatóságát az eszköz-közti hitelesítéssel garantálva
-
-Az Element teljesen más, mint a többi üzenetküldő és csapatmunka alkalmazás, mert nyílt forráskódú, és decentralizált (nem központilag irányított).
-
-Az Element lehetővé teszi, hogy saját szervert futtass - vagy válassz egy szolgáltatót - így te birtoklod az adataidat, ezáltal megőrizve a magánszférád és a biztonságod. Egy nyitott hálózathoz ad hozzáférést, így nem csak a többi Element felhasználóval tudsz beszélgetni, hanem másokkal is. Ráadásul nagyon biztonságos.
-
-Az Element-tel azért válik mindez lehetővé, mert a Matrix hálózatra épül - egy nyílt, decentralizált kommunikációs szabványra.
-
-Az Element a te kezedbe adja az irányítást azáltal, hogy eldöntheted, ki tárolja a beszélgetéseidet. Az Element alkalmazásból több féle szolgáltatót is választhatsz:
-
-1. Regisztrálhatsz ingyen egy fiókot a matrix.org nyilvános szerveren, amit a Matrix fejlesztői üzemeltetnek, vagy választhatsz a több ezer, ingyenes szerver közül, amit önkéntesek üzemeltetnek
-2. A saját számítógépeden is futtathatsz szervert
-3. Előfizethetsz egy saját szerverre az Element Matrix Szolgáltatások platformon
-
-Miért jó az Element-et választani?
-
-ADATAID MEGVÉDÉSE: Eldöntheted, hol tárold az adataid és üzeneteid. A te tulajdonodban van, nem valami megacégnél, ami bányássza az adataid, vagy továbbadja másoknak.
-
-NYÍLT BESZÉLGETÉS, ÉS CSAPATMUNKA: Akárkivel cseveghetsz a Matrix hálózatban, akár az Element-et használják, akár valamilyen másik Matrix alkalmazást, de még akkor is, ha egy másik csevegő hálózatot használnak, olyat, mint például a Slack, IRC, vagy az XMPP.
-
-SZUPER-BIZTONSÁGOS: Valódi, végpontok közötti titkosítás (csak a beszélgetés résztvevői tudják elolvasni az üzeneteket), és eszköz-közti hitelesítés, hogy ellenőrizhesd a résztvevők eszközeit.
-
-TELJES KOMMUNIKÁCIÓ: Üzenetküldés, hang- és videóhívások, fájlmegosztás, képernyőmegosztás, és egy rakás integráció, bot, és widget. Hozz létre szobákat, közösségeket, maradj elérhető, és végezzétek el a feladatokat.
-
-AKÁRHOL, AHOL CSAK SZÜKSÉG VAN RÁ: Akárhol is vagy, maradj elérhető, a teljes mértékben szinkronizált beszélgetésekkel az összes eszközödön, és a weben a https://app.element.io oldalon.
diff --git a/fastlane/metadata/android/hu/short_description.txt b/fastlane/metadata/android/hu/short_description.txt
deleted file mode 100644
index 89f7c13f54..0000000000
--- a/fastlane/metadata/android/hu/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-Biztonságos, decentralizált chat és VoIP. Tartsd az adataid biztonságban.
diff --git a/fastlane/metadata/android/hu/title.txt b/fastlane/metadata/android/hu/title.txt
deleted file mode 100644
index 8e493d2d08..0000000000
--- a/fastlane/metadata/android/hu/title.txt
+++ /dev/null
@@ -1 +0,0 @@
-Element (régebben Riot.im)
diff --git a/fastlane/metadata/android/id/changelogs/40100100.txt b/fastlane/metadata/android/id/changelogs/40100100.txt
new file mode 100644
index 0000000000..96a8f506b3
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100100.txt
@@ -0,0 +1,2 @@
+Versi baru ini terutama berisi perbaikan bug dan peningkatan. Mengirim pesan sekarang jauh lebih cepat.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.10
diff --git a/fastlane/metadata/android/id/changelogs/40100110.txt b/fastlane/metadata/android/id/changelogs/40100110.txt
new file mode 100644
index 0000000000..9f86005d8b
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100110.txt
@@ -0,0 +1,2 @@
+Versi baru ini terutama berisi antarmuka pengguna dan peningkatan pengalaman pengguna. Sekarang Anda dapat mengundang teman, dan membuat sebuah DM sangat cepat dengan memindai kode QR.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.11
diff --git a/fastlane/metadata/android/id/changelogs/40100120.txt b/fastlane/metadata/android/id/changelogs/40100120.txt
new file mode 100644
index 0000000000..3067b6367d
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100120.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Pratinjau URL, keyboard Emoji baru, kemampuan pengaturan ruangan baru, dan salju untuk Natal!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.12
diff --git a/fastlane/metadata/android/id/changelogs/40100130.txt b/fastlane/metadata/android/id/changelogs/40100130.txt
new file mode 100644
index 0000000000..df52988b6c
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100130.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Pratinjau URL, keyboard Emoji baru, kemampuan pengaturan ruangan baru, dan salju untuk Natal!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.13
diff --git a/fastlane/metadata/android/id/changelogs/40100140.txt b/fastlane/metadata/android/id/changelogs/40100140.txt
new file mode 100644
index 0000000000..5243adc1a8
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100140.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Edit izin ruangan, tema cahaya/gelap otomatis, dan banyak perbaikan bug.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.14
diff --git a/fastlane/metadata/android/id/changelogs/40100150.txt b/fastlane/metadata/android/id/changelogs/40100150.txt
new file mode 100644
index 0000000000..54c307b9b6
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100150.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Dukungan login sosial.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15
diff --git a/fastlane/metadata/android/id/changelogs/40100160.txt b/fastlane/metadata/android/id/changelogs/40100160.txt
new file mode 100644
index 0000000000..3e357db352
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100160.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Dukungan login sosial.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15 dan https://github.com/vector-im/element-android/releases/tag/v1.0.16
diff --git a/fastlane/metadata/android/id/changelogs/40100170.txt b/fastlane/metadata/android/id/changelogs/40100170.txt
new file mode 100644
index 0000000000..77f638a7fd
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40100170.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.17
diff --git a/fastlane/metadata/android/id/changelogs/40101000.txt b/fastlane/metadata/android/id/changelogs/40101000.txt
new file mode 100644
index 0000000000..acfe661354
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101000.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: perbaikan VoIP (panggilan audio dan video dalam DM) dan perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.0
diff --git a/fastlane/metadata/android/id/changelogs/40101010.txt b/fastlane/metadata/android/id/changelogs/40101010.txt
new file mode 100644
index 0000000000..a9903a90bd
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101010.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.1
diff --git a/fastlane/metadata/android/id/changelogs/40101020.txt b/fastlane/metadata/android/id/changelogs/40101020.txt
new file mode 100644
index 0000000000..d654bda4fe
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101020.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.2
diff --git a/fastlane/metadata/android/id/changelogs/40101030.txt b/fastlane/metadata/android/id/changelogs/40101030.txt
new file mode 100644
index 0000000000..283c201b2f
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101030.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.3
diff --git a/fastlane/metadata/android/id/changelogs/40101040.txt b/fastlane/metadata/android/id/changelogs/40101040.txt
new file mode 100644
index 0000000000..fdb94db53d
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug!
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/id/changelogs/40101050.txt b/fastlane/metadata/android/id/changelogs/40101050.txt
new file mode 100644
index 0000000000..856530c703
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: perbaikan hot-fix untuk 1.1.4
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/id/changelogs/40101060.txt b/fastlane/metadata/android/id/changelogs/40101060.txt
new file mode 100644
index 0000000000..1810ecc3aa
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: perbaikan hot-fix untuk 1.1.5
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/id/changelogs/40101070.txt b/fastlane/metadata/android/id/changelogs/40101070.txt
new file mode 100644
index 0000000000..0087d51703
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: dukungan beta untuk Spaces. Kompres video sebelum mengirim.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/id/changelogs/40101080.txt b/fastlane/metadata/android/id/changelogs/40101080.txt
new file mode 100644
index 0000000000..cb98796449
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: perbaikan untuk Spaces.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/id/changelogs/40101090.txt b/fastlane/metadata/android/id/changelogs/40101090.txt
new file mode 100644
index 0000000000..f6f535fe64
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: menambahkan dukungan untuk jaringan gitter.im.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/id/changelogs/40101100.txt b/fastlane/metadata/android/id/changelogs/40101100.txt
new file mode 100644
index 0000000000..121d84ca50
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: pembaruan tema dan gaya dan fitur-fitur baru untuk Spaces.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/id/changelogs/40101110.txt b/fastlane/metadata/android/id/changelogs/40101110.txt
new file mode 100644
index 0000000000..63c97253c4
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: pembaruan tema dan gaya dan fitur baru untuk spaces (perbaikan bug untuk 1.1.10)
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/id/changelogs/40101120.txt b/fastlane/metadata/android/id/changelogs/40101120.txt
new file mode 100644
index 0000000000..b8f23c530b
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: pembaruan tema dan gaya dan perbaiki crash setelah panggilan video
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/id/changelogs/40101130.txt b/fastlane/metadata/android/id/changelogs/40101130.txt
new file mode 100644
index 0000000000..51c532725b
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: terutama pembaruan stabilitas dan perbaikan bug.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/id/changelogs/40101140.txt b/fastlane/metadata/android/id/changelogs/40101140.txt
new file mode 100644
index 0000000000..af1e203dde
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: memperbaiki masalah tentang pesan terenkripsi.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/id/changelogs/40101150.txt b/fastlane/metadata/android/id/changelogs/40101150.txt
new file mode 100644
index 0000000000..f3aec557d0
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: implementasi pesan suara dalam pengaturan labs.
+Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt
new file mode 100644
index 0000000000..0a18b8d64a
--- /dev/null
+++ b/fastlane/metadata/android/id/full_description.txt
@@ -0,0 +1,39 @@
+Element adalah perpesanan yang aman dan aplikasi kolaborasi tim produktivitas yang ideal untuk obrolan grup saat bekerja jarak jauh. Aplikasi obrolan ini menggunakan enkripsi ujung-ke-ujung untuk memberikan konferensi video, berbagi file, dan panggilan suara.
+
+Fitur Element termasuk:
+- Alat komunikasi online yang canggih
+- Pesan terenkripsi sepenuhnya untuk memungkinkan komunikasi perusahaan yang lebih aman, bahkan untuk pekerja jarak jauh
+- Obrolan terdesentralisasi berdasarkan framework sumber-terbuka Matrix
+- Berbagi file dengan aman dengan data terenkripsi saat mengelola proyek
+- Obrolan video dengan VoIP dan berbagi layar
+- Integrasi yang mudah dengan alat kolaborasi online favorit Anda, alat manajemen proyek, layanan VoIP dan aplikasi perpesanan tim lainnya
+
+Element benar-benar berbeda dari aplikasi perpesanan dan kolaborasi lainnya. Ini beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi terdesentralisasi. Ini memungkinkan hosting sendiri untuk memberi pengguna kepemilikan maksimum dan kontrol data dan pesan mereka.
+
+Pesan privasi dan terenkripsi
+Element melindungi Anda dari iklan yang tidak diinginkan, data penambangan dan taman berdinding. Ini juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu melalui enkripsi ujung-ke-ujung dan verifikasi perangkat yang di-cross-signed.
+
+Element memberi Anda kendali atas privasi Anda sambil memungkinkan Anda untuk berkomunikasi dengan aman dengan siapa pun di jaringan Matrix, atau alat kolaborasi bisnis lainnya dengan mengintegrasikan dengan aplikasi seperti Slack.
+
+Element dapat dihost sendiri
+Untuk memungkinkan lebih banyak kendali atas data dan percakapan sensitif Anda, Element bisa dihost sendiri atau Anda dapat memilih host berbasis Matrix - standar untuk komunikasi terdesentralisasi sumber-terbuka. Element memberi Anda privasi, kepatuhan keamanan, dan fleksibilitas integrasi.
+
+Miliki data Anda
+Anda memutuskan di mana menyimpan data dan pesan Anda. Tanpa risiko penambangan data atau akses dari pihak ketiga.
+
+Element menempatkan Anda dalam kendali dengan cara yang berbeda:
+1. Dapatkan akun gratis pada server publik matrix.org yang dihost oleh pengembang Matrix, atau memilih dari ribuan server publik yang dihost oleh sukarelawan
+2. Host sendiri akun Anda dengan menjalankan server pada infrastruktur IT Anda sendiri
+3. Daftar untuk akun di server khusus dengan hanya berlangganan platform hosting Element Matrix Services
+
+Pesan terbuka dan kolaborasi
+Anda dapat mengobrol dengan siapa saja di jaringan Matrix, apakah mereka menggunakan Element, aplikasi Matrix lain atau bahkan jika mereka menggunakan aplikasi perpesanan yang berbeda.
+
+Sangat aman
+Enkripsi ujung-ke-ujung beneran (hanya mereka yang dalam percakapan dapat mendekripsi pesan), dan verifikasi perangkat yang di-cross-signed.
+
+Komunikasi dan integrasi lengkap
+Perpesanan, panggilan suara dan video, berbagi file, berbagi layar dan banyak integrasi, bot dan widget. Buat ruangan, komunitas, tetap terhubung dan selesaikan hal-hal.
+
+Ambil di mana Anda tinggalkan
+Tetap terhubung di mana pun Anda berada dengan riwayat pesan yang sepenuhnya disinkronkan di semua perangkat Anda dan di web di https://app.element.io
diff --git a/fastlane/metadata/android/id/short_description.txt b/fastlane/metadata/android/id/short_description.txt
new file mode 100644
index 0000000000..e6c3a2f7a9
--- /dev/null
+++ b/fastlane/metadata/android/id/short_description.txt
@@ -0,0 +1 @@
+Perpesanan grup - pesan terenkripsi, panggilan grup dan video
diff --git a/fastlane/metadata/android/id/title.txt b/fastlane/metadata/android/id/title.txt
new file mode 100644
index 0000000000..aec5dc9351
--- /dev/null
+++ b/fastlane/metadata/android/id/title.txt
@@ -0,0 +1 @@
+Element - Perpesanan Aman
diff --git a/fastlane/metadata/android/it/changelogs/40100100.txt b/fastlane/metadata/android/it-IT/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100100.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100110.txt b/fastlane/metadata/android/it-IT/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100110.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100120.txt b/fastlane/metadata/android/it-IT/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100120.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100130.txt b/fastlane/metadata/android/it-IT/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100130.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100140.txt b/fastlane/metadata/android/it-IT/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100140.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100150.txt b/fastlane/metadata/android/it-IT/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100150.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100160.txt b/fastlane/metadata/android/it-IT/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100160.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/it/changelogs/40100170.txt b/fastlane/metadata/android/it-IT/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40100170.txt
rename to fastlane/metadata/android/it-IT/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101000.txt b/fastlane/metadata/android/it-IT/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101000.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101010.txt b/fastlane/metadata/android/it-IT/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101010.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101020.txt b/fastlane/metadata/android/it-IT/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101020.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101030.txt b/fastlane/metadata/android/it-IT/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101030.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101040.txt b/fastlane/metadata/android/it-IT/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101040.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101050.txt b/fastlane/metadata/android/it-IT/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101050.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/it/changelogs/40101060.txt b/fastlane/metadata/android/it-IT/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/it/changelogs/40101060.txt
rename to fastlane/metadata/android/it-IT/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101070.txt b/fastlane/metadata/android/it-IT/changelogs/40101070.txt
new file mode 100644
index 0000000000..6f7ffcd958
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: supporto beta per gli Spazi. Compressione video prima dell'invio.
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101080.txt b/fastlane/metadata/android/it-IT/changelogs/40101080.txt
new file mode 100644
index 0000000000..9964245d4d
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: miglioramenti per gli Spazi.
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101090.txt b/fastlane/metadata/android/it-IT/changelogs/40101090.txt
new file mode 100644
index 0000000000..d1d89c8f41
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: aggiunto supporto per la rete gitter.im .
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101100.txt b/fastlane/metadata/android/it-IT/changelogs/40101100.txt
new file mode 100644
index 0000000000..6f2447e5f6
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: aggiornati tema e stile e nuove funzioni per gli spazi .
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101110.txt b/fastlane/metadata/android/it-IT/changelogs/40101110.txt
new file mode 100644
index 0000000000..263f46b4f1
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: aggiornati tema e stile e nuove funzioni per gli spazi (bugfix per 1.1.10)
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101120.txt b/fastlane/metadata/android/it-IT/changelogs/40101120.txt
new file mode 100644
index 0000000000..382b490745
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: aggiornati tema e stile, corretto un crash dopo videochiamata
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101130.txt b/fastlane/metadata/android/it-IT/changelogs/40101130.txt
new file mode 100644
index 0000000000..2c7fc1a614
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: aggiornamento di stabilità e correzione errori.
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101140.txt b/fastlane/metadata/android/it-IT/changelogs/40101140.txt
new file mode 100644
index 0000000000..30921e31c6
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: corretto un problema con i messaggi cifrati.
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/it-IT/changelogs/40101150.txt b/fastlane/metadata/android/it-IT/changelogs/40101150.txt
new file mode 100644
index 0000000000..7a7eef5757
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: implementazione messaggi vocali nelle impostazioni Laboratori.
+Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/it/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/it/full_description.txt
rename to fastlane/metadata/android/it-IT/full_description.txt
diff --git a/fastlane/metadata/android/it/short_description.txt b/fastlane/metadata/android/it-IT/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/it/short_description.txt
rename to fastlane/metadata/android/it-IT/short_description.txt
diff --git a/fastlane/metadata/android/it/title.txt b/fastlane/metadata/android/it-IT/title.txt
similarity index 100%
rename from fastlane/metadata/android/it/title.txt
rename to fastlane/metadata/android/it-IT/title.txt
diff --git a/fastlane/metadata/android/he/changelogs/40100100.txt b/fastlane/metadata/android/iw-IL/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/he/changelogs/40100100.txt
rename to fastlane/metadata/android/iw-IL/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/he/changelogs/40100110.txt b/fastlane/metadata/android/iw-IL/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/he/changelogs/40100110.txt
rename to fastlane/metadata/android/iw-IL/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/he/changelogs/40100120.txt b/fastlane/metadata/android/iw-IL/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/he/changelogs/40100120.txt
rename to fastlane/metadata/android/iw-IL/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/he/changelogs/40100130.txt b/fastlane/metadata/android/iw-IL/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/he/changelogs/40100130.txt
rename to fastlane/metadata/android/iw-IL/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/he/full_description.txt b/fastlane/metadata/android/iw-IL/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/he/full_description.txt
rename to fastlane/metadata/android/iw-IL/full_description.txt
diff --git a/fastlane/metadata/android/he/short_description.txt b/fastlane/metadata/android/iw-IL/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/he/short_description.txt
rename to fastlane/metadata/android/iw-IL/short_description.txt
diff --git a/fastlane/metadata/android/he/title.txt b/fastlane/metadata/android/iw-IL/title.txt
similarity index 100%
rename from fastlane/metadata/android/he/title.txt
rename to fastlane/metadata/android/iw-IL/title.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100100.txt b/fastlane/metadata/android/ja-JP/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100100.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100110.txt b/fastlane/metadata/android/ja-JP/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100110.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100120.txt b/fastlane/metadata/android/ja-JP/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100120.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100130.txt b/fastlane/metadata/android/ja-JP/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100130.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100140.txt b/fastlane/metadata/android/ja-JP/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100140.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100150.txt b/fastlane/metadata/android/ja-JP/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100150.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100160.txt b/fastlane/metadata/android/ja-JP/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100160.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40100170.txt b/fastlane/metadata/android/ja-JP/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40100170.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40101000.txt b/fastlane/metadata/android/ja-JP/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40101000.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40101010.txt b/fastlane/metadata/android/ja-JP/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40101010.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40101020.txt b/fastlane/metadata/android/ja-JP/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40101020.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/ja/changelogs/40101030.txt b/fastlane/metadata/android/ja-JP/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/ja/changelogs/40101030.txt
rename to fastlane/metadata/android/ja-JP/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/ja/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/ja/full_description.txt
rename to fastlane/metadata/android/ja-JP/full_description.txt
diff --git a/fastlane/metadata/android/ja/short_description.txt b/fastlane/metadata/android/ja-JP/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/ja/short_description.txt
rename to fastlane/metadata/android/ja-JP/short_description.txt
diff --git a/fastlane/metadata/android/ja/title.txt b/fastlane/metadata/android/ja-JP/title.txt
similarity index 100%
rename from fastlane/metadata/android/ja/title.txt
rename to fastlane/metadata/android/ja-JP/title.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100100.txt b/fastlane/metadata/android/no-NO/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100100.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100110.txt b/fastlane/metadata/android/no-NO/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100110.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100120.txt b/fastlane/metadata/android/no-NO/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100120.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100130.txt b/fastlane/metadata/android/no-NO/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100130.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100140.txt b/fastlane/metadata/android/no-NO/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100140.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100150.txt b/fastlane/metadata/android/no-NO/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100150.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100160.txt b/fastlane/metadata/android/no-NO/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100160.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40100170.txt b/fastlane/metadata/android/no-NO/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40100170.txt
rename to fastlane/metadata/android/no-NO/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40101000.txt b/fastlane/metadata/android/no-NO/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40101000.txt
rename to fastlane/metadata/android/no-NO/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40101010.txt b/fastlane/metadata/android/no-NO/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40101010.txt
rename to fastlane/metadata/android/no-NO/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40101020.txt b/fastlane/metadata/android/no-NO/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40101020.txt
rename to fastlane/metadata/android/no-NO/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/nb-NO/changelogs/40101030.txt b/fastlane/metadata/android/no-NO/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/changelogs/40101030.txt
rename to fastlane/metadata/android/no-NO/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/nb-NO/full_description.txt b/fastlane/metadata/android/no-NO/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/full_description.txt
rename to fastlane/metadata/android/no-NO/full_description.txt
diff --git a/fastlane/metadata/android/nb-NO/short_description.txt b/fastlane/metadata/android/no-NO/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/short_description.txt
rename to fastlane/metadata/android/no-NO/short_description.txt
diff --git a/fastlane/metadata/android/nb-NO/title.txt b/fastlane/metadata/android/no-NO/title.txt
similarity index 100%
rename from fastlane/metadata/android/nb-NO/title.txt
rename to fastlane/metadata/android/no-NO/title.txt
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40100170.txt b/fastlane/metadata/android/pt-BR/changelogs/40100170.txt
index 15081f160f..2292ddab98 100644
--- a/fastlane/metadata/android/pt-BR/changelogs/40100170.txt
+++ b/fastlane/metadata/android/pt-BR/changelogs/40100170.txt
@@ -1,2 +1,2 @@
-Principais mudanças nessa versão: correções de erros!
-Registro de todas as alterações: https://github.com/vector-im/element-android/releases/tag/v1.0.17
+Principais alterações nesta versão: Correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.0.17
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101000.txt b/fastlane/metadata/android/pt-BR/changelogs/40101000.txt
index 8138e376c6..8cdb122f14 100644
--- a/fastlane/metadata/android/pt-BR/changelogs/40101000.txt
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101000.txt
@@ -1,2 +1,2 @@
-Principais mudanças nesta versão: Melhoria de VoIP (chamadas de áudio e vídeo em conversas) e correção de erros!
-Registro de alterações completo: https://github.com/vector-im/element-android/releases/tag/v1.1.0
+Principais alterações nesta versão: melhoramento de VoIP (chamadas de áudio e vídeo em DM) e correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.0
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101010.txt b/fastlane/metadata/android/pt-BR/changelogs/40101010.txt
index 56f9c2955d..3a1128f229 100644
--- a/fastlane/metadata/android/pt-BR/changelogs/40101010.txt
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101010.txt
@@ -1,2 +1,2 @@
-Principais mudanças nesta versão: melhoria de desempenho e correção de erros!
-Registro de alterações completo: https://github.com/vector-im/element-android/releases/tag/v1.1.1
+Principais alterações nesta versão: melhoramento de performance e correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.1
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101020.txt b/fastlane/metadata/android/pt-BR/changelogs/40101020.txt
new file mode 100644
index 0000000000..7ee163e003
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101020.txt
@@ -0,0 +1,2 @@
+Principais alterações nesta versão: melhoramento de performance e correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.2
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101030.txt b/fastlane/metadata/android/pt-BR/changelogs/40101030.txt
new file mode 100644
index 0000000000..e83058e014
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101030.txt
@@ -0,0 +1,2 @@
+Principais alterações nesta versão: melhoramento de performance e correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.3
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101040.txt b/fastlane/metadata/android/pt-BR/changelogs/40101040.txt
new file mode 100644
index 0000000000..c58ede0161
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+Principais alterações nesta versão: melhora de performance e correções de bugs!
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101050.txt b/fastlane/metadata/android/pt-BR/changelogs/40101050.txt
new file mode 100644
index 0000000000..5ab2dbee0d
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+Principais alterações nesta versão: correções quentes para 1.1.4
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101060.txt b/fastlane/metadata/android/pt-BR/changelogs/40101060.txt
new file mode 100644
index 0000000000..062b53d279
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+Principais alterações nesta versão: correções quentes para 1.1.5
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101070.txt b/fastlane/metadata/android/pt-BR/changelogs/40101070.txt
new file mode 100644
index 0000000000..5667b1609a
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: suporte beta para Espaços. Comprimir vídeo antes de enviar.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101080.txt b/fastlane/metadata/android/pt-BR/changelogs/40101080.txt
new file mode 100644
index 0000000000..7922e6d800
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: melhoramento para Espaços.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101090.txt b/fastlane/metadata/android/pt-BR/changelogs/40101090.txt
new file mode 100644
index 0000000000..3246596eab
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: adicionar supporte a rede gitter.im.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101100.txt b/fastlane/metadata/android/pt-BR/changelogs/40101100.txt
new file mode 100644
index 0000000000..4efd042313
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: atualização de tema e estilo e novas funcionalidades para espaços.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101110.txt b/fastlane/metadata/android/pt-BR/changelogs/40101110.txt
new file mode 100644
index 0000000000..ac98ef9e3b
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: atualização de tema e estilo e novas funcionalidades para espaços (bugfix para 1.1.10)
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101120.txt b/fastlane/metadata/android/pt-BR/changelogs/40101120.txt
new file mode 100644
index 0000000000..4e8b0a0901
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: atualização de tema e estilo e consertar um crash depois de chamada de vídeo
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101130.txt b/fastlane/metadata/android/pt-BR/changelogs/40101130.txt
new file mode 100644
index 0000000000..cadd1619d6
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: principalmente atualização de estabilidade e consertos de bug.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101140.txt b/fastlane/metadata/android/pt-BR/changelogs/40101140.txt
new file mode 100644
index 0000000000..2d33d46e3a
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: consertar um problema sobre mensagens encriptadas.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40101150.txt b/fastlane/metadata/android/pt-BR/changelogs/40101150.txt
new file mode 100644
index 0000000000..3be1d63d46
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: implementação de mensagem de voz em configurações labs.
+Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/pt-BR/full_description.txt b/fastlane/metadata/android/pt-BR/full_description.txt
index 82b38b473c..7bb3d0981d 100644
--- a/fastlane/metadata/android/pt-BR/full_description.txt
+++ b/fastlane/metadata/android/pt-BR/full_description.txt
@@ -1,30 +1,39 @@
-Element é um novo tipo de aplicativo de mensagens e colaboração que:
+Element é tanto um mensageiro seguro como um app de colaboração de time de produtividade que é ideal para chats de grupo enquanto se trabalha remotamente. Este app de chat usa encriptação ponta-a-ponta para prover conferência de vídeo, compartilhamento de arquivo e chamadas de voz poderasos.
-1. Coloca você no controle de sua privacidade;
-2. Permite que você se comunique com qualquer pessoa na rede Matrix e, através de integrações, outros aplicativos como o Slack;
-3. Protege você de anúncios, mineração de dados e de ecossistemas fechados;
-4. Faz uso da criptografia de ponta a ponta, com autoverificação para confirmar outras pessoas.
+As funções de Element incluem:
+- Ferramentas de comunicação online avançadas
+- Mensagens completamente encriptadas para permitir comunicação de corporação mais segura, até para pessoas trabalhando remotamente
+- Chat descentralizado baseado na framework open source Matrix
+- Compartilhamento de arquivo seguramente com dados encriptados enquanto se gerencia projetos
+- Chats de vídeo com Voz sobre IP e compartilhamento de tela
+- Integração fácil com suas ferramentas de colaboração online favoritas, ferramentas de gerenciamento de projetos, serviços de VoIP e outros apps de mensageria de time
-Element é completamente diferente de outros aplicativos de mensagem e colaboração porque é descentralizado e código aberto.
+Element é completamente diferente de outros apps de mensageria e colaboração. Ele opera em Matrix, uma rede aberta para mensageria segura e comunicação descentralizada. Ele permite auto-hospedagem para dar a usuárias(os) máxima propriedade e controle de seus dados e suas mensagens.
-É possível hospedar um servidor ou escolher um servidor hospedeiro, para que você tenha privacidade, controle e que você seja o dono de seus dados e conversas. Com o Element, você possui acesso a uma rede aberta; então você não está preso falando somente com outros usuários no Element. O Element também é muito seguro.
+Privacidade e mensageria encriptada
+Element protege você de ads indesejados, datamining e jardins murados. Ele também assegura todos os seus dados, vídeo um-a-um e comunicação de voz através de encriptação ponta-a-ponta e verificação de dispositivo assinada cruzado.
-Element é capaz de fazer tudo isso porque ele opera no Matrix, o padrão para comunicação aberta e descentralizada.
+Element dá a você controle sobre sua privacidade enquanto permite a você se comunicar seguramente com qualquer pessoa na rede Matrix, ou outras ferramentas de colaboração ao se integrar com apps tais como Slack.
-Element coloca você no controle ao permitir quem hospeda suas conversas. Neste aplicativo, você pode escolher hospedar de maneiras diferentes:
+Element pode ser auto-hospedado
+Para permitir mais controle de seus dados e conversas sensíveis, Element pode ser auto-hospedado ou você pode escolher qualquer host baseado em Matrix - o standard para comunicação open source e descentralizada. Element dá a você privacidade, conformidade de segurança e flexibilidade de integração.
-1. Crie uma conta gratuita no servidor público matrix.org;
-2. Hospede sua conta no seu servidor;
-3. Entre em uma conta em um servidor customizado ao simplesmente se inscrever na plataforma de hospedagem Serviços Matrix Element.
+Tenha posse de seus dados
+Você decide onde manter seus dados e mensagens. Sem o risco de data mining ou acesso de terceiros.
-Por que escolher o Element?
+Element põe você em controle de diferentes maneiras:
+1. Pegar uma conta grátis no servidor público matrix.org hospedado pelos desenvolvedores Matrix, ou escolha de milhares de servidores públicos hospedados por pessoas se voluntariando
+2. Auto-hospedar sua conta ao rodar um servidor em sua própria infraestrutura de TI
+3. Fazer signup para uma conta num servidor personalizado ao simplesmente assinar a plataforma de hospedagem Element Matrix Services
-SEJA O DONO DE SEUS DADOS: você decide onde manter seus dados e mensagens. Você é o dono deles e também os controla, não alguma mega corporação que minera os seus dados ou compartilha eles com terceiros.
+Mensageria e colaboração abertos
+Você pode fazer chat com qualquer pessoa na rede Matrix, caso ela esteja usando Element, um outro app de Matrix ou mesmo se ela estiver usando um app de mensageria diferente.
-COLABORAÇÃO E MENSAGENS ABERTAS: você pode falar com qualquer outra pessoa na rede Matrix, não importa se ela está usando o Element ou algum outro aplicativo Matrix, ou até mesmo se ela está utilizando um sistema de mensagens diferente como o Slack, IRC ou XMPP.
+Super seguro
+Encriptação ponta-a-ponta real (somente aquelas/es na conversa podem decriptar mensagens), e verificação de dispositivo assinada cuzado.
-SUPER-SEGURO: criptografia de ponta a ponta verdadeira (apenas aqueles na conversa podem descriptografar mensagens), e assinatura cruzada para verificar os dispositivos de participantes de conversas.
+Comunicação e integração completas
+Messageria, chamadas de voz e vídeo, compartilhamento de arquivo, compartilhamento de tela e um monte de integrações, bots e widgets. Construa salas, comunidades, fique em contato e tenha as coisas feitas.
-COMUNICAÇÃO COMPLETA: mensagens, chamadas de voz, chamadas de vídeo, compartilhamento de arquivos, compartilhamento de tela e um monte de integrações, robôs e widgets. Construa salas, comunidades, mantenha contato e faça seus projetos.
-
-NÃO IMPORTA ONDE VOCÊ ESTEJA: mantenha contato não importa onde você esteja com o histórico sincronizado de mensagens em todos os seus dispositivos e no navegador em https://app.element.io.
+Continue de onde você parou
+Fique em contato onde quer que você esteja com histórico de mensagem completamente sincronizado por todos os seus dispositivos e na web em https://app.element.io
diff --git a/fastlane/metadata/android/pt-BR/short_description.txt b/fastlane/metadata/android/pt-BR/short_description.txt
index 853f629c30..d5f82d8623 100644
--- a/fastlane/metadata/android/pt-BR/short_description.txt
+++ b/fastlane/metadata/android/pt-BR/short_description.txt
@@ -1 +1 @@
-Conversas e chamadas seguras e descentralizadas. Mantenha seus dados protegidos.
+Mensageiro de grupo - mensageria, chat de grupo e chamadas de vídeo encriptados
diff --git a/fastlane/metadata/android/pt-BR/title.txt b/fastlane/metadata/android/pt-BR/title.txt
index 5d2ae0c353..90dbcf1bba 100644
--- a/fastlane/metadata/android/pt-BR/title.txt
+++ b/fastlane/metadata/android/pt-BR/title.txt
@@ -1 +1 @@
-Element (o novo Riot.im)
+Element - Mensageiro Seguro
diff --git a/fastlane/metadata/android/ro/short_description.txt b/fastlane/metadata/android/ro/short_description.txt
new file mode 100644
index 0000000000..86abb501b1
--- /dev/null
+++ b/fastlane/metadata/android/ro/short_description.txt
@@ -0,0 +1 @@
+Mesagerie de grup - mesaje criptate, comunicare de grup și apeluri video
diff --git a/fastlane/metadata/android/ro/title.txt b/fastlane/metadata/android/ro/title.txt
new file mode 100644
index 0000000000..09a73b82e2
--- /dev/null
+++ b/fastlane/metadata/android/ro/title.txt
@@ -0,0 +1 @@
+Element - Mesagerie securizată
diff --git a/fastlane/metadata/android/ru/changelogs/40100100.txt b/fastlane/metadata/android/ru-RU/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100100.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100110.txt b/fastlane/metadata/android/ru-RU/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100110.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100120.txt b/fastlane/metadata/android/ru-RU/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100120.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100130.txt b/fastlane/metadata/android/ru-RU/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100130.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100140.txt b/fastlane/metadata/android/ru-RU/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100140.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100150.txt b/fastlane/metadata/android/ru-RU/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100150.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100160.txt b/fastlane/metadata/android/ru-RU/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100160.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40100170.txt b/fastlane/metadata/android/ru-RU/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40100170.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40101000.txt b/fastlane/metadata/android/ru-RU/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40101000.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40101010.txt b/fastlane/metadata/android/ru-RU/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40101010.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40101020.txt b/fastlane/metadata/android/ru-RU/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40101020.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/ru/changelogs/40101030.txt b/fastlane/metadata/android/ru-RU/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/ru/changelogs/40101030.txt
rename to fastlane/metadata/android/ru-RU/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101040.txt b/fastlane/metadata/android/ru-RU/changelogs/40101040.txt
new file mode 100644
index 0000000000..0fa9e956c0
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: улучшение и исправления ошибок!
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101050.txt b/fastlane/metadata/android/ru-RU/changelogs/40101050.txt
new file mode 100644
index 0000000000..c40bcab325
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: исправление для 1.1.4
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101060.txt b/fastlane/metadata/android/ru-RU/changelogs/40101060.txt
new file mode 100644
index 0000000000..44be6599ec
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: исправление для 1.1.5
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101070.txt b/fastlane/metadata/android/ru-RU/changelogs/40101070.txt
new file mode 100644
index 0000000000..4a400e8dc6
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: бета-поддержка Пространств. Сжатие видео перед отправкой.
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101080.txt b/fastlane/metadata/android/ru-RU/changelogs/40101080.txt
new file mode 100644
index 0000000000..a695b9301d
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: Усовершенствованы Пространства!
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101090.txt b/fastlane/metadata/android/ru-RU/changelogs/40101090.txt
new file mode 100644
index 0000000000..5233f3985b
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: добавлена поддержка сети gitter.im.
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101100.txt b/fastlane/metadata/android/ru-RU/changelogs/40101100.txt
new file mode 100644
index 0000000000..fa3e77adcd
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Основные изменения этой версии: обновлен внешний вид и новые возможности для пространств
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101110.txt b/fastlane/metadata/android/ru-RU/changelogs/40101110.txt
new file mode 100644
index 0000000000..b5dcad40e2
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Основные изменения этой версии: обновлен внешний вид и новые возможности для пространств (bugfix для 1.1.10)
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101120.txt b/fastlane/metadata/android/ru-RU/changelogs/40101120.txt
new file mode 100644
index 0000000000..b76827916d
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: обновление темы и стиля и исправления сбоев после видеовызова
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101130.txt b/fastlane/metadata/android/ru-RU/changelogs/40101130.txt
new file mode 100644
index 0000000000..c1ed9005aa
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: улучшение стабильности и исправления ошибок.
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101140.txt b/fastlane/metadata/android/ru-RU/changelogs/40101140.txt
new file mode 100644
index 0000000000..1c8c7cb356
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Основные изменения в этой версии: исправление проблемы с зашифрованными сообщениями.
+Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt
new file mode 100644
index 0000000000..3d21b20a90
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/full_description.txt
@@ -0,0 +1,39 @@
+Element - это одновременно безопасный мессенджер и приложение для совместной работы, которое идеально подходит для групповых чатов при удаленной работе. Это приложение для чатов использует сквозное шифрование для обеспечения мощных видеоконференций, обмена файлами и голосовых звонков.
+
+Особенности Element включают:
+- Передовые средства онлайн-общения
+- Полностью зашифрованные сообщения, обеспечивающие безопасное корпоративное общение даже для удаленных работников
+- Децентрализованный чат на базе платформы Matrix с открытым исходным кодом
+- Безопасный обмен файлами с зашифрованными данными при управлении проектами
+- Видеочаты с VoIP и совместным использованием экрана
+- Простая интеграция с вашими любимыми инструментами для совместной работы в Интернете, средствами управления проектами, VoIP-сервисами и другими приложениями для обмена сообщениями в команде.
+
+Element полностью отличается от других приложений для обмена сообщениями и совместной работы. Он работает на базе Matrix, открытой сети для безопасного обмена сообщениями и децентрализованного общения. Он позволяет самостоятельно размещать свои данные и сообщения, предоставляя пользователям максимальный контроль над ними.
+
+Приватность и зашифрованный обмен сообщениями.
+Element защищает вас от нежелательной рекламы, сбора данных и "садов". Он также защищает все ваши данные, видео- и голосовую связь один на один благодаря сквозному шифрованию и перекрестной проверке устройств.
+
+Element дает вам контроль над вашей конфиденциальностью, позволяя безопасно общаться с любым человеком в сети Matrix или с другими инструментами совместной работы благодаря интеграции с такими приложениями, как Slack.
+
+Element может быть размещен самостоятельно.
+Чтобы обеспечить больший контроль над конфиденциальными данными и разговорами, Element может быть размещен самостоятельно или вы можете выбрать любой хост на базе Matrix - стандарт децентрализованного общения с открытым исходным кодом. Element обеспечивает конфиденциальность, соответствие требованиям безопасности и гибкость интеграции.
+
+Владение своими данными.
+Вы сами решаете, где хранить свои данные и сообщения. Без риска добычи данных или доступа третьих лиц.
+
+Element дает вам возможность контролировать ситуацию различными способами:
+1. Получить бесплатный аккаунт на публичном сервере matrix.org, размещенном разработчиками Matrix, или выбрать один из тысяч публичных серверов, размещенных добровольцами.
+2. Самостоятельно разместить свою учетную запись, запустив сервер на собственной IT-инфраструктуре.
+3. Зарегистрировать учетную запись на пользовательском сервере, просто подписавшись на хостинг-платформу Element Matrix Services.
+
+Открытый обмен сообщениями и сотрудничество.
+Вы можете общаться с любым человеком в сети Matrix, независимо от того, использует ли он Element, другое приложение Matrix или даже если он использует другое приложение для обмена сообщениями.
+
+Супербезопасно
+Настоящее сквозное шифрование (только участники разговора могут расшифровывать сообщения) и проверка устройств с перекрестной подписью.
+
+Полная коммуникация и интеграция.
+Обмен сообщениями, голосовые и видеозвонки, совместное использование файлов, совместное использование экрана и целый ряд интеграций, ботов и виджетов. Создавайте комнаты, сообщества, оставайтесь на связи и выполняйте задачи.
+
+Восстанавливайте связь с того места, где остановились.
+Оставайтесь на связи, где бы вы ни находились, с полностью синхронизированной историей сообщений на всех ваших устройствах и в Интернете по адресу https://app.element.io
diff --git a/fastlane/metadata/android/ru-RU/short_description.txt b/fastlane/metadata/android/ru-RU/short_description.txt
new file mode 100644
index 0000000000..8f7566d208
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/short_description.txt
@@ -0,0 +1 @@
+Групповой мессенджер - зашифрованные сообщения, групповые беседы и видеовызовы
diff --git a/fastlane/metadata/android/ru-RU/title.txt b/fastlane/metadata/android/ru-RU/title.txt
new file mode 100644
index 0000000000..b7b25082a4
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/title.txt
@@ -0,0 +1 @@
+Element - Безопасный мессенджер
diff --git a/fastlane/metadata/android/ru/full_description.txt b/fastlane/metadata/android/ru/full_description.txt
deleted file mode 100644
index 2ac7f9be54..0000000000
--- a/fastlane/metadata/android/ru/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Element - это новый тип приложения для обмена сообщениями и совместной работы, которое:
-
-1. Позволяет вам контролировать вашу конфиденциальность
-2. Позволяет общаться с кем угодно в сети Matrix и даже за ее пределами за счет интеграции с такими приложениями, как Slack
-3. Защищает вас от рекламы, данных и огороженных стеной садов
-4. Обеспечивает безопасность с помощью сквозного шифрования с перекрестной подписью для проверки других пользователей
-
-Element полностью отличается от других приложений для обмена сообщениями и совместной работы, потому что он децентрализован и имеет открытый исходный код.
-
-Element позволяет вам самостоятельно размещать или выбирать хост-узел, чтобы у вас была конфиденциальность, право собственности и контроль над своими данными и разговорами. Он предоставляет вам доступ к открытой сети, поэтому вы не ограничены общением исключительно с пользователями Element. И он очень надежен и безопаснен.
-
-Element может делать все это, потому что он работает на Matrix - стандарте открытого, децентрализованного общения.
-
-Element предоставляет вам полный контроль, позволяя выбрать поставщиков услуг, обслуживающих серверы с вашими беседами. Вы свободны выбрать любой способ размещения прямо из приложения Element:
-
-1. Получить бесплатную учетную запись на общедоступном сервере matrix.org, размещенном разработчиками Matrix, или выберите один из тысяч общедоступных серверов, размещенных волонтерами.
-2. Разместить свою учетную запись на собственном сервере
-3. Зарегистрироваться на индивидуальном сервере, просто подписавшись на услуги платформы Element Matrix Services
-
-Почему выбирают Element?
-
-СОБСТВЕННЫЕ ДАННЫЕ: Вы решаете, где хранить свои данные и сообщения. Вы владеете ими и контролируете их, а не какая-то мегакорпорация, что собирает ваши данные и предоставляет сторонним лицам доступ к ним.
-
-ОТКРЫТОЕ ОБЩЕНИЕ И СОТРУДНИЧЕСТВО: Вы можете общаться с кем угодно в сети Matrix, независимо от того, используют ли они приложение Element или другое приложение Matrix, и даже если они используют другую систему обмена сообщениями, такую как Slack, IRC или XMPP.
-
-СУПЕР-БЕЗОПАСНОСТЬ: Настоящее сквозное шифрование (только участники разговора могут расшифровывать сообщения) и перекрестная подпись для проверки устройств участников разговора.
-
-ПОЛНАЯ КОММУНИКАЦИЯ: Обмен сообщениями, голосовые и видеозвонки, совместное использование файлов, совместное использование экрана и целый ряд интеграций, ботов и виджетов. Создавайте комнаты, сообщества, оставайтесь на связи и добивайтесь результатов.
-
-ВЫ ВЕЗДЕ: Оставайтесь на связи, где бы вы ни находились, благодаря полностью синхронизированной истории сообщений на всех ваших устройствах и в Интернете по адресу https://app.element.io.
diff --git a/fastlane/metadata/android/ru/short_description.txt b/fastlane/metadata/android/ru/short_description.txt
deleted file mode 100644
index 64452ed22d..0000000000
--- a/fastlane/metadata/android/ru/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-Защищённый децентрализованный чат и звонки. Держите ваши данные в безопасности.
diff --git a/fastlane/metadata/android/ru/title.txt b/fastlane/metadata/android/ru/title.txt
deleted file mode 100644
index 00e488e69f..0000000000
--- a/fastlane/metadata/android/ru/title.txt
+++ /dev/null
@@ -1 +0,0 @@
-Element (ранее Riot.im)
diff --git a/fastlane/metadata/android/si/title.txt b/fastlane/metadata/android/si-LK/title.txt
similarity index 100%
rename from fastlane/metadata/android/si/title.txt
rename to fastlane/metadata/android/si-LK/title.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100100.txt b/fastlane/metadata/android/sv-SE/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100100.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100110.txt b/fastlane/metadata/android/sv-SE/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100110.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100120.txt b/fastlane/metadata/android/sv-SE/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100120.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100130.txt b/fastlane/metadata/android/sv-SE/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100130.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100140.txt b/fastlane/metadata/android/sv-SE/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100140.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100150.txt b/fastlane/metadata/android/sv-SE/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100150.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100160.txt b/fastlane/metadata/android/sv-SE/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100160.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40100170.txt b/fastlane/metadata/android/sv-SE/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40100170.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101000.txt b/fastlane/metadata/android/sv-SE/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101000.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101010.txt b/fastlane/metadata/android/sv-SE/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101010.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101020.txt b/fastlane/metadata/android/sv-SE/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101020.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101030.txt b/fastlane/metadata/android/sv-SE/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101030.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101040.txt b/fastlane/metadata/android/sv-SE/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101040.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101050.txt b/fastlane/metadata/android/sv-SE/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101050.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/sv/changelogs/40101060.txt b/fastlane/metadata/android/sv-SE/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/sv/changelogs/40101060.txt
rename to fastlane/metadata/android/sv-SE/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101070.txt b/fastlane/metadata/android/sv-SE/changelogs/40101070.txt
new file mode 100644
index 0000000000..4756a2d028
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: betastöd för utrymmen. Komprimera video innan den skickas.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101080.txt b/fastlane/metadata/android/sv-SE/changelogs/40101080.txt
new file mode 100644
index 0000000000..38d704f995
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: förbättringar för utrymmen.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101090.txt b/fastlane/metadata/android/sv-SE/changelogs/40101090.txt
new file mode 100644
index 0000000000..e1b5900a30
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: lägg till stöd för gitter.im-nätverket.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101100.txt b/fastlane/metadata/android/sv-SE/changelogs/40101100.txt
new file mode 100644
index 0000000000..bc7a6de663
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: tema- och stiluppdatering och nya funktioner för utrymmen.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101110.txt b/fastlane/metadata/android/sv-SE/changelogs/40101110.txt
new file mode 100644
index 0000000000..176fd38769
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: tema- och stiluppdatering och nya funktioner för utrymmen (buggfix för 1.1.10).
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101120.txt b/fastlane/metadata/android/sv-SE/changelogs/40101120.txt
new file mode 100644
index 0000000000..aeef7814ee
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: tema- och stiluppdatering och fixa en krasch efter videosamtal.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101130.txt b/fastlane/metadata/android/sv-SE/changelogs/40101130.txt
new file mode 100644
index 0000000000..def96d7315
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: huvudsakligen stabilitets- och buggfixuppdatering.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101140.txt b/fastlane/metadata/android/sv-SE/changelogs/40101140.txt
new file mode 100644
index 0000000000..96203647b9
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: fixa ett problem med krypterade meddelanden.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40101150.txt b/fastlane/metadata/android/sv-SE/changelogs/40101150.txt
new file mode 100644
index 0000000000..db74658651
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: röstmeddelandeimplementation under experimentinställningar.
+Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/sv/full_description.txt b/fastlane/metadata/android/sv-SE/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/sv/full_description.txt
rename to fastlane/metadata/android/sv-SE/full_description.txt
diff --git a/fastlane/metadata/android/sv/short_description.txt b/fastlane/metadata/android/sv-SE/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/sv/short_description.txt
rename to fastlane/metadata/android/sv-SE/short_description.txt
diff --git a/fastlane/metadata/android/sv/title.txt b/fastlane/metadata/android/sv-SE/title.txt
similarity index 100%
rename from fastlane/metadata/android/sv/title.txt
rename to fastlane/metadata/android/sv-SE/title.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100100.txt b/fastlane/metadata/android/tr-TR/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100100.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100110.txt b/fastlane/metadata/android/tr-TR/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100110.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100120.txt b/fastlane/metadata/android/tr-TR/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100120.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100130.txt b/fastlane/metadata/android/tr-TR/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100130.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100140.txt b/fastlane/metadata/android/tr-TR/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100140.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40100170.txt b/fastlane/metadata/android/tr-TR/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40100170.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40101000.txt b/fastlane/metadata/android/tr-TR/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40101000.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/tr/changelogs/40101010.txt b/fastlane/metadata/android/tr-TR/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/tr/changelogs/40101010.txt
rename to fastlane/metadata/android/tr-TR/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/tr/full_description.txt b/fastlane/metadata/android/tr-TR/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/tr/full_description.txt
rename to fastlane/metadata/android/tr-TR/full_description.txt
diff --git a/fastlane/metadata/android/tr/short_description.txt b/fastlane/metadata/android/tr-TR/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/tr/short_description.txt
rename to fastlane/metadata/android/tr-TR/short_description.txt
diff --git a/fastlane/metadata/android/tr/title.txt b/fastlane/metadata/android/tr-TR/title.txt
similarity index 100%
rename from fastlane/metadata/android/tr/title.txt
rename to fastlane/metadata/android/tr-TR/title.txt
diff --git a/fastlane/metadata/android/uk/changelogs/40101040.txt b/fastlane/metadata/android/uk/changelogs/40101040.txt
new file mode 100644
index 0000000000..663133a99c
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: поліпшення швидкодії та виправлення помилок!
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/uk/changelogs/40101050.txt b/fastlane/metadata/android/uk/changelogs/40101050.txt
new file mode 100644
index 0000000000..00f44f2606
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: виправлення для 1.1.4
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/uk/changelogs/40101060.txt b/fastlane/metadata/android/uk/changelogs/40101060.txt
new file mode 100644
index 0000000000..8a4ae2a4d2
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: виправлення для 1.1.5
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/uk/changelogs/40101070.txt b/fastlane/metadata/android/uk/changelogs/40101070.txt
new file mode 100644
index 0000000000..4d60bb1704
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: бета-підтримка Spaces. Стиснення відео перед надсиланням.
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/uk/changelogs/40101080.txt b/fastlane/metadata/android/uk/changelogs/40101080.txt
new file mode 100644
index 0000000000..c174603258
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+Основні зміни у цій версії: Вдосконалено Простори!
+Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/uk/changelogs/40101090.txt b/fastlane/metadata/android/uk/changelogs/40101090.txt
new file mode 100644
index 0000000000..af822ad291
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+Основні зміни цієї версії: підтримка мережі gitter.im.
+Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/uk/changelogs/40101100.txt b/fastlane/metadata/android/uk/changelogs/40101100.txt
new file mode 100644
index 0000000000..c1fde35579
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+Основні зміни цієї версії: оновлено зовнішній вигляд та нові можливості для просторів
+Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/uk/changelogs/40101110.txt b/fastlane/metadata/android/uk/changelogs/40101110.txt
new file mode 100644
index 0000000000..9aa1195e49
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+Основні зміни цієї версії: оновлено зовнішній вигляд та нові можливості для просторів (bugfix для 1.1.10)
+Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/uk/changelogs/40101120.txt b/fastlane/metadata/android/uk/changelogs/40101120.txt
new file mode 100644
index 0000000000..f738d32b83
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: оновлення теми та стилю та виправлення збоїв після відеовиклику
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/uk/changelogs/40101130.txt b/fastlane/metadata/android/uk/changelogs/40101130.txt
new file mode 100644
index 0000000000..fd6dcb9e97
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: в поліпшення стабільності та виправлення помилок.
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/uk/changelogs/40101140.txt b/fastlane/metadata/android/uk/changelogs/40101140.txt
new file mode 100644
index 0000000000..f2040a29d8
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+Основні зміни у цій версії: виправлення проблеми із зашифрованими повідомленнями.
+Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt
index 026ae4162a..df06315754 100644
--- a/fastlane/metadata/android/uk/full_description.txt
+++ b/fastlane/metadata/android/uk/full_description.txt
@@ -1,30 +1,39 @@
-Element — це застосунок для спілкування та співпраці нового типу, який:
+Element — це і безпечний месенджер, і застосунок для співпраці команди, який ідеально підходить для групових бесід під час віддаленої роботи. Цей застосунок для спілкування застосовує наскрізне шифрування для забезпечення відеоконференцій, обміну файлами та голосових викликів.
-1. Надає вам повний контроль за своєю конфіденційністю
-2. Дозволяє спілкування з будь-ким у мережі Matrix та поза нею, інтегруючись із такими застосунками, як Slack
-3. Убезпечує вас від реклами, збору даних та штучних обмежень
-4. Захищає ваше спілкування наскрізним шифруванням із перехресним підписуванням для звірення інших осіб
+Можливості Element включають:
+- Розширені засоби спілкування в Інтернеті
+- Повністю зашифровані повідомлення для надання можливості безпечнішого корпоративного спілкування, навіть для віддалених працівників
+- Децентралізований чат на основі відкритого коду Matrix
+- Безпечний обмін файлами із зашифрованими даними для керування проєктами
+- Відеочати з передачею голосу через IP та показом екрану іншим
+- Проста інтеграція з вашими улюбленими інструментами для онлайн-співпраці, інструментами керування проєктами, послугами VoIP та іншими застосунками обміну повідомленнями для команд
-Element ґрунтовно відрізняється від інших застосунків для спілкування та співпраці тому що він є децентралізованим та відкритоджерельним.
+Element цілковито відрізняється від інших застосунків обміну повідомленнями та спільної роботи. Він працює на Matrix, відкритій мережі для безпечного обміну повідомленнями та децентралізованого зв'язку. Це дозволяє самостійне розгортання, щоб надати користувачам якнайбільше володіння та контролю над їх даними та повідомленнями.
-Element дозволяє вам розміщувати сервер в себе або обирати будь-якого з надавачів послуг, таким чином забезпечуючи вам конфіденційність і можливість володіти власними даними й бесідами та контролювати їх. Він надає вам доступ до відкритої мережі, тож ви не є обмеженими спілкуванням виключно з користувачами Element. І він є дуже надійним та безпечним.
+Приватність та обмін зашифрованими повідомленнями
+Element захищає вас від небажаної реклами, збору даних та обмежень. Він також захищає всі ваші дані, відео та голосовий зв'язок віч-на-віч за допомогою наскрізного шифрування та взаємного підписування пристроїв.
-Element здатен забезпечити усе це завдяки тому, що він заснований на протоколі Matrix — стандарті для відкритого та децентралізованого спілкування.
+Element дає вам можливість контролювати вашу приватність, одночасно дозволяючи вам безпечно спілкуватися з будь-ким у мережі Matrix або через інші інструменти ділової співпраці, інтегрувавшись із такими програмами, як Slack.
-Element надає вам повний контроль, дозволяючи обирати з-поміж надавачів послуг, що обслуговують сервери з вашими бесідами. Ви вільні обрати будь-який спосіб розміщення прямо з застосунку Element:
+Element можна розгортати самостійно
+Щоб забезпечити більше контролю над вашими приватними даними та розмовами, Element можна самостійно розміщувати або ви можете вибрати будь-який вузол на основі Matrix — стандарт для децентралізованого спілкування з відкритим кодом. Element надає вам приватність, відповідність безпеці та гнучкість інтеграції.
-1. Отримати безкоштовний обліковий запис на загальнодоступному сервері matrix.org, який обслуговують розробники Matrix, чи на одному з тисяч публічних серверів, які обслуговують волонтери
-2. Розмістити свій обліковий запис на власному сервері
-3. Зареєструватись на індивідуальному сервері, просто підписавшись на послуги платформи Element Matrix Services
+Ваші дані
+Ви вирішуєте, де зберігати свої дані та повідомлення. Без ризику видобутку даних або стороннього доступу.
-Чому я маю обрати Element?
+Element надає такі можливості на вибір:
+1. Отримайте безплатний обліковий запис на загальнодоступному сервері matrix.org, розміщеному розробниками Matrix, або виберіть серед тисяч загальнодоступних серверів, розміщених волонтерами
+2. Самостійно розмістіть свій обліковий запис, запустивши сервер на власній ІТ-інфраструктурі
+3. Зареєструйте обліковий запис на власному сервері, просто підписавшись на хостинг-платформу Element Matrix Services
-ВОЛОДІЙТЕ ВАШИМИ ДАНИМИ: Ви вирішуєте де тримати ваші дані та повідомлення. Саме ви володієте ними та контролюєте їх, а не якась Мегакорпорація, що збирає ваші дані та надає стороннім особам доступ до них.
+Відкриті обмін повідомленнями та співпраця
+Ви можете спілкуватися з усіма у мережі Matrix, незалежно від того, чи користуються вони Element, іншим застосунком Matrix або навіть якщо іншим застосунком для обміну повідомленнями.
-ВІДКРИТІ ОБМІН ПОВІДОМЛЕННЯМИ ТА СПІВПРАЦЯ: Ви можете балакати з будь-ким у мережі Matrix, хоч вони користуються Element, хоч іншим застосунком для Matrix, і навіть якщо вони користуються іншою системою обміну повідомленнями на кшталт Slack, IRC чи XMPP.
+Надбезпечний
+Справжнє наскрізне шифрування (лише учасники бесіди можуть розшифровувати повідомлення) та взаємне підписування пристроїв.
-НАДБЕЗПЕЧНІСТЬ: Справжнє наскрізне шифрування (лише ваші співрозмовники здатні дешифровувати повідомлення) та перехресне підписування для звірення пристроїв інших учасників бесіди.
+Повноцінні спілкування та інтеграція
+Обмін повідомленнями, голосові та відеовиклики, обмін файлами, спільний доступ до екрана та ціла купа інтеграцій, ботів та віджетів. Створюйте кімнати, спільноти, залишайтеся на зв’язку та виконуйте завдання.
-ДОВЕРШЕНИЙ ЗВʼЯЗОК: Повідомлення, голосові та відеодзвінки, обмін файлами, розподіл екрану та ціла купа інтеграцій, ботів та знадобів. Створюйте кімнати й спільноти, залишайтесь на зв'язку та завершуйте свої справи.
-
-ДЕ Б ВИ НЕ БУЛИ: Залишайтесь на зв'язку де б ви не були, разом з синхронізовною історією листувань на усіх ваших пристроях та в Інтернеті на https://app.element.io.
+Продовжуйте, де зупинилися
+Залишайтеся на зв'язку, де б ви не знаходились, з повністю синхронізованою історією повідомлень на всіх своїх пристроях та в Інтернеті за адресою https://app.element.io
diff --git a/fastlane/metadata/android/uk/short_description.txt b/fastlane/metadata/android/uk/short_description.txt
index 116f6f95b7..fa42cce81e 100644
--- a/fastlane/metadata/android/uk/short_description.txt
+++ b/fastlane/metadata/android/uk/short_description.txt
@@ -1 +1 @@
-Захищене децентралізоване листування та дзвінки. Тримайте ваші дані в безпеці.
+Груповий месенджер — зашифровані повідомлення, групові бесіди та відеовиклики
diff --git a/fastlane/metadata/android/uk/title.txt b/fastlane/metadata/android/uk/title.txt
index 88e3f7c573..0a170676ff 100644
--- a/fastlane/metadata/android/uk/title.txt
+++ b/fastlane/metadata/android/uk/title.txt
@@ -1 +1 @@
-Element (раніше Riot.im)
+Element — Безпечний месенджер
diff --git a/fastlane/metadata/android/vi/short_description.txt b/fastlane/metadata/android/vi/short_description.txt
index b41ac0ce82..cead47480f 100644
--- a/fastlane/metadata/android/vi/short_description.txt
+++ b/fastlane/metadata/android/vi/short_description.txt
@@ -1 +1 @@
-Ứng dụng chat và gọi phân tán bảo mật. Bảo vệ dữ liệu của bạn khỏi bên thứ ba.
+Nhắn tin nhóm - tin nhắn được mã hoá, cuộc trò chuyện nhóm và cuộc gọi video
diff --git a/fastlane/metadata/android/vi/title.txt b/fastlane/metadata/android/vi/title.txt
index 2a3bef31df..8ef5498c44 100644
--- a/fastlane/metadata/android/vi/title.txt
+++ b/fastlane/metadata/android/vi/title.txt
@@ -1 +1 @@
-Element (trước là Riot.im)
+Element - Nhắn tin bảo mật
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100100.txt b/fastlane/metadata/android/zh-CN/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100100.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100110.txt b/fastlane/metadata/android/zh-CN/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100110.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100120.txt b/fastlane/metadata/android/zh-CN/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100120.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100130.txt b/fastlane/metadata/android/zh-CN/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100130.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100140.txt b/fastlane/metadata/android/zh-CN/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100140.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100150.txt b/fastlane/metadata/android/zh-CN/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100150.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100160.txt b/fastlane/metadata/android/zh-CN/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100160.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40100170.txt b/fastlane/metadata/android/zh-CN/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40100170.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40101000.txt b/fastlane/metadata/android/zh-CN/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40101000.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/zh-Hans/changelogs/40101010.txt b/fastlane/metadata/android/zh-CN/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hans/changelogs/40101010.txt
rename to fastlane/metadata/android/zh-CN/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101020.txt b/fastlane/metadata/android/zh-CN/changelogs/40101020.txt
new file mode 100644
index 0000000000..0de3f2aed0
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101020.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:改进性能和错误修复!
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.2
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101030.txt b/fastlane/metadata/android/zh-CN/changelogs/40101030.txt
new file mode 100644
index 0000000000..5a7fae92d5
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101030.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:改进性能和修复错误!
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.3
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101040.txt b/fastlane/metadata/android/zh-CN/changelogs/40101040.txt
new file mode 100644
index 0000000000..44a3547b3e
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101040.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:改进性能和修复错误!
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.4
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101050.txt b/fastlane/metadata/android/zh-CN/changelogs/40101050.txt
new file mode 100644
index 0000000000..c320815a00
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101050.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:1.1.4 的热修复
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.5
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101060.txt b/fastlane/metadata/android/zh-CN/changelogs/40101060.txt
new file mode 100644
index 0000000000..193ef8f48e
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101060.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:1.1.5 的热修复
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.6
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101070.txt b/fastlane/metadata/android/zh-CN/changelogs/40101070.txt
new file mode 100644
index 0000000000..ba8e92be9b
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+此版本中的主要更新:对「空间」的测试版支持。发送前压缩视频。
+完整的更新记录:https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101080.txt b/fastlane/metadata/android/zh-CN/changelogs/40101080.txt
new file mode 100644
index 0000000000..64b6462ad2
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+此版本的主要变化:对空间进行改进。
+完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101090.txt b/fastlane/metadata/android/zh-CN/changelogs/40101090.txt
new file mode 100644
index 0000000000..c4c6b349c8
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+此版本的主要变化:为 gitter.im 网络提供支持。
+完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101100.txt b/fastlane/metadata/android/zh-CN/changelogs/40101100.txt
new file mode 100644
index 0000000000..b748f34290
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+此版本的主要变化:主题和样式更新以及空间的新功能。
+完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/zh-CN/changelogs/40101110.txt b/fastlane/metadata/android/zh-CN/changelogs/40101110.txt
new file mode 100644
index 0000000000..ef3f46e07d
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+此版本的主要变化:主题和样式更新以及空间的新功能(1.1.10 的错误修复)
+完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt
new file mode 100644
index 0000000000..fa6b00f1e4
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/full_description.txt
@@ -0,0 +1,39 @@
+Element 不仅是安全的通讯软件,同时也是生产力团队协作应用,非常适合在远端工作时进行群组聊天。此聊天应用使用了端到端加密来提供强大的视频会议、文件分享与语音通话功能。
+
+Element 的功能包含了:
+- 进阶的线上通讯工具
+- 完全加密的信息,即使对于远端工作者来说,也可以有更安全的公司通讯
+- 以 Matrix 开放源码框架为基础的去中心化的聊天
+- 在管理项目时通过加密资料安全地分享文件
+- 包含了 VoIP 与画面分享的视频聊天
+- 与你最喜欢的协作工具、项目管理工具、VoIP 服务与其他团队信息应用轻松整合
+
+Element 与其他信息传递与协作应用完全不同。它在 Matrix(一个用于安全传递讯息与去中心化通讯的开放网络)上运行。其可以自建,让使用者对他们的资料和信息拥有最大的所有权与控制权。
+
+隐私与加密信息传递
+Element 保护你不受不想要的广告、信息泄露与围城侵扰。其也通过端到端加密与交叉签章装置验证保护了你所有的资料,并提供一对一视频以及语音通讯。
+
+Element 通过与其他商业协作工具,如 Slack 等应用整合,让你可以在控制你的隐私的同时,也可以与 Matrix 网络上的任何人安全地通讯。
+
+Element 可以自建
+为了可以完整控制你的敏感资料与对话,Element 可以自建,你也可以选择任何以 Matrix 为基础的服务提供商,开放源码、去中心化的通讯标准。Element 为你提供隐私、安全合规与整合灵活性。
+
+拥有你的资料
+你可以决定将你的资料与信息储存在何处。没有信息泄露或被第三方爬取的风险。
+
+Element 透过不同的方式让你掌控一切:
+1. 在 Matrix 开发者架设的 matrix.org 公开服务器上取得免费帐号,或是从数千个由志愿者架设的公开服务器中选择
+2. 在你自己的 IT 基础架构上的服务器自行托管你的帐号
+3. 只要订阅 Element Matrix Services 托管平台就可以在自定义的服务器上注册帐号
+
+开放信息传递与协作
+你可以与 Matrix 网络上的任何人聊天,不论他们是使用 Element、其他 Matrix 应用或其他通讯应用。
+
+超级安全
+真正的端到端加密(仅有那些在对话中的可以解密讯息)以及交叉签章装置验证。
+
+完整的通讯与整合
+信息传递、语音与视频通话、文件分享、画面分享与超多的整合、机器人与挂件。建构聊天室、社群、保持联络并完成工作。
+
+从上次离开的地方开始
+无论你身在何处,都可以透过在你所有设备与网页 https://app.element.io 间完全同步的信息历史保持联络
diff --git a/fastlane/metadata/android/zh-CN/short_description.txt b/fastlane/metadata/android/zh-CN/short_description.txt
new file mode 100644
index 0000000000..e271e7f9a4
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/short_description.txt
@@ -0,0 +1 @@
+群组消息应用-加密的消息传递、群组聊天和视频通话
diff --git a/fastlane/metadata/android/zh-CN/title.txt b/fastlane/metadata/android/zh-CN/title.txt
new file mode 100644
index 0000000000..aad1a96f19
--- /dev/null
+++ b/fastlane/metadata/android/zh-CN/title.txt
@@ -0,0 +1 @@
+Element - 安全消息应用
diff --git a/fastlane/metadata/android/zh-Hans/full_description.txt b/fastlane/metadata/android/zh-Hans/full_description.txt
deleted file mode 100644
index 4791c9652b..0000000000
--- a/fastlane/metadata/android/zh-Hans/full_description.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Element 是一种新型的通讯与协作应用:
-
-1. 使您可以掌控您的隐私
-2. 使您与 Matrix 网络中的任何人交流,甚至可以通过集成功能与如 Slack 之类的其他应用通讯
-3. 保护您免受广告,大数据挖掘和封闭服务的侵害
-4. 通过端到端加密保证安全,通过交叉签名验证其他人
-
-Element 与其他通讯与协作应用完全不同,因为它是去中心化且开源的。
-
-Element 允许您自托管——或者选择托管商——因此,您能拥有数据和会话的隐私权,所有权和控制权。它允许您访问开放网络;因此,您可以与 Element 用户以外的人交流。并且它非常安全。
-
-Element 之所以可以做到这些,是因为它在 Matrix 上运行——开放,去中心化通讯的标准。
-
-通过让您选择由谁来托管您的会话,Element 让您掌控一切。在 Element 应用中,您可以选择不同的托管方式:
-
-1. 在由 Matrix 开发者托管的 matrix.org 公共服务器上获取免费帐户,或从志愿者托管的上千个公共服务器中选择
-2. 在您自己的硬件上运行服务器,自托管您的会话
-3. 通过订阅 Element Matrix Services 托管平台,简单地在自定义服务器上注册账户
-
-为什么选择 Element?
-
-掌控您的数据:您来决定存放您的数据和消息的位置。拥有并控制它的是您,而不是挖掘您的数据或与第三方分享的巨型企业。
-
-开放通讯与协作:您可以与 Matrix 网络中的任何人聊天,不论他们使用 Element 还是其他 Matrix 应用,甚至/即使他们在使用不同的通讯系统,例如 Slack,IRC 或 XMPP。
-
-超级安全:支持真正的端到端加密(仅有会话中的人可以解密消息),还有能够验证会话参与方的设备的交叉签名。
-
-完善的通讯方式:消息,语音和视频通话,文件共享,屏幕共享和大量集成功能,机器人和小挂件。建立房间与社区,保持联系并完成工作。
-
-随时随地:消息历史可在您的全部设备和 https://app.element.io 网页端之间完全同步,无论您在哪里,都可以保持联系。
diff --git a/fastlane/metadata/android/zh-Hans/short_description.txt b/fastlane/metadata/android/zh-Hans/short_description.txt
deleted file mode 100644
index 53d7d33403..0000000000
--- a/fastlane/metadata/android/zh-Hans/short_description.txt
+++ /dev/null
@@ -1 +0,0 @@
-安全、去中心化的聊天与 VoIP 通话。保护您的数据不被第三方窃取。
diff --git a/fastlane/metadata/android/zh-Hans/title.txt b/fastlane/metadata/android/zh-Hans/title.txt
deleted file mode 100644
index 03aecdd2cb..0000000000
--- a/fastlane/metadata/android/zh-Hans/title.txt
+++ /dev/null
@@ -1 +0,0 @@
-Element(曾为 Riot.im)
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100100.txt b/fastlane/metadata/android/zh-TW/changelogs/40100100.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100100.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100100.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100110.txt b/fastlane/metadata/android/zh-TW/changelogs/40100110.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100110.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100110.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100120.txt b/fastlane/metadata/android/zh-TW/changelogs/40100120.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100120.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100120.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100130.txt b/fastlane/metadata/android/zh-TW/changelogs/40100130.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100130.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100130.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100140.txt b/fastlane/metadata/android/zh-TW/changelogs/40100140.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100140.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100140.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100150.txt b/fastlane/metadata/android/zh-TW/changelogs/40100150.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100150.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100150.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100160.txt b/fastlane/metadata/android/zh-TW/changelogs/40100160.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100160.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100160.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40100170.txt b/fastlane/metadata/android/zh-TW/changelogs/40100170.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40100170.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40100170.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101000.txt b/fastlane/metadata/android/zh-TW/changelogs/40101000.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101000.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101000.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101010.txt b/fastlane/metadata/android/zh-TW/changelogs/40101010.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101010.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101010.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101020.txt b/fastlane/metadata/android/zh-TW/changelogs/40101020.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101020.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101020.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101030.txt b/fastlane/metadata/android/zh-TW/changelogs/40101030.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101030.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101030.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101040.txt b/fastlane/metadata/android/zh-TW/changelogs/40101040.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101040.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101040.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101050.txt b/fastlane/metadata/android/zh-TW/changelogs/40101050.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101050.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101050.txt
diff --git a/fastlane/metadata/android/zh-Hant/changelogs/40101060.txt b/fastlane/metadata/android/zh-TW/changelogs/40101060.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/changelogs/40101060.txt
rename to fastlane/metadata/android/zh-TW/changelogs/40101060.txt
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101070.txt b/fastlane/metadata/android/zh-TW/changelogs/40101070.txt
new file mode 100644
index 0000000000..c62c7d5224
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101070.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:對「空間」的測試版支援。傳送前壓縮影片。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.7
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101080.txt b/fastlane/metadata/android/zh-TW/changelogs/40101080.txt
new file mode 100644
index 0000000000..4ed232fe70
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101080.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:改善「空間」的功能。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.8
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101090.txt b/fastlane/metadata/android/zh-TW/changelogs/40101090.txt
new file mode 100644
index 0000000000..84e46bdd76
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101090.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:新增對 gitter.im 網路的支援。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.9
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101100.txt b/fastlane/metadata/android/zh-TW/changelogs/40101100.txt
new file mode 100644
index 0000000000..08e081fd8b
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101100.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:佈景主題與樣式更新,以及空間的新功能。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.10
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101110.txt b/fastlane/metadata/android/zh-TW/changelogs/40101110.txt
new file mode 100644
index 0000000000..91bbc18fff
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101110.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:佈景主題與樣式更新,以及空間的新功能(1.1.10 的臭蟲修復版本)
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.11
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101120.txt b/fastlane/metadata/android/zh-TW/changelogs/40101120.txt
new file mode 100644
index 0000000000..152173fe1b
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101120.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:佈景主題與樣式更新,以及修復視訊通話後當機的問題
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.12
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101130.txt b/fastlane/metadata/android/zh-TW/changelogs/40101130.txt
new file mode 100644
index 0000000000..88f439281f
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101130.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:主要是穩定性與臭蟲修復更新。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.13
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101140.txt b/fastlane/metadata/android/zh-TW/changelogs/40101140.txt
new file mode 100644
index 0000000000..3eb5aa35ed
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101140.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:修復關於加密訊息的問題。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.14
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40101150.txt b/fastlane/metadata/android/zh-TW/changelogs/40101150.txt
new file mode 100644
index 0000000000..c730151fe7
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40101150.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:實驗室設定下,語音訊息的實作。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.1.15
diff --git a/fastlane/metadata/android/zh-Hant/full_description.txt b/fastlane/metadata/android/zh-TW/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/full_description.txt
rename to fastlane/metadata/android/zh-TW/full_description.txt
diff --git a/fastlane/metadata/android/zh-Hant/short_description.txt b/fastlane/metadata/android/zh-TW/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/short_description.txt
rename to fastlane/metadata/android/zh-TW/short_description.txt
diff --git a/fastlane/metadata/android/zh-Hant/title.txt b/fastlane/metadata/android/zh-TW/title.txt
similarity index 100%
rename from fastlane/metadata/android/zh-Hant/title.txt
rename to fastlane/metadata/android/zh-TW/title.txt
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c023..7454180f2a 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e1e2fd2c75..17ba19021b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=13bf8d3cf8eeeb5770d19741a59bde9bd966dd78d17f1bbad787a05ef19d1c2d
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
+distributionSha256Sum=9bb8bc05f562f2d42bdf1ba8db62f6b6fa1c3bf6c392228802cc7cb0578fe7e0
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 4f906e0c81..744e882ed5 100755
--- a/gradlew
+++ b/gradlew
@@ -72,7 +72,7 @@ case "`uname`" in
Darwin* )
darwin=true
;;
- MINGW* )
+ MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
diff --git a/library/ui-styles/.gitignore b/library/ui-styles/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/library/ui-styles/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/library/ui-styles/build.gradle b/library/ui-styles/build.gradle
new file mode 100644
index 0000000000..e264ef8319
--- /dev/null
+++ b/library/ui-styles/build.gradle
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+ id 'com.android.library'
+ id 'kotlin-android'
+}
+
+android {
+ compileSdkVersion 30
+ buildToolsVersion "30.0.3"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ viewBinding true
+ }
+}
+
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation 'com.google.android.material:material:1.4.0'
+ // Pref theme
+ implementation 'androidx.preference:preference-ktx:1.1.1'
+ // PFLockScreen attrs
+ implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
+ // dialpad dimen
+ implementation 'im.dlg:android-dialer:1.2.5'
+ // AudioRecordView attr
+ implementation 'com.github.Armen101:AudioRecordView:1.0.5'
+}
\ No newline at end of file
diff --git a/library/ui-styles/src/debug/AndroidManifest.xml b/library/ui-styles/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000000..e32676136d
--- /dev/null
+++ b/library/ui-styles/src/debug/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugBottomSheet.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugBottomSheet.kt
new file mode 100644
index 0000000000..9998fd661f
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugBottomSheet.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import im.vector.lib.ui.styles.databinding.ActivityDebugMaterialThemeBinding
+
+class DebugBottomSheet : BottomSheetDialogFragment() {
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ // Reuse tha Activity layout
+ val binding = ActivityDebugMaterialThemeBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+}
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeActivity.kt
new file mode 100644
index 0000000000..553d495e22
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeActivity.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+import android.os.Bundle
+import android.view.Menu
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.snackbar.Snackbar
+import im.vector.lib.ui.styles.R
+import im.vector.lib.ui.styles.databinding.ActivityDebugMaterialThemeBinding
+import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog
+
+// Rendering is not the same with VectorBaseActivity
+abstract class DebugMaterialThemeActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val views = ActivityDebugMaterialThemeBinding.inflate(layoutInflater)
+ setContentView(views.root)
+
+ setSupportActionBar(views.debugToolbar)
+ supportActionBar?.let {
+ it.setDisplayShowHomeEnabled(true)
+ it.setDisplayHomeAsUpEnabled(true)
+ }
+
+ views.debugShowSnackbar.setOnClickListener {
+ Snackbar.make(views.coordinatorLayout, "Snackbar!", Snackbar.LENGTH_SHORT)
+ .setAction("Action") { }
+ .show()
+ }
+
+ views.debugShowToast.setOnClickListener {
+ Toast.makeText(this, "Toast", Toast.LENGTH_SHORT).show()
+ }
+
+ views.debugShowDialog.setOnClickListener {
+ showTestDialog(0)
+ }
+
+ views.debugShowDialogDestructive.setOnClickListener {
+ showTestDialog(R.style.ThemeOverlay_Vector_MaterialAlertDialog_Destructive)
+ }
+
+ views.debugShowDialogNegativeDestructive.setOnClickListener {
+ showTestDialog(R.style.ThemeOverlay_Vector_MaterialAlertDialog_NegativeDestructive)
+ }
+
+ views.debugShowProgressDialog.setOnClickListener {
+ MaterialProgressDialog(this)
+ .show(message = "Progress Dialog\nLine 2", cancellable = true)
+ }
+
+ views.debugShowBottomSheet.setOnClickListener {
+ DebugBottomSheet().show(supportFragmentManager, "TAG")
+ }
+ }
+
+ private fun showTestDialog(theme: Int) {
+ MaterialAlertDialogBuilder(this, theme)
+ .setTitle("Dialog title")
+ .setMessage("Dialog content\nLine 2")
+ .setIcon(R.drawable.ic_debug_icon)
+ .setPositiveButton("Positive", null)
+ .setNegativeButton("Negative", null)
+ .setNeutralButton("Neutral", null)
+ .show()
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_debug, menu)
+ return true
+ }
+}
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkDefaultActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkDefaultActivity.kt
new file mode 100644
index 0000000000..d24ceb6ede
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkDefaultActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeDarkDefaultActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkTestActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkTestActivity.kt
new file mode 100644
index 0000000000..fea1f27dae
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkTestActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeDarkTestActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkVectorActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkVectorActivity.kt
new file mode 100644
index 0000000000..379d55d006
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeDarkVectorActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeDarkVectorActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightDefaultActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightDefaultActivity.kt
new file mode 100644
index 0000000000..57f172bdc3
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightDefaultActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeLightDefaultActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightTestActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightTestActivity.kt
new file mode 100644
index 0000000000..d3a6c757fb
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightTestActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeLightTestActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightVectorActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightVectorActivity.kt
new file mode 100644
index 0000000000..3fafa61421
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugMaterialThemeLightVectorActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugMaterialThemeLightVectorActivity : DebugMaterialThemeActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesActivity.kt
new file mode 100644
index 0000000000..50d1e344e9
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesActivity.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import im.vector.lib.ui.styles.databinding.ActivityDebugButtonStylesBinding
+
+abstract class DebugVectorButtonStylesActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val views = ActivityDebugButtonStylesBinding.inflate(layoutInflater)
+ setContentView(views.root)
+ }
+}
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesDarkActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesDarkActivity.kt
new file mode 100644
index 0000000000..102ca53f3c
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesDarkActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugVectorButtonStylesDarkActivity : DebugVectorButtonStylesActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesLightActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesLightActivity.kt
new file mode 100644
index 0000000000..c1b01dc6a3
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorButtonStylesLightActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugVectorButtonStylesLightActivity : DebugVectorButtonStylesActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewActivity.kt
new file mode 100644
index 0000000000..db50500195
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewActivity.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+import android.os.Bundle
+import android.text.InputType
+import android.widget.EditText
+import androidx.appcompat.app.AppCompatActivity
+import im.vector.lib.ui.styles.databinding.ActivityDebugTextViewBinding
+
+// Rendering is not the same with VectorBaseActivity
+abstract class DebugVectorTextViewActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val views = ActivityDebugTextViewBinding.inflate(layoutInflater)
+ setContentView(views.root)
+
+ views.debugShowPassword.setOnClickListener {
+ views.debugTextInputEditText.showPassword(true)
+ }
+ views.debugHidePassword.setOnClickListener {
+ views.debugTextInputEditText.showPassword(false)
+ }
+ }
+
+ private fun EditText.showPassword(visible: Boolean) {
+ if (visible) {
+ inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+ } else {
+ inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
+ }
+ }
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewDarkActivity.kt
similarity index 79%
rename from vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt
rename to library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewDarkActivity.kt
index d1d3061cad..2d95056fef 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewDarkActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 New Vector Ltd
+ * Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package im.vector.app.features.debug
+package im.vector.lib.ui.styles.debug
-class DebugMaterialThemeLightActivity : DebugMaterialThemeActivity()
+class DebugVectorTextViewDarkActivity : DebugVectorTextViewActivity()
diff --git a/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewLightActivity.kt b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewLightActivity.kt
new file mode 100644
index 0000000000..33e4a0f075
--- /dev/null
+++ b/library/ui-styles/src/debug/java/im/vector/lib/ui/styles/debug/DebugVectorTextViewLightActivity.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.debug
+
+class DebugVectorTextViewLightActivity : DebugVectorTextViewActivity()
diff --git a/library/ui-styles/src/debug/res/drawable/ic_debug_icon.xml b/library/ui-styles/src/debug/res/drawable/ic_debug_icon.xml
new file mode 100644
index 0000000000..08af7d6539
--- /dev/null
+++ b/library/ui-styles/src/debug/res/drawable/ic_debug_icon.xml
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/vector/src/debug/res/drawable/linear_divider.xml b/library/ui-styles/src/debug/res/drawable/linear_divider.xml
similarity index 100%
rename from vector/src/debug/res/drawable/linear_divider.xml
rename to library/ui-styles/src/debug/res/drawable/linear_divider.xml
diff --git a/library/ui-styles/src/debug/res/layout/activity_debug_button_styles.xml b/library/ui-styles/src/debug/res/layout/activity_debug_button_styles.xml
new file mode 100644
index 0000000000..0f129fb406
--- /dev/null
+++ b/library/ui-styles/src/debug/res/layout/activity_debug_button_styles.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/debug/res/layout/activity_debug_material_theme.xml b/library/ui-styles/src/debug/res/layout/activity_debug_material_theme.xml
new file mode 100644
index 0000000000..4828810e34
--- /dev/null
+++ b/library/ui-styles/src/debug/res/layout/activity_debug_material_theme.xml
@@ -0,0 +1,525 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/debug/res/layout/activity_debug_text_view.xml b/library/ui-styles/src/debug/res/layout/activity_debug_text_view.xml
new file mode 100644
index 0000000000..1b38f04b97
--- /dev/null
+++ b/library/ui-styles/src/debug/res/layout/activity_debug_text_view.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/debug/res/menu/menu_debug.xml b/library/ui-styles/src/debug/res/menu/menu_debug.xml
new file mode 100644
index 0000000000..c58a29db8f
--- /dev/null
+++ b/library/ui-styles/src/debug/res/menu/menu_debug.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/vector/src/debug/res/values/styles.xml b/library/ui-styles/src/debug/res/values/debug_styles.xml
similarity index 61%
rename from vector/src/debug/res/values/styles.xml
rename to library/ui-styles/src/debug/res/values/debug_styles.xml
index 063f652d08..d025ba1784 100644
--- a/vector/src/debug/res/values/styles.xml
+++ b/library/ui-styles/src/debug/res/values/debug_styles.xml
@@ -6,32 +6,11 @@
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/AndroidManifest.xml b/library/ui-styles/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..19aa89e2e7
--- /dev/null
+++ b/library/ui-styles/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/java/MaterialProgressDialog.kt b/library/ui-styles/src/main/java/MaterialProgressDialog.kt
new file mode 100644
index 0000000000..9523c5c19c
--- /dev/null
+++ b/library/ui-styles/src/main/java/MaterialProgressDialog.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.lib.ui.styles.dialogs
+
+import android.content.Context
+import android.view.LayoutInflater
+import androidx.appcompat.app.AlertDialog
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import im.vector.lib.ui.styles.R
+import im.vector.lib.ui.styles.databinding.DialogProgressMaterialBinding
+
+class MaterialProgressDialog(val context: Context) {
+ fun show(message: CharSequence, cancellable: Boolean = false): AlertDialog {
+ val view = LayoutInflater.from(context).inflate(R.layout.dialog_progress_material, null)
+ val views = DialogProgressMaterialBinding.bind(view)
+ views.message.text = message
+
+ return MaterialAlertDialogBuilder(context)
+ .setCancelable(cancellable)
+ .setView(view)
+ .show()
+ }
+}
diff --git a/library/ui-styles/src/main/res/color/bottom_navigation_icon_tint_selector.xml b/library/ui-styles/src/main/res/color/bottom_navigation_icon_tint_selector.xml
new file mode 100644
index 0000000000..403ed865e7
--- /dev/null
+++ b/library/ui-styles/src/main/res/color/bottom_navigation_icon_tint_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/color/button_background_tint_selector.xml b/library/ui-styles/src/main/res/color/button_background_tint_selector.xml
new file mode 100644
index 0000000000..57135b1eb9
--- /dev/null
+++ b/library/ui-styles/src/main/res/color/button_background_tint_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/color/button_social_google_background_selector_dark.xml b/library/ui-styles/src/main/res/color/button_social_google_background_selector_dark.xml
similarity index 73%
rename from vector/src/main/res/color/button_social_google_background_selector_dark.xml
rename to library/ui-styles/src/main/res/color/button_social_google_background_selector_dark.xml
index 1369414e58..3893ce3e34 100644
--- a/vector/src/main/res/color/button_social_google_background_selector_dark.xml
+++ b/library/ui-styles/src/main/res/color/button_social_google_background_selector_dark.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/color/button_social_google_background_selector_light.xml b/library/ui-styles/src/main/res/color/button_social_google_background_selector_light.xml
new file mode 100644
index 0000000000..dc80f861b9
--- /dev/null
+++ b/library/ui-styles/src/main/res/color/button_social_google_background_selector_light.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/color/color_primary_alpha25.xml b/library/ui-styles/src/main/res/color/color_primary_alpha25.xml
new file mode 100644
index 0000000000..5afa385f3c
--- /dev/null
+++ b/library/ui-styles/src/main/res/color/color_primary_alpha25.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/drawable-hdpi/riot_splash_white.png b/library/ui-styles/src/main/res/drawable-hdpi/element_splash_white.png
similarity index 100%
rename from vector/src/main/res/drawable-hdpi/riot_splash_white.png
rename to library/ui-styles/src/main/res/drawable-hdpi/element_splash_white.png
diff --git a/vector/src/main/res/drawable-mdpi/riot_splash_white.png b/library/ui-styles/src/main/res/drawable-mdpi/element_splash_white.png
similarity index 100%
rename from vector/src/main/res/drawable-mdpi/riot_splash_white.png
rename to library/ui-styles/src/main/res/drawable-mdpi/element_splash_white.png
diff --git a/vector/src/main/res/drawable-xhdpi/riot_splash_white.png b/library/ui-styles/src/main/res/drawable-xhdpi/element_splash_white.png
similarity index 100%
rename from vector/src/main/res/drawable-xhdpi/riot_splash_white.png
rename to library/ui-styles/src/main/res/drawable-xhdpi/element_splash_white.png
diff --git a/vector/src/main/res/drawable-xxhdpi/riot_splash_white.png b/library/ui-styles/src/main/res/drawable-xxhdpi/element_splash_white.png
similarity index 100%
rename from vector/src/main/res/drawable-xxhdpi/riot_splash_white.png
rename to library/ui-styles/src/main/res/drawable-xxhdpi/element_splash_white.png
diff --git a/vector/src/main/res/drawable-xxxhdpi/riot_splash_white.png b/library/ui-styles/src/main/res/drawable-xxxhdpi/element_splash_white.png
similarity index 100%
rename from vector/src/main/res/drawable-xxxhdpi/riot_splash_white.png
rename to library/ui-styles/src/main/res/drawable-xxxhdpi/element_splash_white.png
diff --git a/library/ui-styles/src/main/res/drawable/bg_bottom_navigation.xml b/library/ui-styles/src/main/res/drawable/bg_bottom_navigation.xml
new file mode 100644
index 0000000000..3011da0026
--- /dev/null
+++ b/library/ui-styles/src/main/res/drawable/bg_bottom_navigation.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/bg_pin_key.xml b/library/ui-styles/src/main/res/drawable/bg_pin_key.xml
similarity index 100%
rename from vector/src/main/res/drawable/bg_pin_key.xml
rename to library/ui-styles/src/main/res/drawable/bg_pin_key.xml
diff --git a/library/ui-styles/src/main/res/drawable/bg_round_corner_8dp.xml b/library/ui-styles/src/main/res/drawable/bg_round_corner_8dp.xml
new file mode 100644
index 0000000000..f44b146021
--- /dev/null
+++ b/library/ui-styles/src/main/res/drawable/bg_round_corner_8dp.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/element_logo_green.xml b/library/ui-styles/src/main/res/drawable/element_logo_green.xml
similarity index 100%
rename from vector/src/main/res/drawable/element_logo_green.xml
rename to library/ui-styles/src/main/res/drawable/element_logo_green.xml
diff --git a/vector/src/main/res/drawable/file_progress_bar.xml b/library/ui-styles/src/main/res/drawable/file_progress_bar.xml
similarity index 71%
rename from vector/src/main/res/drawable/file_progress_bar.xml
rename to library/ui-styles/src/main/res/drawable/file_progress_bar.xml
index 4c96aaebf6..d175b871f7 100644
--- a/vector/src/main/res/drawable/file_progress_bar.xml
+++ b/library/ui-styles/src/main/res/drawable/file_progress_bar.xml
@@ -4,7 +4,7 @@
-
+
@@ -12,7 +12,7 @@
-
+
diff --git a/vector/src/main/res/drawable/ic_search.xml b/library/ui-styles/src/main/res/drawable/ic_search.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_search.xml
rename to library/ui-styles/src/main/res/drawable/ic_search.xml
diff --git a/vector/src/main/res/drawable/ic_social_apple.xml b/library/ui-styles/src/main/res/drawable/ic_social_apple.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_apple.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_apple.xml
diff --git a/vector/src/main/res/drawable/ic_social_facebook.xml b/library/ui-styles/src/main/res/drawable/ic_social_facebook.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_facebook.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_facebook.xml
diff --git a/vector/src/main/res/drawable/ic_social_github.xml b/library/ui-styles/src/main/res/drawable/ic_social_github.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_github.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_github.xml
diff --git a/vector/src/main/res/drawable/ic_social_gitlab.xml b/library/ui-styles/src/main/res/drawable/ic_social_gitlab.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_gitlab.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_gitlab.xml
diff --git a/vector/src/main/res/drawable/ic_social_google.xml b/library/ui-styles/src/main/res/drawable/ic_social_google.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_google.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_google.xml
diff --git a/vector/src/main/res/drawable/ic_social_twitter.xml b/library/ui-styles/src/main/res/drawable/ic_social_twitter.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_social_twitter.xml
rename to library/ui-styles/src/main/res/drawable/ic_social_twitter.xml
diff --git a/vector/src/main/res/drawable/ic_x_gray.xml b/library/ui-styles/src/main/res/drawable/ic_x_gray.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_x_gray.xml
rename to library/ui-styles/src/main/res/drawable/ic_x_gray.xml
diff --git a/vector/src/main/res/drawable/pin_code_dot_empty.xml b/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml
similarity index 81%
rename from vector/src/main/res/drawable/pin_code_dot_empty.xml
rename to library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml
index 6ee800a07d..1827a7682b 100644
--- a/vector/src/main/res/drawable/pin_code_dot_empty.xml
+++ b/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml
@@ -4,7 +4,7 @@
android:shape="oval">
-
-
+
-
+
+ android:src="@drawable/element_splash_white" />
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/vector_label_background.xml b/library/ui-styles/src/main/res/drawable/vector_label_background.xml
similarity index 66%
rename from vector/src/main/res/drawable/vector_label_background.xml
rename to library/ui-styles/src/main/res/drawable/vector_label_background.xml
index e721c1dd69..bc8fd22a4d 100644
--- a/vector/src/main/res/drawable/vector_label_background.xml
+++ b/library/ui-styles/src/main/res/drawable/vector_label_background.xml
@@ -4,10 +4,10 @@
-
+
+ android:color="?vctr_fab_label_stroke" />
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/layout/dialog_progress_material.xml b/library/ui-styles/src/main/res/layout/dialog_progress_material.xml
new file mode 100644
index 0000000000..09c88cc50b
--- /dev/null
+++ b/library/ui-styles/src/main/res/layout/dialog_progress_material.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/transition/image_preview_transition.xml b/library/ui-styles/src/main/res/transition/image_preview_transition.xml
similarity index 100%
rename from vector/src/main/res/transition/image_preview_transition.xml
rename to library/ui-styles/src/main/res/transition/image_preview_transition.xml
diff --git a/vector/src/main/res/values-land/dimens.xml b/library/ui-styles/src/main/res/values-land/dimens.xml
similarity index 100%
rename from vector/src/main/res/values-land/dimens.xml
rename to library/ui-styles/src/main/res/values-land/dimens.xml
diff --git a/vector/src/main/res/values-land/styles.xml b/library/ui-styles/src/main/res/values-land/styles.xml
similarity index 100%
rename from vector/src/main/res/values-land/styles.xml
rename to library/ui-styles/src/main/res/values-land/styles.xml
diff --git a/library/ui-styles/src/main/res/values-land/styles_dial_pad.xml b/library/ui-styles/src/main/res/values-land/styles_dial_pad.xml
new file mode 100644
index 0000000000..39c5bf9aa6
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-land/styles_dial_pad.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values-ldrtl/integers.xml b/library/ui-styles/src/main/res/values-ldrtl/integers.xml
similarity index 62%
rename from vector/src/main/res/values-ldrtl/integers.xml
rename to library/ui-styles/src/main/res/values-ldrtl/integers.xml
index e8a746b687..88b587c96f 100644
--- a/vector/src/main/res/values-ldrtl/integers.xml
+++ b/library/ui-styles/src/main/res/values-ldrtl/integers.xml
@@ -1,6 +1,7 @@
+ -1180
\ No newline at end of file
diff --git a/vector/src/main/res/values-sw600dp/dimens.xml b/library/ui-styles/src/main/res/values-sw600dp/dimens.xml
similarity index 100%
rename from vector/src/main/res/values-sw600dp/dimens.xml
rename to library/ui-styles/src/main/res/values-sw600dp/dimens.xml
diff --git a/library/ui-styles/src/main/res/values-v23/theme_black.xml b/library/ui-styles/src/main/res/values-v23/theme_black.xml
new file mode 100644
index 0000000000..e0399f6449
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v23/theme_black.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values-v23/theme_dark.xml b/library/ui-styles/src/main/res/values-v23/theme_dark.xml
new file mode 100644
index 0000000000..45b340eaad
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v23/theme_dark.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values-v23/theme_light.xml b/library/ui-styles/src/main/res/values-v23/theme_light.xml
new file mode 100644
index 0000000000..28a78b98bf
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v23/theme_light.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values-v27/theme_black.xml b/library/ui-styles/src/main/res/values-v27/theme_black.xml
new file mode 100644
index 0000000000..2a18b021e3
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v27/theme_black.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values-v27/theme_dark.xml b/library/ui-styles/src/main/res/values-v27/theme_dark.xml
new file mode 100644
index 0000000000..ee654bbaab
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v27/theme_dark.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values-v27/theme_light.xml b/library/ui-styles/src/main/res/values-v27/theme_light.xml
new file mode 100644
index 0000000000..0151130f5a
--- /dev/null
+++ b/library/ui-styles/src/main/res/values-v27/theme_light.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values-w820dp/dimens.xml b/library/ui-styles/src/main/res/values-w820dp/dimens.xml
similarity index 100%
rename from vector/src/main/res/values-w820dp/dimens.xml
rename to library/ui-styles/src/main/res/values-w820dp/dimens.xml
diff --git a/library/ui-styles/src/main/res/values/attrs_room_message_colors.xml b/library/ui-styles/src/main/res/values/attrs_room_message_colors.xml
new file mode 100644
index 0000000000..68b64c21b0
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/attrs_room_message_colors.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/attrs_social_login_button.xml b/library/ui-styles/src/main/res/values/attrs_social_login_button.xml
new file mode 100644
index 0000000000..e988646049
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/attrs_social_login_button.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/values/bools.xml b/library/ui-styles/src/main/res/values/bools.xml
similarity index 100%
rename from vector/src/main/res/values/bools.xml
rename to library/ui-styles/src/main/res/values/bools.xml
diff --git a/library/ui-styles/src/main/res/values/colors.xml b/library/ui-styles/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..9d5f15cbde
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/colors.xml
@@ -0,0 +1,135 @@
+
+
+
+
+ @color/palette_melon
+ #2f9edb
+
+
+ #2f9edb
+ ?colorError
+
+
+ #14368BD6
+ @color/palette_azure
+
+
+ @color/palette_azure
+ @color/palette_melon
+
+
+
+ #99000000
+ #27303A
+
+ #FF61708B
+ #1E61708B
+
+
+
+ @android:color/black
+
+ #80000000
+
+ #55000000
+ #8A000000
+
+
+ @color/element_system_light
+ @color/element_system_light
+ @color/element_background_dark
+ @color/element_system_dark
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #FF61708B
+ #FF61708B
+ #FF61708B
+
+
+ @android:color/white
+ #FF181B21
+ #FF181B21
+
+
+ #1EFFFFFF
+ @android:color/black
+ @android:color/black
+
+
+ #FF2E2F32
+ #FFA1B2D1
+ #FFA1B2D1
+
+
+ #66000000
+ #BF000000
+ #BF000000
+
+
+ #FFFFFFFF
+ #FF22262E
+ #FF090A0C
+
+
+ #FFE9EDF1
+ #FF22262E
+ #FF090A0C
+
+
+ #EBEFF5
+ #27303A
+ #27303A
+
+
+ #61708B
+ #E3E8F0
+ #E3E8F0
+
+
+ #AAAAAAAA
+ #55555555
+
+
+ #EEEEEE
+ #61708B
+
+
+ #FFF3F8FD
+ #22252B
+ #22252B
+
+
+ #2011BC8A
+ #4011BC8A
+ #4011BC8A
+
+
+
+ #FFF8E3
+ #22262E
+
+
+ @color/black_alpha
+ @android:color/transparent
+
+
+ @color/palette_black_900
+ @color/palette_gray_400
+
+
diff --git a/library/ui-styles/src/main/res/values/colors_password_strength.xml b/library/ui-styles/src/main/res/values/colors_password_strength.xml
new file mode 100644
index 0000000000..038f42044c
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/colors_password_strength.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ #FFF56679
+ #FFFFC666
+ #FFF8E71C
+ #FF7AC9A1
+ #FF9E9E9E
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml
similarity index 100%
rename from vector/src/main/res/values/dimens.xml
rename to library/ui-styles/src/main/res/values/dimens.xml
diff --git a/library/ui-styles/src/main/res/values/dimens_font.xml b/library/ui-styles/src/main/res/values/dimens_font.xml
new file mode 100644
index 0000000000..1b5a826acb
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/dimens_font.xml
@@ -0,0 +1,13 @@
+
+
+
+ 24sp
+ 18sp
+ 16sp
+ 14sp
+ 12sp
+ 10sp
+
+ 14sp
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values/integers.xml b/library/ui-styles/src/main/res/values/integers.xml
similarity index 84%
rename from vector/src/main/res/values/integers.xml
rename to library/ui-styles/src/main/res/values/integers.xml
index 75e8bb6f9a..2f6a1b0bc4 100644
--- a/vector/src/main/res/values/integers.xml
+++ b/library/ui-styles/src/main/res/values/integers.xml
@@ -7,6 +7,7 @@
200
+ 10750
diff --git a/library/ui-styles/src/main/res/values/palette.xml b/library/ui-styles/src/main/res/values/palette.xml
new file mode 100644
index 0000000000..ed12f10af3
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/palette.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ #368BD6
+ #74D12C
+ #AC3BA8
+ #03B381
+ #E64F7A
+ #FF812D
+
+ #0DBD8B
+ #FFFFFF
+ #FF5B55
+ #7E69FF
+ #2DC2C5
+ #5C56F5
+ #0086E6
+
+
+
+ #F4F6FA
+ #E3E8F0
+ #C1C6CD
+ #8D97A5
+ #737D8C
+ #17191C
+ #F4F9FD
+
+
+ #A9B2BC
+ #8E99A4
+ #6F7882
+ #394049
+ #15191E
+ #21262C
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/palette_mobile.xml b/library/ui-styles/src/main/res/values/palette_mobile.xml
new file mode 100644
index 0000000000..c22b9705c7
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/palette_mobile.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+ @color/palette_element_green
+ @color/palette_element_green
+
+ @color/palette_vermilion
+ @color/palette_vermilion
+
+ @color/palette_links
+ @color/palette_links
+
+
+
+
+
+
+
+
+ @color/palette_black_900
+ @color/palette_gray_200
+ @color/palette_gray_150
+ @color/palette_gray_100
+ @color/palette_gray_50
+
+ @color/palette_white
+ @color/palette_gray_250
+ @color/palette_gray_300
+ @color/palette_gray_400
+ @color/palette_gray_450
+
+
+ @color/palette_gray_25
+ @color/palette_black_950
+ @color/palette_black_950
+
+ @color/palette_white
+ @color/palette_black_800
+ @android:color/black
+
+ @color/palette_azure
+ @color/palette_grape
+ @color/palette_verde
+ @color/palette_polly
+ @color/palette_melon
+ @color/palette_aqua
+ @color/palette_prune
+ @color/palette_kiwi
+
+
+ @color/palette_verde
+ @color/palette_azure
+ @color/palette_grape
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values/attrs_badge_fab.xml b/library/ui-styles/src/main/res/values/stylable_badge_floating_action_button.xml
similarity index 100%
rename from vector/src/main/res/values/attrs_badge_fab.xml
rename to library/ui-styles/src/main/res/values/stylable_badge_floating_action_button.xml
diff --git a/library/ui-styles/src/main/res/values/stylable_bottom_sheet_action.xml b/library/ui-styles/src/main/res/values/stylable_bottom_sheet_action.xml
new file mode 100644
index 0000000000..d6fa160d6b
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_bottom_sheet_action.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/values/attrs_state_button.xml b/library/ui-styles/src/main/res/values/stylable_button_state_view.xml
similarity index 95%
rename from vector/src/main/res/values/attrs_state_button.xml
rename to library/ui-styles/src/main/res/values/stylable_button_state_view.xml
index 7d2583cdfe..3681884735 100644
--- a/vector/src/main/res/values/attrs_state_button.xml
+++ b/library/ui-styles/src/main/res/values/stylable_button_state_view.xml
@@ -2,12 +2,9 @@
-
-
-
\ No newline at end of file
diff --git a/vector/src/main/res/values/attrs_max_height_scroll_view.xml b/library/ui-styles/src/main/res/values/stylable_max_height_scroll_view.xml
similarity index 100%
rename from vector/src/main/res/values/attrs_max_height_scroll_view.xml
rename to library/ui-styles/src/main/res/values/stylable_max_height_scroll_view.xml
diff --git a/library/ui-styles/src/main/res/values/stylable_pool_result_line.xml b/library/ui-styles/src/main/res/values/stylable_pool_result_line.xml
new file mode 100644
index 0000000000..93e9851106
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_pool_result_line.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/values/attrs_reaction_button.xml b/library/ui-styles/src/main/res/values/stylable_reaction_button.xml
similarity index 100%
rename from vector/src/main/res/values/attrs_reaction_button.xml
rename to library/ui-styles/src/main/res/values/stylable_reaction_button.xml
diff --git a/library/ui-styles/src/main/res/values/stylable_sign_out_bottom_sheet_action_button.xml b/library/ui-styles/src/main/res/values/stylable_sign_out_bottom_sheet_action_button.xml
new file mode 100644
index 0000000000..068fb93e1b
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_sign_out_bottom_sheet_action_button.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/stylable_social_login_button_view.xml b/library/ui-styles/src/main/res/values/stylable_social_login_button_view.xml
new file mode 100644
index 0000000000..5e0b17f7df
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_social_login_button_view.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/stylable_wizard_button_view.xml b/library/ui-styles/src/main/res/values/stylable_wizard_button_view.xml
new file mode 100644
index 0000000000..2705abd7ca
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_wizard_button_view.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/values/style_snackbar.xml b/library/ui-styles/src/main/res/values/style_snackbar.xml
similarity index 51%
rename from vector/src/main/res/values/style_snackbar.xml
rename to library/ui-styles/src/main/res/values/style_snackbar.xml
index 3a826a6dda..d15f846d8f 100644
--- a/vector/src/main/res/values/style_snackbar.xml
+++ b/library/ui-styles/src/main/res/values/style_snackbar.xml
@@ -1,15 +1,15 @@
-
-
-
diff --git a/vector/src/main/res/values/styles.xml b/library/ui-styles/src/main/res/values/styles.xml
similarity index 66%
rename from vector/src/main/res/values/styles.xml
rename to library/ui-styles/src/main/res/values/styles.xml
index 8cc1fe70d8..b028d2e219 100644
--- a/vector/src/main/res/values/styles.xml
+++ b/library/ui-styles/src/main/res/values/styles.xml
@@ -1,8 +1,6 @@
-
-
diff --git a/library/ui-styles/src/main/res/values/styles_action_mode.xml b/library/ui-styles/src/main/res/values/styles_action_mode.xml
new file mode 100644
index 0000000000..f6e6079633
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_action_mode.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_alert_dialog.xml b/library/ui-styles/src/main/res/values/styles_alert_dialog.xml
new file mode 100644
index 0000000000..69abc85c39
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_alert_dialog.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_app_bar_layout.xml b/library/ui-styles/src/main/res/values/styles_app_bar_layout.xml
new file mode 100644
index 0000000000..973a2c5e4a
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_app_bar_layout.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_attachments.xml b/library/ui-styles/src/main/res/values/styles_attachments.xml
new file mode 100644
index 0000000000..18c2e3f95f
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_attachments.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_bottom_navigation.xml b/library/ui-styles/src/main/res/values/styles_bottom_navigation.xml
new file mode 100644
index 0000000000..8925d6a74f
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_bottom_navigation.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_bottom_sheet.xml b/library/ui-styles/src/main/res/values/styles_bottom_sheet.xml
new file mode 100644
index 0000000000..9f17342ede
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_bottom_sheet.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_buttons.xml b/library/ui-styles/src/main/res/values/styles_buttons.xml
new file mode 100644
index 0000000000..ad90469a52
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_buttons.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_dial_pad.xml b/library/ui-styles/src/main/res/values/styles_dial_pad.xml
new file mode 100644
index 0000000000..34e128c56d
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_dial_pad.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_edit_text.xml b/library/ui-styles/src/main/res/values/styles_edit_text.xml
new file mode 100644
index 0000000000..cc1041a2ce
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_edit_text.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_jump_to_unread.xml b/library/ui-styles/src/main/res/values/styles_jump_to_unread.xml
new file mode 100644
index 0000000000..21f0ebd5d4
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_jump_to_unread.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_label.xml b/library/ui-styles/src/main/res/values/styles_label.xml
new file mode 100644
index 0000000000..3f38855430
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_label.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values/styles_login.xml b/library/ui-styles/src/main/res/values/styles_login.xml
similarity index 89%
rename from vector/src/main/res/values/styles_login.xml
rename to library/ui-styles/src/main/res/values/styles_login.xml
index 8cba34daf3..ab2cb44c5a 100644
--- a/vector/src/main/res/values/styles_login.xml
+++ b/library/ui-styles/src/main/res/values/styles_login.xml
@@ -35,17 +35,17 @@
32dp
-
-
-
diff --git a/vector/src/main/res/values/styles_pin_code.xml b/library/ui-styles/src/main/res/values/styles_pin_code.xml
similarity index 69%
rename from vector/src/main/res/values/styles_pin_code.xml
rename to library/ui-styles/src/main/res/values/styles_pin_code.xml
index ecf217bf03..2b6c113359 100644
--- a/vector/src/main/res/values/styles_pin_code.xml
+++ b/library/ui-styles/src/main/res/values/styles_pin_code.xml
@@ -2,11 +2,11 @@
@@ -15,7 +15,7 @@
@drawable/pin_code_dots
-
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_popup.xml b/library/ui-styles/src/main/res/values/styles_popup.xml
new file mode 100644
index 0000000000..2aad848989
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_popup.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_progress.xml b/library/ui-styles/src/main/res/values/styles_progress.xml
new file mode 100644
index 0000000000..712e7e98b6
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_progress.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_search_view.xml b/library/ui-styles/src/main/res/values/styles_search_view.xml
new file mode 100644
index 0000000000..e1439697c9
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_search_view.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_social_login.xml b/library/ui-styles/src/main/res/values/styles_social_login.xml
new file mode 100644
index 0000000000..b527d5bfdc
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_social_login.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_text_view.xml b/library/ui-styles/src/main/res/values/styles_text_view.xml
new file mode 100644
index 0000000000..77e32da345
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_text_view.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_timeline.xml b/library/ui-styles/src/main/res/values/styles_timeline.xml
new file mode 100644
index 0000000000..7fd7eac0ec
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_timeline.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_toolbar.xml b/library/ui-styles/src/main/res/values/styles_toolbar.xml
new file mode 100644
index 0000000000..9f6ba102ed
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_toolbar.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/styles_voice_message.xml b/library/ui-styles/src/main/res/values/styles_voice_message.xml
new file mode 100644
index 0000000000..59fea75074
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_voice_message.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/text_appearances.xml b/library/ui-styles/src/main/res/values/text_appearances.xml
new file mode 100644
index 0000000000..4ad3fd493e
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/text_appearances.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/theme_black.xml b/library/ui-styles/src/main/res/values/theme_black.xml
new file mode 100644
index 0000000000..c472a4fae5
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/theme_black.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/values/theme_common.xml b/library/ui-styles/src/main/res/values/theme_common.xml
similarity index 63%
rename from vector/src/main/res/values/theme_common.xml
rename to library/ui-styles/src/main/res/values/theme_common.xml
index e9fbe40e5a..2e9c2c5123 100644
--- a/vector/src/main/res/values/theme_common.xml
+++ b/library/ui-styles/src/main/res/values/theme_common.xml
@@ -2,22 +2,19 @@
-
-
-
-
-
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml
new file mode 100644
index 0000000000..17e0ff2938
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/theme_light.xml
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/release/res/values/styles.xml b/library/ui-styles/src/release/res/values/styles.xml
similarity index 100%
rename from vector/src/release/res/values/styles.xml
rename to library/ui-styles/src/release/res/values/styles.xml
diff --git a/matrix-sdk-android-rx/build.gradle b/matrix-sdk-android-rx/build.gradle
index 37b0ff8d00..899432b498 100644
--- a/matrix-sdk-android-rx/build.gradle
+++ b/matrix-sdk-android-rx/build.gradle
@@ -35,7 +35,7 @@ android {
dependencies {
implementation project(":matrix-sdk-android")
- implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlin_coroutines_version"
diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt
index 21db4e1893..b3495c4493 100644
--- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt
+++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt
@@ -23,6 +23,7 @@ import io.reactivex.Single
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxSingle
import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.room.Room
@@ -146,6 +147,10 @@ class RxRoom(private val room: Room) {
fun deleteAvatar(): Completable = rxCompletable {
room.deleteAvatar()
}
+
+ fun sendMedia(attachment: ContentAttachmentData, compressBeforeSending: Boolean, roomIds: Set): Completable = rxCompletable {
+ room.sendMedia(attachment, compressBeforeSending, roomIds)
+ }
}
fun Room.rx(): RxRoom {
diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
index 67a35cac2e..58fb760ff5 100644
--- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
+++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
@@ -35,6 +35,7 @@ import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.pushers.Pusher
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
+import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
@@ -177,10 +178,17 @@ class RxSession(private val session: Session) {
}
}
- fun liveAccountData(types: Set): Observable> {
- return session.getLiveAccountDataEvents(types).asObservable()
+ fun liveUserAccountData(types: Set): Observable> {
+ return session.accountDataService().getLiveUserAccountDataEvents(types).asObservable()
.startWithCallable {
- session.getAccountDataEvents(types)
+ session.accountDataService().getUserAccountDataEvents(types)
+ }
+ }
+
+ fun liveRoomAccountData(types: Set): Observable> {
+ return session.accountDataService().getLiveRoomAccountDataEvents(types).asObservable()
+ .startWithCallable {
+ session.accountDataService().getRoomAccountDataEvents(types)
}
}
@@ -202,7 +210,7 @@ class RxSession(private val session: Session) {
fun liveSecretSynchronisationInfo(): Observable {
return Observable.combineLatest, Optional, Optional, SecretsSynchronisationInfo>(
- liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)),
+ liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)),
liveCrossSigningInfo(session.myUserId),
liveCrossSigningPrivateKeys(),
Function3 { _, crossSigningInfo, pInfo ->
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index a65dc6298e..96c9fdb1e6 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath "io.realm:realm-gradle-plugin:10.5.0"
+ classpath "io.realm:realm-gradle-plugin:10.6.1"
}
}
@@ -112,7 +112,7 @@ dependencies {
def lifecycle_version = '2.2.0'
def arch_version = '2.1.0'
def markwon_version = '3.1.0'
- def daggerVersion = '2.35.1'
+ def daggerVersion = '2.38'
def work_version = '2.5.0'
def retrofit_version = '2.9.0'
@@ -120,8 +120,8 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
- implementation "androidx.appcompat:appcompat:1.2.0"
- implementation "androidx.core:core-ktx:1.3.2"
+ implementation "androidx.appcompat:appcompat:1.3.1"
+ implementation "androidx.core:core-ktx:1.6.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
@@ -155,7 +155,7 @@ dependencies {
implementation "io.arrow-kt:arrow-instances-core:$arrow_version"
// olm lib is now hosted by jitpack: https://jitpack.io/#org.matrix.gitlab.matrix-org/olm
- implementation 'org.matrix.gitlab.matrix-org:olm:3.2.2'
+ implementation 'org.matrix.gitlab.matrix-org:olm:3.2.4'
// DI
implementation "com.google.dagger:dagger:$daggerVersion"
@@ -169,30 +169,30 @@ dependencies {
implementation 'com.otaliastudios:transcoder:0.10.3'
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.23'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.28'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.5.1'
//testImplementation 'org.robolectric:shadows-support-v4:3.0'
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
- testImplementation 'io.mockk:mockk:1.11.0'
- testImplementation 'org.amshove.kluent:kluent-android:1.65'
+ testImplementation 'io.mockk:mockk:1.12.0'
+ testImplementation 'org.amshove.kluent:kluent-android:1.68'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
// Plant Timber tree for test
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
kaptAndroidTest "com.google.dagger:dagger-compiler:$daggerVersion"
- androidTestImplementation 'androidx.test:core:1.3.0'
- androidTestImplementation 'androidx.test:runner:1.3.0'
- androidTestImplementation 'androidx.test:rules:1.3.0'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- androidTestImplementation 'org.amshove.kluent:kluent-android:1.65'
- androidTestImplementation 'io.mockk:mockk-android:1.11.0'
+ androidTestImplementation 'androidx.test:core:1.4.0'
+ androidTestImplementation 'androidx.test:runner:1.4.0'
+ androidTestImplementation 'androidx.test:rules:1.4.0'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation 'org.amshove.kluent:kluent-android:1.68'
+ androidTestImplementation 'io.mockk:mockk-android:1.12.0'
androidTestImplementation "androidx.arch.core:core-testing:$arch_version"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
// Plant Timber tree for test
androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
- androidTestUtil 'androidx.test:orchestrator:1.3.0'
+ androidTestUtil 'androidx.test:orchestrator:1.4.0'
}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SpaceOrderTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SpaceOrderTest.kt
new file mode 100644
index 0000000000..3270dfb757
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SpaceOrderTest.kt
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk
+
+import org.amshove.kluent.internal.assertEquals
+import org.junit.Assert
+import org.junit.Test
+import org.matrix.android.sdk.api.session.space.SpaceOrderUtils
+
+class SpaceOrderTest {
+
+ @Test
+ fun testOrderBetweenNodesWithOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to "a",
+ "roomId2" to "m",
+ "roomId3" to "z"
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)
+
+ Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
+ Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId1")
+
+ Assert.assertTrue("m" < orderCommand[0].order)
+ Assert.assertTrue(orderCommand[0].order < "z")
+ }
+
+ @Test
+ fun testMoveLastBetweenNodesWithOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to "a",
+ "roomId2" to "m",
+ "roomId3" to "z"
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 2)
+
+ Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
+ Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId1")
+
+ Assert.assertTrue("z" < orderCommand[0].order)
+ }
+
+ @Test
+ fun testMoveUpNoOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to null,
+ "roomId2" to null,
+ "roomId3" to null
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)
+
+ Assert.assertTrue("2 orders change should be needed", orderCommand.size == 2)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId2", reOrdered[0].first)
+ Assert.assertEquals("roomId1", reOrdered[1].first)
+ Assert.assertEquals("roomId3", reOrdered[2].first)
+ }
+
+ @Test
+ fun testMoveUpNotEnoughSpace() {
+ val orderedSpaces = listOf(
+ "roomId1" to "a",
+ "roomId2" to "j",
+ "roomId3" to "k"
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)
+
+ Assert.assertTrue("more orders change should be needed", orderCommand.size > 1)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId2", reOrdered[0].first)
+ Assert.assertEquals("roomId1", reOrdered[1].first)
+ Assert.assertEquals("roomId3", reOrdered[2].first)
+ }
+
+ @Test
+ fun testMoveEndNoOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to null,
+ "roomId2" to null,
+ "roomId3" to null
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 2)
+
+ // Actually 2 could be enough... as it's last it can stays with null
+ Assert.assertEquals("3 orders change should be needed", 3, orderCommand.size)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId2", reOrdered[0].first)
+ Assert.assertEquals("roomId3", reOrdered[1].first)
+ Assert.assertEquals("roomId1", reOrdered[2].first)
+ }
+
+ @Test
+ fun testMoveUpBiggerOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to "aaaa",
+ "roomId2" to "ffff",
+ "roomId3" to "pppp",
+ "roomId4" to null,
+ "roomId5" to null,
+ "roomId6" to null
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId2", 3)
+
+ // Actually 2 could be enough... as it's last it can stays with null
+ Assert.assertEquals("3 orders change should be needed", 3, orderCommand.size)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId1", reOrdered[0].first)
+ Assert.assertEquals("roomId3", reOrdered[1].first)
+ Assert.assertEquals("roomId4", reOrdered[2].first)
+ Assert.assertEquals("roomId5", reOrdered[3].first)
+ Assert.assertEquals("roomId2", reOrdered[4].first)
+ Assert.assertEquals("roomId6", reOrdered[5].first)
+ }
+
+ @Test
+ fun testMoveDownBetweenNodesWithOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to "a",
+ "roomId2" to "m",
+ "roomId3" to "z"
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId3", -1)
+
+ Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
+ Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId3")
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId1", reOrdered[0].first)
+ Assert.assertEquals("roomId3", reOrdered[1].first)
+ Assert.assertEquals("roomId2", reOrdered[2].first)
+ }
+
+ @Test
+ fun testMoveDownNoOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to null,
+ "roomId2" to null,
+ "roomId3" to null
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId3", -1)
+
+ Assert.assertTrue("2 orders change should be needed", orderCommand.size == 2)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId1", reOrdered[0].first)
+ Assert.assertEquals("roomId3", reOrdered[1].first)
+ Assert.assertEquals("roomId2", reOrdered[2].first)
+ }
+
+ @Test
+ fun testMoveDownBiggerOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to "aaaa",
+ "roomId2" to "ffff",
+ "roomId3" to "pppp",
+ "roomId4" to null,
+ "roomId5" to null,
+ "roomId6" to null
+ ).assertSpaceOrdered()
+
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId5", -4)
+
+ Assert.assertEquals("1 order change should be needed", 1, orderCommand.size)
+
+ val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)
+
+ Assert.assertEquals("roomId5", reOrdered[0].first)
+ Assert.assertEquals("roomId1", reOrdered[1].first)
+ Assert.assertEquals("roomId2", reOrdered[2].first)
+ Assert.assertEquals("roomId3", reOrdered[3].first)
+ Assert.assertEquals("roomId4", reOrdered[4].first)
+ Assert.assertEquals("roomId6", reOrdered[5].first)
+ }
+
+ @Test
+ fun testMultipleMoveOrder() {
+ val orderedSpaces = listOf(
+ "roomId1" to null,
+ "roomId2" to null,
+ "roomId3" to null,
+ "roomId4" to null,
+ "roomId5" to null,
+ "roomId6" to null
+ ).assertSpaceOrdered()
+
+ // move 5 to Top
+ val fiveToTop = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId5", -4)
+
+ val fiveTopReOrder = reOrderWithCommands(orderedSpaces, fiveToTop)
+
+ // now move 4 to second
+ val orderCommand = SpaceOrderUtils.orderCommandsForMove(fiveTopReOrder, "roomId4", -3)
+
+ val reOrdered = reOrderWithCommands(fiveTopReOrder, orderCommand)
+ // second order should cost 1 re-order
+ Assert.assertEquals(1, orderCommand.size)
+
+ Assert.assertEquals("roomId5", reOrdered[0].first)
+ Assert.assertEquals("roomId4", reOrdered[1].first)
+ Assert.assertEquals("roomId1", reOrdered[2].first)
+ Assert.assertEquals("roomId2", reOrdered[3].first)
+ Assert.assertEquals("roomId3", reOrdered[4].first)
+ Assert.assertEquals("roomId6", reOrdered[5].first)
+ }
+
+ @Test
+ fun testComparator() {
+ listOf(
+ "roomId2" to "a",
+ "roomId1" to "b",
+ "roomId3" to null,
+ "roomId4" to null
+ ).assertSpaceOrdered()
+ }
+
+ private fun reOrderWithCommands(orderedSpaces: List>, orderCommand: List) =
+ orderedSpaces.map { orderInfo ->
+ orderInfo.first to (orderCommand.find { it.spaceId == orderInfo.first }?.order ?: orderInfo.second)
+ }
+ .sortedWith(testSpaceComparator)
+
+ private fun List>.assertSpaceOrdered(): List> {
+ assertEquals(this, this.sortedWith(testSpaceComparator))
+ return this
+ }
+
+ private val testSpaceComparator = compareBy, String?>(nullsLast()) { it.second }.thenBy { it.first }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/StringOrderTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/StringOrderTest.kt
new file mode 100644
index 0000000000..a625362c04
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/StringOrderTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk
+
+import org.amshove.kluent.internal.assertEquals
+import org.junit.Assert
+import org.junit.Test
+import org.matrix.android.sdk.api.MatrixPatterns
+import org.matrix.android.sdk.api.util.StringOrderUtils
+
+class StringOrderTest {
+
+ @Test
+ fun testbasing() {
+ assertEquals("a", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
+ assertEquals("element", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
+ assertEquals("matrix", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
+ }
+
+ @Test
+ fun testValid() {
+ println(StringOrderUtils.DEFAULT_ALPHABET.joinToString(","))
+
+ assert(MatrixPatterns.isValidOrderString("a"))
+ assert(MatrixPatterns.isValidOrderString(" "))
+ assert(MatrixPatterns.isValidOrderString("abc"))
+ assert(!MatrixPatterns.isValidOrderString("abcê"))
+ assert(!MatrixPatterns.isValidOrderString(""))
+ assert(MatrixPatterns.isValidOrderString("!"))
+ assert(MatrixPatterns.isValidOrderString("!\"#\$%&'()*+,012"))
+ assert(!MatrixPatterns.isValidOrderString(Char(' '.code - 1).toString()))
+
+ assert(!MatrixPatterns.isValidOrderString(
+ buildString {
+ for (i in 0..49) {
+ append(StringOrderUtils.DEFAULT_ALPHABET.random())
+ }
+ }
+ ))
+
+ assert(MatrixPatterns.isValidOrderString(
+ buildString {
+ for (i in 0..48) {
+ append(StringOrderUtils.DEFAULT_ALPHABET.random())
+ }
+ }
+ ))
+ }
+
+ @Test
+ fun testAverage() {
+ assertAverage("${StringOrderUtils.DEFAULT_ALPHABET.first()}", "m")
+ assertAverage("aa", "aab")
+ assertAverage("matrix", "element")
+ assertAverage("mmm", "mmmmm")
+ assertAverage("aab", "aa")
+ assertAverage("", "aa")
+ assertAverage("a", "z")
+ assertAverage("ground", "sky")
+ }
+
+ @Test
+ fun testMidPoints() {
+ val orders = StringOrderUtils.midPoints("element", "matrix", 4)
+ assertEquals(4, orders!!.size)
+ assert("element" < orders[0])
+ assert(orders[0] < orders[1])
+ assert(orders[1] < orders[2])
+ assert(orders[2] < orders[3])
+ assert(orders[3] < "matrix")
+
+ println("element < ${orders.joinToString(" < ") { "[$it]" }} < matrix")
+
+ val orders2 = StringOrderUtils.midPoints("a", "d", 4)
+ assertEquals(null, orders2)
+ }
+
+ @Test
+ fun testRenumberNeeded() {
+ assertEquals(null, StringOrderUtils.average("a", "a"))
+ assertEquals(null, StringOrderUtils.average("", ""))
+ assertEquals(null, StringOrderUtils.average("a", "b"))
+ assertEquals(null, StringOrderUtils.average("b", "a"))
+ assertEquals(null, StringOrderUtils.average("mmmm", "mmmm"))
+ assertEquals(null, StringOrderUtils.average("a${Char(0)}", "a"))
+ }
+
+ private fun assertAverage(first: String, second: String) {
+ val left = first.takeIf { first < second } ?: second
+ val right = first.takeIf { first > second } ?: second
+ val av1 = StringOrderUtils.average(left, right)!!
+ println("[$left] < [$av1] < [$right]")
+ Assert.assertTrue(left < av1)
+ Assert.assertTrue(av1 < right)
+ }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
index 287a4233d9..6e07223ac7 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
@@ -78,7 +78,7 @@ class CommonTestHelper(context: Context) {
}
/**
- * Create a Home server configuration, with Http connection allowed for test
+ * Create a homeserver configuration, with Http connection allowed for test
*/
fun createHomeServerConfig(): HomeServerConnectionConfig {
return HomeServerConnectionConfig.Builder()
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt
index 33de345630..1d05e655af 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt
@@ -26,6 +26,7 @@ import org.matrix.android.sdk.internal.di.MatrixModule
import org.matrix.android.sdk.internal.di.MatrixScope
import org.matrix.android.sdk.internal.di.NetworkModule
import org.matrix.android.sdk.internal.raw.RawModule
+import org.matrix.android.sdk.internal.util.system.SystemModule
@Component(modules = [
TestModule::class,
@@ -33,6 +34,7 @@ import org.matrix.android.sdk.internal.raw.RawModule
NetworkModule::class,
AuthModule::class,
RawModule::class,
+ SystemModule::class,
TestNetworkModule::class
])
@MatrixScope
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt
index eb8b8b9730..89d297c592 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt
@@ -816,7 +816,7 @@ class KeysBackupTest : InstrumentedTest {
// - Do an e2e backup to the homeserver
mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
- // Get key backup version from the home server
+ // Get key backup version from the homeserver
val keysVersionResult = mTestHelper.doSync {
keysBackup.getCurrentVersion(it)
}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt
index eb4773f3c8..d14de30c90 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt
@@ -76,7 +76,7 @@ class QuadSTests : InstrumentedTest {
var accountData: UserAccountDataEvent? = null
val liveAccountData = runBlocking(Dispatchers.Main) {
- aliceSession.getLiveAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID")
+ aliceSession.accountDataService().getLiveUserAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID")
}
val accountDataObserver = Observer?> { t ->
if (t?.getOrNull()?.type == "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") {
@@ -104,7 +104,7 @@ class QuadSTests : InstrumentedTest {
val defaultDataLock = CountDownLatch(1)
val liveDefAccountData = runBlocking(Dispatchers.Main) {
- aliceSession.getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
+ aliceSession.accountDataService().getLiveUserAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
}
val accountDefDataObserver = Observer?> { t ->
if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) {
@@ -206,7 +206,7 @@ class QuadSTests : InstrumentedTest {
)
}
- val accountDataEvent = aliceSession.getAccountDataEvent("my.secret")
+ val accountDataEvent = aliceSession.accountDataService().getUserAccountDataEvent("my.secret")
val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *>
assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0)
@@ -280,7 +280,7 @@ class QuadSTests : InstrumentedTest {
var accountData: UserAccountDataEvent? = null
val liveAccountData = runBlocking(Dispatchers.Main) {
- session.getLiveAccountDataEvent(type)
+ session.accountDataService().getLiveUserAccountDataEvent(type)
}
val accountDataObserver = Observer?> { t ->
if (t?.getOrNull()?.type == type) {
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt
new file mode 100644
index 0000000000..7ee6caed0d
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.securestorage
+
+import android.os.Build
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.matrix.android.sdk.InstrumentedTest
+import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
+import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
+import java.io.ByteArrayOutputStream
+import java.util.UUID
+
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class SecretStoringUtilsTest : InstrumentedTest {
+
+ private val buildVersionSdkIntProvider = TestBuildVersionSdkIntProvider()
+ private val secretStoringUtils = SecretStoringUtils(context(), buildVersionSdkIntProvider)
+
+ companion object {
+ const val TEST_STR = "This is something I want to store safely!"
+ }
+
+ @Test
+ fun testStringNominalCaseApi21() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.LOLLIPOP
+ // Encrypt
+ val encrypted = secretStoringUtils.securelyStoreString(TEST_STR, alias)
+ // Decrypt
+ val decrypted = secretStoringUtils.loadSecureSecret(encrypted, alias)
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testStringNominalCaseApi23() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.M
+ // Encrypt
+ val encrypted = secretStoringUtils.securelyStoreString(TEST_STR, alias)
+ // Decrypt
+ val decrypted = secretStoringUtils.loadSecureSecret(encrypted, alias)
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testStringNominalCaseApi30() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.R
+ // Encrypt
+ val encrypted = secretStoringUtils.securelyStoreString(TEST_STR, alias)
+ // Decrypt
+ val decrypted = secretStoringUtils.loadSecureSecret(encrypted, alias)
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testStringMigration21_23() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.LOLLIPOP
+ // Encrypt
+ val encrypted = secretStoringUtils.securelyStoreString(TEST_STR, alias)
+
+ // Simulate a system upgrade
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.M
+
+ // Decrypt
+ val decrypted = secretStoringUtils.loadSecureSecret(encrypted, alias)
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testObjectNominalCaseApi21() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.LOLLIPOP
+
+ // Encrypt
+ val encrypted = ByteArrayOutputStream().also { outputStream ->
+ outputStream.use {
+ secretStoringUtils.securelyStoreObject(TEST_STR, alias, it)
+ }
+ }
+ .toByteArray()
+ .toBase64NoPadding()
+ // Decrypt
+ val decrypted = encrypted.fromBase64().inputStream().use {
+ secretStoringUtils.loadSecureSecret(it, alias)
+ }
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testObjectNominalCaseApi23() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.M
+
+ // Encrypt
+ val encrypted = ByteArrayOutputStream().also { outputStream ->
+ outputStream.use {
+ secretStoringUtils.securelyStoreObject(TEST_STR, alias, it)
+ }
+ }
+ .toByteArray()
+ .toBase64NoPadding()
+ // Decrypt
+ val decrypted = encrypted.fromBase64().inputStream().use {
+ secretStoringUtils.loadSecureSecret(it, alias)
+ }
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testObjectNominalCaseApi30() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.R
+
+ // Encrypt
+ val encrypted = ByteArrayOutputStream().also { outputStream ->
+ outputStream.use {
+ secretStoringUtils.securelyStoreObject(TEST_STR, alias, it)
+ }
+ }
+ .toByteArray()
+ .toBase64NoPadding()
+ // Decrypt
+ val decrypted = encrypted.fromBase64().inputStream().use {
+ secretStoringUtils.loadSecureSecret(it, alias)
+ }
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ @Test
+ fun testObjectMigration21_23() {
+ val alias = generateAlias()
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.LOLLIPOP
+
+ // Encrypt
+ val encrypted = ByteArrayOutputStream().also { outputStream ->
+ outputStream.use {
+ secretStoringUtils.securelyStoreObject(TEST_STR, alias, it)
+ }
+ }
+ .toByteArray()
+ .toBase64NoPadding()
+
+ // Simulate a system upgrade
+ buildVersionSdkIntProvider.value = Build.VERSION_CODES.M
+
+ // Decrypt
+ val decrypted = encrypted.fromBase64().inputStream().use {
+ secretStoringUtils.loadSecureSecret(it, alias)
+ }
+ decrypted shouldBeEqualTo TEST_STR
+ secretStoringUtils.safeDeleteKey(alias)
+ }
+
+ private fun generateAlias() = UUID.randomUUID().toString()
+}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/TestBuildVersionSdkIntProvider.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/TestBuildVersionSdkIntProvider.kt
new file mode 100644
index 0000000000..b08c88fb24
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/TestBuildVersionSdkIntProvider.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.securestorage
+
+import org.matrix.android.sdk.internal.util.system.BuildVersionSdkIntProvider
+
+class TestBuildVersionSdkIntProvider : BuildVersionSdkIntProvider {
+ var value: Int = 0
+
+ override fun get() = value
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt
index d8532c77c8..9a5e40ffeb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt
@@ -16,8 +16,12 @@
package org.matrix.android.sdk.api
+import org.matrix.android.sdk.BuildConfig
+import timber.log.Timber
+
/**
* This class contains pattern to match the different Matrix ids
+ * Ref: https://matrix.org/docs/spec/appendices#identifier-grammar
*/
object MatrixPatterns {
@@ -25,7 +29,7 @@ object MatrixPatterns {
private const val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?"
// regex pattern to find matrix user ids in a string.
- // See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
+ // See https://matrix.org/docs/spec/appendices#historical-user-ids
private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = MATRIX_USER_IDENTIFIER_REGEX.toRegex(RegexOption.IGNORE_CASE)
@@ -71,6 +75,9 @@ object MatrixPatterns {
private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = LINK_TO_APP_ROOM_ALIAS_REGEXP.toRegex(RegexOption.IGNORE_CASE)
+ // ascii characters in the range \x20 (space) to \x7E (~)
+ val ORDER_STRING_REGEX = "[ -~]+".toRegex()
+
// list of patterns to find some matrix item.
val MATRIX_PATTERNS = listOf(
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID,
@@ -146,4 +153,32 @@ object MatrixPatterns {
fun extractServerNameFromId(matrixId: String?): String? {
return matrixId?.substringAfter(":", missingDelimiterValue = "")?.takeIf { it.isNotEmpty() }
}
+
+ /**
+ * Orders which are not strings, or do not consist solely of ascii characters in the range \x20 (space) to \x7E (~),
+ * or consist of more than 50 characters, are forbidden and the field should be ignored if received.
+ */
+ fun isValidOrderString(order: String?): Boolean {
+ return order != null && order.length < 50 && order matches ORDER_STRING_REGEX
+ }
+
+ fun candidateAliasFromRoomName(name: String): String {
+ return Regex("\\s").replace(name.lowercase(), "_").let {
+ "[^a-z0-9._%#@=+-]".toRegex().replace(it, "")
+ }
+ }
+
+ /**
+ * Return the domain form a userId
+ * Examples:
+ * - "@alice:domain.org".getDomain() will return "domain.org"
+ * - "@bob:domain.org:3455".getDomain() will return "domain.org:3455"
+ */
+ fun String.getDomain(): String {
+ if (BuildConfig.DEBUG && !isUserId(this)) {
+ // They are some invalid userId localpart in the wild, but the domain part should be there anyway
+ Timber.w("Not a valid user ID: $this")
+ }
+ return substringAfter(":")
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt
index e1c5171bfc..215f0a0351 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt
@@ -18,11 +18,11 @@ package org.matrix.android.sdk.api.auth.data
import android.net.Uri
import com.squareup.moshi.JsonClass
+import okhttp3.CipherSuite
+import okhttp3.TlsVersion
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
import org.matrix.android.sdk.internal.util.ensureTrailingSlash
-import okhttp3.CipherSuite
-import okhttp3.TlsVersion
/**
* This data class holds how to connect to a specific Homeserver.
@@ -31,7 +31,12 @@ import okhttp3.TlsVersion
*/
@JsonClass(generateAdapter = true)
data class HomeServerConnectionConfig(
+ // This is the homeserver URL entered by the user
val homeServerUri: Uri,
+ // This is the homeserver base URL for the client-server API. Default to homeServerUri,
+ // but can be updated with data from .Well-Known before login, and/or with the data
+ // included in the login response
+ val homeServerUriBase: Uri = homeServerUri,
val identityServerUri: Uri? = null,
val antiVirusServerUri: Uri? = null,
val allowedFingerprints: List = emptyList(),
@@ -47,7 +52,6 @@ data class HomeServerConnectionConfig(
* This builder should be use to create a [HomeServerConnectionConfig] instance.
*/
class Builder {
-
private lateinit var homeServerUri: Uri
private var identityServerUri: Uri? = null
private var antiVirusServerUri: Uri? = null
@@ -69,14 +73,14 @@ data class HomeServerConnectionConfig(
*/
fun withHomeServerUri(hsUri: Uri): Builder {
if (hsUri.scheme != "http" && hsUri.scheme != "https") {
- throw RuntimeException("Invalid home server URI: $hsUri")
+ throw RuntimeException("Invalid homeserver URI: $hsUri")
}
// ensure trailing /
val hsString = hsUri.toString().ensureTrailingSlash()
homeServerUri = try {
Uri.parse(hsString)
} catch (e: Exception) {
- throw RuntimeException("Invalid home server URI: $hsUri")
+ throw RuntimeException("Invalid homeserver URI: $hsUri")
}
return this
}
@@ -134,7 +138,7 @@ data class HomeServerConnectionConfig(
}
/**
- * Add an accepted TLS version for TLS connections with the home server.
+ * Add an accepted TLS version for TLS connections with the homeserver.
*
* @param tlsVersion the tls version to add to the set of TLS versions accepted.
* @return this builder
@@ -156,7 +160,7 @@ data class HomeServerConnectionConfig(
}
/**
- * Add a TLS cipher suite to the list of accepted TLS connections with the home server.
+ * Add a TLS cipher suite to the list of accepted TLS connections with the homeserver.
*
* @param tlsCipherSuite the tls cipher suite to add.
* @return this builder
@@ -234,16 +238,16 @@ data class HomeServerConnectionConfig(
*/
fun build(): HomeServerConnectionConfig {
return HomeServerConnectionConfig(
- homeServerUri,
- identityServerUri,
- antiVirusServerUri,
- allowedFingerprints,
- shouldPin,
- tlsVersions,
- tlsCipherSuites,
- shouldAcceptTlsExtensions,
- allowHttpExtension,
- forceUsageTlsVersions
+ homeServerUri = homeServerUri,
+ identityServerUri = identityServerUri,
+ antiVirusServerUri = antiVirusServerUri,
+ allowedFingerprints = allowedFingerprints,
+ shouldPin = shouldPin,
+ tlsVersions = tlsVersions,
+ tlsCipherSuites = tlsCipherSuites,
+ shouldAcceptTlsExtensions = shouldAcceptTlsExtensions,
+ allowHttpExtension = allowHttpExtension,
+ forceUsageTlsVersions = forceUsageTlsVersions
)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SessionParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SessionParams.kt
index b2a57c7f5c..b490ac877e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SessionParams.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SessionParams.kt
@@ -51,13 +51,18 @@ data class SessionParams(
val deviceId = credentials.deviceId
/**
- * The current homeserver Url. It can be different that the homeserver url entered
- * during login phase, because a redirection may have occurred
+ * The homeserver Url entered by the user during the login phase.
*/
val homeServerUrl = homeServerConnectionConfig.homeServerUri.toString()
/**
- * The current homeserver host
+ * The current homeserver Url for client-server API. It can be different that the homeserver url entered
+ * during login phase, because a redirection may have occurred
+ */
+ val homeServerUrlBase = homeServerConnectionConfig.homeServerUriBase.toString()
+
+ /**
+ * The current homeserver host, using what has been entered by the user during login phase
*/
val homeServerHost = homeServerConnectionConfig.homeServerUri.host
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt
index cfaf74ce24..a0733dda97 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt
@@ -48,14 +48,35 @@ data class SsoIdentityProvider(
*/
@Json(name = "brand") val brand: String?
-) : Parcelable {
+) : Parcelable, Comparable {
companion object {
- const val BRAND_GOOGLE = "org.matrix.google"
- const val BRAND_GITHUB = "org.matrix.github"
- const val BRAND_APPLE = "org.matrix.apple"
- const val BRAND_FACEBOOK = "org.matrix.facebook"
- const val BRAND_TWITTER = "org.matrix.twitter"
- const val BRAND_GITLAB = "org.matrix.gitlab"
+ const val BRAND_GOOGLE = "google"
+ const val BRAND_GITHUB = "github"
+ const val BRAND_APPLE = "apple"
+ const val BRAND_FACEBOOK = "facebook"
+ const val BRAND_TWITTER = "twitter"
+ const val BRAND_GITLAB = "gitlab"
+ }
+
+ override fun compareTo(other: SsoIdentityProvider): Int {
+ return other.toPriority().compareTo(toPriority())
+ }
+
+ private fun toPriority(): Int {
+ return when (brand) {
+ // We are on Android, so user is more likely to have a Google account
+ BRAND_GOOGLE -> 5
+ // Facebook is also an important SSO provider
+ BRAND_FACEBOOK -> 4
+ // Twitter is more for professionals
+ BRAND_TWITTER -> 3
+ // Here it's very for techie people
+ BRAND_GITHUB,
+ BRAND_GITLAB -> 2
+ // And finally, if the account has been created with an iPhone...
+ BRAND_APPLE -> 1
+ else -> 0
+ }
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginProfileInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginProfileInfo.kt
new file mode 100644
index 0000000000..288a6d1232
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginProfileInfo.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.auth.login
+
+data class LoginProfileInfo(
+ val matrixId: String,
+ val displayName: String?,
+ val fullAvatarUrl: String?
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
index da6eb0c3ac..a2a9373837 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
@@ -24,6 +24,11 @@ import org.matrix.android.sdk.api.session.Session
* More documentation can be found in the file https://github.com/vector-im/element-android/blob/main/docs/signin.md
*/
interface LoginWizard {
+ /**
+ * Get some information about a matrixId: displayName and avatar url
+ */
+ suspend fun getProfileInfo(matrixId: String): LoginProfileInfo
+
/**
* Login to the homeserver.
*
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt
index 2b1c1c09b3..ac740ddab7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt
@@ -38,7 +38,7 @@ data class RegistrationFlowResponse(
val completedStages: List? = null,
/**
- * The session identifier that the client must pass back to the home server, if one is provided,
+ * The session identifier that the client must pass back to the homeserver, if one is provided,
* in subsequent attempts to authenticate in the same API call.
*/
@Json(name = "session")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/wellknown/WellknownResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/wellknown/WellknownResult.kt
index c68a9e9699..56257db79c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/wellknown/WellknownResult.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/wellknown/WellknownResult.kt
@@ -22,11 +22,6 @@ import org.matrix.android.sdk.api.auth.data.WellKnown
* Ref: https://matrix.org/docs/spec/client_server/latest#well-known-uri
*/
sealed class WellknownResult {
- /**
- * The provided matrixId is no valid. Unable to extract a domain name.
- */
- object InvalidMatrixId : WellknownResult()
-
/**
* Retrieve the specific piece of information from the user in a way which fits within the existing client user experience,
* if the client is inclined to do so. Failure can take place instead if no good user experience for this is possible at this point.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixIdFailure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixIdFailure.kt
new file mode 100644
index 0000000000..8f7bca803d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixIdFailure.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.failure
+
+sealed class MatrixIdFailure : Failure.FeatureFailure() {
+ object InvalidMatrixId : MatrixIdFailure()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/logger/LoggerTag.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/logger/LoggerTag.kt
new file mode 100644
index 0000000000..51f9b50699
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/logger/LoggerTag.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.logger
+
+/**
+ * Parent class for custom logger tags. Can be used with Timber :
+ *
+ * val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
+ * Timber.tag(loggerTag.value).v("My log message")
+ */
+open class LoggerTag(_value: String, parentTag: LoggerTag? = null) {
+
+ object VOIP : LoggerTag("VOIP")
+
+ val value: String = if (parentTag == null) {
+ _value
+ } else {
+ "${parentTag.value}/$_value"
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
index d9bf5cfd13..4534368679 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
@@ -31,7 +31,13 @@ interface PushRuleService {
suspend fun addPushRule(kind: RuleKind, pushRule: PushRule)
- suspend fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule)
+ /**
+ * Enables/Disables a push rule and updates the actions if necessary
+ * @param enable Enables/Disables the rule
+ * @param actions Actions to update if not null
+ */
+
+ suspend fun updatePushRuleActions(kind: RuleKind, ruleId: String, enable: Boolean, actions: List?)
suspend fun removePushRule(kind: RuleKind, pushRule: PushRule)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt
index 3a9fc4fb83..31d7770a9f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.pushrules.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.pushrules.Action
import org.matrix.android.sdk.api.pushrules.getActions
import org.matrix.android.sdk.api.pushrules.toJson
@@ -100,6 +101,13 @@ data class PushRule(
)
}
+ /**
+ * Get the highlight status. As spec mentions assume false if no tweak present.
+ */
+ fun getHighlight(): Boolean {
+ return getActions().filterIsInstance().firstOrNull()?.highlight.orFalse()
+ }
+
/**
* Set the notification status.
*
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
index f1722b2189..3366d040f7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
@@ -29,8 +29,10 @@ interface RawService {
/**
* Specific case for the well-known file. Cache validity is 8 hours
+ * @param domain the domain to get the .well-known file, for instance "matrix.org".
+ * The URL will be "https://{domain}/.well-known/matrix/client"
*/
- suspend fun getWellknown(userId: String): String
+ suspend fun getWellknown(domain: String): String
/**
* Clear all the cache data
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
index 86252665a6..2f981ffbbe 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
@@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.failure.GlobalError
import org.matrix.android.sdk.api.federation.FederationService
import org.matrix.android.sdk.api.pushrules.PushRuleService
import org.matrix.android.sdk.api.session.account.AccountService
-import org.matrix.android.sdk.api.session.accountdata.AccountDataService
+import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService
import org.matrix.android.sdk.api.session.cache.CacheService
import org.matrix.android.sdk.api.session.call.CallSignalingService
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
@@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.identity.IdentityService
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
+import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.pushers.PushersService
@@ -77,7 +78,6 @@ interface Session :
InitialSyncProgressService,
HomeServerCapabilitiesService,
SecureStorageService,
- AccountDataService,
AccountService {
/**
@@ -233,6 +233,16 @@ interface Session :
*/
fun spaceService(): SpaceService
+ /**
+ * Returns the open id service associated with the session
+ */
+ fun openIdService(): OpenIdService
+
+ /**
+ * Returns the account data service associated with the session
+ */
+ fun accountDataService(): SessionAccountDataService
+
/**
* Add a listener to the session.
* @param listener the listener to add.
@@ -256,12 +266,17 @@ interface Session :
* A global session listener to get notified for some events.
*/
interface Listener : SessionLifecycleObserver {
+ /**
+ * Called when the session received new invites to room so the client can react to it once.
+ */
+ fun onNewInvitedRoom(session: Session, roomId: String) = Unit
+
/**
* Possible cases:
* - The access token is not valid anymore,
* - a M_CONSENT_NOT_GIVEN error has been received from the homeserver
*/
- fun onGlobalError(session: Session, globalError: GlobalError)
+ fun onGlobalError(session: Session, globalError: GlobalError) = Unit
}
val sharedSecretStorageService: SharedSecretStorageService
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/SessionAccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/SessionAccountDataService.kt
new file mode 100644
index 0000000000..2ffb9112d1
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/SessionAccountDataService.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.accountdata
+
+import androidx.lifecycle.LiveData
+import org.matrix.android.sdk.api.session.events.model.Content
+import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent
+import org.matrix.android.sdk.api.util.Optional
+
+/**
+ * This service is attached globally to the session.
+ */
+interface SessionAccountDataService {
+ /**
+ * Retrieve the account data with the provided type or null if not found
+ */
+ fun getUserAccountDataEvent(type: String): UserAccountDataEvent?
+
+ /**
+ * Observe the account data with the provided type
+ */
+ fun getLiveUserAccountDataEvent(type: String): LiveData>
+
+ /**
+ * Retrieve the account data with the provided types. The return list can have a different size that
+ * the size of the types set, because some AccountData may not exist.
+ * If an empty set is provided, all the AccountData are retrieved
+ */
+ fun getUserAccountDataEvents(types: Set): List
+
+ /**
+ * Observe the account data with the provided types. If an empty set is provided, all the AccountData are observed
+ */
+ fun getLiveUserAccountDataEvents(types: Set): LiveData>
+
+ /**
+ * Retrieve the room account data with the provided types. The return list can have a different size that
+ * the size of the types set, because some AccountData may not exist.
+ * If an empty set is provided, all the room AccountData are retrieved
+ */
+ fun getRoomAccountDataEvents(types: Set): List
+
+ /**
+ * Observe the room account data with the provided types. If an empty set is provided, AccountData of every room are observed
+ */
+ fun getLiveRoomAccountDataEvents(types: Set): LiveData>
+
+ /**
+ * Update the account data with the provided type and the provided account data content
+ */
+ suspend fun updateUserAccountData(type: String, content: Content)
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt
index 744e3e5379..77381a28c4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt
@@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Content
/**
* This is a simplified Event with just a type and a content.
- * Currently used types are defined in [UserAccountDataTypes].
+ * Currently used types are defined in [UserAccountDataTypes]
*/
@JsonClass(generateAdapter = true)
data class UserAccountDataEvent(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt
new file mode 100644
index 0000000000..43e6872525
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.call
+
+import java.util.UUID
+
+object CallIdGenerator {
+ fun generate() = UUID.randomUUID().toString()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
index 303add747f..d17be59cd4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
@@ -17,6 +17,7 @@
package org.matrix.android.sdk.api.session.call
import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallAssertedIdentityContent
import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
@@ -61,4 +62,9 @@ interface CallListener {
* Called when the call has been managed by an other session
*/
fun onCallManagedByOtherSession(callId: String)
+
+ /**
+ * Called when an asserted identity event is received
+ */
+ fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
index dc67aa536a..c34744e75f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
@@ -20,8 +20,6 @@ interface CallSignalingService {
suspend fun getTurnServer(): TurnServerResponse
- fun getPSTNProtocolChecker(): PSTNProtocolChecker
-
/**
* Create an outgoing call
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
index 2dbd1c9b01..47a63b4a25 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
@@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.call
+import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
+
sealed class CallState {
/** Idle, setting up objects */
@@ -42,6 +44,6 @@ sealed class CallState {
* */
data class Connected(val iceConnectionState: MxPeerConnectionState) : CallState()
- /** Terminated. Incoming/Outgoing call, the call is terminated */
- object Terminated : CallState()
+ /** Ended. Incoming/Outgoing call, the call is terminated */
+ data class Ended(val reason: EndCallReason? = null) : CallState()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
index 7533619eb0..dd23e81cc6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
@@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.call
import org.matrix.android.sdk.api.session.room.model.call.CallCandidate
import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
-import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
+import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
import org.matrix.android.sdk.api.session.room.model.call.SdpType
import org.matrix.android.sdk.api.util.Optional
@@ -26,8 +26,12 @@ interface MxCallDetail {
val callId: String
val isOutgoing: Boolean
val roomId: String
- val opponentUserId: String
val isVideoCall: Boolean
+ val ourPartyId: String
+ val opponentPartyId: Optional?
+ val opponentVersion: Int
+ val opponentUserId: String
+ val capabilities: CallCapabilities?
}
/**
@@ -39,12 +43,6 @@ interface MxCall : MxCallDetail {
const val VOIP_PROTO_VERSION = 1
}
- val ourPartyId: String
- var opponentPartyId: Optional?
- var opponentVersion: Int
-
- var capabilities: CallCapabilities?
-
var state: CallState
/**
@@ -71,7 +69,7 @@ interface MxCall : MxCallDetail {
/**
* End the call
*/
- fun hangUp(reason: CallHangupContent.Reason? = null)
+ fun hangUp(reason: EndCallReason? = null)
/**
* Start a call
@@ -91,8 +89,12 @@ interface MxCall : MxCallDetail {
/**
* Send a m.call.replaces event to initiate call transfer.
+ * See [org.matrix.android.sdk.api.session.room.model.call.CallReplacesContent] for documentation about the parameters
*/
- suspend fun transfer(targetUserId: String, targetRoomId: String?)
+ suspend fun transfer(targetUserId: String,
+ targetRoomId: String?,
+ createCallId: String?,
+ awaitCallId: String?)
fun addListener(listener: StateListener)
fun removeListener(listener: StateListener)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt
deleted file mode 100644
index 6627f62e24..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.session.call
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import org.matrix.android.sdk.api.extensions.tryOrNull
-import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
-import org.matrix.android.sdk.internal.session.SessionScope
-import org.matrix.android.sdk.internal.session.thirdparty.GetThirdPartyProtocolsTask
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import timber.log.Timber
-import java.util.concurrent.atomic.AtomicBoolean
-import javax.inject.Inject
-
-private const val PSTN_VECTOR_KEY = "im.vector.protocol.pstn"
-private const val PSTN_MATRIX_KEY = "m.protocol.pstn"
-
-/**
- * This class is responsible for checking if the HS support the PSTN protocol.
- * As long as the request succeed, it'll check only once by session.
- */
-@SessionScope
-class PSTNProtocolChecker @Inject internal constructor(private val taskExecutor: TaskExecutor,
- private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask) {
-
- interface Listener {
- fun onPSTNSupportUpdated()
- }
-
- private var alreadyChecked = AtomicBoolean(false)
-
- private val pstnSupportListeners = mutableListOf()
-
- fun addListener(listener: Listener) {
- pstnSupportListeners.add(listener)
- }
-
- fun removeListener(listener: Listener) {
- pstnSupportListeners.remove(listener)
- }
-
- var supportedPSTNProtocol: String? = null
- private set
-
- fun checkForPSTNSupportIfNeeded() {
- if (alreadyChecked.get()) return
- taskExecutor.executorScope.checkForPSTNSupport()
- }
-
- private fun CoroutineScope.checkForPSTNSupport() = launch {
- try {
- supportedPSTNProtocol = getSupportedPSTN(3)
- alreadyChecked.set(true)
- if (supportedPSTNProtocol != null) {
- pstnSupportListeners.forEach {
- tryOrNull { it.onPSTNSupportUpdated() }
- }
- }
- } catch (failure: Throwable) {
- Timber.v("Fail to get supported PSTN, will check again next time.")
- }
- }
-
- private suspend fun getSupportedPSTN(maxTries: Int): String? {
- val thirdPartyProtocols: Map = try {
- getThirdPartyProtocolsTask.execute(Unit)
- } catch (failure: Throwable) {
- if (maxTries == 1) {
- throw failure
- } else {
- // Wait for 10s before trying again
- delay(10_000L)
- return getSupportedPSTN(maxTries - 1)
- }
- }
- return when {
- thirdPartyProtocols.containsKey(PSTN_VECTOR_KEY) -> PSTN_VECTOR_KEY
- thirdPartyProtocols.containsKey(PSTN_MATRIX_KEY) -> PSTN_MATRIX_KEY
- else -> null
- }
- }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt
index 98a84b8b66..7ee26de8db 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt
@@ -35,7 +35,8 @@ data class ContentAttachmentData(
val name: String? = null,
val queryUri: Uri,
val mimeType: String?,
- val type: Type
+ val type: Type,
+ val waveform: List? = null
) : Parcelable {
@JsonClass(generateAdapter = false)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
index 1b7a5243e2..e3f00a24b6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
@@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
-import kotlin.jvm.Throws
interface CryptoService {
@@ -82,9 +81,11 @@ interface CryptoService {
fun getDeviceTrackingStatus(userId: String): Int
- fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?, callback: MatrixCallback)
+ suspend fun importRoomKeys(roomKeysAsArray: ByteArray,
+ password: String,
+ progressListener: ProgressListener?): ImportRoomKeysResult
- fun exportRoomKeys(password: String, callback: MatrixCallback)
+ suspend fun exportRoomKeys(password: String): ByteArray
fun setRoomBlacklistUnverifiedDevices(roomId: String)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
index 465d00168f..4464427b90 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
@@ -28,7 +28,7 @@ import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo
interface KeysBackupService {
/**
- * Retrieve the current version of the backup from the home server
+ * Retrieve the current version of the backup from the homeserver
*
* It can be different than keysBackupVersion.
* @param callback onSuccess(null) will be called if there is no backup on the server
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt
index 7d0f04ebcf..a4cc133398 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt
@@ -54,7 +54,7 @@ enum class KeysBackupState {
// Need to check the current backup version on the homeserver
Unknown,
- // Checking if backup is enabled on home server
+ // Checking if backup is enabled on homeserver
CheckingBackUpOnHomeserver,
// Backup has been stopped because a new backup version has been detected on the homeserver
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
index 6400dd6444..3d82846e7e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
@@ -104,7 +104,7 @@ data class Event(
/**
* The `age` value transcoded in a timestamp based on the device clock when the SDK received
- * the event from the home server.
+ * the event from the homeserver.
* Unlike `age`, this value is static.
*/
@Transient
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
index d2befca1ee..9c3fdd57da 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
@@ -31,9 +31,7 @@ object EventType {
const val TYPING = "m.typing"
const val REDACTION = "m.room.redaction"
const val RECEIPT = "m.receipt"
- const val TAG = "m.tag"
const val ROOM_KEY = "m.room_key"
- const val FULLY_READ = "m.fully_read"
const val PLUMBING = "m.room.plumbing"
const val BOT_OPTIONS = "m.room.bot.options"
const val PREVIEW_URLS = "org.matrix.room.preview_urls"
@@ -78,6 +76,8 @@ object EventType {
const val CALL_NEGOTIATE = "m.call.negotiate"
const val CALL_REJECT = "m.call.reject"
const val CALL_HANGUP = "m.call.hangup"
+ const val CALL_ASSERTED_IDENTITY = "m.call.asserted_identity"
+ const val CALL_ASSERTED_IDENTITY_PREFIX = "org.matrix.call.asserted_identity"
// This type is not processed by the client, just sent to the server
const val CALL_REPLACES = "m.call.replaces"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
index da99ab8d54..b49236c338 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
@@ -32,9 +32,71 @@ data class HomeServerCapabilities(
/**
* Default identity server url, provided in Wellknown
*/
- val defaultIdentityServerUrl: String? = null
+ val defaultIdentityServerUrl: String? = null,
+ /**
+ * Room versions supported by the server
+ * This capability describes the default and available room versions a server supports, and at what level of stability.
+ * Clients should make use of this capability to determine if users need to be encouraged to upgrade their rooms.
+ */
+ val roomVersions: RoomVersionCapabilities? = null
) {
+
+ enum class RoomCapabilitySupport {
+ SUPPORTED,
+ SUPPORTED_UNSTABLE,
+ UNSUPPORTED,
+ UNKNOWN
+ }
+
+ /**
+ * Check if a feature is supported by the homeserver.
+ * @return
+ * UNKNOWN if the server does not implement room caps
+ * UNSUPPORTED if this feature is not supported
+ * SUPPORTED if this feature is supported by a stable version
+ * SUPPORTED_UNSTABLE if this feature is supported by an unstable version
+ * (unstable version should only be used for dev/experimental purpose)
+ */
+ fun isFeatureSupported(feature: String): RoomCapabilitySupport {
+ if (roomVersions?.capabilities == null) return RoomCapabilitySupport.UNKNOWN
+ val info = roomVersions.capabilities[feature] ?: return RoomCapabilitySupport.UNSUPPORTED
+
+ val preferred = info.preferred ?: info.support.lastOrNull()
+ val versionCap = roomVersions.supportedVersion.firstOrNull { it.version == preferred }
+
+ return when {
+ versionCap == null -> {
+ RoomCapabilitySupport.UNKNOWN
+ }
+ versionCap.status == RoomVersionStatus.STABLE -> {
+ RoomCapabilitySupport.SUPPORTED
+ }
+ else -> {
+ RoomCapabilitySupport.SUPPORTED_UNSTABLE
+ }
+ }
+ }
+ fun isFeatureSupported(feature: String, byRoomVersion: String): Boolean {
+ if (roomVersions?.capabilities == null) return false
+ val info = roomVersions.capabilities[feature] ?: return false
+
+ return info.preferred == byRoomVersion || info.support.contains(byRoomVersion)
+ }
+
+ /**
+ * Use this method to know if you should force a version when creating
+ * a room that requires this feature.
+ * You can also use #isFeatureSupported prior to this call to check if the
+ * feature is supported and report some feedback to user.
+ */
+ fun versionOverrideForFeature(feature: String) : String? {
+ val cap = roomVersions?.capabilities?.get(feature)
+ return cap?.preferred ?: cap?.support?.lastOrNull()
+ }
+
companion object {
const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L
+ const val ROOM_CAP_KNOCK = "knock"
+ const val ROOM_CAP_RESTRICTED = "restricted"
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/RoomVersionModel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/RoomVersionModel.kt
new file mode 100644
index 0000000000..9f8e9aa1d1
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/RoomVersionModel.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.homeserver
+
+data class RoomVersionCapabilities(
+ val defaultRoomVersion: String,
+ val supportedVersion: List,
+ // Keys are capabilities defined per spec, as for now knock or restricted
+ val capabilities: Map?
+)
+
+data class RoomVersionInfo(
+ val version: String,
+ val status: RoomVersionStatus
+)
+
+data class RoomCapabilitySupport(
+ val preferred: String?,
+ val support: List
+)
+
+enum class RoomVersionStatus {
+ STABLE,
+ UNSTABLE
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
index 8f8967e8fb..ae546b6cec 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
@@ -35,7 +35,7 @@ interface IdentityService {
/**
* Check if the identity server is valid
* See https://matrix.org/docs/spec/identity_service/latest#status-check
- * RiotX SDK only supports identity server API v2
+ * Matrix Android SDK2 only supports identity server API v2
*/
suspend fun isValidIdentityServer(url: String)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdService.kt
new file mode 100644
index 0000000000..65f6214f93
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdService.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.openid
+
+interface OpenIdService {
+
+ /**
+ * Gets an OpenID token object that the requester may supply to another service to verify their identity in Matrix.
+ * The generated token is only valid for exchanging for user information from the federation API for OpenID.
+ */
+ suspend fun getOpenIdToken(): OpenIdToken
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdToken.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdToken.kt
new file mode 100644
index 0000000000..2c2ea65681
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/openid/OpenIdToken.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.openid
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+data class OpenIdToken(
+ /**
+ * Required. An access token the consumer may use to verify the identity of the person who generated the token.
+ * This is given to the federation API GET /openid/userinfo to verify the user's identity.
+ */
+ @Json(name = "access_token")
+ val accessToken: String,
+
+ /**
+ * Required. The string "Bearer".
+ */
+ @Json(name = "token_type")
+ val tokenType: String,
+
+ /**
+ * Required. The homeserver domain the consumer should use when attempting to verify the user's identity.
+ */
+ @Json(name = "matrix_server_name")
+ val matrixServerName: String,
+
+ /**
+ * Required. The number of seconds before this token expires and a new one must be generated.
+ */
+ @Json(name = "expires_in")
+ val expiresIn: Int
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt
index ac1d726d03..a6d4583c76 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt
@@ -54,7 +54,7 @@ interface PermalinkService {
*
* @return the permalink, or null in case of error
*/
- fun createRoomPermalink(roomId: String): String?
+ fun createRoomPermalink(roomId: String, viaServers: List? = null): String?
/**
* Creates a permalink for an event. If you have an event you can use [createPermalink]
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt
new file mode 100644
index 0000000000..6f607569c0
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room
+
+import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
+
+sealed class AliasAvailabilityResult {
+ object Available: AliasAvailabilityResult()
+ data class NotAvailable(val roomAliasError: RoomAliasError) : AliasAvailabilityResult()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
index 8c434fc440..ebe96b6382 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt
@@ -17,6 +17,7 @@
package org.matrix.android.sdk.api.session.room
import androidx.lifecycle.LiveData
+import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataService
import org.matrix.android.sdk.api.session.room.alias.AliasService
import org.matrix.android.sdk.api.session.room.call.RoomCallService
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
@@ -33,6 +34,7 @@ import org.matrix.android.sdk.api.session.room.tags.TagsService
import org.matrix.android.sdk.api.session.room.timeline.TimelineService
import org.matrix.android.sdk.api.session.room.typing.TypingService
import org.matrix.android.sdk.api.session.room.uploads.UploadsService
+import org.matrix.android.sdk.api.session.room.version.RoomVersionService
import org.matrix.android.sdk.api.session.search.SearchResult
import org.matrix.android.sdk.api.session.space.Space
import org.matrix.android.sdk.api.util.Optional
@@ -55,7 +57,9 @@ interface Room :
RoomCallService,
RelationService,
RoomCryptoService,
- RoomPushRuleService {
+ RoomPushRuleService,
+ RoomAccountDataService,
+ RoomVersionService {
/**
* The roomId of this room
@@ -86,12 +90,12 @@ interface Room :
* @return The search result
*/
suspend fun search(searchTerm: String,
- nextBatch: String?,
- orderByRecent: Boolean,
- limit: Int,
- beforeLimit: Int,
- afterLimit: Int,
- includeProfile: Boolean): SearchResult
+ nextBatch: String?,
+ orderByRecent: Boolean,
+ limit: Int,
+ beforeLimit: Int,
+ afterLimit: Int,
+ includeProfile: Boolean): SearchResult
/**
* Use this room as a Space, if the type is correct.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
index 176de8e408..f3e3913bc1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
@@ -40,4 +40,6 @@ interface RoomDirectoryService {
* Set the visibility of a room in the directory
*/
suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility)
+
+ suspend fun checkAliasAvailability(aliasLocalPart: String?) : AliasAvailabilityResult
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
index 871c5378a6..b7377df1b3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
@@ -125,6 +125,12 @@ interface RoomService {
*/
suspend fun deleteRoomAlias(roomAlias: String)
+ /**
+ * Return the current local changes membership for the given room.
+ * see [getChangeMembershipsLive] for more details.
+ */
+ fun getChangeMemberships(roomIdOrAlias: String): ChangeMembershipState
+
/**
* Return a live data of all local changes membership that happened since the session has been opened.
* It allows you to track this in your client to known what is currently being processed by the SDK.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
index 88ec2de768..b440857518 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
@@ -39,12 +39,6 @@ fun spaceSummaryQueryParams(init: (RoomSummaryQueryParams.Builder.() -> Unit) =
.build()
}
-enum class RoomCategoryFilter {
- ONLY_DM,
- ONLY_ROOMS,
- ALL
-}
-
/**
* This class can be used to filter room summaries to use with:
* [org.matrix.android.sdk.api.session.room.Room] and [org.matrix.android.sdk.api.session.room.RoomService]
@@ -59,11 +53,10 @@ data class RoomSummaryQueryParams(
val excludeType: List?,
val includeType: List?,
val activeSpaceFilter: ActiveSpaceFilter?,
- var activeGroupId: String? = null
+ val activeGroupId: String? = null
) {
class Builder {
-
var roomId: QueryStringValue = QueryStringValue.IsNotEmpty
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
var canonicalAlias: QueryStringValue = QueryStringValue.NoCondition
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataEvent.kt
new file mode 100644
index 0000000000..eb676ab5e7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataEvent.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.accountdata
+
+import org.matrix.android.sdk.api.session.events.model.Content
+
+/**
+ * This is a simplified Event with just a roomId, a type and a content.
+ * Currently used types are defined in [RoomAccountDataTypes].
+ */
+data class RoomAccountDataEvent(
+ val roomId: String,
+ val type: String,
+ val content: Content
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataService.kt
similarity index 83%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataService.kt
index 5ebeaad3de..190749c85c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataService.kt
@@ -14,34 +14,37 @@
* limitations under the License.
*/
-package org.matrix.android.sdk.api.session.accountdata
+package org.matrix.android.sdk.api.session.room.accountdata
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.util.Optional
-interface AccountDataService {
+/**
+ * This service is attached to a single room.
+ */
+interface RoomAccountDataService {
/**
* Retrieve the account data with the provided type or null if not found
*/
- fun getAccountDataEvent(type: String): UserAccountDataEvent?
+ fun getAccountDataEvent(type: String): RoomAccountDataEvent?
/**
* Observe the account data with the provided type
*/
- fun getLiveAccountDataEvent(type: String): LiveData>
+ fun getLiveAccountDataEvent(type: String): LiveData>
/**
* Retrieve the account data with the provided types. The return list can have a different size that
* the size of the types set, because some AccountData may not exist.
* If an empty set is provided, all the AccountData are retrieved
*/
- fun getAccountDataEvents(types: Set): List
+ fun getAccountDataEvents(types: Set): List
/**
* Observe the account data with the provided types. If an empty set is provided, all the AccountData are observed
*/
- fun getLiveAccountDataEvents(types: Set): LiveData>
+ fun getLiveAccountDataEvents(types: Set): LiveData>
/**
* Update the account data with the provided type and the provided account data content
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt
new file mode 100644
index 0000000000..96eb86c0d6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.accountdata
+
+object RoomAccountDataTypes {
+ const val EVENT_TYPE_VIRTUAL_ROOM = "im.vector.is_virtual_room"
+ const val EVENT_TYPE_TAG = "m.tag"
+ const val EVENT_TYPE_FULLY_READ = "m.fully_read"
+ const val EVENT_TYPE_SPACE_ORDER = "org.matrix.msc3230.space_order" // m.space_order
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt
index 2d31930b33..8cd2a0538d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt
@@ -30,5 +30,9 @@ data class SpaceChildInfo(
val autoJoin: Boolean,
val viaServers: List,
val parentRoomId: String?,
- val suggested: Boolean?
+ val suggested: Boolean?,
+ val canonicalAlias: String?,
+ val aliases: List?,
+ val worldReadable: Boolean
+
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
index 45a54bb379..180b32db05 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
@@ -44,7 +44,7 @@ data class CallAnswerContent(
* Capability advertisement.
*/
@Json(name = "capabilities") val capabilities: CallCapabilities? = null
-): CallSignallingContent {
+): CallSignalingContent {
@JsonClass(generateAdapter = true)
data class Answer(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAssertedIdentityContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAssertedIdentityContent.kt
new file mode 100644
index 0000000000..4c5413425f
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAssertedIdentityContent.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This event is sent by the callee when they wish to answer the call.
+ */
+@JsonClass(generateAdapter = true)
+data class CallAssertedIdentityContent(
+ /**
+ * Required. The ID of the call this event relates to.
+ */
+ @Json(name = "call_id") override val callId: String,
+ /**
+ * Required. ID to let user identify remote echo of their own events
+ */
+ @Json(name = "party_id") override val partyId: String? = null,
+ /**
+ * Required. The version of the VoIP specification this messages adheres to.
+ */
+ @Json(name = "version") override val version: String?,
+
+ /**
+ * Optional. Used to inform the transferee who they're now speaking to.
+ */
+ @Json(name = "asserted_identity") val assertedIdentity: AssertedIdentity? = null
+) : CallSignalingContent {
+
+ /**
+ * A user ID may be included if relevant, but unlike target_user, it is purely informational.
+ * The asserted identity may not represent a matrix user at all,
+ * in which case just a display_name may be given, or a perhaps a display_name and avatar_url.
+ */
+ @JsonClass(generateAdapter = true)
+ data class AssertedIdentity(
+ @Json(name = "id") val id: String? = null,
+ @Json(name = "display_name") val displayName: String? = null,
+ @Json(name = "avatar_url") val avatarUrl: String? = null
+ )
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
index 7bfe7a97ac..dc0a1e3b2e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
@@ -41,4 +41,4 @@ data class CallCandidatesContent(
* Required. The version of the VoIP specification this messages adheres to.
*/
@Json(name = "version") override val version: String?
-): CallSignallingContent
+): CallSignalingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
index 0acc409053..31f801dd6f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
@@ -43,26 +43,5 @@ data class CallHangupContent(
* or `invite_timeout` for when the other party did not answer in time.
* One of: ["ice_failed", "invite_timeout"]
*/
- @Json(name = "reason") val reason: Reason? = null
-) : CallSignallingContent {
- @JsonClass(generateAdapter = false)
- enum class Reason {
- @Json(name = "ice_failed")
- ICE_FAILED,
-
- @Json(name = "ice_timeout")
- ICE_TIMEOUT,
-
- @Json(name = "user_hangup")
- USER_HANGUP,
-
- @Json(name = "user_media_failed")
- USER_MEDIA_FAILED,
-
- @Json(name = "invite_timeout")
- INVITE_TIMEOUT,
-
- @Json(name = "unknown_error")
- UNKWOWN_ERROR
- }
-}
+ @Json(name = "reason") val reason: EndCallReason? = null
+) : CallSignalingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
index 42489bc0ce..e4332f0ea7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
@@ -55,7 +55,7 @@ data class CallInviteContent(
*/
@Json(name = "capabilities") val capabilities: CallCapabilities? = null
-): CallSignallingContent {
+): CallSignalingContent {
@JsonClass(generateAdapter = true)
data class Offer(
/**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt
index 040993bb51..68dd5ef043 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt
@@ -47,7 +47,7 @@ data class CallNegotiateContent(
*/
@Json(name = "version") override val version: String?
- ): CallSignallingContent {
+ ): CallSignalingContent {
@JsonClass(generateAdapter = true)
data class Description(
/**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt
index 1da229b179..1b9a7186e2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt
@@ -36,5 +36,10 @@ data class CallRejectContent(
/**
* Required. The version of the VoIP specification this message adheres to.
*/
- @Json(name = "version") override val version: String?
-) : CallSignallingContent
+ @Json(name = "version") override val version: String?,
+
+ /**
+ * Optional error reason for the reject.
+ */
+ @Json(name = "reason") val reason: EndCallReason? = null
+) : CallSignalingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt
index 97a3b8c7a7..4559c5db6d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt
@@ -38,30 +38,30 @@ data class CallReplacesContent(
*/
@Json(name = "replacement_id") val replacementId: String? = null,
/**
- * Optional. If specified, the transferee client waits for an invite to this room and joins it
- * (possibly waiting for user confirmation) and then continues the transfer in this room.
- * If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing.
+ * Optional. If specified, the transferee client waits for an invite to this room and joins it
+ * (possibly waiting for user confirmation) and then continues the transfer in this room.
+ * If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing.
*/
- @Json(name = "target_room") val targerRoomId: String? = null,
+ @Json(name = "target_room") val targetRoomId: String? = null,
/**
- * An object giving information about the transfer target
+ * An object giving information about the transfer target
*/
@Json(name = "target_user") val targetUser: TargetUser? = null,
/**
- * If specified, gives the call ID for the transferee's client to use when placing the replacement call.
- * Mutually exclusive with await_call
+ * If specified, gives the call ID for the transferee's client to use when placing the replacement call.
+ * Mutually exclusive with await_call
*/
@Json(name = "create_call") val createCall: String? = null,
/**
- * If specified, gives the call ID that the transferee's client should wait for.
- * Mutually exclusive with create_call.
+ * If specified, gives the call ID that the transferee's client should wait for.
+ * Mutually exclusive with create_call.
*/
@Json(name = "await_call") val awaitCall: String? = null,
/**
* Required. The version of the VoIP specification this messages adheres to.
*/
@Json(name = "version") override val version: String?
-): CallSignallingContent {
+): CallSignalingContent {
@JsonClass(generateAdapter = true)
data class TargetUser(
@@ -77,6 +77,5 @@ data class CallReplacesContent(
* Optional. The avatar URL of the transfer target.
*/
@Json(name = "avatar_url") val avatarUrl: String?
-
)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt
index 6ea70ac990..795f332711 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt
@@ -41,4 +41,4 @@ data class CallSelectAnswerContent(
* Required. The version of the VoIP specification this message adheres to.
*/
@Json(name = "version") override val version: String?
-): CallSignallingContent
+): CallSignalingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt
similarity index 96%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt
index f8d8c2a5e8..92b43dd22c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt
@@ -16,7 +16,7 @@
package org.matrix.android.sdk.api.session.room.model.call
-interface CallSignallingContent {
+interface CallSignalingContent {
/**
* Required. A unique identifier for the call.
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/EndCallReason.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/EndCallReason.kt
new file mode 100644
index 0000000000..60e038b2f9
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/EndCallReason.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = false)
+enum class EndCallReason {
+ @Json(name = "ice_failed")
+ ICE_FAILED,
+
+ @Json(name = "ice_timeout")
+ ICE_TIMEOUT,
+
+ @Json(name = "user_hangup")
+ USER_HANGUP,
+
+ @Json(name = "replaced")
+ REPLACED,
+
+ @Json(name = "user_media_failed")
+ USER_MEDIA_FAILED,
+
+ @Json(name = "invite_timeout")
+ INVITE_TIMEOUT,
+
+ @Json(name = "unknown_error")
+ UNKWOWN_ERROR,
+
+ @Json(name = "user_busy")
+ USER_BUSY,
+
+ @Json(name = "answered_elsewhere")
+ ANSWERED_ELSEWHERE
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
index ca8c66bb3b..5667906000 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
@@ -22,10 +22,8 @@ import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
-import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
-// TODO Give a way to include other initial states
open class CreateRoomParams {
/**
* A public visibility indicates that the room will be shown in the published room list.
@@ -103,6 +101,13 @@ open class CreateRoomParams {
*/
val creationContent = mutableMapOf()
+ /**
+ * A list of state events to set in the new room. This allows the user to override the default state events
+ * set in the new room. The expected format of the state events are an object with type, state_key and content keys set.
+ * Takes precedence over events set by preset, but gets overridden by name and topic keys.
+ */
+ val initialStates = mutableListOf()
+
/**
* Set to true to disable federation of this room.
* Default: false
@@ -156,7 +161,7 @@ open class CreateRoomParams {
var roomVersion: String? = null
- var joinRuleRestricted: List? = null
+ var featurePreset: RoomFeaturePreset? = null
companion object {
private const val CREATION_CONTENT_KEY_M_FEDERATE = "m.federate"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomStateEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomStateEvent.kt
new file mode 100644
index 0000000000..fcfdc3e333
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomStateEvent.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.model.create
+
+import org.matrix.android.sdk.api.session.events.model.Content
+
+data class CreateRoomStateEvent(
+ /**
+ * Required. The type of event to send.
+ */
+ val type: String,
+
+ /**
+ * Required. The content of the event.
+ */
+ val content: Content,
+
+ /**
+ * The state_key of the state event. Defaults to an empty string.
+ */
+ val stateKey: String = ""
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt
new file mode 100644
index 0000000000..f5f722d783
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.model.create
+
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toContent
+import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
+import org.matrix.android.sdk.api.session.room.model.GuestAccess
+import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
+
+interface RoomFeaturePreset {
+
+ fun updateRoomParams(params: CreateRoomParams)
+
+ fun setupInitialStates(): List?
+}
+
+class RestrictedRoomPreset(val homeServerCapabilities: HomeServerCapabilities, val restrictedList: List) : RoomFeaturePreset {
+
+ override fun updateRoomParams(params: CreateRoomParams) {
+ params.historyVisibility = params.historyVisibility ?: RoomHistoryVisibility.SHARED
+ params.guestAccess = params.guestAccess ?: GuestAccess.Forbidden
+ params.roomVersion = homeServerCapabilities.versionOverrideForFeature(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
+ }
+
+ override fun setupInitialStates(): List? {
+ return listOf(
+ Event(
+ type = EventType.STATE_ROOM_JOIN_RULES,
+ stateKey = "",
+ content = RoomJoinRulesContent(
+ _joinRules = RoomJoinRules.RESTRICTED.value,
+ allowList = restrictedList
+ ).toContent()
+ )
+ )
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioInfo.kt
index b72c8e5dfd..ea6bdfafad 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioInfo.kt
@@ -24,15 +24,15 @@ data class AudioInfo(
/**
* The mimetype of the audio e.g. "audio/aac".
*/
- @Json(name = "mimetype") val mimeType: String?,
+ @Json(name = "mimetype") val mimeType: String? = null,
/**
* The size of the audio clip in bytes.
*/
- @Json(name = "size") val size: Long = 0,
+ @Json(name = "size") val size: Long? = null,
/**
* The duration of the audio in milliseconds.
*/
- @Json(name = "duration") val duration: Int = 0
+ @Json(name = "duration") val duration: Int? = null
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioWaveformInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioWaveformInfo.kt
new file mode 100644
index 0000000000..d576f1057a
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/AudioWaveformInfo.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.model.message
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * See https://github.com/matrix-org/matrix-doc/blob/travis/msc/audio-waveform/proposals/3246-audio-waveform.md
+ */
+@JsonClass(generateAdapter = true)
+data class AudioWaveformInfo(
+ @Json(name = "duration")
+ val duration: Int? = null,
+
+ /**
+ * The array should have no less than 30 elements and no more than 120.
+ * List of integers between zero and 1024, inclusive.
+ */
+ @Json(name = "waveform")
+ val waveform: List? = null
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt
index fcf3d73cbe..1bcb10d88c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt
@@ -20,6 +20,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
+import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
@JsonClass(generateAdapter = true)
@@ -50,9 +51,19 @@ data class MessageAudioContent(
/**
* Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption.
*/
- @Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
+ @Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null,
+
+ /**
+ * Encapsulates waveform and duration of the audio.
+ */
+ @Json(name = "org.matrix.msc1767.audio") val audioWaveformInfo: AudioWaveformInfo? = null,
+
+ /**
+ * Indicates that is a voice message.
+ */
+ @Json(name = "org.matrix.msc3245.voice") val voiceMessageIndicator: JsonDict? = null
) : MessageWithAttachmentContent {
override val mimeType: String?
- get() = encryptedFileInfo?.mimetype ?: audioInfo?.mimeType
+ get() = audioInfo?.mimeType
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt
index d93f115322..96877b4d9f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt
@@ -60,8 +60,7 @@ data class MessageFileContent(
) : MessageWithAttachmentContent {
override val mimeType: String?
- get() = encryptedFileInfo?.mimetype
- ?: info?.mimeType
+ get() = info?.mimeType
?: MimeTypeMap.getFileExtensionFromUrl(filename ?: body)?.let { extension ->
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt
index 73e27b64e3..73fd1eab56 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt
@@ -20,7 +20,6 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
-import org.matrix.android.sdk.api.util.MimeTypes
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
@JsonClass(generateAdapter = true)
@@ -55,5 +54,5 @@ data class MessageImageContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageImageInfoContent {
override val mimeType: String?
- get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: MimeTypes.Images
+ get() = info?.mimeType
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt
index 280316d4b5..8e1d4d3d75 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt
@@ -55,5 +55,5 @@ data class MessageStickerContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageImageInfoContent {
override val mimeType: String?
- get() = encryptedFileInfo?.mimetype ?: info?.mimeType
+ get() = info?.mimeType
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt
index c96a800ee5..1e8959afc3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt
@@ -35,5 +35,5 @@ object MessageType {
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
const val MSGTYPE_CONFETTI = "nic.custom.confetti"
- const val MSGTYPE_SNOW = "io.element.effect.snowfall"
+ const val MSGTYPE_SNOWFALL = "io.element.effect.snowfall"
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt
index b7581c9fbf..3f5d2dab2e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt
@@ -53,5 +53,5 @@ data class MessageVideoContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageWithAttachmentContent {
override val mimeType: String?
- get() = encryptedFileInfo?.mimetype ?: videoInfo?.mimeType
+ get() = videoInfo?.mimeType
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt
index 888950dc12..b78cd5e032 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt
@@ -28,7 +28,8 @@ sealed class PeekResult {
val numJoinedMembers: Int?,
val roomType: String?,
val viaServers: List,
- val someMembers: List?
+ val someMembers: List?,
+ val isPublic: Boolean
) : PeekResult()
data class PeekingNotAllowed(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
index e614ea91d6..4d3f95233d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
@@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.api.util.Optional
@@ -53,7 +54,7 @@ interface StateService {
/**
* Update the join rule and/or the guest access
*/
- suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?)
+ suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?, allowList: List? = null)
/**
* Update the avatar of the room
@@ -91,4 +92,8 @@ interface StateService {
* @param eventTypes Set of eventType to observe. If empty, all state events will be observed
*/
fun getStateEventsLive(eventTypes: Set, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData>
+
+ suspend fun setJoinRulePublic()
+ suspend fun setJoinRuleInviteOnly()
+ suspend fun setJoinRuleRestricted(allowList: List)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt
new file mode 100644
index 0000000000..ea67b55174
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.room.version
+
+interface RoomVersionService {
+ /**
+ * Return the room version of this room
+ */
+ fun getRoomVersion(): String
+
+ /**
+ * Upgrade to the given room version
+ * @return the replacement room id
+ */
+ suspend fun upgradeToVersion(version: String): String
+
+ /**
+ * Get the recommended room version for the current homeserver
+ */
+ fun getRecommendedVersion() : String
+
+ /**
+ * Ask if the user has enough power level to upgrade the room
+ */
+ fun userMayUpgradeRoom(userId: String): Boolean
+
+ /**
+ * Return true if the current room version is declared unstable by the homeserver
+ */
+ fun isUsingUnstableRoomVersion(): Boolean
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt
index db25762c2f..3bae6126e0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.space
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.RoomSummary
+import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
interface Space {
@@ -38,6 +39,8 @@ interface Space {
autoJoin: Boolean = false,
suggested: Boolean? = false)
+ fun getChildInfo(roomId: String): SpaceChildContent?
+
suspend fun removeChildren(roomId: String)
@Throws
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceOrderUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceOrderUtils.kt
new file mode 100644
index 0000000000..844a5adcb4
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceOrderUtils.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.space
+
+import org.matrix.android.sdk.api.util.StringOrderUtils
+
+/**
+ * Adds some utilities to compute correct string orders when ordering spaces.
+ * After moving a space (e.g via DnD), client should limit the number of room account data update.
+ * For example if the space is moved between two other spaces with orders, just update the moved space order by computing
+ * a mid point between the surrounding orders.
+ * If the space is moved after a space with no order, all the previous spaces should be then ordered,
+ * and the computed orders should be chosen so that there is enough gaps in between them to facilitate future re-order.
+ * Re numbering (i.e change all spaces m.space.order account data) should be avoided as much as possible,
+ * as the updates might not be atomic for other clients and would makes spaces jump around.
+ */
+object SpaceOrderUtils {
+
+ data class SpaceReOrderCommand(
+ val spaceId: String,
+ val order: String
+ )
+
+ /**
+ * Returns a minimal list of order change in order to re order the space list as per given move.
+ */
+ fun orderCommandsForMove(orderedSpacesToOrderMap: List>, movedSpaceId: String, delta: Int): List {
+ val movedIndex = orderedSpacesToOrderMap.indexOfFirst { it.first == movedSpaceId }
+ if (movedIndex == -1) return emptyList()
+ if (delta == 0) return emptyList()
+
+ val targetIndex = if (delta > 0) movedIndex + delta else (movedIndex + delta - 1)
+
+ val nodesToReNumber = mutableListOf()
+ var lowerBondOrder: String? = null
+ var index = targetIndex
+ while (index >= 0 && lowerBondOrder == null) {
+ val node = orderedSpacesToOrderMap.getOrNull(index)
+ if (node != null /*null when adding at the end*/) {
+ val nodeOrder = node.second
+ if (node.first == movedSpaceId) break
+ if (nodeOrder == null) {
+ nodesToReNumber.add(0, node.first)
+ } else {
+ lowerBondOrder = nodeOrder
+ }
+ }
+ index--
+ }
+ nodesToReNumber.add(movedSpaceId)
+ val afterSpace: Pair? = if (orderedSpacesToOrderMap.indices.contains(targetIndex + 1)) {
+ orderedSpacesToOrderMap[targetIndex + 1]
+ } else null
+
+ val defaultMaxOrder = CharArray(4) { StringOrderUtils.DEFAULT_ALPHABET.last() }
+ .joinToString("")
+
+ val defaultMinOrder = CharArray(4) { StringOrderUtils.DEFAULT_ALPHABET.first() }
+ .joinToString("")
+
+ val afterOrder = afterSpace?.second ?: defaultMaxOrder
+
+ val beforeOrder = lowerBondOrder ?: defaultMinOrder
+
+ val newOrder = StringOrderUtils.midPoints(beforeOrder, afterOrder, nodesToReNumber.size)
+
+ if (newOrder.isNullOrEmpty()) {
+ // re order all?
+ val expectedList = orderedSpacesToOrderMap.toMutableList()
+ expectedList.removeAt(movedIndex).let {
+ expectedList.add(movedIndex + delta, it)
+ }
+
+ return StringOrderUtils.midPoints(defaultMinOrder, defaultMaxOrder, orderedSpacesToOrderMap.size)?.let { orders ->
+ expectedList.mapIndexed { index, pair ->
+ SpaceReOrderCommand(
+ pair.first,
+ orders[index]
+ )
+ }
+ } ?: emptyList()
+ } else {
+ return nodesToReNumber.mapIndexed { i, s ->
+ SpaceReOrderCommand(
+ s,
+ newOrder[i]
+ )
+ }
+ }
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt
index fedf38fe06..e5288e4045 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt
@@ -36,7 +36,11 @@ interface SpaceService {
/**
* Just a shortcut for space creation for ease of use
*/
- suspend fun createSpace(name: String, topic: String?, avatarUri: Uri?, isPublic: Boolean): String
+ suspend fun createSpace(name: String,
+ topic: String?,
+ avatarUri: Uri?,
+ isPublic: Boolean,
+ roomAliasLocalPart: String? = null): String
/**
* Get a space from a roomId
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/SpaceOrderContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/SpaceOrderContent.kt
new file mode 100644
index 0000000000..a8578347c8
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/SpaceOrderContent.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.space.model
+
+import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.MatrixPatterns
+
+/**
+ * {
+ * "type": "m.space_order",
+ * "content": {
+ * "order": "..."
+ * }
+ * }
+ */
+@JsonClass(generateAdapter = true)
+data class SpaceOrderContent(
+ val order: String? = null
+) {
+ fun safeOrder(): String? {
+ return order?.takeIf { MatrixPatterns.isValidOrderString(it) }
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/TopLevelSpaceComparator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/TopLevelSpaceComparator.kt
new file mode 100644
index 0000000000..8af4f3a149
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/model/TopLevelSpaceComparator.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.session.space.model
+
+import org.matrix.android.sdk.api.session.room.model.RoomSummary
+
+// Can't use regular compare by because Null is considered less than any value, and for space order it's the opposite
+class TopLevelSpaceComparator(val orders: Map) : Comparator {
+
+ override fun compare(left: RoomSummary?, right: RoomSummary?): Int {
+ val leftOrder = left?.roomId?.let { orders[it] }
+ val rightOrder = right?.roomId?.let { orders[it] }
+ return if (leftOrder != null && rightOrder != null) {
+ leftOrder.compareTo(rightOrder)
+ } else {
+ if (leftOrder == null) {
+ if (rightOrder == null) {
+ compareValues(left?.roomId, right?.roomId)
+ } else {
+ 1
+ }
+ } else {
+ -1
+ }
+ }
+// .also {
+// Timber.w("VAL: compare(${left?.displayName} | $leftOrder ,${right?.displayName} | $rightOrder) = $it")
+// }
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt
index d77dfcfe35..246813a524 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt
@@ -22,16 +22,16 @@ import org.matrix.android.sdk.api.util.JsonDict
@JsonClass(generateAdapter = true)
data class ThirdPartyUser(
- /*
- Required. A Matrix User ID represting a third party user.
+ /**
+ * Required. A Matrix User ID representing a third party user.
*/
@Json(name = "userid") val userId: String,
- /*
- Required. The protocol ID that the third party location is a part of.
+ /**
+ * Required. The protocol ID that the third party location is a part of.
*/
@Json(name = "protocol") val protocol: String,
- /*
- Required. Information used to identify this third party location.
+ /**
+ * Required. Information used to identify this third party location.
*/
@Json(name = "fields") val fields: JsonDict
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt
index 3bf3f66e40..3d2773fb4b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt
@@ -20,6 +20,7 @@ import org.matrix.android.sdk.BuildConfig
import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
+import org.matrix.android.sdk.api.session.room.model.RoomType
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
@@ -38,6 +39,8 @@ sealed class MatrixItem(
init {
if (BuildConfig.DEBUG) checkId()
}
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
}
data class EventItem(override val id: String,
@@ -47,6 +50,8 @@ sealed class MatrixItem(
init {
if (BuildConfig.DEBUG) checkId()
}
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
}
data class RoomItem(override val id: String,
@@ -56,6 +61,19 @@ sealed class MatrixItem(
init {
if (BuildConfig.DEBUG) checkId()
}
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
+ }
+
+ data class SpaceItem(override val id: String,
+ override val displayName: String? = null,
+ override val avatarUrl: String? = null)
+ : MatrixItem(id, displayName, avatarUrl) {
+ init {
+ if (BuildConfig.DEBUG) checkId()
+ }
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
}
data class RoomAliasItem(override val id: String,
@@ -68,6 +86,8 @@ sealed class MatrixItem(
// Best name is the id, and we keep the displayName of the room for the case we need the first letter
override fun getBestName() = id
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
}
data class GroupItem(override val id: String,
@@ -80,6 +100,8 @@ sealed class MatrixItem(
// Best name is the id, and we keep the displayName of the room for the case we need the first letter
override fun getBestName() = id
+
+ override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
}
open fun getBestName(): String {
@@ -92,12 +114,15 @@ sealed class MatrixItem(
}
}
+ abstract fun updateAvatar(newAvatar: String?): MatrixItem
+
/**
* Return the prefix as defined in the matrix spec (and not extracted from the id)
*/
fun getIdPrefix() = when (this) {
is UserItem -> '@'
is EventItem -> '$'
+ is SpaceItem,
is RoomItem -> '!'
is RoomAliasItem -> '#'
is GroupItem -> '+'
@@ -148,7 +173,11 @@ fun User.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
fun GroupSummary.toMatrixItem() = MatrixItem.GroupItem(groupId, displayName, avatarUrl)
-fun RoomSummary.toMatrixItem() = MatrixItem.RoomItem(roomId, displayName, avatarUrl)
+fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) {
+ MatrixItem.SpaceItem(roomId, displayName, avatarUrl)
+} else {
+ MatrixItem.RoomItem(roomId, displayName, avatarUrl)
+}
fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl)
@@ -159,4 +188,8 @@ fun RoomMemberSummary.toMatrixItem() = MatrixItem.UserItem(userId, displayName,
fun SenderInfo.toMatrixItem() = MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl)
-fun SpaceChildInfo.toMatrixItem() = MatrixItem.RoomItem(childRoomId, name, avatarUrl)
+fun SpaceChildInfo.toMatrixItem() = if (roomType == RoomType.SPACE) {
+ MatrixItem.SpaceItem(childRoomId, name ?: canonicalAlias, avatarUrl)
+} else {
+ MatrixItem.RoomItem(childRoomId, name ?: canonicalAlias, avatarUrl)
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt
index 182b37f2ad..ef47775f1b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt
@@ -31,6 +31,8 @@ object MimeTypes {
const val Jpeg = "image/jpeg"
const val Gif = "image/gif"
+ const val Ogg = "audio/ogg"
+
fun String?.normalizeMimeType() = if (this == BadJpg) Jpeg else this
fun String?.isMimeTypeImage() = this?.startsWith("image/").orFalse()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt
new file mode 100644
index 0000000000..83c8585941
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.api.util
+
+import java.math.BigInteger
+
+object StringOrderUtils {
+
+ val DEFAULT_ALPHABET = buildString {
+ for (i in 0x20..0x7E) {
+ append(Char(i))
+ }
+ }.toCharArray()
+
+ // /=Range(0x20, 0x7E)
+
+ fun average(left: String, right: String, alphabet: CharArray = DEFAULT_ALPHABET): String? {
+ return midPoints(left, right, 1, alphabet)?.firstOrNull()
+ }
+
+ fun midPoints(left: String, right: String, count: Int, alphabet: CharArray = DEFAULT_ALPHABET): List? {
+ if (left == right) return null // no space in between..
+ if (left > right) return midPoints(right, left, count, alphabet)
+ val size = maxOf(left.length, right.length)
+ val leftPadded = pad(left, size, alphabet.first())
+ val rightPadded = pad(right, size, alphabet.first())
+ val b1 = stringToBase(leftPadded, alphabet)
+ val b2 = stringToBase(rightPadded, alphabet)
+ val step = (b2.minus(b1)).div(BigInteger("${count + 1}"))
+ val orders = mutableListOf()
+ var previous = left
+ for (i in 0 until count) {
+ val newOrder = baseToString(b1.add(step.multiply(BigInteger("${i + 1}"))), alphabet)
+ orders.add(newOrder)
+ // ensure there was enought precision
+ if (previous >= newOrder) return null
+ previous = newOrder
+ }
+ return orders.takeIf { orders.last() < right }
+ }
+
+ private fun pad(string: String, size: Int, padding: Char): String {
+ val raw = string.toCharArray()
+ return CharArray(size).also {
+ for (index in it.indices) {
+ if (index < raw.size) {
+ it[index] = raw[index]
+ } else {
+ it[index] = padding
+ }
+ }
+ }.joinToString("")
+ }
+
+ fun baseToString(x: BigInteger, alphabet: CharArray): String {
+ val len = alphabet.size.toBigInteger()
+ if (x < len) {
+ return alphabet[x.toInt()].toString()
+ } else {
+ return baseToString(x.div(len), alphabet) + alphabet[x.rem(len).toInt()].toString()
+ }
+ }
+
+ fun stringToBase(x: String, alphabet: CharArray): BigInteger {
+ if (x.isEmpty()) throw IllegalArgumentException()
+ val len = alphabet.size.toBigInteger()
+ var result = BigInteger("0")
+ x.reversed().forEachIndexed { index, c ->
+ result += (alphabet.indexOf(c).toBigInteger() * len.pow(index))
+ }
+ return result
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt
index 441232f57f..c746ad863a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt
@@ -51,7 +51,7 @@ internal class SessionManager @Inject constructor(private val matrixComponent: M
}
}
- private fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
+ fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
return sessionComponents.getOrPut(sessionParams.credentials.sessionId()) {
DaggerSessionComponent
.factory()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
index f93f285c6e..50d9e5a06c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
@@ -17,11 +17,12 @@
package org.matrix.android.sdk.internal.auth
import org.matrix.android.sdk.api.auth.data.Credentials
+import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.auth.data.Availability
import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
import org.matrix.android.sdk.internal.auth.data.PasswordLoginParams
-import org.matrix.android.sdk.internal.auth.data.RiotConfig
import org.matrix.android.sdk.internal.auth.data.TokenLoginParams
+import org.matrix.android.sdk.internal.auth.data.WebClientConfig
import org.matrix.android.sdk.internal.auth.login.ResetPasswordMailConfirmed
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationResponse
@@ -43,16 +44,16 @@ import retrofit2.http.Url
*/
internal interface AuthAPI {
/**
- * Get a Riot config file, using the name including the domain
+ * Get a Web client config file, using the name including the domain
*/
@GET("config.{domain}.json")
- suspend fun getRiotConfigDomain(@Path("domain") domain: String): RiotConfig
+ suspend fun getWebClientConfigDomain(@Path("domain") domain: String): WebClientConfig
/**
- * Get a Riot config file
+ * Get a Web client default config file
*/
@GET("config.json")
- suspend fun getRiotConfig(): RiotConfig
+ suspend fun getWebClientConfig(): WebClientConfig
/**
* Get the version information of the homeserver
@@ -73,6 +74,15 @@ internal interface AuthAPI {
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "register/available")
suspend fun registerAvailable(@Query("username") username: String): Availability
+ /**
+ * Get the combined profile information for this user.
+ * This API may be used to fetch the user's own profile information or other users; either locally or on remote homeservers.
+ * This API may return keys which are not limited to displayname or avatar_url.
+ * @param userId the user id to fetch profile info
+ */
+ @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "profile/{userId}")
+ suspend fun getProfile(@Path("userId") userId: String): JsonDict
+
/**
* Add 3Pid during registration
* Ref: https://gist.github.com/jryans/839a09bf0c5a70e2f36ed990d50ed928
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt
index e0c52cf9ca..3742a429d2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt
@@ -33,7 +33,6 @@ internal const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/"
* Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login
*/
internal const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect"
-internal const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect"
internal const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
index 46256f4b81..e76dc28734 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
@@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.auth
import android.net.Uri
import dagger.Lazy
import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.MatrixPatterns
+import org.matrix.android.sdk.api.MatrixPatterns.getDomain
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
@@ -28,10 +30,11 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
import org.matrix.android.sdk.api.failure.Failure
+import org.matrix.android.sdk.api.failure.MatrixIdFailure
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.util.appendParamToUrl
import org.matrix.android.sdk.internal.SessionManager
-import org.matrix.android.sdk.internal.auth.data.RiotConfig
+import org.matrix.android.sdk.internal.auth.data.WebClientConfig
import org.matrix.android.sdk.internal.auth.db.PendingSessionData
import org.matrix.android.sdk.internal.auth.login.DefaultLoginWizard
import org.matrix.android.sdk.internal.auth.login.DirectLoginTask
@@ -88,11 +91,9 @@ internal class DefaultAuthenticationService @Inject constructor(
return buildString {
append(homeServerUrlBase)
+ append(SSO_REDIRECT_PATH)
if (providerId != null) {
- append(MSC2858_SSO_REDIRECT_PATH)
append("/$providerId")
- } else {
- append(SSO_REDIRECT_PATH)
}
// Set the redirect url
appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl)
@@ -124,7 +125,7 @@ internal class DefaultAuthenticationService @Inject constructor(
private fun getHomeServerUrlBase(): String? {
return pendingSessionData
?.homeServerConnectionConfig
- ?.homeServerUri
+ ?.homeServerUriBase
?.toString()
?.trim { it == '/' }
}
@@ -145,9 +146,9 @@ internal class DefaultAuthenticationService @Inject constructor(
return result.fold(
{
// The homeserver exists and up to date, keep the config
- // Homeserver url may have been changed, if it was a Riot url
+ // Homeserver url may have been changed, if it was a Web client url
val alteredHomeServerConnectionConfig = homeServerConnectionConfig.copy(
- homeServerUri = Uri.parse(it.homeServerUrl)
+ homeServerUriBase = Uri.parse(it.homeServerUrl)
)
pendingSessionData = PendingSessionData(alteredHomeServerConnectionConfig)
@@ -156,7 +157,7 @@ internal class DefaultAuthenticationService @Inject constructor(
},
{
if (it is UnrecognizedCertificateException) {
- throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUri.toString(), it.fingerprint)
+ throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUriBase.toString(), it.fingerprint)
} else {
throw it
}
@@ -167,46 +168,57 @@ internal class DefaultAuthenticationService @Inject constructor(
private suspend fun getLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
- // First check the homeserver version
- return runCatching {
- executeRequest(null) {
- authAPI.versions()
+ // First check if there is a well-known file
+ return try {
+ getWellknownLoginFlowInternal(homeServerConnectionConfig)
+ } catch (failure: Throwable) {
+ if (failure is Failure.OtherServerError
+ && failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
+ // 404, no well-known data, try direct access to the API
+ // First check the homeserver version
+ return runCatching {
+ executeRequest(null) {
+ authAPI.versions()
+ }
+ }
+ .map { versions ->
+ // Ok, it seems that the homeserver url is valid
+ getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUriBase.toString())
+ }
+ .fold(
+ {
+ it
+ },
+ {
+ if (it is Failure.OtherServerError
+ && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
+ // It's maybe a Web client url?
+ getWebClientDomainLoginFlowInternal(homeServerConnectionConfig)
+ } else {
+ throw it
+ }
+ }
+ )
+ } else {
+ throw failure
}
}
- .map { versions ->
- // Ok, it seems that the homeserver url is valid
- getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUri.toString())
- }
- .fold(
- {
- it
- },
- {
- if (it is Failure.OtherServerError
- && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
- // It's maybe a Riot url?
- getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
- } else {
- throw it
- }
- }
- )
}
- private suspend fun getRiotDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
+ private suspend fun getWebClientDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
val domain = homeServerConnectionConfig.homeServerUri.host
- ?: return getRiotLoginFlowInternal(homeServerConnectionConfig)
+ ?: return getWebClientLoginFlowInternal(homeServerConnectionConfig)
- // Ok, try to get the config.domain.json file of a RiotWeb client
+ // Ok, try to get the config.domain.json file of a Web client
return runCatching {
executeRequest(null) {
- authAPI.getRiotConfigDomain(domain)
+ authAPI.getWebClientConfigDomain(domain)
}
}
- .map { riotConfig ->
- onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
+ .map { webClientConfig ->
+ onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
}
.fold(
{
@@ -216,7 +228,7 @@ internal class DefaultAuthenticationService @Inject constructor(
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// Try with config.json
- getRiotLoginFlowInternal(homeServerConnectionConfig)
+ getWebClientLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
@@ -224,40 +236,24 @@ internal class DefaultAuthenticationService @Inject constructor(
)
}
- private suspend fun getRiotLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
+ private suspend fun getWebClientLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
- // Ok, try to get the config.json file of a RiotWeb client
- return runCatching {
- executeRequest(null) {
- authAPI.getRiotConfig()
- }
+ // Ok, try to get the config.json file of a Web client
+ return executeRequest(null) {
+ authAPI.getWebClientConfig()
}
- .map { riotConfig ->
- onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
+ .let { webClientConfig ->
+ onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
}
- .fold(
- {
- it
- },
- {
- if (it is Failure.OtherServerError
- && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
- // Try with wellknown
- getWellknownLoginFlowInternal(homeServerConnectionConfig)
- } else {
- throw it
- }
- }
- )
}
- private suspend fun onRiotConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, riotConfig: RiotConfig): LoginFlowResult {
- val defaultHomeServerUrl = riotConfig.getPreferredHomeServerUrl()
+ private suspend fun onWebClientConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, webClientConfig: WebClientConfig): LoginFlowResult {
+ val defaultHomeServerUrl = webClientConfig.getPreferredHomeServerUrl()
if (defaultHomeServerUrl?.isNotEmpty() == true) {
// Ok, good sign, we got a default hs url
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
- homeServerUri = Uri.parse(defaultHomeServerUrl)
+ homeServerUriBase = Uri.parse(defaultHomeServerUrl)
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
@@ -277,15 +273,13 @@ internal class DefaultAuthenticationService @Inject constructor(
val domain = homeServerConnectionConfig.homeServerUri.host
?: throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
- // Create a fake userId, for the getWellknown task
- val fakeUserId = "@alice:$domain"
- val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(fakeUserId, homeServerConnectionConfig))
+ val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(domain, homeServerConnectionConfig))
return when (wellknownResult) {
is WellknownResult.Prompt -> {
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
- homeServerUri = Uri.parse(wellknownResult.homeServerUrl),
- identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) }
+ homeServerUriBase = Uri.parse(wellknownResult.homeServerUrl),
+ identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) } ?: homeServerConnectionConfig.identityServerUri
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
@@ -381,7 +375,14 @@ internal class DefaultAuthenticationService @Inject constructor(
override suspend fun getWellKnownData(matrixId: String,
homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult {
- return getWellknownTask.execute(GetWellknownTask.Params(matrixId, homeServerConnectionConfig))
+ if (!MatrixPatterns.isUserId(matrixId)) {
+ throw MatrixIdFailure.InvalidMatrixId
+ }
+
+ return getWellknownTask.execute(GetWellknownTask.Params(
+ domain = matrixId.getDomain(),
+ homeServerConnectionConfig = homeServerConnectionConfig)
+ )
}
override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
@@ -392,7 +393,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
- val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUri.toString())
+ val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUriBase.toString())
return retrofit.create(AuthAPI::class.java)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt
index 867cf46b8d..bc3d887000 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt
@@ -42,7 +42,7 @@ internal class DefaultIsValidClientServerApiTask @Inject constructor(
override suspend fun execute(params: IsValidClientServerApiTask.Params): Boolean {
val client = buildClient(params.homeServerConnectionConfig)
- val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
+ val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
val authAPI = retrofitFactory.create(client, homeServerUrl)
.create(AuthAPI::class.java)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
index 7c4a0c38ec..cc00c963ea 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
@@ -38,7 +38,7 @@ internal class DefaultSessionCreator @Inject constructor(
) : SessionCreator {
/**
- * Credentials can affect the homeServerConnectionConfig, override home server url and/or
+ * Credentials can affect the homeServerConnectionConfig, override homeserver url and/or
* identity server url if provided in the credentials
*/
override suspend fun createSession(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session {
@@ -49,6 +49,8 @@ internal class DefaultSessionCreator @Inject constructor(
// remove trailing "/"
?.trim { it == '/' }
?.takeIf { it.isNotBlank() }
+ // It can be the same value, so in this case, do not check again the validity
+ ?.takeIf { it != homeServerConnectionConfig.homeServerUriBase.toString() }
?.also { Timber.d("Overriding homeserver url to $it (will check if valid)") }
?.let { Uri.parse(it) }
?.takeIf {
@@ -56,7 +58,7 @@ internal class DefaultSessionCreator @Inject constructor(
tryOrNull {
isValidClientServerApiTask.execute(
IsValidClientServerApiTask.Params(
- homeServerConnectionConfig.copy(homeServerUri = it)
+ homeServerConnectionConfig.copy(homeServerUriBase = it)
)
)
.also { Timber.d("Overriding homeserver url: $it") }
@@ -66,7 +68,7 @@ internal class DefaultSessionCreator @Inject constructor(
val sessionParams = SessionParams(
credentials = credentials,
homeServerConnectionConfig = homeServerConnectionConfig.copy(
- homeServerUri = overriddenUrl ?: homeServerConnectionConfig.homeServerUri,
+ homeServerUriBase = overriddenUrl ?: homeServerConnectionConfig.homeServerUriBase,
identityServerUri = credentials.discoveryInformation?.identityServer?.baseURL
// remove trailing "/"
?.trim { it == '/' }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
index d0d17e2cd5..c718fae390 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt
@@ -42,7 +42,7 @@ internal data class LoginFlow(
* the client can show a button for each of the supported providers
* See MSC #2858
*/
- @Json(name = "org.matrix.msc2858.identity_providers")
+ @Json(name = "identity_providers")
val ssoIdentityProvider: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/RiotConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/WebClientConfig.kt
similarity index 84%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/RiotConfig.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/WebClientConfig.kt
index e61358a67b..65c3dc64a6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/RiotConfig.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/WebClientConfig.kt
@@ -20,7 +20,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
-internal data class RiotConfig(
+internal data class WebClientConfig(
/**
* This is now deprecated, but still used first, rather than value from "default_server_config"
*/
@@ -28,7 +28,7 @@ internal data class RiotConfig(
val defaultHomeServerUrl: String?,
@Json(name = "default_server_config")
- val defaultServerConfig: RiotConfigDefaultServerConfig?
+ val defaultServerConfig: WebClientConfigDefaultServerConfig?
) {
fun getPreferredHomeServerUrl(): String? {
return defaultHomeServerUrl
@@ -38,13 +38,13 @@ internal data class RiotConfig(
}
@JsonClass(generateAdapter = true)
-internal data class RiotConfigDefaultServerConfig(
+internal data class WebClientConfigDefaultServerConfig(
@Json(name = "m.homeserver")
- val homeServer: RiotConfigBaseConfig? = null
+ val homeServer: WebClientConfigBaseConfig? = null
)
@JsonClass(generateAdapter = true)
-internal data class RiotConfigBaseConfig(
+internal data class WebClientConfigBaseConfig(
@Json(name = "base_url")
val baseURL: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt
index bb2667228b..c2104690b3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt
@@ -16,17 +16,19 @@
package org.matrix.android.sdk.internal.auth.db
-import org.matrix.android.sdk.api.auth.data.Credentials
-import org.matrix.android.sdk.api.auth.data.sessionId
-import org.matrix.android.sdk.internal.di.MoshiProvider
+import android.net.Uri
import io.realm.DynamicRealm
import io.realm.RealmMigration
+import org.matrix.android.sdk.api.auth.data.Credentials
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+import org.matrix.android.sdk.api.auth.data.sessionId
+import org.matrix.android.sdk.internal.di.MoshiProvider
import timber.log.Timber
internal object AuthRealmMigration : RealmMigration {
// Current schema version
- const val SCHEMA_VERSION = 3L
+ const val SCHEMA_VERSION = 4L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.d("Migrating Auth Realm from $oldVersion to $newVersion")
@@ -34,6 +36,7 @@ internal object AuthRealmMigration : RealmMigration {
if (oldVersion <= 0) migrateTo1(realm)
if (oldVersion <= 1) migrateTo2(realm)
if (oldVersion <= 2) migrateTo3(realm)
+ if (oldVersion <= 3) migrateTo4(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@@ -81,4 +84,34 @@ internal object AuthRealmMigration : RealmMigration {
}
?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID)
}
+
+ private fun migrateTo4(realm: DynamicRealm) {
+ Timber.d("Step 3 -> 4")
+ Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value")
+
+ val adapter = MoshiProvider.providesMoshi()
+ .adapter(HomeServerConnectionConfig::class.java)
+
+ realm.schema.get("SessionParamsEntity")
+ ?.transform {
+ val homeserverConnectionConfigJson = it.getString(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON)
+
+ val homeserverConnectionConfig = adapter
+ .fromJson(homeserverConnectionConfigJson)
+
+ val homeserverUrl = homeserverConnectionConfig?.homeServerUri?.toString()
+ // Special case for matrix.org. Old session may use "https://matrix.org", newer one may use
+ // "https://matrix-client.matrix.org". So fix that here
+ val alteredHomeserverConnectionConfig =
+ if (homeserverUrl == "https://matrix.org" || homeserverUrl == "https://matrix-client.matrix.org") {
+ homeserverConnectionConfig.copy(
+ homeServerUri = Uri.parse("https://matrix.org"),
+ homeServerUriBase = Uri.parse("https://matrix-client.matrix.org")
+ )
+ } else {
+ homeserverConnectionConfig
+ }
+ it.set(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, adapter.toJson(alteredHomeserverConnectionConfig))
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
index 8b81f42e03..854caf8a62 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
@@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.auth.login
import android.util.Patterns
+import org.matrix.android.sdk.api.auth.login.LoginProfileInfo
import org.matrix.android.sdk.api.auth.login.LoginWizard
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
import org.matrix.android.sdk.api.session.Session
@@ -30,6 +31,7 @@ import org.matrix.android.sdk.internal.auth.db.PendingSessionData
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
import org.matrix.android.sdk.internal.auth.registration.RegisterAddThreePidTask
import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.session.content.DefaultContentUrlResolver
internal class DefaultLoginWizard(
private val authAPI: AuthAPI,
@@ -39,6 +41,15 @@ internal class DefaultLoginWizard(
private var pendingSessionData: PendingSessionData = pendingSessionStore.getPendingSessionData() ?: error("Pending session data should exist here")
+ private val getProfileTask: GetProfileTask = DefaultGetProfileTask(
+ authAPI,
+ DefaultContentUrlResolver(pendingSessionData.homeServerConnectionConfig)
+ )
+
+ override suspend fun getProfileInfo(matrixId: String): LoginProfileInfo {
+ return getProfileTask.execute(GetProfileTask.Params(matrixId))
+ }
+
override suspend fun login(login: String,
password: String,
deviceName: String): Session {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt
index 77bbb8096f..3888633723 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt
@@ -50,7 +50,7 @@ internal class DefaultDirectLoginTask @Inject constructor(
override suspend fun execute(params: DirectLoginTask.Params): Session {
val client = buildClient(params.homeServerConnectionConfig)
- val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
+ val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
val authAPI = retrofitFactory.create(client, homeServerUrl)
.create(AuthAPI::class.java)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/GetProfileTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/GetProfileTask.kt
new file mode 100644
index 0000000000..bb9faf49c4
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/GetProfileTask.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.auth.login
+
+import org.matrix.android.sdk.api.auth.login.LoginProfileInfo
+import org.matrix.android.sdk.api.session.content.ContentUrlResolver
+import org.matrix.android.sdk.api.session.profile.ProfileService
+import org.matrix.android.sdk.internal.auth.AuthAPI
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+
+internal interface GetProfileTask : Task {
+ data class Params(
+ val userId: String
+ )
+}
+
+internal class DefaultGetProfileTask(
+ private val authAPI: AuthAPI,
+ private val contentUrlResolver: ContentUrlResolver
+) : GetProfileTask {
+
+ override suspend fun execute(params: GetProfileTask.Params): LoginProfileInfo {
+ val info = executeRequest(null) {
+ authAPI.getProfile(params.userId)
+ }
+
+ return LoginProfileInfo(
+ matrixId = params.userId,
+ displayName = info[ProfileService.DISPLAY_NAME_KEY] as? String,
+ fullAvatarUrl = contentUrlResolver.resolveFullSize(info[ProfileService.AVATAR_URL_KEY] as? String)
+ )
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
index e114f86a99..84d4fef5af 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
@@ -112,7 +112,6 @@ internal abstract class CryptoModule {
@SessionScope
fun providesRealmConfiguration(@SessionFilesDirectory directory: File,
@UserMd5 userMd5: String,
- realmCryptoStoreMigration: RealmCryptoStoreMigration,
realmKeysUtils: RealmKeysUtils): RealmConfiguration {
return RealmConfiguration.Builder()
.directory(directory)
@@ -123,7 +122,7 @@ internal abstract class CryptoModule {
.modules(RealmCryptoStoreModule())
.allowWritesOnUiThread(true)
.schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
- .migration(realmCryptoStoreMigration)
+ .migration(RealmCryptoStoreMigration)
.build()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
index 7f5cfe8df1..563c890950 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
@@ -314,6 +314,12 @@ internal class DefaultCryptoService @Inject constructor(
cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) {
// Open the store
cryptoStore.open()
+
+ if (!cryptoStore.areDeviceKeysUploaded()) {
+ // Schedule upload of OTK
+ oneTimeKeysUploader.updateOneTimeKeyCount(0)
+ }
+
// this can throw if no network
tryOrNull {
uploadDeviceKeys()
@@ -388,7 +394,7 @@ internal class DefaultCryptoService @Inject constructor(
cryptoStore.close()
}
- // Aways enabled on RiotX
+ // Always enabled on Matrix Android SDK2
override fun isCryptoEnabled() = true
/**
@@ -905,7 +911,7 @@ internal class DefaultCryptoService @Inject constructor(
* Upload my user's device keys.
*/
private suspend fun uploadDeviceKeys() {
- if (cryptoStore.getDeviceKeysUploaded()) {
+ if (cryptoStore.areDeviceKeysUploaded()) {
Timber.d("Keys already uploaded, nothing to do")
return
}
@@ -928,14 +934,10 @@ internal class DefaultCryptoService @Inject constructor(
* Export the crypto keys
*
* @param password the password
- * @param callback the exported keys
+ * @return the exported keys
*/
- override fun exportRoomKeys(password: String, callback: MatrixCallback) {
- cryptoCoroutineScope.launch(coroutineDispatchers.main) {
- runCatching {
- exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT)
- }.foldToCallback(callback)
- }
+ override suspend fun exportRoomKeys(password: String): ByteArray {
+ return exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT)
}
/**
@@ -963,42 +965,37 @@ internal class DefaultCryptoService @Inject constructor(
* @param roomKeysAsArray the room keys as array.
* @param password the password
* @param progressListener the progress listener
- * @param callback the asynchronous callback.
+ * @return the result ImportRoomKeysResult
*/
- override fun importRoomKeys(roomKeysAsArray: ByteArray,
- password: String,
- progressListener: ProgressListener?,
- callback: MatrixCallback) {
- cryptoCoroutineScope.launch(coroutineDispatchers.main) {
- runCatching {
- withContext(coroutineDispatchers.crypto) {
- Timber.v("## CRYPTO | importRoomKeys starts")
+ override suspend fun importRoomKeys(roomKeysAsArray: ByteArray,
+ password: String,
+ progressListener: ProgressListener?): ImportRoomKeysResult {
+ return withContext(coroutineDispatchers.crypto) {
+ Timber.v("## CRYPTO | importRoomKeys starts")
- val t0 = System.currentTimeMillis()
- val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password)
- val t1 = System.currentTimeMillis()
+ val t0 = System.currentTimeMillis()
+ val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password)
+ val t1 = System.currentTimeMillis()
- Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms")
+ Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms")
- val importedSessions = MoshiProvider.providesMoshi()
- .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java))
- .fromJson(roomKeys)
+ val importedSessions = MoshiProvider.providesMoshi()
+ .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java))
+ .fromJson(roomKeys)
- val t2 = System.currentTimeMillis()
+ val t2 = System.currentTimeMillis()
- Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms")
+ Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms")
- if (importedSessions == null) {
- throw Exception("Error")
- }
+ if (importedSessions == null) {
+ throw Exception("Error")
+ }
- megolmSessionDataImporter.handle(
- megolmSessionsData = importedSessions,
- fromBackup = false,
- progressListener = progressListener
- )
- }
- }.foldToCallback(callback)
+ megolmSessionDataImporter.handle(
+ megolmSessionsData = importedSessions,
+ fromBackup = false,
+ progressListener = progressListener
+ )
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt
index 63f15aaf6e..79910c6de2 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt
@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.crypto
+import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.auth.data.Credentials
@@ -336,7 +337,12 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
downloadKeysForUsersTask.execute(params)
} catch (throwable: Throwable) {
Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error")
- onKeysDownloadFailed(filteredUsers)
+ if (throwable is CancellationException) {
+ // the crypto module is getting closed, so we cannot access the DB anymore
+ Timber.w("The crypto module is closed, ignoring this error")
+ } else {
+ onKeysDownloadFailed(filteredUsers)
+ }
throw throwable
}
Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt
index 6695234d62..c4b62fe9fe 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt
@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.crypto
+import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.internal.crypto.model.MXKey
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
@@ -77,6 +78,10 @@ internal class OneTimeKeysUploader @Inject constructor(
// discard the oldest private keys first. This will eventually clean
// out stale private keys that won't receive a message.
val keyLimit = floor(maxOneTimeKeys / 2.0).toInt()
+ if (oneTimeKeyCount == null) {
+ // Ask the server how many otk he has
+ oneTimeKeyCount = fetchOtkCount()
+ }
val oneTimeKeyCountFromSync = oneTimeKeyCount
if (oneTimeKeyCountFromSync != null) {
// We need to keep a pool of one time public keys on the server so that
@@ -90,17 +95,22 @@ internal class OneTimeKeysUploader @Inject constructor(
// private keys clogging up our local storage.
// So we need some kind of engineering compromise to balance all of
// these factors.
- try {
+ tryOrNull("Unable to upload OTK") {
val uploadedKeys = uploadOTK(oneTimeKeyCountFromSync, keyLimit)
Timber.v("## uploadKeys() : success, $uploadedKeys key(s) sent")
- } finally {
- oneTimeKeyCheckInProgress = false
}
} else {
Timber.w("maybeUploadOneTimeKeys: waiting to know the number of OTK from the sync")
- oneTimeKeyCheckInProgress = false
lastOneTimeKeyCheck = 0
}
+ oneTimeKeyCheckInProgress = false
+ }
+
+ private suspend fun fetchOtkCount(): Int? {
+ return tryOrNull("Unable to get OTK count") {
+ val result = uploadKeysTask.execute(UploadKeysTask.Params(null, null))
+ result.oneTimeKeyCountsForAlgorithm(MXKey.KEY_SIGNED_CURVE_25519_TYPE)
+ }
}
/**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
index a29ac457fb..70d2022299 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
@@ -155,7 +155,7 @@ internal class MXMegolmDecryption(private val userId: String,
withHeldInfo.code?.value ?: "",
withHeldInfo.reason)
} else {
- // This is un-used in riotX SDK, not sure if needed
+ // This is un-used in Matrix Android SDK2, not sure if needed
// addEventToPendingList(event, timeline)
if (requestKeysOnFail) {
requestKeysForEvent(event, false)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt
index 5a9852b6db..70730326da 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt
@@ -39,7 +39,9 @@ internal object MXEncryptedAttachments {
private const val SECRET_KEY_SPEC_ALGORITHM = "AES"
private const val MESSAGE_DIGEST_ALGORITHM = "SHA-256"
- fun encrypt(clearStream: InputStream, mimetype: String?, outputFile: File, progress: ((current: Int, total: Int) -> Unit)): EncryptedFileInfo {
+ fun encrypt(clearStream: InputStream,
+ outputFile: File,
+ progress: ((current: Int, total: Int) -> Unit)): EncryptedFileInfo {
val t0 = System.currentTimeMillis()
val secureRandom = SecureRandom()
val initVectorBytes = ByteArray(16) { 0.toByte() }
@@ -86,7 +88,6 @@ internal object MXEncryptedAttachments {
return EncryptedFileInfo(
url = null,
- mimetype = mimetype,
key = EncryptedFileKey(
alg = "A256CTR",
ext = true,
@@ -155,10 +156,9 @@ internal object MXEncryptedAttachments {
* Encrypt an attachment stream.
* DO NOT USE for big files, it will load all in memory
* @param attachmentStream the attachment stream. Will be closed after this method call.
- * @param mimetype the mime type
* @return the encryption file info
*/
- fun encryptAttachment(attachmentStream: InputStream, mimetype: String?): EncryptionResult {
+ fun encryptAttachment(attachmentStream: InputStream): EncryptionResult {
val t0 = System.currentTimeMillis()
val secureRandom = SecureRandom()
@@ -207,7 +207,6 @@ internal object MXEncryptedAttachments {
return EncryptionResult(
encryptedFileInfo = EncryptedFileInfo(
url = null,
- mimetype = mimetype,
key = EncryptedFileKey(
alg = "A256CTR",
ext = true,
@@ -232,7 +231,9 @@ internal object MXEncryptedAttachments {
* @param outputStream the outputStream where the decrypted attachment will be write.
* @return true in case of success, false in case of error
*/
- fun decryptAttachment(attachmentStream: InputStream?, elementToDecrypt: ElementToDecrypt?, outputStream: OutputStream): Boolean {
+ fun decryptAttachment(attachmentStream: InputStream?,
+ elementToDecrypt: ElementToDecrypt?,
+ outputStream: OutputStream): Boolean {
// sanity checks
if (null == attachmentStream || elementToDecrypt == null) {
Timber.e("## decryptAttachment() : null stream")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt
index 4004294d97..5e7744853a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt
@@ -18,8 +18,6 @@ package org.matrix.android.sdk.internal.crypto.model
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys
import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo
-import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMapper
-import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity
data class CryptoDeviceInfo(
val deviceId: String,
@@ -77,7 +75,3 @@ data class CryptoDeviceInfo(
internal fun CryptoDeviceInfo.toRest(): DeviceKeys {
return CryptoInfoMapper.map(this)
}
-
-internal fun CryptoDeviceInfo.toEntity(): DeviceInfoEntity {
- return CryptoMapper.mapToEntity(this)
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt
index 00b8bde5d9..68cc41005e 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt
@@ -56,7 +56,7 @@ data class MXDeviceInfo(
val signatures: Map>? = null,
/*
- * Additional data from the home server.
+ * Additional data from the homeserver.
*/
@Json(name = "unsigned")
val unsigned: JsonDict? = null,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt
index 0ed6c0dac9..4fc3adb42c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt
@@ -29,12 +29,6 @@ data class EncryptedFileInfo(
@Json(name = "url")
val url: String? = null,
- /**
- * Not documented
- */
- @Json(name = "mimetype")
- val mimetype: String? = null,
-
/**
* Required. A JSON Web Key object.
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
index 1f80ce2c81..fb10cf4482 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
@@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.secrets
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.listeners.ProgressListener
-import org.matrix.android.sdk.api.session.accountdata.AccountDataService
+import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
@@ -56,7 +56,7 @@ import kotlin.experimental.and
internal class DefaultSharedSecretStorageService @Inject constructor(
@UserId private val userId: String,
- private val accountDataService: AccountDataService,
+ private val accountDataService: SessionAccountDataService,
private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val cryptoCoroutineScope: CoroutineScope
@@ -84,7 +84,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
)
} ?: storageKeyContent
- accountDataService.updateAccountData("$KEY_ID_BASE.$keyId", signedContent.toContent())
+ accountDataService.updateUserAccountData("$KEY_ID_BASE.$keyId", signedContent.toContent())
SsssKeyCreationInfo(
keyId = keyId,
content = storageKeyContent,
@@ -113,7 +113,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
)
} ?: storageKeyContent
- accountDataService.updateAccountData(
+ accountDataService.updateUserAccountData(
"$KEY_ID_BASE.$keyId",
signedContent.toContent()
)
@@ -127,11 +127,11 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
}
override fun hasKey(keyId: String): Boolean {
- return accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId") != null
+ return accountDataService.getUserAccountDataEvent("$KEY_ID_BASE.$keyId") != null
}
override fun getKey(keyId: String): KeyInfoResult {
- val accountData = accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId")
+ val accountData = accountDataService.getUserAccountDataEvent("$KEY_ID_BASE.$keyId")
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(keyId))
return SecretStorageKeyContent.fromJson(accountData.content)?.let {
KeyInfoResult.Success(
@@ -143,14 +143,14 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
override suspend fun setDefaultKey(keyId: String) {
val existingKey = getKey(keyId)
if (existingKey is KeyInfoResult.Success) {
- accountDataService.updateAccountData(DEFAULT_KEY_ID, mapOf("key" to keyId))
+ accountDataService.updateUserAccountData(DEFAULT_KEY_ID, mapOf("key" to keyId))
} else {
throw SharedSecretStorageError.UnknownKey(keyId)
}
}
override fun getDefaultKey(): KeyInfoResult {
- val accountData = accountDataService.getAccountDataEvent(DEFAULT_KEY_ID)
+ val accountData = accountDataService.getUserAccountDataEvent(DEFAULT_KEY_ID)
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID))
val keyId = accountData.content["key"] as? String
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID))
@@ -178,7 +178,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
}
}
- accountDataService.updateAccountData(
+ accountDataService.updateUserAccountData(
type = name,
content = mapOf("encrypted" to encryptedContents)
)
@@ -288,7 +288,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
}
override fun getAlgorithmsForSecret(name: String): List {
- val accountData = accountDataService.getAccountDataEvent(name)
+ val accountData = accountDataService.getUserAccountDataEvent(name)
?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.UnknownSecret(name)))
val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *>
?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.SecretNotEncrypted(name)))
@@ -303,7 +303,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
}
override suspend fun getSecret(name: String, keyId: String?, secretKey: SsssKeySpec): String {
- val accountData = accountDataService.getAccountDataEvent(name) ?: throw SharedSecretStorageError.UnknownSecret(name)
+ val accountData = accountDataService.getUserAccountDataEvent(name) ?: throw SharedSecretStorageError.UnknownSecret(name)
val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *> ?: throw SharedSecretStorageError.SecretNotEncrypted(name)
val key = keyId?.let { getKey(it) } as? KeyInfoResult.Success ?: getDefaultKey() as? KeyInfoResult.Success
?: throw SharedSecretStorageError.UnknownKey(name)
@@ -368,7 +368,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
}
secretNames.forEach { secretName ->
- val secretEvent = accountDataService.getAccountDataEvent(secretName)
+ val secretEvent = accountDataService.getUserAccountDataEvent(secretName)
?: return IntegrityResult.Error(SharedSecretStorageError.UnknownSecret(secretName))
if ((secretEvent.content["encrypted"] as? Map<*, *>)?.get(keyInfo.id) == null) {
return IntegrityResult.Error(SharedSecretStorageError.SecretNotEncryptedWithKey(secretName, keyInfo.id))
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
index 181bd94cc7..3d12e74fcd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt
@@ -475,7 +475,7 @@ internal interface IMXCryptoStore {
fun getGossipingEvents(): List
fun setDeviceKeysUploaded(uploaded: Boolean)
- fun getDeviceKeysUploaded(): Boolean
+ fun areDeviceKeysUploaded(): Boolean
fun tidyUpDataBase()
fun logDbUsageInfo()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
index 9ae93d61eb..d997998836 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
@@ -51,7 +51,6 @@ import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
-import org.matrix.android.sdk.internal.crypto.model.toEntity
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo
@@ -280,24 +279,37 @@ internal class RealmCryptoStore @Inject constructor(
override fun storeUserDevices(userId: String, devices: Map?) {
doRealmTransaction(realmConfiguration) { realm ->
if (devices == null) {
+ Timber.d("Remove user $userId")
// Remove the user
UserEntity.delete(realm, userId)
} else {
- UserEntity.getOrCreate(realm, userId)
- .let { u ->
- // Add the devices
- val currentKnownDevices = u.devices.toList()
- val new = devices.map { entry -> entry.value.toEntity() }
- new.forEach { entity ->
- // Maintain first time seen
- val existing = currentKnownDevices.firstOrNull { it.deviceId == entity.deviceId && it.identityKey == entity.identityKey }
- entity.firstTimeSeenLocalTs = existing?.firstTimeSeenLocalTs ?: System.currentTimeMillis()
- realm.insertOrUpdate(entity)
- }
- // Ensure all other devices are deleted
- u.devices.clearWith { it.deleteOnCascade() }
- u.devices.addAll(new)
+ val userEntity = UserEntity.getOrCreate(realm, userId)
+ // First delete the removed devices
+ val deviceIds = devices.keys
+ userEntity.devices.toTypedArray().iterator().let {
+ while (it.hasNext()) {
+ val deviceInfoEntity = it.next()
+ if (deviceInfoEntity.deviceId !in deviceIds) {
+ Timber.d("Remove device ${deviceInfoEntity.deviceId} of user $userId")
+ deviceInfoEntity.deleteOnCascade()
}
+ }
+ }
+ // Then update existing devices or add new one
+ devices.values.forEach { cryptoDeviceInfo ->
+ val existingDeviceInfoEntity = userEntity.devices.firstOrNull { it.deviceId == cryptoDeviceInfo.deviceId }
+ if (existingDeviceInfoEntity == null) {
+ // Add the device
+ Timber.d("Add device ${cryptoDeviceInfo.deviceId} of user $userId")
+ val newEntity = CryptoMapper.mapToEntity(cryptoDeviceInfo)
+ newEntity.firstTimeSeenLocalTs = System.currentTimeMillis()
+ userEntity.devices.add(newEntity)
+ } else {
+ // Update the device
+ Timber.d("Update device ${cryptoDeviceInfo.deviceId} of user $userId")
+ CryptoMapper.updateDeviceInfoEntity(existingDeviceInfoEntity, cryptoDeviceInfo)
+ }
+ }
}
}
}
@@ -937,7 +949,7 @@ internal class RealmCryptoStore @Inject constructor(
}
}
- override fun getDeviceKeysUploaded(): Boolean {
+ override fun areDeviceKeysUploaded(): Boolean {
return doWithRealm(realmConfiguration) {
it.where().findFirst()?.deviceKeysSentToServer
} ?: false
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt
index bca7914388..2846be9932 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt
@@ -18,6 +18,9 @@ package org.matrix.android.sdk.internal.crypto.store.db
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
+import io.realm.DynamicRealm
+import io.realm.RealmMigration
+import io.realm.RealmObjectSchema
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo
@@ -35,29 +38,24 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntit
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields
+import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields
+import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.di.SerializeNulls
-import io.realm.DynamicRealm
-import io.realm.RealmMigration
-import io.realm.RealmObjectSchema
-import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields
import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2
import timber.log.Timber
-import javax.inject.Inject
import org.matrix.androidsdk.crypto.data.MXDeviceInfo as LegacyMXDeviceInfo
-internal class RealmCryptoStoreMigration @Inject constructor(private val crossSigningKeysMapper: CrossSigningKeysMapper) : RealmMigration {
+internal object RealmCryptoStoreMigration : RealmMigration {
- companion object {
- // 0, 1, 2: legacy Riot-Android
- // 3: migrate to RiotX schema
- // 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6)
- const val CRYPTO_STORE_SCHEMA_VERSION = 12L
- }
+ // 0, 1, 2: legacy Riot-Android
+ // 3: migrate to RiotX schema
+ // 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6)
+ const val CRYPTO_STORE_SCHEMA_VERSION = 13L
private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema {
if (!hasField(fieldName)) {
@@ -95,6 +93,7 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi
if (oldVersion <= 9) migrateTo10(realm)
if (oldVersion <= 10) migrateTo11(realm)
if (oldVersion <= 11) migrateTo12(realm)
+ if (oldVersion <= 12) migrateTo13(realm)
}
private fun migrateTo1Legacy(realm: DynamicRealm) {
@@ -384,6 +383,8 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi
private fun migrateTo7(realm: DynamicRealm) {
Timber.d("Step 6 -> 7")
Timber.d("Updating KeyInfoEntity table")
+ val crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi())
+
val keyInfoEntities = realm.where("KeyInfoEntity").findAll()
try {
keyInfoEntities.forEach {
@@ -497,4 +498,60 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi
realm.schema.get("CryptoRoomEntity")
?.addRealmObjectField(CryptoRoomEntityFields.OUTBOUND_SESSION_INFO.`$`, outboundEntitySchema)
}
+
+ // Version 13L delete unreferenced TrustLevelEntity
+ private fun migrateTo13(realm: DynamicRealm) {
+ Timber.d("Step 12 -> 13")
+
+ // Use a trick to do that... Ref: https://stackoverflow.com/questions/55221366
+ val trustLevelEntitySchema = realm.schema.get("TrustLevelEntity")
+
+ /*
+ Creating a new temp field called isLinked which is set to true for those which are
+ references by other objects. Rest of them are set to false. Then removing all
+ those which are false and hence duplicate and unnecessary. Then removing the temp field
+ isLinked
+ */
+ var mainCounter = 0
+ var deviceInfoCounter = 0
+ var keyInfoCounter = 0
+ val deleteCounter: Int
+
+ trustLevelEntitySchema
+ ?.addField("isLinked", Boolean::class.java)
+ ?.transform { obj ->
+ // Setting to false for all by default
+ obj.set("isLinked", false)
+ mainCounter++
+ }
+
+ realm.schema.get("DeviceInfoEntity")?.transform { obj ->
+ // Setting to true for those which are referenced in DeviceInfoEntity
+ deviceInfoCounter++
+ obj.getObject("trustLevelEntity")?.set("isLinked", true)
+ }
+
+ realm.schema.get("KeyInfoEntity")?.transform { obj ->
+ // Setting to true for those which are referenced in KeyInfoEntity
+ keyInfoCounter++
+ obj.getObject("trustLevelEntity")?.set("isLinked", true)
+ }
+
+ // Removing all those which are set as false
+ realm.where("TrustLevelEntity")
+ .equalTo("isLinked", false)
+ .findAll()
+ .also { deleteCounter = it.size }
+ .deleteAllFromRealm()
+
+ trustLevelEntitySchema?.removeField("isLinked")
+
+ Timber.w("TrustLevelEntity cleanup: $mainCounter entities")
+ Timber.w("TrustLevelEntity cleanup: $deviceInfoCounter entities referenced in DeviceInfoEntities")
+ Timber.w("TrustLevelEntity cleanup: $keyInfoCounter entities referenced in KeyInfoEntity")
+ Timber.w("TrustLevelEntity cleanup: $deleteCounter entities deleted!")
+ if (mainCounter != deviceInfoCounter + keyInfoCounter + deleteCounter) {
+ Timber.e("TrustLevelEntity cleanup: Something is not correct...")
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt
index 37d1441690..7ba986699a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt
@@ -44,23 +44,32 @@ object CryptoMapper {
))
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
- return DeviceInfoEntity(
- primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId),
- userId = deviceInfo.userId,
- deviceId = deviceInfo.deviceId,
- algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms),
- keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys),
- signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures),
- isBlocked = deviceInfo.isBlocked,
- trustLevelEntity = deviceInfo.trustLevel?.let {
- TrustLevelEntity(
- crossSignedVerified = it.crossSigningVerified,
- locallyVerified = it.locallyVerified
- )
- },
- // We store the device name if present now
- unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName
- )
+ return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
+ .also { updateDeviceInfoEntity(it, deviceInfo) }
+ }
+
+ internal fun updateDeviceInfoEntity(entity: DeviceInfoEntity, deviceInfo: CryptoDeviceInfo) {
+ entity.userId = deviceInfo.userId
+ entity.deviceId = deviceInfo.deviceId
+ entity.algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms)
+ entity.keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys)
+ entity.signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures)
+ entity.isBlocked = deviceInfo.isBlocked
+ val deviceInfoTrustLevel = deviceInfo.trustLevel
+ if (deviceInfoTrustLevel == null) {
+ entity.trustLevelEntity?.deleteFromRealm()
+ entity.trustLevelEntity = null
+ } else {
+ if (entity.trustLevelEntity == null) {
+ // Create a new TrustLevelEntity object
+ entity.trustLevelEntity = TrustLevelEntity()
+ }
+ // Update the existing TrustLevelEntity object
+ entity.trustLevelEntity?.crossSignedVerified = deviceInfoTrustLevel.crossSigningVerified
+ entity.trustLevelEntity?.locallyVerified = deviceInfoTrustLevel.locallyVerified
+ }
+ // We store the device name if present now
+ entity.unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName
}
internal fun mapToModel(deviceInfoEntity: DeviceInfoEntity): CryptoDeviceInfo {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
index f8a8354e48..1d40e5defd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
@@ -97,7 +97,7 @@ internal class DefaultInitializeCrossSigningTask @Inject constructor(
Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
- // Sign userSigningKey with master
+ // Sign selfSigningKey with master
val signedSSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
.key(sskPublicKey)
.build()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
index 0dbbe656c7..45f8143937 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
@@ -68,7 +68,7 @@ internal class VerificationTransportToDevice(
contentMap.setObject(otherUserId, it, keyReq)
}
sendToDeviceTask
- .configureWith(SendToDeviceTask.Params(MessageType.MSGTYPE_VERIFICATION_REQUEST, contentMap, localId)) {
+ .configureWith(SendToDeviceTask.Params(MessageType.MSGTYPE_VERIFICATION_REQUEST, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
Timber.v("## verification [$tx.transactionId] send toDevice request success")
@@ -124,7 +124,7 @@ internal class VerificationTransportToDevice(
contentMap.setObject(tx.otherUserId, tx.otherDeviceId, toSendToDeviceObject)
sendToDeviceTask
- .configureWith(SendToDeviceTask.Params(type, contentMap, tx.transactionId)) {
+ .configureWith(SendToDeviceTask.Params(type, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
Timber.v("## SAS verification [$tx.transactionId] toDevice type '$type' success.")
@@ -155,7 +155,7 @@ internal class VerificationTransportToDevice(
val contentMap = MXUsersDevicesMap()
contentMap.setObject(otherUserId, otherUserDeviceId, cancelMessage)
sendToDeviceTask
- .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_DONE, contentMap, transactionId)) {
+ .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_DONE, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
onDone?.invoke()
@@ -176,7 +176,7 @@ internal class VerificationTransportToDevice(
val contentMap = MXUsersDevicesMap()
contentMap.setObject(otherUserId, otherUserDeviceId, cancelMessage)
sendToDeviceTask
- .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId)) {
+ .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
Timber.v("## SAS verification [$transactionId] canceled for reason ${code.value}")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
index 0e3a7a2c49..d5ff7a0f84 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
@@ -71,7 +71,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context,
val encodedKey = Base64.encodeToString(key, Base64.NO_PADDING)
val toStore = secretStoringUtils.securelyStoreString(encodedKey, alias)
sharedPreferences.edit {
- putString("${ENCRYPTED_KEY_PREFIX}_$alias", Base64.encodeToString(toStore!!, Base64.NO_PADDING))
+ putString("${ENCRYPTED_KEY_PREFIX}_$alias", Base64.encodeToString(toStore, Base64.NO_PADDING))
}
return key
}
@@ -84,7 +84,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context,
val encryptedB64 = sharedPreferences.getString("${ENCRYPTED_KEY_PREFIX}_$alias", null)
val encryptedKey = Base64.decode(encryptedB64, Base64.NO_PADDING)
val b64 = secretStoringUtils.loadSecureSecret(encryptedKey, alias)
- return Base64.decode(b64!!, Base64.NO_PADDING)
+ return Base64.decode(b64, Base64.NO_PADDING)
}
fun configureEncryption(realmConfigurationBuilder: RealmConfiguration.Builder, alias: String) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
index d810c8b1a8..28ae4d8bfd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
@@ -20,7 +20,9 @@ import io.realm.DynamicRealm
import io.realm.FieldAttribute
import io.realm.RealmMigration
import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
+import org.matrix.android.sdk.api.session.room.model.VersioningState
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
@@ -30,6 +32,7 @@ import org.matrix.android.sdk.internal.database.model.EventEntityFields
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
+import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
@@ -38,14 +41,12 @@ import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFie
import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.di.MoshiProvider
+import org.matrix.android.sdk.internal.query.process
import timber.log.Timber
-import javax.inject.Inject
-class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
+internal object RealmSessionStoreMigration : RealmMigration {
- companion object {
- const val SESSION_STORE_SCHEMA_VERSION = 13L
- }
+ const val SESSION_STORE_SCHEMA_VERSION = 16L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
@@ -63,6 +64,9 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
if (oldVersion <= 10) migrateTo11(realm)
if (oldVersion <= 11) migrateTo12(realm)
if (oldVersion <= 12) migrateTo13(realm)
+ if (oldVersion <= 13) migrateTo14(realm)
+ if (oldVersion <= 14) migrateTo15(realm)
+ if (oldVersion <= 15) migrateTo16(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@@ -278,11 +282,52 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
private fun migrateTo13(realm: DynamicRealm) {
Timber.d("Step 12 -> 13")
-
// Fix issue with the nightly build. Eventually play again the migration which has been included in migrateTo12()
realm.schema.get("SpaceChildSummaryEntity")
?.takeIf { !it.hasField(SpaceChildSummaryEntityFields.SUGGESTED) }
?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java)
?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true)
}
+
+ private fun migrateTo14(realm: DynamicRealm) {
+ Timber.d("Step 13 -> 14")
+ val roomAccountDataSchema = realm.schema.create("RoomAccountDataEntity")
+ .addField(RoomAccountDataEntityFields.CONTENT_STR, String::class.java)
+ .addField(RoomAccountDataEntityFields.TYPE, String::class.java, FieldAttribute.INDEXED)
+
+ realm.schema.get("RoomEntity")
+ ?.addRealmListField(RoomEntityFields.ACCOUNT_DATA.`$`, roomAccountDataSchema)
+
+ realm.schema.get("RoomSummaryEntity")
+ ?.addField(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, Boolean::class.java, FieldAttribute.INDEXED)
+ ?.transform {
+ val isHiddenFromUser = it.getString(RoomSummaryEntityFields.VERSIONING_STATE_STR) == VersioningState.UPGRADED_ROOM_JOINED.name
+ it.setBoolean(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, isHiddenFromUser)
+ }
+
+ roomAccountDataSchema.isEmbedded = true
+ }
+
+ private fun migrateTo15(realm: DynamicRealm) {
+ Timber.d("Step 14 -> 15")
+ // fix issue with flattenParentIds on DM that kept growing with duplicate
+ // so we reset it, will be updated next sync
+ realm.where("RoomSummaryEntity")
+ .process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships())
+ .equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
+ .findAll()
+ .onEach {
+ it.setString(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, null)
+ }
+ }
+
+ private fun migrateTo16(realm: DynamicRealm) {
+ Timber.d("Step 15 -> 16")
+ realm.schema.get("HomeServerCapabilitiesEntity")
+ ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java)
+ ?.transform { obj ->
+ // Schedule a refresh of the capabilities
+ obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
index 244fe3432a..1771c5b202 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
@@ -43,7 +43,6 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
@SessionFilesDirectory val directory: File,
@SessionId val sessionId: String,
@UserMd5 val userMd5: String,
- val migration: RealmSessionStoreMigration,
context: Context) {
// Keep legacy preferences name for compatibility reason
@@ -72,7 +71,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
.allowWritesOnUiThread(true)
.modules(SessionRealmModule())
.schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION)
- .migration(migration)
+ .migration(RealmSessionStoreMigration)
.build()
// Try creating a realm instance and if it succeeds we can clear the flag
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt
index 54315a1835..dca0f927ad 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt
@@ -17,9 +17,11 @@
package org.matrix.android.sdk.internal.database.mapper
import com.squareup.moshi.Moshi
-import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE
-import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
+import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent
+import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE
+import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntity
+import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
import javax.inject.Inject
internal class AccountDataMapper @Inject constructor(moshi: Moshi) {
@@ -32,4 +34,12 @@ internal class AccountDataMapper @Inject constructor(moshi: Moshi) {
content = entity.contentStr?.let { adapter.fromJson(it) }.orEmpty()
)
}
+
+ fun map(roomId: String, entity: RoomAccountDataEntity): RoomAccountDataEvent {
+ return RoomAccountDataEvent(
+ roomId = roomId,
+ type = entity.type ?: "",
+ content = entity.contentStr?.let { adapter.fromJson(it) }.orEmpty()
+ )
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
index b18c67294f..8b6d263f8c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
@@ -16,8 +16,16 @@
package org.matrix.android.sdk.internal.database.mapper
+import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
+import org.matrix.android.sdk.api.session.homeserver.RoomCapabilitySupport
+import org.matrix.android.sdk.api.session.homeserver.RoomVersionCapabilities
+import org.matrix.android.sdk.api.session.homeserver.RoomVersionInfo
+import org.matrix.android.sdk.api.session.homeserver.RoomVersionStatus
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
+import org.matrix.android.sdk.internal.di.MoshiProvider
+import org.matrix.android.sdk.internal.session.homeserver.RoomVersions
+import org.matrix.android.sdk.internal.session.room.version.DefaultRoomVersionService
/**
* HomeServerCapabilitiesEntity -> HomeSeverCapabilities
@@ -29,7 +37,39 @@ internal object HomeServerCapabilitiesMapper {
canChangePassword = entity.canChangePassword,
maxUploadFileSize = entity.maxUploadFileSize,
lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported,
- defaultIdentityServerUrl = entity.defaultIdentityServerUrl
+ defaultIdentityServerUrl = entity.defaultIdentityServerUrl,
+ roomVersions = mapRoomVersion(entity.roomVersionsJson)
)
}
+
+ private fun mapRoomVersion(roomVersionsJson: String?): RoomVersionCapabilities? {
+ roomVersionsJson ?: return null
+
+ return tryOrNull {
+ MoshiProvider.providesMoshi().adapter(RoomVersions::class.java).fromJson(roomVersionsJson)?.let { roomVersions ->
+ RoomVersionCapabilities(
+ defaultRoomVersion = roomVersions.default ?: DefaultRoomVersionService.DEFAULT_ROOM_VERSION,
+ supportedVersion = roomVersions.available?.entries?.map { entry ->
+ RoomVersionInfo(entry.key, RoomVersionStatus.STABLE
+ .takeIf { entry.value == "stable" }
+ ?: RoomVersionStatus.UNSTABLE)
+ }.orEmpty(),
+ capabilities = roomVersions.roomCapabilities?.entries?.mapNotNull { entry ->
+ (entry.value as? Map<*, *>)?.let {
+ val preferred = it["preferred"] as? String ?: return@mapNotNull null
+ val support = (it["support"] as? List<*>)?.filterIsInstance()
+ entry.key to RoomCapabilitySupport(preferred, support.orEmpty())
+ }
+ }?.toMap()
+ // Just for debug purpose
+// ?: mapOf(
+// HomeServerCapabilities.ROOM_CAP_RESTRICTED to RoomCapabilitySupport(
+// preferred = null,
+// support = listOf("org.matrix.msc3083")
+// )
+// )
+ )
+ }
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
index fbecbf37be..c32c019625 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt
@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.database.mapper
+import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo
@@ -90,7 +91,10 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
autoJoin = it.autoJoin ?: false,
viaServers = it.viaServers.toList(),
parentRoomId = roomSummaryEntity.roomId,
- suggested = it.suggested
+ suggested = it.suggested,
+ canonicalAlias = it.childSummaryEntity?.canonicalAlias,
+ aliases = it.childSummaryEntity?.aliases?.toList(),
+ worldReadable = it.childSummaryEntity?.joinRules == RoomJoinRules.PUBLIC
)
},
flattenParentIds = roomSummaryEntity.flattenParentIds?.split("|") ?: emptyList()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
index 763dcf80a2..980449ddfb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
@@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
internal open class HomeServerCapabilitiesEntity(
var canChangePassword: Boolean = true,
+ var roomVersionsJson: String? = null,
var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN,
var lastVersionIdentityServerSupported: Boolean = false,
var defaultIdentityServerUrl: String? = null,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt
new file mode 100644
index 0000000000..40040b5738
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.database.model
+
+import io.realm.RealmObject
+import io.realm.annotations.Index
+import io.realm.annotations.RealmClass
+
+@RealmClass(embedded = true)
+internal open class RoomAccountDataEntity(
+ @Index var type: String? = null,
+ var contentStr: String? = null
+) : RealmObject()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt
index 58297776f0..65483e05bf 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt
@@ -23,7 +23,8 @@ import io.realm.annotations.PrimaryKey
internal open class RoomEntity(@PrimaryKey var roomId: String = "",
var chunks: RealmList = RealmList(),
- var sendingTimelineEvents: RealmList = RealmList()
+ var sendingTimelineEvents: RealmList = RealmList(),
+ var accountData: RealmList = RealmList()
) : RealmObject() {
private var membershipStr: String = Membership.NONE.name
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
index 1001f9cd66..64dc08e827 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt
@@ -232,6 +232,12 @@ internal open class RoomSummaryEntity(
}
}
+ @Index
+ var isHiddenFromUser: Boolean = false
+ set(value) {
+ if (value != field) field = value
+ }
+
@Index
private var versioningStateStr: String = VersioningState.NONE.name
var versioningState: VersioningState
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
index 72ae512fa5..19472e21d9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
@@ -62,6 +62,7 @@ import io.realm.annotations.RealmModule
UserAccountDataEntity::class,
ScalarTokenEntity::class,
WellknownIntegrationManagerConfigEntity::class,
+ RoomAccountDataEntity::class,
SpaceChildSummaryEntity::class,
SpaceParentSummaryEntity::class
])
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/UserAccountDataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/UserAccountDataEntity.kt
index cfdb84d033..e258c20df5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/UserAccountDataEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/UserAccountDataEntity.kt
@@ -20,7 +20,7 @@ import io.realm.RealmObject
import io.realm.annotations.Index
/**
- * Clients can store custom config data for their account on their HomeServer.
+ * Clients can store custom config data for their account on their homeserver.
* This account data will be synced between different devices and can persist across installations on a particular device.
* Users may only view the account data for their own account.
* The account_data may be either global or scoped to a particular rooms.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt
index 27e8d9d8d1..a551f97379 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt
@@ -29,6 +29,10 @@ internal fun RoomEntity.Companion.where(realm: Realm, roomId: String): RealmQuer
.equalTo(RoomEntityFields.ROOM_ID, roomId)
}
+internal fun RoomEntity.Companion.getOrCreate(realm: Realm, roomId: String): RoomEntity {
+ return where(realm, roomId).findFirst() ?: realm.createObject(RoomEntity::class.java, roomId)
+}
+
internal fun RoomEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery {
val query = realm.where()
if (membership != null) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
index 9d6fa29bb2..5bc519e960 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt
@@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.session.TestInterceptor
import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
+import org.matrix.android.sdk.internal.util.system.SystemModule
import org.matrix.olm.OlmManager
import java.io.File
@@ -44,6 +45,7 @@ import java.io.File
NetworkModule::class,
AuthModule::class,
RawModule::class,
+ SystemModule::class,
NoOpTestModule::class
])
@MatrixScope
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt
index 320bf1d445..a4eef80c58 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt
@@ -37,7 +37,8 @@ internal abstract class FederationModule {
fun providesFederationAPI(@Unauthenticated okHttpClient: Lazy,
sessionParams: SessionParams,
retrofitFactory: RetrofitFactory): FederationAPI {
- return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrl).create(FederationAPI::class.java)
+ return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrlBase)
+ .create(FederationAPI::class.java)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt
index e0e2f96fa9..ad2aff4c9d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt
@@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.legacy.riot.HomeServerConnectionConfig as
internal class DefaultLegacySessionImporter @Inject constructor(
private val context: Context,
private val sessionParamsStore: SessionParamsStore,
- private val realmCryptoStoreMigration: RealmCryptoStoreMigration,
private val realmKeysUtils: RealmKeysUtils
) : LegacySessionImporter {
@@ -153,7 +152,7 @@ internal class DefaultLegacySessionImporter @Inject constructor(
}
private fun importCryptoDb(legacyConfig: LegacyHomeServerConnectionConfig) {
- // Here we migrate the DB, we copy the crypto DB to the location specific to RiotX, and we encrypt it.
+ // Here we migrate the DB, we copy the crypto DB to the location specific to Matrix SDK2, and we encrypt it.
val userMd5 = legacyConfig.credentials.userId.md5()
val sessionId = legacyConfig.credentials.let { (if (it.deviceId.isNullOrBlank()) it.userId else "${it.userId}|${it.deviceId}").md5() }
@@ -172,17 +171,17 @@ internal class DefaultLegacySessionImporter @Inject constructor(
.name("crypto_store.realm")
.modules(RealmCryptoStoreModule())
.schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
- .migration(realmCryptoStoreMigration)
+ .migration(RealmCryptoStoreMigration)
.build()
Timber.d("Migration: copy DB to encrypted DB")
Realm.getInstance(realmConfiguration).use {
- // Move the DB to the new location, handled by RiotX
+ // Move the DB to the new location, handled by Matrix SDK2
it.writeEncryptedCopyTo(File(newLocation, realmConfiguration.realmFileName), realmKeysUtils.getRealmEncryptionKey(keyAlias))
}
}
- // Delete all the files created by Riot Android which will not be used anymore by RiotX
+ // Delete all the files created by Riot Android which will not be used anymore by Element
private fun clearFileSystem(legacyConfig: LegacyHomeServerConnectionConfig) {
val cryptoFolder = legacyConfig.credentials.userId.md5()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java
index 6844744044..0ca0c7db85 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java
@@ -41,7 +41,7 @@ public class Credentials {
public String deviceId;
- // Optional data that may contain info to override home server and/or identity server
+ // Optional data that may contain info to override homeserver and/or identity server
public WellKnown wellKnown;
public JSONObject toJson() throws JSONException {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java
index 21d069f295..75fc187c45 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java
@@ -44,7 +44,7 @@ import timber.log.Timber;
*/
public class HomeServerConnectionConfig {
- // the home server URI
+ // the homeserver URI
private Uri mHomeServerUri;
// the jitsi server URI. Can be null
@Nullable
@@ -82,7 +82,7 @@ public class HomeServerConnectionConfig {
}
/**
- * Update the home server URI.
+ * Update the homeserver URI.
*
* @param uri the new HS uri
*/
@@ -91,7 +91,7 @@ public class HomeServerConnectionConfig {
}
/**
- * @return the home server uri
+ * @return the homeserver uri
*/
public Uri getHomeserverUri() {
return mHomeServerUri;
@@ -145,7 +145,7 @@ public class HomeServerConnectionConfig {
public void setCredentials(Credentials credentials) {
mCredentials = credentials;
- // Override home server url and/or identity server url if provided
+ // Override homeserver url and/or identity server url if provided
if (credentials.wellKnown != null) {
if (credentials.wellKnown.homeServer != null) {
String homeServerUrl = credentials.wellKnown.homeServer.baseURL;
@@ -200,7 +200,7 @@ public class HomeServerConnectionConfig {
}
/**
- * TLS versions accepted for TLS connections with the home server.
+ * TLS versions accepted for TLS connections with the homeserver.
*/
@Nullable
public List getAcceptedTlsVersions() {
@@ -208,7 +208,7 @@ public class HomeServerConnectionConfig {
}
/**
- * TLS cipher suites accepted for TLS connections with the home server.
+ * TLS cipher suites accepted for TLS connections with the homeserver.
*/
@Nullable
public List getAcceptedTlsCipherSuites() {
@@ -426,7 +426,7 @@ public class HomeServerConnectionConfig {
*/
public Builder withHomeServerUri(final Uri homeServerUri) {
if (homeServerUri == null || (!"http".equals(homeServerUri.getScheme()) && !"https".equals(homeServerUri.getScheme()))) {
- throw new RuntimeException("Invalid home server URI: " + homeServerUri);
+ throw new RuntimeException("Invalid homeserver URI: " + homeServerUri);
}
// remove trailing /
@@ -435,7 +435,7 @@ public class HomeServerConnectionConfig {
String url = homeServerUri.toString();
mHomeServerConnectionConfig.mHomeServerUri = Uri.parse(url.substring(0, url.length() - 1));
} catch (Exception e) {
- throw new RuntimeException("Invalid home server URI: " + homeServerUri);
+ throw new RuntimeException("Invalid homeserver URI: " + homeServerUri);
}
} else {
mHomeServerConnectionConfig.mHomeServerUri = homeServerUri;
@@ -549,7 +549,7 @@ public class HomeServerConnectionConfig {
}
/**
- * Add an accepted TLS version for TLS connections with the home server.
+ * Add an accepted TLS version for TLS connections with the homeserver.
*
* @param tlsVersion the tls version to add to the set of TLS versions accepted.
* @return this builder
@@ -577,7 +577,7 @@ public class HomeServerConnectionConfig {
}
/**
- * Add a TLS cipher suite to the list of accepted TLS connections with the home server.
+ * Add a TLS cipher suite to the list of accepted TLS connections with the homeserver.
*
* @param tlsCipherSuite the tls cipher suite to add.
* @return this builder
@@ -666,7 +666,7 @@ public class HomeServerConnectionConfig {
public HomeServerConnectionConfig build() {
// Check mandatory parameters
if (mHomeServerConnectionConfig.mHomeServerUri == null) {
- throw new RuntimeException("Home server URI not set");
+ throw new RuntimeException("Homeserver URI not set");
}
return mHomeServerConnectionConfig;
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java
index 516007524e..2820b66886 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java
@@ -38,7 +38,7 @@ import timber.log.Timber;
public class LoginStorage {
private static final String PREFS_LOGIN = "Vector.LoginStorage";
- // multi accounts + home server config
+ // multi accounts + homeserver config
private static final String PREFS_KEY_CONNECTION_CONFIGS = "PREFS_KEY_CONNECTION_CONFIGS";
private final Context mContext;
@@ -49,7 +49,7 @@ public class LoginStorage {
}
/**
- * @return the list of home server configurations.
+ * @return the list of homeserver configurations.
*/
public List getCredentialsList() {
SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE);
@@ -85,7 +85,7 @@ public class LoginStorage {
/**
* Add a credentials to the credentials list
*
- * @param config the home server config to add.
+ * @param config the homeserver config to add.
*/
public void addCredentials(HomeServerConnectionConfig config) {
if (null != config && config.getCredentials() != null) {
@@ -203,4 +203,4 @@ public class LoginStorage {
//Need to commit now because called before forcing an app restart
editor.commit();
}
-}
\ No newline at end of file
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt
index 9afdb40ed1..8be11e80f3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt
@@ -16,13 +16,13 @@
package org.matrix.android.sdk.internal.network
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.failure.GlobalError
import org.matrix.android.sdk.internal.auth.SessionParamsStore
import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.task.TaskExecutor
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@@ -44,7 +44,6 @@ internal class GlobalErrorHandler @Inject constructor(
sessionParamsStore.setTokenInvalid(sessionId)
}
}
-
listener?.onGlobalError(globalError)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt
index 973c120f59..1a88404128 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt
@@ -36,7 +36,7 @@ internal class UserAgentHolder @Inject constructor(private val context: Context,
/**
* Create an user agent with the application version.
- * Ex: RiotX/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSDK_X 1.0)
+ * Ex: Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSDK_X 1.0)
*
* @param flavorDescription the flavor description
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt
index 9d7263f56a..976751446b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt
@@ -253,7 +253,7 @@ internal object CertUtil {
val list = ArrayList()
list.add(builder.build())
// TODO: we should display a warning if user enter an http url
- if (hsConfig.allowHttpExtension || hsConfig.homeServerUri.toString().startsWith("http://")) {
+ if (hsConfig.allowHttpExtension || hsConfig.homeServerUriBase.toString().startsWith("http://")) {
list.add(ConnectionSpec.CLEARTEXT)
}
return list
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
index 42b826de16..bca1e498de 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
@@ -29,10 +29,9 @@ internal class DefaultRawService @Inject constructor(
return getUrlTask.execute(GetUrlTask.Params(url, cacheStrategy))
}
- override suspend fun getWellknown(userId: String): String {
- val homeServerDomain = userId.substringAfter(":")
+ override suspend fun getWellknown(domain: String): String {
return getUrl(
- "https://$homeServerDomain/.well-known/matrix/client",
+ "https://$domain/.well-known/matrix/client",
CacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt
index a284d976d0..414c018074 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt
@@ -25,6 +25,7 @@ import kotlinx.coroutines.completeWith
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
+import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
import org.matrix.android.sdk.api.session.file.FileService
import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt
@@ -33,6 +34,7 @@ import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificateWithProgress
import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor.Companion.DOWNLOAD_PROGRESS_INTERCEPTOR_HEADER
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
+import org.matrix.android.sdk.internal.util.file.AtomicFileCreator
import org.matrix.android.sdk.internal.util.md5
import org.matrix.android.sdk.internal.util.writeToFile
import timber.log.Timber
@@ -96,6 +98,9 @@ internal class DefaultFileService @Inject constructor(
}
}
+ var atomicFileDownload: AtomicFileCreator? = null
+ var atomicFileDecrypt: AtomicFileCreator? = null
+
if (existingDownload != null) {
// FIXME If the first downloader cancels then we'll unfortunately be cancelled too.
return existingDownload.await()
@@ -120,19 +125,30 @@ internal class DefaultFileService @Inject constructor(
.header(DOWNLOAD_PROGRESS_INTERCEPTOR_HEADER, url)
.build()
- val response = okHttpClient.newCall(request).execute()
-
- if (!response.isSuccessful) {
- throw IOException()
+ val response = try {
+ okHttpClient.newCall(request).execute()
+ } catch (failure: Throwable) {
+ throw if (failure is IOException) {
+ Failure.NetworkConnection(failure)
+ } else {
+ failure
+ }
}
- val source = response.body?.source() ?: throw IOException()
+ if (!response.isSuccessful) {
+ throw Failure.NetworkConnection(IOException())
+ }
+
+ val source = response.body?.source() ?: throw Failure.NetworkConnection(IOException())
Timber.v("Response size ${response.body?.contentLength()} - Stream available: ${!source.exhausted()}")
// Write the file to cache (encrypted version if the file is encrypted)
- writeToFile(source.inputStream(), cachedFiles.file)
+ // Write to a part file first, so if we abort before done, we don't have a broken cached file
+ val atomicFileCreator = AtomicFileCreator(cachedFiles.file).also { atomicFileDownload = it }
+ writeToFile(source.inputStream(), atomicFileCreator.partFile)
response.close()
+ atomicFileCreator.commit()
} else {
Timber.v("## FileService: cache hit for $url")
}
@@ -145,8 +161,10 @@ internal class DefaultFileService @Inject constructor(
Timber.v("## FileService: decrypt file")
// Ensure the parent folder exists
cachedFiles.decryptedFile.parentFile?.mkdirs()
+ // Write to a part file first, so if we abort before done, we don't have a broken cached file
+ val atomicFileCreator = AtomicFileCreator(cachedFiles.decryptedFile).also { atomicFileDecrypt = it }
val decryptSuccess = cachedFiles.file.inputStream().use { inputStream ->
- cachedFiles.decryptedFile.outputStream().buffered().use { outputStream ->
+ atomicFileCreator.partFile.outputStream().buffered().use { outputStream ->
MXEncryptedAttachments.decryptAttachment(
inputStream,
elementToDecrypt,
@@ -154,6 +172,7 @@ internal class DefaultFileService @Inject constructor(
)
}
}
+ atomicFileCreator.commit()
if (!decryptSuccess) {
throw IllegalStateException("Decryption error")
}
@@ -174,6 +193,11 @@ internal class DefaultFileService @Inject constructor(
}
toNotify?.completeWith(result)
+ result.onFailure {
+ atomicFileDownload?.cancel()
+ atomicFileDecrypt?.cancel()
+ }
+
return result.getOrThrow()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
index 53e13c14ec..c2bd1e24ed 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
@@ -29,7 +29,7 @@ import org.matrix.android.sdk.api.pushrules.PushRuleService
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
import org.matrix.android.sdk.api.session.account.AccountService
-import org.matrix.android.sdk.api.session.accountdata.AccountDataService
+import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService
import org.matrix.android.sdk.api.session.cache.CacheService
import org.matrix.android.sdk.api.session.call.CallSignalingService
import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker
@@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesServi
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
+import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.pushers.PushersService
@@ -116,7 +117,7 @@ internal class DefaultSession @Inject constructor(
private val contentDownloadStateTracker: ContentDownloadStateTracker,
private val initialSyncProgressService: Lazy,
private val homeServerCapabilitiesService: Lazy,
- private val accountDataService: Lazy,
+ private val accountDataService: Lazy,
private val _sharedSecretStorageService: Lazy,
private val accountService: Lazy,
private val eventService: Lazy,
@@ -125,9 +126,11 @@ internal class DefaultSession @Inject constructor(
private val thirdPartyService: Lazy,
private val callSignalingService: Lazy,
private val spaceService: Lazy,
+ private val openIdService: Lazy,
@UnauthenticatedWithCertificate
private val unauthenticatedWithCertificateOkHttpClient: Lazy
) : Session,
+ GlobalErrorHandler.Listener,
RoomService by roomService.get(),
RoomDirectoryService by roomDirectoryService.get(),
GroupService by groupService.get(),
@@ -142,9 +145,7 @@ internal class DefaultSession @Inject constructor(
SecureStorageService by secureStorageService.get(),
HomeServerCapabilitiesService by homeServerCapabilitiesService.get(),
ProfileService by profileService.get(),
- AccountDataService by accountDataService.get(),
- AccountService by accountService.get(),
- GlobalErrorHandler.Listener {
+ AccountService by accountService.get() {
override val sharedSecretStorageService: SharedSecretStorageService
get() = _sharedSecretStorageService.get()
@@ -162,16 +163,16 @@ internal class DefaultSession @Inject constructor(
override fun open() {
assert(!isOpen)
isOpen = true
+ globalErrorHandler.listener = this
cryptoService.get().ensureDevice()
uiHandler.post {
lifecycleObservers.forEach {
it.onSessionStarted(this)
}
- sessionListeners.dispatch {
- it.onSessionStarted(this)
+ sessionListeners.dispatch { _, listener ->
+ listener.onSessionStarted(this)
}
}
- globalErrorHandler.listener = this
}
override fun requireBackgroundSync() {
@@ -211,13 +212,13 @@ internal class DefaultSession @Inject constructor(
// timelineEventDecryptor.destroy()
uiHandler.post {
lifecycleObservers.forEach { it.onSessionStopped(this) }
- sessionListeners.dispatch {
- it.onSessionStopped(this)
+ sessionListeners.dispatch { _, listener ->
+ listener.onSessionStopped(this)
}
}
cryptoService.get().close()
- isOpen = false
globalErrorHandler.listener = null
+ isOpen = false
}
override fun getSyncStateLive() = getSyncThread().liveState()
@@ -241,8 +242,8 @@ internal class DefaultSession @Inject constructor(
lifecycleObservers.forEach {
it.onClearCache(this)
}
- sessionListeners.dispatch {
- it.onClearCache(this)
+ sessionListeners.dispatch { _, listener ->
+ listener.onClearCache(this)
}
}
withContext(NonCancellable) {
@@ -252,8 +253,8 @@ internal class DefaultSession @Inject constructor(
}
override fun onGlobalError(globalError: GlobalError) {
- sessionListeners.dispatch {
- it.onGlobalError(this, globalError)
+ sessionListeners.dispatch { _, listener ->
+ listener.onGlobalError(this, globalError)
}
}
@@ -289,6 +290,10 @@ internal class DefaultSession @Inject constructor(
override fun spaceService(): SpaceService = spaceService.get()
+ override fun openIdService(): OpenIdService = openIdService.get()
+
+ override fun accountDataService(): SessionAccountDataService = accountDataService.get()
+
override fun getOkHttpClient(): OkHttpClient {
return unauthenticatedWithCertificateOkHttpClient.get()
}
@@ -308,7 +313,7 @@ internal class DefaultSession @Inject constructor(
override fun getUiaSsoFallbackUrl(authenticationSessionId: String): String {
val hsBas = sessionParams.homeServerConnectionConfig
- .homeServerUri
+ .homeServerUriBase
.toString()
.trim { it == '/' }
return buildString {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
index 541c877b1d..9a936b73c2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
@@ -64,6 +64,7 @@ import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataModul
import org.matrix.android.sdk.internal.session.widgets.WidgetModule
import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
+import org.matrix.android.sdk.internal.util.system.SystemModule
@Component(dependencies = [MatrixComponent::class],
modules = [
@@ -80,6 +81,7 @@ import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
CacheModule::class,
MediaModule::class,
CryptoModule::class,
+ SystemModule::class,
PushersModule::class,
OpenIdModule::class,
WidgetModule::class,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt
index 563ff4ada3..d5c661b1e4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt
@@ -16,10 +16,17 @@
package org.matrix.android.sdk.internal.session
+import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.Session
+import org.matrix.android.sdk.internal.SessionManager
+import org.matrix.android.sdk.internal.di.SessionId
+import timber.log.Timber
import javax.inject.Inject
-internal class SessionListeners @Inject constructor() {
+@SessionScope
+internal class SessionListeners @Inject constructor(
+ @SessionId private val sessionId: String,
+ private val sessionManager: SessionManager) {
private val listeners = mutableSetOf()
@@ -35,11 +42,18 @@ internal class SessionListeners @Inject constructor() {
}
}
- fun dispatch(block: (Session.Listener) -> Unit) {
+ fun dispatch(block: (Session, Session.Listener) -> Unit) {
synchronized(listeners) {
+ val session = getSession() ?: return Unit.also {
+ Timber.w("You don't have any attached session")
+ }
listeners.forEach {
- block(it)
+ tryOrNull { block(session, it) }
}
}
}
+
+ private fun getSession(): Session? {
+ return sessionManager.getSessionComponent(sessionId)?.session()
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
index 63423b72c6..cb29cb4819 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
@@ -34,10 +34,11 @@ import org.matrix.android.sdk.api.auth.data.sessionId
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
-import org.matrix.android.sdk.api.session.accountdata.AccountDataService
+import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService
import org.matrix.android.sdk.api.session.events.EventService
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
+import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.securestorage.SecureStorageService
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
@@ -82,6 +83,7 @@ import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapab
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
+import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor
import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor
@@ -91,7 +93,7 @@ import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProces
import org.matrix.android.sdk.internal.session.room.tombstone.RoomTombstoneEventProcessor
import org.matrix.android.sdk.internal.session.securestorage.DefaultSecureStorageService
import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker
-import org.matrix.android.sdk.internal.session.user.accountdata.DefaultAccountDataService
+import org.matrix.android.sdk.internal.session.user.accountdata.DefaultSessionAccountDataService
import org.matrix.android.sdk.internal.session.widgets.DefaultWidgetURLFormatter
import org.matrix.android.sdk.internal.util.md5
import retrofit2.Retrofit
@@ -259,7 +261,7 @@ internal abstract class SessionModule {
sessionParams: SessionParams,
retrofitFactory: RetrofitFactory): Retrofit {
return retrofitFactory
- .create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString())
+ .create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUriBase.toString())
}
@JvmStatic
@@ -362,7 +364,7 @@ internal abstract class SessionModule {
abstract fun bindHomeServerCapabilitiesService(service: DefaultHomeServerCapabilitiesService): HomeServerCapabilitiesService
@Binds
- abstract fun bindAccountDataService(service: DefaultAccountDataService): AccountDataService
+ abstract fun bindSessionAccountDataService(service: DefaultSessionAccountDataService): SessionAccountDataService
@Binds
abstract fun bindEventService(service: DefaultEventService): EventService
@@ -373,6 +375,9 @@ internal abstract class SessionModule {
@Binds
abstract fun bindPermalinkService(service: DefaultPermalinkService): PermalinkService
+ @Binds
+ abstract fun bindOpenIdTokenService(service: DefaultOpenIdService): OpenIdService
+
@Binds
abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
index a190ff62ac..bdc254fc99 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
@@ -20,11 +20,14 @@ import io.realm.Realm
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.internal.database.model.EventInsertType
+import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
import org.matrix.android.sdk.internal.session.SessionScope
import timber.log.Timber
import javax.inject.Inject
+private val loggerTag = LoggerTag("CallEventProcessor", LoggerTag.VOIP)
+
@SessionScope
internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler)
: EventInsertLiveProcessor {
@@ -37,7 +40,9 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
EventType.CALL_CANDIDATES,
EventType.CALL_INVITE,
EventType.CALL_HANGUP,
- EventType.ENCRYPTED
+ EventType.ENCRYPTED,
+ EventType.CALL_ASSERTED_IDENTITY,
+ EventType.CALL_ASSERTED_IDENTITY_PREFIX
)
private val eventsToPostProcess = mutableListOf()
@@ -57,9 +62,8 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
return eventType == EventType.CALL_INVITE
}
- suspend fun processFastLane(event: Event) {
- eventsToPostProcess.add(event)
- onPostProcess()
+ fun processFastLane(event: Event) {
+ dispatchToCallSignalingHandlerIfNeeded(event)
}
override suspend fun onPostProcess() {
@@ -70,15 +74,8 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
}
private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) {
- val now = System.currentTimeMillis()
- // TODO might check if an invite is not closed (hangup/answered) in the same event batch?
event.roomId ?: return Unit.also {
- Timber.w("Event with no room id ${event.eventId}")
- }
- val age = now - (event.ageLocalTs ?: now)
- if (age > 40_000) {
- // To old to ring?
- return
+ Timber.tag(loggerTag.value).w("Event with no room id ${event.eventId}")
}
callSignalingHandler.onCallEvent(event)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt
index 1de2d8a106..dad17f4ac9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt
@@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.call.CallListener
import org.matrix.android.sdk.api.session.call.MxCall
import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallAssertedIdentityContent
import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
@@ -64,6 +65,10 @@ internal class CallListenersDispatcher(private val listeners: Set)
it.onCallNegotiateReceived(callNegotiateContent)
}
+ override fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent) = dispatch {
+ it.onCallAssertedIdentityReceived(callAssertedIdentityContent)
+ }
+
private fun dispatch(lambda: (CallListener) -> Unit) {
listeners.toList().forEach {
tryOrNull {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt
index 8d7e9e819a..59058bf976 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt
@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.session.call
+import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.CallListener
import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxCall
@@ -23,26 +24,28 @@ import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallAssertedIdentityContent
import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
-import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
-import org.matrix.android.sdk.api.session.room.model.call.CallSignallingContent
-import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.SessionScope
import timber.log.Timber
-import java.math.BigDecimal
import javax.inject.Inject
+private val loggerTag = LoggerTag("CallSignalingHandler", LoggerTag.VOIP)
+private const val MAX_AGE_TO_RING = 40_000
+
@SessionScope
internal class CallSignalingHandler @Inject constructor(private val activeCallHandler: ActiveCallHandler,
private val mxCallFactory: MxCallFactory,
@UserId private val userId: String) {
+ private val invitedCallIds = mutableSetOf()
private val callListeners = mutableSetOf()
private val callListenersDispatcher = CallListenersDispatcher(callListeners)
@@ -56,30 +59,44 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
fun onCallEvent(event: Event) {
when (event.getClearType()) {
- EventType.CALL_ANSWER -> {
+ EventType.CALL_ANSWER -> {
handleCallAnswerEvent(event)
}
- EventType.CALL_INVITE -> {
+ EventType.CALL_INVITE -> {
handleCallInviteEvent(event)
}
- EventType.CALL_HANGUP -> {
+ EventType.CALL_HANGUP -> {
handleCallHangupEvent(event)
}
- EventType.CALL_REJECT -> {
+ EventType.CALL_REJECT -> {
handleCallRejectEvent(event)
}
- EventType.CALL_CANDIDATES -> {
+ EventType.CALL_CANDIDATES -> {
handleCallCandidatesEvent(event)
}
- EventType.CALL_SELECT_ANSWER -> {
+ EventType.CALL_SELECT_ANSWER -> {
handleCallSelectAnswerEvent(event)
}
- EventType.CALL_NEGOTIATE -> {
+ EventType.CALL_NEGOTIATE -> {
handleCallNegotiateEvent(event)
}
+ EventType.CALL_ASSERTED_IDENTITY,
+ EventType.CALL_ASSERTED_IDENTITY_PREFIX -> {
+ handleCallAssertedIdentityEvent(event)
+ }
}
}
+ private fun handleCallAssertedIdentityEvent(event: Event) {
+ val content = event.getClearContent().toModel() ?: return
+ val call = content.getCall() ?: return
+ if (call.ourPartyId == content.partyId) {
+ // Ignore remote echo (not that we send asserted identity, but still...)
+ return
+ }
+ callListenersDispatcher.onCallAssertedIdentityReceived(content)
+ }
+
private fun handleCallNegotiateEvent(event: Event) {
val content = event.getClearContent().toModel() ?: return
val call = content.getCall() ?: return
@@ -98,12 +115,12 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
return
}
if (call.isOutgoing) {
- Timber.v("Got selectAnswer for an outbound call: ignoring")
+ Timber.tag(loggerTag.value).v("Got selectAnswer for an outbound call: ignoring")
return
}
val selectedPartyId = content.selectedPartyId
if (selectedPartyId == null) {
- Timber.w("Got nonsensical select_answer with null selected_party_id: ignoring")
+ Timber.tag(loggerTag.value).w("Got nonsensical select_answer with null selected_party_id: ignoring")
return
}
callListenersDispatcher.onCallSelectAnswerReceived(content)
@@ -117,7 +134,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
return
}
if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
- Timber.v("Ignoring candidates from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
+ Timber.tag(loggerTag.value).v("Ignoring candidates from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
return
}
callListenersDispatcher.onCallIceCandidateReceived(call, content)
@@ -150,10 +167,10 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
// a partner yet but we're treating the hangup as a reject as per VoIP v0)
if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
- Timber.v("Ignoring hangup from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
+ Timber.tag(loggerTag.value).v("Ignoring hangup from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
return
}
- if (call.state != CallState.Terminated) {
+ if (call.state !is CallState.Ended) {
activeCallHandler.removeCall(content.callId)
callListenersDispatcher.onCallHangupReceived(content)
}
@@ -167,20 +184,26 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
if (event.roomId == null || event.senderId == null) {
return
}
+ val now = System.currentTimeMillis()
+ val age = now - (event.ageLocalTs ?: now)
+ if (age > MAX_AGE_TO_RING) {
+ Timber.tag(loggerTag.value).w("Call invite is too old to ring.")
+ return
+ }
val content = event.getClearContent().toModel() ?: return
content.callId ?: return
- if (activeCallHandler.getCallWithId(content.callId) != null) {
+ if (invitedCallIds.contains(content.callId)) {
// Call is already known, maybe due to fast lane. Ignore
- Timber.d("Ignoring already known call invite")
+ Timber.tag(loggerTag.value).d("Ignoring already known call invite")
return
}
-
val incomingCall = mxCallFactory.createIncomingCall(
roomId = event.roomId,
opponentUserId = event.senderId,
content = content
) ?: return
+ invitedCallIds.add(content.callId)
activeCallHandler.addCall(incomingCall)
callListenersDispatcher.onCallInviteReceived(incomingCall, content)
}
@@ -192,34 +215,34 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
// Ignore remote echo
return
}
+ if (event.roomId == null || event.senderId == null) {
+ return
+ }
if (event.senderId == userId) {
// discard current call, it's answered by another of my session
activeCallHandler.removeCall(call.callId)
callListenersDispatcher.onCallManagedByOtherSession(content.callId)
} else {
if (call.opponentPartyId != null) {
- Timber.v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}")
+ Timber.tag(loggerTag.value)
+ .v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}")
return
}
- call.apply {
- opponentPartyId = Optional.from(content.partyId)
- opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION
- capabilities = content.capabilities ?: CallCapabilities()
- }
+ mxCallFactory.updateOutgoingCallWithOpponentData(call, event.senderId, content, content.capabilities)
callListenersDispatcher.onCallAnswerReceived(content)
}
}
- private fun MxCall.partyIdsMatches(contentSignallingContent: CallSignallingContent): Boolean {
- return opponentPartyId?.getOrNull() == contentSignallingContent.partyId
+ private fun MxCall.partyIdsMatches(contentSignalingContent: CallSignalingContent): Boolean {
+ return opponentPartyId?.getOrNull() == contentSignalingContent.partyId
}
- private fun CallSignallingContent.getCall(): MxCall? {
+ private fun CallSignalingContent.getCall(): MxCall? {
val currentCall = callId?.let {
activeCallHandler.getCallWithId(it)
}
if (currentCall == null) {
- Timber.v("Call with id $callId is null")
+ Timber.tag(loggerTag.value).v("Call with id $callId is null")
}
return currentCall
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
index 7d046cb642..4a949e21a6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
@@ -19,10 +19,8 @@ package org.matrix.android.sdk.internal.session.call
import org.matrix.android.sdk.api.session.call.CallListener
import org.matrix.android.sdk.api.session.call.CallSignalingService
import org.matrix.android.sdk.api.session.call.MxCall
-import org.matrix.android.sdk.api.session.call.PSTNProtocolChecker
import org.matrix.android.sdk.api.session.call.TurnServerResponse
import org.matrix.android.sdk.internal.session.SessionScope
-import timber.log.Timber
import javax.inject.Inject
@SessionScope
@@ -30,18 +28,13 @@ internal class DefaultCallSignalingService @Inject constructor(
private val callSignalingHandler: CallSignalingHandler,
private val mxCallFactory: MxCallFactory,
private val activeCallHandler: ActiveCallHandler,
- private val turnServerDataSource: TurnServerDataSource,
- private val pstnProtocolChecker: PSTNProtocolChecker
+ private val turnServerDataSource: TurnServerDataSource
) : CallSignalingService {
override suspend fun getTurnServer(): TurnServerResponse {
return turnServerDataSource.getTurnServer()
}
- override fun getPSTNProtocolChecker(): PSTNProtocolChecker {
- return pstnProtocolChecker
- }
-
override fun createOutgoingCall(roomId: String, otherUserId: String, isVideoCall: Boolean): MxCall {
return mxCallFactory.createOutgoingCall(roomId, otherUserId, isVideoCall).also {
activeCallHandler.addCall(it)
@@ -57,7 +50,6 @@ internal class DefaultCallSignalingService @Inject constructor(
}
override fun getCallWithId(callId: String): MxCall? {
- Timber.v("## VOIP getCallWithId $callId all calls ${activeCallHandler.getActiveCallsLiveData().value?.map { it.callId }}")
return activeCallHandler.getCallWithId(callId)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt
index b14cdca63c..547be2253f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt
@@ -17,18 +17,17 @@
package org.matrix.android.sdk.internal.session.call
import org.matrix.android.sdk.api.MatrixConfiguration
+import org.matrix.android.sdk.api.session.call.CallIdGenerator
import org.matrix.android.sdk.api.session.call.MxCall
import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
-import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent
import org.matrix.android.sdk.internal.di.DeviceId
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.call.model.MxCallImpl
import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask
import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
-import java.math.BigDecimal
-import java.util.UUID
import javax.inject.Inject
internal class MxCallFactory @Inject constructor(
@@ -48,32 +47,38 @@ internal class MxCallFactory @Inject constructor(
roomId = roomId,
userId = userId,
ourPartyId = deviceId ?: "",
- opponentUserId = opponentUserId,
isVideoCall = content.isVideo(),
localEchoEventFactory = localEchoEventFactory,
eventSenderProcessor = eventSenderProcessor,
matrixConfiguration = matrixConfiguration,
getProfileInfoTask = getProfileInfoTask
).apply {
- opponentPartyId = Optional.from(content.partyId)
- opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION
- capabilities = content.capabilities ?: CallCapabilities()
+ updateOpponentData(opponentUserId, content, content.capabilities)
}
}
fun createOutgoingCall(roomId: String, opponentUserId: String, isVideoCall: Boolean): MxCall {
return MxCallImpl(
- callId = UUID.randomUUID().toString(),
+ callId = CallIdGenerator.generate(),
isOutgoing = true,
roomId = roomId,
userId = userId,
ourPartyId = deviceId ?: "",
- opponentUserId = opponentUserId,
isVideoCall = isVideoCall,
localEchoEventFactory = localEchoEventFactory,
eventSenderProcessor = eventSenderProcessor,
matrixConfiguration = matrixConfiguration,
getProfileInfoTask = getProfileInfoTask
- )
+ ).apply {
+ // Setup with this userId, might be updated when processing the Answer event
+ this.opponentUserId = opponentUserId
+ }
+ }
+
+ fun updateOutgoingCallWithOpponentData(call: MxCall,
+ userId: String,
+ content: CallSignalingContent,
+ callCapabilities: CallCapabilities?) {
+ (call as? MxCallImpl)?.updateOpponentData(userId, content, callCapabilities)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
index 88fba0ea85..9fc84e6fe5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
@@ -17,6 +17,8 @@
package org.matrix.android.sdk.internal.session.call.model
import org.matrix.android.sdk.api.MatrixConfiguration
+import org.matrix.android.sdk.api.logger.LoggerTag
+import org.matrix.android.sdk.api.session.call.CallIdGenerator
import org.matrix.android.sdk.api.session.call.CallState
import org.matrix.android.sdk.api.session.call.MxCall
import org.matrix.android.sdk.api.session.events.model.Content
@@ -36,6 +38,8 @@ import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
import org.matrix.android.sdk.api.session.room.model.call.CallReplacesContent
import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent
+import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
import org.matrix.android.sdk.api.session.room.model.call.SdpType
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.internal.session.call.DefaultCallSignalingService
@@ -43,14 +47,15 @@ import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask
import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
import timber.log.Timber
-import java.util.UUID
+import java.math.BigDecimal
+
+private val loggerTag = LoggerTag("MxCallImpl", LoggerTag.VOIP)
internal class MxCallImpl(
override val callId: String,
override val isOutgoing: Boolean,
override val roomId: String,
private val userId: String,
- override val opponentUserId: String,
override val isVideoCall: Boolean,
override val ourPartyId: String,
private val localEchoEventFactory: LocalEchoEventFactory,
@@ -61,8 +66,16 @@ internal class MxCallImpl(
override var opponentPartyId: Optional? = null
override var opponentVersion: Int = MxCall.VOIP_PROTO_VERSION
+ override lateinit var opponentUserId: String
override var capabilities: CallCapabilities? = null
+ fun updateOpponentData(userId: String, content: CallSignalingContent, callCapabilities: CallCapabilities?) {
+ opponentPartyId = Optional.from(content.partyId)
+ opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION
+ opponentUserId = userId
+ capabilities = callCapabilities ?: CallCapabilities()
+ }
+
override var state: CallState = CallState.Idle
set(value) {
field = value
@@ -84,7 +97,7 @@ internal class MxCallImpl(
try {
it.onStateUpdate(this)
} catch (failure: Throwable) {
- Timber.d("dispatchStateChange failed for call $callId : ${failure.localizedMessage}")
+ Timber.tag(loggerTag.value).d("dispatchStateChange failed for call $callId : ${failure.localizedMessage}")
}
}
}
@@ -100,7 +113,7 @@ internal class MxCallImpl(
override fun offerSdp(sdpString: String) {
if (!isOutgoing) return
- Timber.v("## VOIP offerSdp $callId")
+ Timber.tag(loggerTag.value).v("offerSdp $callId")
state = CallState.Dialing
CallInviteContent(
callId = callId,
@@ -115,7 +128,7 @@ internal class MxCallImpl(
}
override fun sendLocalCallCandidates(candidates: List) {
- Timber.v("Send local call canditates $callId: $candidates")
+ Timber.tag(loggerTag.value).v("Send local call canditates $callId: $candidates")
CallCandidatesContent(
callId = callId,
partyId = ourPartyId,
@@ -132,11 +145,11 @@ internal class MxCallImpl(
override fun reject() {
if (opponentVersion < 1) {
- Timber.v("Opponent version is less than 1 ($opponentVersion): sending hangup instead of reject")
- hangUp()
+ Timber.tag(loggerTag.value).v("Opponent version is less than 1 ($opponentVersion): sending hangup instead of reject")
+ hangUp(EndCallReason.USER_HANGUP)
return
}
- Timber.v("## VOIP reject $callId")
+ Timber.tag(loggerTag.value).v("reject $callId")
CallRejectContent(
callId = callId,
partyId = ourPartyId,
@@ -144,24 +157,24 @@ internal class MxCallImpl(
)
.let { createEventAndLocalEcho(type = EventType.CALL_REJECT, roomId = roomId, content = it.toContent()) }
.also { eventSenderProcessor.postEvent(it) }
- state = CallState.Terminated
+ state = CallState.Ended(reason = EndCallReason.USER_HANGUP)
}
- override fun hangUp(reason: CallHangupContent.Reason?) {
- Timber.v("## VOIP hangup $callId")
+ override fun hangUp(reason: EndCallReason?) {
+ Timber.tag(loggerTag.value).v("hangup $callId")
CallHangupContent(
callId = callId,
partyId = ourPartyId,
- reason = reason ?: CallHangupContent.Reason.USER_HANGUP,
+ reason = reason,
version = MxCall.VOIP_PROTO_VERSION.toString()
)
.let { createEventAndLocalEcho(type = EventType.CALL_HANGUP, roomId = roomId, content = it.toContent()) }
.also { eventSenderProcessor.postEvent(it) }
- state = CallState.Terminated
+ state = CallState.Ended(reason)
}
override fun accept(sdpString: String) {
- Timber.v("## VOIP accept $callId")
+ Timber.tag(loggerTag.value).v("accept $callId")
if (isOutgoing) return
state = CallState.Answering
CallAnswerContent(
@@ -176,7 +189,7 @@ internal class MxCallImpl(
}
override fun negotiate(sdpString: String, type: SdpType) {
- Timber.v("## VOIP negotiate $callId")
+ Timber.tag(loggerTag.value).v("negotiate $callId")
CallNegotiateContent(
callId = callId,
partyId = ourPartyId,
@@ -189,7 +202,7 @@ internal class MxCallImpl(
}
override fun selectAnswer() {
- Timber.v("## VOIP select answer $callId")
+ Timber.tag(loggerTag.value).v("select answer $callId")
if (isOutgoing) return
state = CallState.Answering
CallSelectAnswerContent(
@@ -202,26 +215,30 @@ internal class MxCallImpl(
.also { eventSenderProcessor.postEvent(it) }
}
- override suspend fun transfer(targetUserId: String, targetRoomId: String?) {
+ override suspend fun transfer(targetUserId: String,
+ targetRoomId: String?,
+ createCallId: String?,
+ awaitCallId: String?) {
val profileInfoParams = GetProfileInfoTask.Params(targetUserId)
val profileInfo = try {
getProfileInfoTask.execute(profileInfoParams)
} catch (failure: Throwable) {
- Timber.v("Fail fetching profile info of $targetUserId while transferring call")
+ Timber.tag(loggerTag.value).v("Fail fetching profile info of $targetUserId while transferring call")
null
}
CallReplacesContent(
callId = callId,
partyId = ourPartyId,
- replacementId = UUID.randomUUID().toString(),
+ replacementId = CallIdGenerator.generate(),
version = MxCall.VOIP_PROTO_VERSION.toString(),
targetUser = CallReplacesContent.TargetUser(
id = targetUserId,
displayName = profileInfo?.get(ProfileService.DISPLAY_NAME_KEY) as? String,
avatarUrl = profileInfo?.get(ProfileService.AVATAR_URL_KEY) as? String
),
- targerRoomId = targetRoomId,
- createCall = UUID.randomUUID().toString()
+ targetRoomId = targetRoomId,
+ awaitCall = awaitCallId,
+ createCall = createCallId
)
.let { createEventAndLocalEcho(type = EventType.CALL_REPLACES, roomId = roomId, content = it.toContent()) }
.also { eventSenderProcessor.postEvent(it) }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt
index b5c1e6a282..8870d92a35 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt
@@ -51,15 +51,12 @@ internal class CleanupSession @Inject constructor(
@UserMd5 private val userMd5: String
) {
suspend fun handle() {
- Timber.d("Cleanup: release session...")
- sessionManager.releaseSession(sessionId)
+ Timber.d("Cleanup: delete session params...")
+ sessionParamsStore.delete(sessionId)
Timber.d("Cleanup: cancel pending works...")
workManagerProvider.cancelAllWorks()
- Timber.d("Cleanup: delete session params...")
- sessionParamsStore.delete(sessionId)
-
Timber.d("Cleanup: clear session data...")
clearSessionDataTask.execute(Unit)
@@ -74,6 +71,9 @@ internal class CleanupSession @Inject constructor(
realmKeysUtils.clear(SessionModule.getKeyAlias(userMd5))
realmKeysUtils.clear(CryptoModule.getKeyAlias(userMd5))
+ Timber.d("Cleanup: release session...")
+ sessionManager.releaseSession(sessionId)
+
// Sanity check
if (BuildConfig.DEBUG) {
Realm.getGlobalInstanceCount(realmSessionConfiguration)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt
index f765056496..e4efdaa254 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt
@@ -26,7 +26,7 @@ private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
- private val baseUrl = homeServerConnectionConfig.homeServerUri.toString().ensureTrailingSlash()
+ private val baseUrl = homeServerConnectionConfig.homeServerUriBase.toString().ensureTrailingSlash()
override val uploadUrl = baseUrl + NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "upload"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt
index 6bb43d599c..6a4dd26392 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt
@@ -47,14 +47,15 @@ import java.io.FileNotFoundException
import java.io.IOException
import javax.inject.Inject
-internal class FileUploader @Inject constructor(@Authenticated
- private val okHttpClient: OkHttpClient,
- private val globalErrorReceiver: GlobalErrorReceiver,
- private val homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService,
- private val context: Context,
- private val temporaryFileCreator: TemporaryFileCreator,
- contentUrlResolver: ContentUrlResolver,
- moshi: Moshi) {
+internal class FileUploader @Inject constructor(
+ @Authenticated private val okHttpClient: OkHttpClient,
+ private val globalErrorReceiver: GlobalErrorReceiver,
+ private val homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService,
+ private val context: Context,
+ private val temporaryFileCreator: TemporaryFileCreator,
+ contentUrlResolver: ContentUrlResolver,
+ moshi: Moshi
+) {
private val uploadUrl = contentUrlResolver.uploadUrl
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
@@ -120,11 +121,17 @@ internal class FileUploader @Inject constructor(@Authenticated
}
}
- private suspend fun upload(uploadBody: RequestBody, filename: String?, progressListener: ProgressRequestBody.Listener?): ContentUploadResponse {
+ private suspend fun upload(uploadBody: RequestBody,
+ filename: String?,
+ progressListener: ProgressRequestBody.Listener?): ContentUploadResponse {
val urlBuilder = uploadUrl.toHttpUrlOrNull()?.newBuilder() ?: throw RuntimeException()
val httpUrl = urlBuilder
- .addQueryParameter("filename", filename)
+ .apply {
+ if (filename != null) {
+ addQueryParameter("filename", filename)
+ }
+ }
.build()
val requestBody = if (progressListener != null) ProgressRequestBody(uploadBody, progressListener) else uploadBody
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt
index c28668a53e..82cd682eae 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt
@@ -23,8 +23,11 @@ import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.util.MimeTypes
import timber.log.Timber
import java.io.ByteArrayOutputStream
+import javax.inject.Inject
-internal object ThumbnailExtractor {
+internal class ThumbnailExtractor @Inject constructor(
+ private val context: Context
+) {
class ThumbnailData(
val width: Int,
@@ -34,22 +37,22 @@ internal object ThumbnailExtractor {
val mimeType: String
)
- fun extractThumbnail(context: Context, attachment: ContentAttachmentData): ThumbnailData? {
+ fun extractThumbnail(attachment: ContentAttachmentData): ThumbnailData? {
return if (attachment.type == ContentAttachmentData.Type.VIDEO) {
- extractVideoThumbnail(context, attachment)
+ extractVideoThumbnail(attachment)
} else {
null
}
}
- private fun extractVideoThumbnail(context: Context, attachment: ContentAttachmentData): ThumbnailData? {
+ private fun extractVideoThumbnail(attachment: ContentAttachmentData): ThumbnailData? {
var thumbnailData: ThumbnailData? = null
val mediaMetadataRetriever = MediaMetadataRetriever()
try {
mediaMetadataRetriever.setDataSource(context, attachment.queryUri)
mediaMetadataRetriever.frameAtTime?.let { thumbnail ->
val outputStream = ByteArrayOutputStream()
- thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
+ thumbnail.compress(Bitmap.CompressFormat.JPEG, 80, outputStream)
val thumbnailWidth = thumbnail.width
val thumbnailHeight = thumbnail.height
val thumbnailSize = outputStream.size()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt
index d5c3deeec6..f14c85cf80 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt
@@ -82,6 +82,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
@Inject lateinit var cancelSendTracker: CancelSendTracker
@Inject lateinit var imageCompressor: ImageCompressor
@Inject lateinit var videoCompressor: VideoCompressor
+ @Inject lateinit var thumbnailExtractor: ThumbnailExtractor
@Inject lateinit var localEchoRepository: LocalEchoRepository
@Inject lateinit var temporaryFileCreator: TemporaryFileCreator
@@ -229,26 +230,31 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
val encryptedFile: File?
val contentUploadResponse = if (params.isEncrypted) {
Timber.v("## Encrypt file")
-
encryptedFile = temporaryFileCreator.create()
.also { filesToDelete.add(it) }
uploadedFileEncryptedFileInfo =
- MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), attachment.getSafeMimeType(), encryptedFile) { read, total ->
+ MXEncryptedAttachments.encrypt(fileToUpload.inputStream(), encryptedFile) { read, total ->
notifyTracker(params) {
contentUploadStateTracker.setEncrypting(it, read.toLong(), total.toLong())
}
}
-
Timber.v("## Uploading file")
-
- fileUploader
- .uploadFile(encryptedFile, attachment.name, MimeTypes.OctetStream, progressListener)
+ fileUploader.uploadFile(
+ file = encryptedFile,
+ filename = null,
+ mimeType = MimeTypes.OctetStream,
+ progressListener = progressListener
+ )
} else {
- Timber.v("## Clear file")
+ Timber.v("## Uploading clear file")
encryptedFile = null
- fileUploader
- .uploadFile(fileToUpload, attachment.name, attachment.getSafeMimeType(), progressListener)
+ fileUploader.uploadFile(
+ file = fileToUpload,
+ filename = attachment.name,
+ mimeType = attachment.getSafeMimeType(),
+ progressListener = progressListener
+ )
}
Timber.v("## Update cache storage for ${contentUploadResponse.contentUri}")
@@ -297,7 +303,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
* If appropriate, it will create and upload a thumbnail
*/
private suspend fun dealWithThumbnail(params: Params): UploadThumbnailResult? {
- return ThumbnailExtractor.extractThumbnail(context, params.attachment)
+ return thumbnailExtractor.extractThumbnail(params.attachment)
?.let { thumbnailData ->
val thumbnailProgressListener = object : ProgressRequestBody.Listener {
override fun onProgress(current: Long, total: Long) {
@@ -309,10 +315,10 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
if (params.isEncrypted) {
Timber.v("Encrypt thumbnail")
notifyTracker(params) { contentUploadStateTracker.setEncryptingThumbnail(it) }
- val encryptionResult = MXEncryptedAttachments.encryptAttachment(thumbnailData.bytes.inputStream(), thumbnailData.mimeType)
+ val encryptionResult = MXEncryptedAttachments.encryptAttachment(thumbnailData.bytes.inputStream())
val contentUploadResponse = fileUploader.uploadByteArray(
byteArray = encryptionResult.encryptedByteArray,
- filename = "thumb_${params.attachment.name}",
+ filename = null,
mimeType = MimeTypes.OctetStream,
progressListener = thumbnailProgressListener
)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/events/DefaultEventService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/events/DefaultEventService.kt
index d7e9ef2ee0..9d80f27e01 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/events/DefaultEventService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/events/DefaultEventService.kt
@@ -29,7 +29,7 @@ internal class DefaultEventService @Inject constructor(
override suspend fun getEvent(roomId: String, eventId: String): Event {
val event = getEventTask.execute(GetEventTask.Params(roomId, eventId))
-
+ event.ageLocalTs = event.unsignedData?.age?.let { System.currentTimeMillis() - it }
// Fast lane to the call event processors: try to make the incoming call ring faster
if (callEventProcessor.shouldProcessFastLane(event.getClearType())) {
callEventProcessor.processFastLane(event)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
index 0ed690d972..4c755b54b5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
@@ -16,18 +16,12 @@
package org.matrix.android.sdk.internal.session.homeserver
-import com.zhuinden.monarchy.Monarchy
-import io.realm.Realm
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
-import org.matrix.android.sdk.internal.database.mapper.HomeServerCapabilitiesMapper
-import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
-import org.matrix.android.sdk.internal.database.query.get
-import org.matrix.android.sdk.internal.di.SessionDatabase
import javax.inject.Inject
internal class DefaultHomeServerCapabilitiesService @Inject constructor(
- @SessionDatabase private val monarchy: Monarchy,
+ private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource,
private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask
) : HomeServerCapabilitiesService {
@@ -36,11 +30,7 @@ internal class DefaultHomeServerCapabilitiesService @Inject constructor(
}
override fun getHomeServerCapabilities(): HomeServerCapabilities {
- return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
- HomeServerCapabilitiesEntity.get(realm)?.let {
- HomeServerCapabilitiesMapper.map(it)
- }
- }
+ return homeServerCapabilitiesDataSource.getHomeServerCapabilities()
?: HomeServerCapabilities()
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt
index ab029a0fce..1fe4f9d90a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.homeserver
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.extensions.orTrue
+import org.matrix.android.sdk.api.util.JsonDict
/**
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-capabilities
@@ -38,9 +39,14 @@ internal data class Capabilities(
* Capability to indicate if the user can change their password.
*/
@Json(name = "m.change_password")
- val changePassword: ChangePassword? = null
+ val changePassword: ChangePassword? = null,
- // No need for m.room_versions for the moment
+ /**
+ * This capability describes the default and available room versions a server supports, and at what level of stability.
+ * Clients should make use of this capability to determine if users need to be encouraged to upgrade their rooms.
+ */
+ @Json(name = "m.room_versions")
+ val roomVersions: RoomVersions? = null
)
@JsonClass(generateAdapter = true)
@@ -52,6 +58,36 @@ internal data class ChangePassword(
val enabled: Boolean?
)
+@JsonClass(generateAdapter = true)
+internal data class RoomVersions(
+ /**
+ * Required. The default room version the server is using for new rooms.
+ */
+ @Json(name = "default")
+ val default: String?,
+
+ /**
+ * Required. A detailed description of the room versions the server supports.
+ */
+ @Json(name = "available")
+ val available: JsonDict? = null,
+
+ /**
+ * "room_capabilities": {
+ * "knock" : {
+ * "preferred": "7",
+ * "support" : ["7"]
+ * },
+ * "restricted" : {
+ * "preferred": "9",
+ * "support" : ["8", "9"]
+ * }
+ * }
+ */
+ @Json(name = "room_capabilities")
+ val roomCapabilities: JsonDict? = null
+)
+
// The spec says: If not present, the client should assume that password changes are possible via the API
internal fun GetCapabilitiesResult.canChangePassword(): Boolean {
return capabilities?.changePassword?.enabled.orTrue()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
index 740370123f..612b98f863 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
@@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.homeserver
import com.zhuinden.monarchy.Monarchy
+import org.matrix.android.sdk.api.MatrixPatterns.getDomain
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
@@ -24,6 +25,7 @@ import org.matrix.android.sdk.internal.auth.version.Versions
import org.matrix.android.sdk.internal.auth.version.isLoginAndRegistrationSupportedBySdk
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
import org.matrix.android.sdk.internal.database.query.getOrCreate
+import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
@@ -89,7 +91,10 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
}.getOrNull()
val wellknownResult = runCatching {
- getWellknownTask.execute(GetWellknownTask.Params(userId, homeServerConnectionConfig))
+ getWellknownTask.execute(GetWellknownTask.Params(
+ domain = userId.getDomain(),
+ homeServerConnectionConfig = homeServerConnectionConfig
+ ))
}.getOrNull()
insertInDb(capabilities, mediaConfig, versions, wellknownResult)
@@ -104,6 +109,10 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
if (getCapabilitiesResult != null) {
homeServerCapabilitiesEntity.canChangePassword = getCapabilitiesResult.canChangePassword()
+
+ homeServerCapabilitiesEntity.roomVersionsJson = getCapabilitiesResult.capabilities?.roomVersions?.let {
+ MoshiProvider.providesMoshi().adapter(RoomVersions::class.java).toJson(it)
+ }
}
if (getMediaConfigResult != null) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesDataSource.kt
new file mode 100644
index 0000000000..6c913fa41e
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerCapabilitiesDataSource.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.homeserver
+
+import com.zhuinden.monarchy.Monarchy
+import io.realm.Realm
+import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
+import org.matrix.android.sdk.internal.database.mapper.HomeServerCapabilitiesMapper
+import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
+import org.matrix.android.sdk.internal.database.query.get
+import org.matrix.android.sdk.internal.di.SessionDatabase
+import javax.inject.Inject
+
+internal class HomeServerCapabilitiesDataSource @Inject constructor(
+ @SessionDatabase private val monarchy: Monarchy
+) {
+ fun getHomeServerCapabilities(): HomeServerCapabilities? {
+ return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
+ HomeServerCapabilitiesEntity.get(realm)?.let {
+ HomeServerCapabilitiesMapper.map(it)
+ }
+ }
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
index 475781ef01..48870b86b7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
@@ -44,7 +44,7 @@ import org.matrix.android.sdk.internal.session.profile.BindThreePidsTask
import org.matrix.android.sdk.internal.session.profile.UnbindThreePidsTask
import org.matrix.android.sdk.internal.session.sync.model.accountdata.IdentityServerContent
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
-import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource
+import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.ensureProtocol
@@ -77,7 +77,7 @@ internal class DefaultIdentityService @Inject constructor(
private val submitTokenForBindingTask: IdentitySubmitTokenForBindingTask,
private val unbindThreePidsTask: UnbindThreePidsTask,
private val identityApiProvider: IdentityApiProvider,
- private val accountDataDataSource: AccountDataDataSource,
+ private val accountDataDataSource: UserAccountDataDataSource,
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
private val sessionParams: SessionParams
) : IdentityService, SessionLifecycleObserver {
@@ -191,7 +191,7 @@ internal class DefaultIdentityService @Inject constructor(
} else {
// Disconnect previous one if any, first, because the token will change.
// In case of error when configuring the new identity server, this is not a big deal,
- // we will ask for a new token on the previous Identity server
+ // we will ask for a new token on the previous identity server
runCatching { identityDisconnectTask.execute(Unit) }
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
@@ -241,7 +241,7 @@ internal class DefaultIdentityService @Inject constructor(
override suspend fun getShareStatus(threePids: List): Map {
// Note: we do not require user consent here, because it is used for emails and phone numbers that the user has already sent
- // to the home server, and not emails and phone numbers from the contact book of the user
+ // to the homeserver, and not emails and phone numbers from the contact book of the user
if (threePids.isEmpty()) {
return emptyMap()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAuthAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAuthAPI.kt
index 1671859585..f77eb296aa 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAuthAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAuthAPI.kt
@@ -16,9 +16,9 @@
package org.matrix.android.sdk.internal.session.identity
+import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.network.NetworkConstants
import org.matrix.android.sdk.internal.session.identity.model.IdentityRegisterResponse
-import org.matrix.android.sdk.internal.session.openid.RequestOpenIdTokenResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
@@ -42,7 +42,7 @@ internal interface IdentityAuthAPI {
suspend fun ping()
/**
- * Ping v1 will be used to check outdated Identity server
+ * Ping v1 will be used to check outdated identity server
*/
@GET("_matrix/identity/api/v1")
suspend fun pingV1()
@@ -52,5 +52,5 @@ internal interface IdentityAuthAPI {
* The request body is the same as the values returned by /openid/request_token in the Client-Server API.
*/
@POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "account/register")
- suspend fun register(@Body openIdToken: RequestOpenIdTokenResponse): IdentityRegisterResponse
+ suspend fun register(@Body openIdToken: OpenIdToken): IdentityRegisterResponse
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt
index 7a39a333a5..4d664b76be 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt
@@ -60,7 +60,6 @@ internal abstract class IdentityModule {
@SessionScope
fun providesIdentityRealmConfiguration(realmKeysUtils: RealmKeysUtils,
@SessionFilesDirectory directory: File,
- migration: RealmIdentityStoreMigration,
@UserMd5 userMd5: String): RealmConfiguration {
return RealmConfiguration.Builder()
.directory(directory)
@@ -69,7 +68,7 @@ internal abstract class IdentityModule {
realmKeysUtils.configureEncryption(this, SessionModule.getKeyAlias(userMd5))
}
.schemaVersion(RealmIdentityStoreMigration.IDENTITY_STORE_SCHEMA_VERSION)
- .migration(migration)
+ .migration(RealmIdentityStoreMigration)
.allowWritesOnUiThread(true)
.modules(IdentityRealmModule())
.build()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityRegisterTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityRegisterTask.kt
index 8cc854bd94..1800d0eebe 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityRegisterTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityRegisterTask.kt
@@ -16,16 +16,16 @@
package org.matrix.android.sdk.internal.session.identity
+import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.session.identity.model.IdentityRegisterResponse
-import org.matrix.android.sdk.internal.session.openid.RequestOpenIdTokenResponse
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface IdentityRegisterTask : Task {
data class Params(
val identityAuthAPI: IdentityAuthAPI,
- val openIdTokenResponse: RequestOpenIdTokenResponse
+ val openIdToken: OpenIdToken
)
}
@@ -33,7 +33,7 @@ internal class DefaultIdentityRegisterTask @Inject constructor() : IdentityRegis
override suspend fun execute(params: IdentityRegisterTask.Params): IdentityRegisterResponse {
return executeRequest(null) {
- params.identityAuthAPI.register(params.openIdTokenResponse)
+ params.identityAuthAPI.register(params.openIdToken)
}
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt
index 6081dbab12..21c0f8eb9e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt
@@ -19,13 +19,10 @@ package org.matrix.android.sdk.internal.session.identity.db
import io.realm.DynamicRealm
import io.realm.RealmMigration
import timber.log.Timber
-import javax.inject.Inject
-internal class RealmIdentityStoreMigration @Inject constructor() : RealmMigration {
+internal object RealmIdentityStoreMigration : RealmMigration {
- companion object {
- const val IDENTITY_STORE_SCHEMA_VERSION = 1L
- }
+ const val IDENTITY_STORE_SCHEMA_VERSION = 1L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.v("Migrating Realm Identity from $oldVersion to $newVersion")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
index 3df9a00cc1..b654b8610d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
@@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.session.SessionLifecycleObserver
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
-import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource
+import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory
import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence
@@ -43,8 +43,8 @@ import javax.inject.Inject
/**
* The integration manager allows to
- * - Get the Integration Manager that a user has explicitly set for its account (via account data)
- * - Get the recommended/preferred Integration Manager list as defined by the HomeServer (via wellknown)
+ * - Get the integration manager that a user has explicitly set for its account (via account data)
+ * - Get the recommended/preferred integration manager list as defined by the homeserver (via wellknown)
* - Check if the user has disabled the integration manager feature
* - Allow / Disallow Integration manager (propagated to other riot clients)
*
@@ -57,7 +57,7 @@ import javax.inject.Inject
internal class IntegrationManager @Inject constructor(matrixConfiguration: MatrixConfiguration,
@SessionDatabase private val monarchy: Monarchy,
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
- private val accountDataDataSource: AccountDataDataSource,
+ private val accountDataDataSource: UserAccountDataDataSource,
private val widgetFactory: WidgetFactory)
: SessionLifecycleObserver {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt
index 38f6b08b43..4e8abcf784 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt
@@ -113,8 +113,8 @@ internal class DefaultPushRuleService @Inject constructor(
addPushRuleTask.execute(AddPushRuleTask.Params(kind, pushRule))
}
- override suspend fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule) {
- updatePushRuleActionsTask.execute(UpdatePushRuleActionsTask.Params(kind, oldPushRule, newPushRule))
+ override suspend fun updatePushRuleActions(kind: RuleKind, ruleId: String, enable: Boolean, actions: List?) {
+ updatePushRuleActionsTask.execute(UpdatePushRuleActionsTask.Params(kind, ruleId, enable, actions))
}
override suspend fun removePushRule(kind: RuleKind, pushRule: PushRule) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt
new file mode 100644
index 0000000000..b90a2435f7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.openid
+
+import org.matrix.android.sdk.api.session.openid.OpenIdService
+import org.matrix.android.sdk.api.session.openid.OpenIdToken
+import javax.inject.Inject
+
+internal class DefaultOpenIdService @Inject constructor(private val getOpenIdTokenTask: GetOpenIdTokenTask): OpenIdService {
+
+ override suspend fun getOpenIdToken(): OpenIdToken {
+ return getOpenIdTokenTask.execute(Unit)
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/GetOpenIdTokenTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/GetOpenIdTokenTask.kt
index 8481a6ab93..a6ad025b8d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/GetOpenIdTokenTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/GetOpenIdTokenTask.kt
@@ -16,20 +16,21 @@
package org.matrix.android.sdk.internal.session.openid
+import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
-internal interface GetOpenIdTokenTask : Task
+internal interface GetOpenIdTokenTask : Task
internal class DefaultGetOpenIdTokenTask @Inject constructor(
@UserId private val userId: String,
private val openIdAPI: OpenIdAPI,
private val globalErrorReceiver: GlobalErrorReceiver) : GetOpenIdTokenTask {
- override suspend fun execute(params: Unit): RequestOpenIdTokenResponse {
+ override suspend fun execute(params: Unit): OpenIdToken {
return executeRequest(globalErrorReceiver) {
openIdAPI.openIdToken(userId)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt
index ed090b845d..eb8c841d57 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt
@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.session.openid
+import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.network.NetworkConstants
import retrofit2.http.Body
@@ -34,5 +35,5 @@ internal interface OpenIdAPI {
*/
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token")
suspend fun openIdToken(@Path("userId") userId: String,
- @Body body: JsonDict = emptyMap()): RequestOpenIdTokenResponse
+ @Body body: JsonDict = emptyMap()): OpenIdToken
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt
index 7db9d8f68a..134da4ce51 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt
@@ -33,8 +33,8 @@ internal class DefaultPermalinkService @Inject constructor(
return permalinkFactory.createPermalink(id)
}
- override fun createRoomPermalink(roomId: String): String? {
- return permalinkFactory.createRoomPermalink(roomId)
+ override fun createRoomPermalink(roomId: String, viaServers: List?): String? {
+ return permalinkFactory.createRoomPermalink(roomId, viaServers)
}
override fun createPermalink(roomId: String, eventId: String): String {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt
index 970752449a..639e45582a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt
@@ -40,11 +40,18 @@ internal class PermalinkFactory @Inject constructor(
} else MATRIX_TO_URL_BASE + escape(id)
}
- fun createRoomPermalink(roomId: String): String? {
+ fun createRoomPermalink(roomId: String, via: List? = null): String? {
return if (roomId.isEmpty()) {
null
} else {
- MATRIX_TO_URL_BASE + escape(roomId) + viaParameterFinder.computeViaParams(userId, roomId)
+ buildString {
+ append(MATRIX_TO_URL_BASE)
+ append(escape(roomId))
+ append(
+ via?.takeIf { it.isNotEmpty() }?.let { viaParameterFinder.asUrlViaParameters(it) }
+ ?: viaParameterFinder.computeViaParams(userId, roomId)
+ )
+ }
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
index 0da60e9ba2..21f55bbc42 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt
@@ -16,17 +16,25 @@
package org.matrix.android.sdk.internal.session.permalinks
+import org.matrix.android.sdk.api.MatrixPatterns.getDomain
+import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.Membership
+import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
+import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.RoomGetter
+import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import java.net.URLEncoder
import javax.inject.Inject
import javax.inject.Provider
internal class ViaParameterFinder @Inject constructor(
@UserId private val userId: String,
- private val roomGetterProvider: Provider
+ private val roomGetterProvider: Provider,
+ private val stateEventDataSource: StateEventDataSource
) {
fun computeViaParams(roomId: String, max: Int): List {
@@ -39,14 +47,17 @@ internal class ViaParameterFinder @Inject constructor(
* current user one.
*/
fun computeViaParams(userId: String, roomId: String): String {
- return computeViaParams(userId, roomId, 3)
- .joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
+ return asUrlViaParameters(computeViaParams(userId, roomId, 3))
+ }
+
+ fun asUrlViaParameters(viaList: List): String {
+ return viaList.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") }
}
fun computeViaParams(userId: String, roomId: String, max: Int): List {
- val userHomeserver = userId.substringAfter(":")
+ val userHomeserver = userId.getDomain()
return getUserIdsOfJoinedMembers(roomId)
- .map { it.substringAfter(":") }
+ .map { it.getDomain() }
.groupBy { it }
.mapValues { it.value.size }
.toMutableMap()
@@ -66,4 +77,28 @@ internal class ViaParameterFinder @Inject constructor(
.orEmpty()
.toSet()
}
+
+ fun computeViaParamsForRestricted(roomId: String, max: Int): List {
+ val userThatCanInvite = roomGetterProvider.get().getRoom(roomId)
+ ?.getRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.JOIN) })
+ ?.map { it.userId }
+ ?.filter { userCanInvite(userId, roomId) }
+ .orEmpty()
+ .toSet()
+
+ return userThatCanInvite.map { it.getDomain() }
+ .groupBy { it }
+ .mapValues { it.value.size }
+ .toMutableMap()
+ .let { map -> map.keys.sortedByDescending { map[it] } }
+ .take(max)
+ }
+
+ fun userCanInvite(userId: String, roomId: String): Boolean {
+ val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition)
+ ?.content?.toModel()
+ ?.let { PowerLevelsHelper(it) }
+
+ return powerLevelsHelper?.isUserAbleToInvite(userId) ?: false
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ProfileAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ProfileAPI.kt
index 485a4973ca..4b56db9f13 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ProfileAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/ProfileAPI.kt
@@ -86,7 +86,7 @@ internal interface ProfileAPI {
suspend fun addMsisdn(@Body body: AddMsisdnBody): AddMsisdnResponse
/**
- * Validate Msisdn code (same model than for Identity server API)
+ * Validate Msisdn code (same model than for identity server API)
*/
@POST
suspend fun validateMsisdn(@Url url: String,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt
index 2a24aee892..b8dbabd09e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/UpdatePushRuleActionsTask.kt
@@ -15,8 +15,9 @@
*/
package org.matrix.android.sdk.internal.session.pushers
+import org.matrix.android.sdk.api.pushrules.Action
import org.matrix.android.sdk.api.pushrules.RuleKind
-import org.matrix.android.sdk.api.pushrules.rest.PushRule
+import org.matrix.android.sdk.api.pushrules.toJson
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
@@ -25,8 +26,9 @@ import javax.inject.Inject
internal interface UpdatePushRuleActionsTask : Task {
data class Params(
val kind: RuleKind,
- val oldPushRule: PushRule,
- val newPushRule: PushRule
+ val ruleId: String,
+ val enable: Boolean,
+ val actions: List?
)
}
@@ -36,20 +38,14 @@ internal class DefaultUpdatePushRuleActionsTask @Inject constructor(
) : UpdatePushRuleActionsTask {
override suspend fun execute(params: UpdatePushRuleActionsTask.Params) {
- if (params.oldPushRule.enabled != params.newPushRule.enabled) {
- // First change enabled state
executeRequest(globalErrorReceiver) {
- pushRulesApi.updateEnableRuleStatus(params.kind.value, params.newPushRule.ruleId, params.newPushRule.enabled)
+ pushRulesApi.updateEnableRuleStatus(params.kind.value, params.ruleId, enable = params.enable)
}
- }
-
- if (params.newPushRule.enabled) {
- // Also ensure the actions are up to date
- val body = mapOf("actions" to params.newPushRule.actions)
-
- executeRequest(globalErrorReceiver) {
- pushRulesApi.updateRuleActions(params.kind.value, params.newPushRule.ruleId, body)
+ if (params.actions != null) {
+ val body = mapOf("actions" to params.actions.toJson())
+ executeRequest(globalErrorReceiver) {
+ pushRulesApi.updateRuleActions(params.kind.value, params.ruleId, body)
+ }
}
- }
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
index a5e066dae8..8afd690f64 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
@@ -20,6 +20,7 @@ import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.session.crypto.CryptoService
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.Room
+import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataService
import org.matrix.android.sdk.api.session.room.alias.AliasService
import org.matrix.android.sdk.api.session.room.call.RoomCallService
import org.matrix.android.sdk.api.session.room.members.MembershipService
@@ -36,6 +37,7 @@ import org.matrix.android.sdk.api.session.room.tags.TagsService
import org.matrix.android.sdk.api.session.room.timeline.TimelineService
import org.matrix.android.sdk.api.session.room.typing.TypingService
import org.matrix.android.sdk.api.session.room.uploads.UploadsService
+import org.matrix.android.sdk.api.session.room.version.RoomVersionService
import org.matrix.android.sdk.api.session.search.SearchResult
import org.matrix.android.sdk.api.session.space.Space
import org.matrix.android.sdk.api.util.Optional
@@ -47,28 +49,30 @@ import org.matrix.android.sdk.internal.session.search.SearchTask
import org.matrix.android.sdk.internal.session.space.DefaultSpace
import org.matrix.android.sdk.internal.util.awaitCallback
import java.security.InvalidParameterException
-import javax.inject.Inject
-internal class DefaultRoom @Inject constructor(override val roomId: String,
- private val roomSummaryDataSource: RoomSummaryDataSource,
- private val timelineService: TimelineService,
- private val sendService: SendService,
- private val draftService: DraftService,
- private val stateService: StateService,
- private val uploadsService: UploadsService,
- private val reportingService: ReportingService,
- private val roomCallService: RoomCallService,
- private val readService: ReadService,
- private val typingService: TypingService,
- private val aliasService: AliasService,
- private val tagsService: TagsService,
- private val cryptoService: CryptoService,
- private val relationService: RelationService,
- private val roomMembersService: MembershipService,
- private val roomPushRuleService: RoomPushRuleService,
- private val sendStateTask: SendStateTask,
- private val viaParameterFinder: ViaParameterFinder,
- private val searchTask: SearchTask) :
+internal class DefaultRoom(override val roomId: String,
+ private val roomSummaryDataSource: RoomSummaryDataSource,
+ private val timelineService: TimelineService,
+ private val sendService: SendService,
+ private val draftService: DraftService,
+ private val stateService: StateService,
+ private val uploadsService: UploadsService,
+ private val reportingService: ReportingService,
+ private val roomCallService: RoomCallService,
+ private val readService: ReadService,
+ private val typingService: TypingService,
+ private val aliasService: AliasService,
+ private val tagsService: TagsService,
+ private val cryptoService: CryptoService,
+ private val relationService: RelationService,
+ private val roomMembersService: MembershipService,
+ private val roomPushRuleService: RoomPushRuleService,
+ private val roomAccountDataService: RoomAccountDataService,
+ private val roomVersionService: RoomVersionService,
+ private val sendStateTask: SendStateTask,
+ private val viaParameterFinder: ViaParameterFinder,
+ private val searchTask: SearchTask
+) :
Room,
TimelineService by timelineService,
SendService by sendService,
@@ -83,7 +87,9 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
TagsService by tagsService,
RelationService by relationService,
MembershipService by roomMembersService,
- RoomPushRuleService by roomPushRuleService {
+ RoomPushRuleService by roomPushRuleService,
+ RoomAccountDataService by roomAccountDataService,
+ RoomVersionService by roomVersionService {
override fun getRoomSummaryLive(): LiveData> {
return roomSummaryDataSource.getRoomSummaryLive(roomId)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
index 218d846afb..7330c91c20 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
@@ -16,10 +16,13 @@
package org.matrix.android.sdk.internal.session.room
+import org.matrix.android.sdk.api.session.room.AliasAvailabilityResult
import org.matrix.android.sdk.api.session.room.RoomDirectoryService
+import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
+import org.matrix.android.sdk.internal.session.room.alias.RoomAliasAvailabilityChecker
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
@@ -28,7 +31,8 @@ import javax.inject.Inject
internal class DefaultRoomDirectoryService @Inject constructor(
private val getPublicRoomTask: GetPublicRoomTask,
private val getRoomDirectoryVisibilityTask: GetRoomDirectoryVisibilityTask,
- private val setRoomDirectoryVisibilityTask: SetRoomDirectoryVisibilityTask
+ private val setRoomDirectoryVisibilityTask: SetRoomDirectoryVisibilityTask,
+ private val roomAliasAvailabilityChecker: RoomAliasAvailabilityChecker
) : RoomDirectoryService {
override suspend fun getPublicRooms(server: String?,
@@ -43,4 +47,13 @@ internal class DefaultRoomDirectoryService @Inject constructor(
override suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility) {
setRoomDirectoryVisibilityTask.execute(SetRoomDirectoryVisibilityTask.Params(roomId, roomDirectoryVisibility))
}
+
+ override suspend fun checkAliasAvailability(aliasLocalPart: String?): AliasAvailabilityResult {
+ return try {
+ roomAliasAvailabilityChecker.check(aliasLocalPart)
+ AliasAvailabilityResult.Available
+ } catch (failure: RoomAliasError) {
+ AliasAvailabilityResult.NotAvailable(failure)
+ }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt
index d9fe1288e2..632ea4c450 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt
@@ -134,6 +134,10 @@ internal class DefaultRoomService @Inject constructor(
deleteRoomAliasTask.execute(DeleteRoomAliasTask.Params(roomAlias))
}
+ override fun getChangeMemberships(roomIdOrAlias: String): ChangeMembershipState {
+ return roomChangeMembershipStateDataSource.getState(roomIdOrAlias)
+ }
+
override fun getChangeMembershipsLive(): LiveData