mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge branch 'release/v1.4.22'
This commit is contained in:
commit
3390e206b0
1802
.editorconfig
1802
.editorconfig
File diff suppressed because it is too large
Load Diff
11
.github/ISSUE_TEMPLATE/bug.yml
vendored
11
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -73,3 +73,14 @@ body:
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Are you willing to provide a PR?
|
||||
description: |
|
||||
Providing a PR can drastically speed up the process of fixing this bug. Don't worry, it's still OK to answer 'No' :).
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
|
11
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
11
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@ -34,3 +34,14 @@ body:
|
||||
placeholder: Is there anything else you'd like to add?
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Are you willing to provide a PR?
|
||||
description: |
|
||||
Don't worry, it's still OK to answer 'No' :).
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
|
26
.github/ISSUE_TEMPLATE/release.yml
vendored
26
.github/ISSUE_TEMPLATE/release.yml
vendored
@ -49,24 +49,34 @@ body:
|
||||
|
||||
### Once tested and validated internally
|
||||
|
||||
- [ ] Create a new beta release on the GooglePlay console and upload the 4 signed Apks.
|
||||
- [ ] Create a new open testing 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
|
||||
- [ ] Notify the F-Droid team so that they can schedule the publication on F-Droid
|
||||
- [ ] Push the open testing release to 100% of the users
|
||||
- [ ] Notify the F-Droid team [here](https://matrix.to/#/!LAAuJLQXYHjMNWKrCK:matrix.org?via=matrix.org&via=bubu1.eu&via=lant.uk) so that they can schedule the publication on F-Droid
|
||||
- [ ] The application is available to the PlayStore testers (live). Google can take between 1 hour and up to 7 days to approve the release.
|
||||
- [ ] The application is available to the F-Droid users.
|
||||
|
||||
### Once Live on PlayStore
|
||||
### Once open testing is live on PlayStore
|
||||
|
||||
- [ ] Ping the Android public room and update its topic
|
||||
- [ ] Add an entry in the internal diary
|
||||
|
||||
### After at least 2 days
|
||||
### Once Live on F-Droid
|
||||
|
||||
- [ ] Update the Android public room topic
|
||||
|
||||
### After at least 2 days (generally next Monday)
|
||||
|
||||
- [ ] 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
|
||||
- [ ] If all is OK, promote the open testing release to production. Generally using a 100% roll out, but can be a smaller value depending on the release content.
|
||||
- [ ] The application is available to the PlayStore users (live). Google can take (again!) between 1 hour and up to 7 days to approve the release.
|
||||
|
||||
### Once production is live on PlayStore
|
||||
|
||||
- [ ] Ping the Android public room and update its topic
|
||||
- [ ] Add an entry in the internal diary
|
||||
|
||||
### Android SDK2
|
||||
|
||||
|
223
.github/workflows/post-pr.yml
vendored
223
.github/workflows/post-pr.yml
vendored
@ -29,200 +29,6 @@ jobs:
|
||||
steps:
|
||||
- run: echo "Run those tests!" # no-op success
|
||||
|
||||
# Run Android Tests
|
||||
integration-tests:
|
||||
name: Matrix SDK - Running Integration Tests
|
||||
needs: should-i-run
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
api-level: [ 28 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 11
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Start synapse server
|
||||
uses: michaelkaye/setup-matrix-synapse@v1.0.3
|
||||
with:
|
||||
uploadLogs: true
|
||||
httpPort: 8080
|
||||
disableRateLimiting: true
|
||||
public_baseurl: "http://10.0.2.2:8080/"
|
||||
# package: org.matrix.android.sdk.session
|
||||
- name: Run integration tests for Matrix SDK [org.matrix.android.sdk.session] API[${{ matrix.api-level }}]
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator-session.log
|
||||
chmod 777 emulator-session.log
|
||||
adb logcat >> emulator-session.log &
|
||||
./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.session' matrix-sdk-android:connectedDebugAndroidTest
|
||||
- name: Read Results [org.matrix.android.sdk.session]
|
||||
if: always()
|
||||
id: get-comment-body-session
|
||||
run: python3 ./tools/ci/render_test_output.py session ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml
|
||||
- name: Remove adb logcat
|
||||
if: always()
|
||||
run: pkill -9 adb
|
||||
- name: Run integration tests for Matrix SDK [org.matrix.android.sdk.account] API[${{ matrix.api-level }}]
|
||||
if: always()
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator-account.log
|
||||
chmod 777 emulator-account.log
|
||||
adb logcat >> emulator-account.log &
|
||||
./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.account' matrix-sdk-android:connectedDebugAndroidTest
|
||||
- name: Read Results [org.matrix.android.sdk.account]
|
||||
if: always()
|
||||
id: get-comment-body-account
|
||||
run: python3 ./tools/ci/render_test_output.py account ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml
|
||||
- name: Remove adb logcat
|
||||
if: always()
|
||||
run: pkill -9 adb
|
||||
# package: org.matrix.android.sdk.internal
|
||||
- name: Run integration tests for Matrix SDK [org.matrix.android.sdk.internal] API[${{ matrix.api-level }}]
|
||||
if: always()
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator-internal.log
|
||||
chmod 777 emulator-internal.log
|
||||
adb logcat >> emulator-internal.log &
|
||||
./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.internal' matrix-sdk-android:connectedDebugAndroidTest
|
||||
- name: Read Results [org.matrix.android.sdk.internal]
|
||||
if: always()
|
||||
id: get-comment-body-internal
|
||||
run: python3 ./tools/ci/render_test_output.py internal ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml
|
||||
- name: Remove adb logcat
|
||||
if: always()
|
||||
run: pkill -9 adb
|
||||
# package: org.matrix.android.sdk.ordering
|
||||
- name: Run integration tests for Matrix SDK [org.matrix.android.sdk.ordering] API[${{ matrix.api-level }}]
|
||||
if: always()
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator-ordering.log
|
||||
chmod 777 emulator-ordering.log
|
||||
adb logcat >> emulator-ordering.log &
|
||||
./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.package='org.matrix.android.sdk.ordering' matrix-sdk-android:connectedDebugAndroidTest
|
||||
- name: Read Results [org.matrix.android.sdk.ordering]
|
||||
if: always()
|
||||
id: get-comment-body-ordering
|
||||
run: python3 ./tools/ci/render_test_output.py ordering ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml
|
||||
- name: Remove adb logcat
|
||||
if: always()
|
||||
run: pkill -9 adb
|
||||
# package: class PermalinkParserTest
|
||||
- name: Run integration tests for Matrix SDK class [org.matrix.android.sdk.PermalinkParserTest] API[${{ matrix.api-level }}]
|
||||
if: always()
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator-permalink.log
|
||||
chmod 777 emulator-permalink.log
|
||||
adb logcat >> emulator-permalink.log &
|
||||
./gradlew $CI_GRADLE_ARG_PROPERTIES -Pandroid.testInstrumentationRunnerArguments.class='org.matrix.android.sdk.PermalinkParserTest' matrix-sdk-android:connectedDebugAndroidTest
|
||||
- name: Read Results [org.matrix.android.sdk.PermalinkParserTest]
|
||||
if: always()
|
||||
id: get-comment-body-permalink
|
||||
run: python3 ./tools/ci/render_test_output.py permalink ./matrix-sdk-android/build/outputs/androidTest-results/connected/*.xml
|
||||
- name: Remove adb logcat
|
||||
if: always()
|
||||
run: pkill -9 adb
|
||||
# package: class PermalinkParserTest
|
||||
- name: Find Comment
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
comment-author: 'github-actions[bot]'
|
||||
body-includes: Integration Tests Results
|
||||
- name: Publish results to PR
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
uses: peter-evans/create-or-update-comment@v2
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
### Matrix SDK
|
||||
## Integration Tests Results:
|
||||
- `[org.matrix.android.sdk.session]`<br>${{ steps.get-comment-body-session.outputs.session }}
|
||||
- `[org.matrix.android.sdk.account]`<br>${{ steps.get-comment-body-account.outputs.account }}
|
||||
- `[org.matrix.android.sdk.internal]`<br>${{ steps.get-comment-body-internal.outputs.internal }}
|
||||
- `[org.matrix.android.sdk.ordering]`<br>${{ steps.get-comment-body-ordering.outputs.ordering }}
|
||||
- `[org.matrix.android.sdk.PermalinkParserTest]`<br>${{ steps.get-comment-body-permalink.outputs.permalink }}
|
||||
edit-mode: replace
|
||||
- name: Upload Test Report Log
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: integrationtest-error-results
|
||||
path: |
|
||||
emulator-permalink.log
|
||||
emulator-internal.log
|
||||
emulator-ordering.log
|
||||
emulator-account.log
|
||||
emulator-session.log
|
||||
|
||||
ui-tests:
|
||||
name: UI Tests (Synapse)
|
||||
needs: should-i-run
|
||||
@ -282,42 +88,13 @@ jobs:
|
||||
emulator.log
|
||||
failure_screenshots/
|
||||
|
||||
codecov-units:
|
||||
name: Unit tests with code coverage
|
||||
needs: should-i-run
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- run: ./gradlew allCodeCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload Codecov data
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: codecov-xml
|
||||
path: |
|
||||
build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml
|
||||
|
||||
# Notify the channel about delayed failures
|
||||
notify:
|
||||
name: Notify matrix
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- should-i-run
|
||||
- integration-tests
|
||||
- ui-tests
|
||||
- codecov-units
|
||||
if: always() && (needs.should-i-run.result == 'success' ) && ((needs.codecov-units.result != 'success' ) || (needs.ui-tests.result != 'success') || (needs.integration-tests.result != 'success'))
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
|
81
.github/workflows/sonarqube.yml
vendored
81
.github/workflows/sonarqube.yml
vendored
@ -1,81 +0,0 @@
|
||||
name: Sonarqube nightly
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 20 * * *'
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
CI_GRADLE_ARG_PROPERTIES: >
|
||||
-Porg.gradle.jvmargs=-Xmx4g
|
||||
-Porg.gradle.parallel=false
|
||||
jobs:
|
||||
codecov-units:
|
||||
name: Unit tests with code coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- run: ./gradlew allCodeCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload Codecov data
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: codecov-xml
|
||||
path: |
|
||||
build/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml
|
||||
|
||||
sonarqube:
|
||||
name: Sonarqube upload
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- codecov-units
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codecov-xml # will restore to allCodeCoverageReport.xml by default; we restore to the same location in following tasks
|
||||
- run: mkdir -p build/reports/jacoco/allCodeCoverageReport/
|
||||
- run: mv allCodeCoverageReport.xml build/reports/jacoco/allCodeCoverageReport/
|
||||
- run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
||||
# Notify the channel about sonarqube failures
|
||||
notify:
|
||||
name: Notify matrix
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- sonarqube
|
||||
- codecov-units
|
||||
if: always() && (needs.sonarqube.result != 'success' || needs.codecov-units.result != 'success')
|
||||
steps:
|
||||
- uses: michaelkaye/matrix-hookshot-action@v1.0.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hookshot_url: ${{ secrets.ELEMENT_ANDROID_HOOKSHOT_URL }}
|
||||
text_template: "Sonarqube run (on ${{ github.ref }}): {{#each job_statuses }}{{#with this }}{{#if completed }} {{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}"
|
||||
html_template: "Sonarqube run (on ${{ github.ref }}): {{#each job_statuses }}{{#with this }}{{#if completed }}<br />{{icon conclusion}} {{name}} <font color='{{color conclusion}}'>{{conclusion}} at {{completed_at}} <a href=\"{{html_url}}\">[details]</a></font>{{/if}}{{/with}}{{/each}}"
|
143
.github/workflows/tests.yml
vendored
143
.github/workflows/tests.yml
vendored
@ -12,73 +12,100 @@ env:
|
||||
-Porg.gradle.parallel=false
|
||||
|
||||
jobs:
|
||||
# Build Android Tests
|
||||
build-android-tests:
|
||||
name: Build Android Tests
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('build-android-tests-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 11
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Build Android Tests
|
||||
run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
|
||||
|
||||
unit-tests:
|
||||
name: Run Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
tests:
|
||||
name: Runs all tests
|
||||
runs-on: macos-latest # for the emulator
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
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 $CI_GRADLE_ARG_PROPERTIES --stacktrace
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- uses: gradle/gradle-build-action@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: michaelkaye/setup-matrix-synapse@v1.0.3
|
||||
with:
|
||||
uploadLogs: true
|
||||
httpPort: 8080
|
||||
disableRateLimiting: true
|
||||
public_baseurl: "http://10.0.2.2:8080/"
|
||||
- name: Run all the codecoverage tests at once
|
||||
id: tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
api-level: 28
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
emulator-build: 7425822
|
||||
script: ./gradlew theCodeCoverageReport -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES
|
||||
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves stes.tests.outcome = 'failure'
|
||||
- name: Run all the codecoverage tests at once (retry if emulator failed)
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
|
||||
with:
|
||||
api-level: 28
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
emulator-build: 7425822
|
||||
script: ./gradlew theCodeCoverageReport -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES
|
||||
- run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES
|
||||
if: always() # we may have failed a previous step and retried, that's OK
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
||||
- name: Format unit test results
|
||||
if: always()
|
||||
run: python3 ./tools/ci/render_test_output.py unit ./**/build/test-results/**/*.xml
|
||||
- name: Publish Unit Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
if: always() &&
|
||||
github.event.sender.login != 'dependabot[bot]' &&
|
||||
( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository )
|
||||
with:
|
||||
files: ./**/build/test-results/**/*.xml
|
||||
|
||||
# Notify the channel about runs against develop or main that have failures, as PRs should have caught these first.
|
||||
notify:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- unit-tests
|
||||
- build-android-tests
|
||||
if: ${{ (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' ) && failure() }}
|
||||
steps:
|
||||
- uses: michaelkaye/matrix-hookshot-action@v0.3.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
matrix_access_token: ${{ secrets.ELEMENT_ANDROID_NOTIFICATION_ACCESS_TOKEN }}
|
||||
matrix_room_id: ${{ secrets.ELEMENT_ANDROID_INTERNAL_ROOM_ID }}
|
||||
text_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}{{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}"
|
||||
html_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}<br />{{icon conclusion }} {{name}} <font color='{{color conclusion }}'>{{conclusion}} at {{completed_at}} <a href=\"{{html_url}}\">[details]</a></font>{{/if}}{{/with}}{{/each}}"
|
||||
# can't be run on macos due to containers.
|
||||
# - name: Publish Unit Test Results
|
||||
# uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
# if: always() &&
|
||||
# github.event.sender.login != 'dependabot[bot]' &&
|
||||
# ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository )
|
||||
# with:
|
||||
# files: ./**/build/test-results/**/*.xml
|
||||
|
||||
# Unneeded as part of the test suite above, kept around in case we want to re-enable them.
|
||||
#
|
||||
# # Build Android Tests
|
||||
# build-android-tests:
|
||||
# name: Build Android Tests
|
||||
# runs-on: ubuntu-latest
|
||||
# concurrency:
|
||||
# group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('build-android-tests-{0}', github.ref) }}
|
||||
# cancel-in-progress: true
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: actions/setup-java@v3
|
||||
# with:
|
||||
# distribution: 'adopt'
|
||||
# java-version: 11
|
||||
# - uses: actions/cache@v3
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.gradle/caches
|
||||
# ~/.gradle/wrapper
|
||||
# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-gradle-
|
||||
# - name: Build Android Tests
|
||||
# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
|
||||
|
||||
|
27
.github/workflows/triage-labelled.yml
vendored
27
.github/workflows/triage-labelled.yml
vendored
@ -9,15 +9,15 @@ jobs:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Polls') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags')
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Polls') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags')
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
with:
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
name: X-Needs-Product to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
@ -105,10 +105,7 @@ jobs:
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
(contains(github.event.issue.labels.*.name, 'A-Spaces') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Space-Settings') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Subspaces') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA'))
|
||||
(contains(github.event.issue.labels.*.name, 'Team: Delight'))
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
@ -201,7 +198,7 @@ jobs:
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc3m-g"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
|
||||
move_ftue_issues:
|
||||
name: Z-FTUE to Mobile FTUE board
|
||||
runs-on: ubuntu-latest
|
||||
|
5
.github/workflows/triage-priority-bugs.yml
vendored
5
.github/workflows/triage-priority-bugs.yml
vendored
@ -14,10 +14,7 @@ jobs:
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Cross-Signing') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Key-Backup') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-SAS-Verification') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-Spaces') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-Spaces-Settings') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-Subspaces')) &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-SAS-Verification')) &&
|
||||
(contains(github.event.issue.labels.*.name, 'T-Defect') &&
|
||||
contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
|
40
CHANGES.md
40
CHANGES.md
@ -1,3 +1,43 @@
|
||||
Changes in Element v1.4.22 (2022-06-14)
|
||||
=======================================
|
||||
|
||||
Features ✨
|
||||
----------
|
||||
- Make read receipt avatar list more compact ([#5970](https://github.com/vector-im/element-android/issues/5970))
|
||||
- Allow .well-known configuration to override key sharing mode ([#6147](https://github.com/vector-im/element-android/issues/6147))
|
||||
- Re-organize location settings flags ([#6244](https://github.com/vector-im/element-android/issues/6244))
|
||||
- Add report action for live location messages ([#6280](https://github.com/vector-im/element-android/issues/6280))
|
||||
|
||||
Bugfixes 🐛
|
||||
----------
|
||||
- Fix cases of missing, swapped, or duplicated messages ([#5528](https://github.com/vector-im/element-android/issues/5528))
|
||||
- Fix wrong status of live location sharing in timeline ([#6209](https://github.com/vector-im/element-android/issues/6209))
|
||||
- Fix StackOverflowError while recording voice message ([#6222](https://github.com/vector-im/element-android/issues/6222))
|
||||
- Text cropped: "Secure backup" ([#6232](https://github.com/vector-im/element-android/issues/6232))
|
||||
- Fix copyright attributions of map views ([#6247](https://github.com/vector-im/element-android/issues/6247))
|
||||
- Fix flickering bottom bar of live location item ([#6264](https://github.com/vector-im/element-android/issues/6264))
|
||||
|
||||
In development 🚧
|
||||
----------------
|
||||
- FTUE - Adds Sign Up tracking ([#5285](https://github.com/vector-im/element-android/issues/5285))
|
||||
|
||||
SDK API changes ⚠️
|
||||
------------------
|
||||
- Some methods from `Session` have been moved to a new `SyncService`, that you can retrieve from a `Session`.
|
||||
- `SyncStatusService` method has been moved to the new `SyncService`
|
||||
- `InitSyncStep` have been moved and renamed to `InitialSyncStep`
|
||||
- `SyncStatusService.Status` has been renamed to `SyncRequestState`
|
||||
- The existing `SyncService` has been renamed to `SyncAndroidService` because of name clash with the new SDK Service ([#6029](https://github.com/vector-im/element-android/issues/6029))
|
||||
- Allows `AuthenticationService.getLoginFlow` to fail without resetting state from previously successful calls ([#6093](https://github.com/vector-im/element-android/issues/6093))
|
||||
- Allows new passwords to be passed at the point of confirmation when resetting a password ([#6169](https://github.com/vector-im/element-android/issues/6169))
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
- Adds support for parsing homeserver versions without a patch number ([#6017](https://github.com/vector-im/element-android/issues/6017))
|
||||
- Updating exit onboarding dialog copy formatting to match iOS ([#6087](https://github.com/vector-im/element-android/issues/6087))
|
||||
- Disables when arrow alignment in code style ([#6126](https://github.com/vector-im/element-android/issues/6126))
|
||||
|
||||
|
||||
Changes in Element 1.4.20 (2022-06-13)
|
||||
======================================
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
[![Buildkite](https://badge.buildkite.com/ad0065c1b70f557cd3b1d3d68f9c2154010f83c4d6f71706a9.svg?branch=develop)](https://buildkite.com/matrix-dot-org/element-android/builds?branch=develop)
|
||||
[![Weblate](https://translate.element.io/widgets/element-android/-/svg-badge.svg)](https://translate.element.io/engage/element-android/?utm_source=widget)
|
||||
[![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org)
|
||||
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=alert_status)](https://sonarcloud.io/dashboard?id=im.vector.app.android)
|
||||
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=im.vector.app.android)
|
||||
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=bugs)](https://sonarcloud.io/dashboard?id=im.vector.app.android)
|
||||
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vector-im_element-android&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=vector-im_element-android&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=vector-im_element-android&metric=bugs)](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
|
||||
# Element Android
|
||||
|
||||
|
10
build.gradle
10
build.gradle
@ -25,7 +25,7 @@ buildscript {
|
||||
classpath libs.gradle.kotlinPlugin
|
||||
classpath libs.gradle.hiltPlugin
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
|
||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
|
||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
|
||||
classpath "com.likethesalad.android:stem-plugin:2.1.1"
|
||||
classpath 'org.owasp:dependency-check-gradle:7.1.0.1'
|
||||
@ -43,7 +43,7 @@ plugins {
|
||||
id "io.gitlab.arturbosch.detekt" version "1.20.0"
|
||||
|
||||
// Dependency Analysis
|
||||
id 'com.autonomousapps.dependency-analysis' version "1.4.0"
|
||||
id 'com.autonomousapps.dependency-analysis' version "1.5.0"
|
||||
}
|
||||
|
||||
// https://github.com/jeremylong/DependencyCheck
|
||||
@ -180,8 +180,8 @@ apply plugin: 'org.sonarqube'
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.projectName", "Element-Android"
|
||||
property "sonar.projectKey", "im.vector.app.android"
|
||||
property "sonar.projectName", "element-android"
|
||||
property "sonar.projectKey", "vector-im_element-android"
|
||||
property "sonar.host.url", "https://sonarcloud.io"
|
||||
property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName
|
||||
property "sonar.sourceEncoding", "UTF-8"
|
||||
@ -191,7 +191,7 @@ sonarqube {
|
||||
property "sonar.links.issue", "https://github.com/vector-im/element-android/issues"
|
||||
property "sonar.organization", "new_vector_ltd_organization"
|
||||
property "sonar.java.coveragePlugin", "jacoco"
|
||||
property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/allCodeCoverageReport/allCodeCoverageReport.xml"
|
||||
property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/theCodeCoverageReport/theCodeCoverageReport.xml"
|
||||
property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid"
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,33 @@
|
||||
def excludes = [ ]
|
||||
def excludes = [
|
||||
// dependency injection graph
|
||||
'**/*Module.*',
|
||||
'**/*Module*.*',
|
||||
|
||||
// Framework entry points
|
||||
'**/*Activity*',
|
||||
'**/*Fragment*',
|
||||
'**/*Application*',
|
||||
|
||||
// We would like to exclude android widgets as well but our naming is inconsistent
|
||||
|
||||
// Proof of concept
|
||||
'**/*Login2*',
|
||||
|
||||
// Generated
|
||||
'**/*JsonAdapter*',
|
||||
'**/*Item.*',
|
||||
'**/*$Holder.*',
|
||||
'**/*ViewHolder.*',
|
||||
'**/*View.*',
|
||||
'**/*BottomSheet.*'
|
||||
]
|
||||
|
||||
def initializeReport(report, projects, classExcludes) {
|
||||
projects.each { project -> project.apply plugin: 'jacoco' }
|
||||
report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/jacoco/*.exec") }
|
||||
report.executionData { fileTree(rootProject.rootDir.absolutePath).include(
|
||||
"**/build/outputs/unit_test_code_coverage/**/*.exec",
|
||||
"**/build/outputs/code_coverage/**/coverage.ec"
|
||||
) }
|
||||
|
||||
report.reports {
|
||||
xml.enabled true
|
||||
@ -18,11 +43,13 @@ def initializeReport(report, projects, classExcludes) {
|
||||
switch (project) {
|
||||
case { project.plugins.hasPlugin("com.android.application") }:
|
||||
androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/gplayDebug")
|
||||
androidSourceDirs.add("${project.buildDir}/generated/source/kapt/gplayDebug")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/kotlin")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/java")
|
||||
break
|
||||
case { project.plugins.hasPlugin("com.android.library") }:
|
||||
androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug")
|
||||
androidSourceDirs.add("${project.buildDir}/generated/source/kapt/debug")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/kotlin")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/java")
|
||||
break
|
||||
@ -43,13 +70,18 @@ def collectProjects(predicate) {
|
||||
return subprojects.findAll { it.buildFile.isFile() && predicate(it) }
|
||||
}
|
||||
|
||||
task allCodeCoverageReport(type: JacocoReport) {
|
||||
task theCodeCoverageReport(type: JacocoReport) {
|
||||
outputs.upToDateWhen { false }
|
||||
rootProject.apply plugin: 'jacoco'
|
||||
// to limit projects in a specific report, add
|
||||
// def excludedProjects = [ ... ]
|
||||
// def projects = collectProjects { !excludedProjects.contains(it.name) }
|
||||
def projects = collectProjects { true }
|
||||
dependsOn { projects*.test }
|
||||
tasks.withType(Test) {
|
||||
jacoco.includeNoLocationClasses = true
|
||||
}
|
||||
def projects = collectProjects { ['vector','matrix-sdk-android'].contains(it.name) }
|
||||
dependsOn {
|
||||
[':vector:testGplayDebugUnitTest'] +
|
||||
[':vector:connectedGplayDebugAndroidTest'] +
|
||||
[':matrix-sdk-android:testDebugUnitTest'] +
|
||||
[':matrix-sdk-android:connectedDebugAndroidTest']
|
||||
}
|
||||
initializeReport(it, projects, excludes)
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ ext.libs = [
|
||||
],
|
||||
androidx : [
|
||||
'activity' : "androidx.activity:activity:1.4.0",
|
||||
'appCompat' : "androidx.appcompat:appcompat:1.4.1",
|
||||
'core' : "androidx.core:core-ktx:1.7.0",
|
||||
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
|
||||
'core' : "androidx.core:core-ktx:1.8.0",
|
||||
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
|
||||
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3",
|
||||
'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1",
|
||||
@ -78,7 +78,7 @@ ext.libs = [
|
||||
'transition' : "androidx.transition:transition:1.2.0",
|
||||
],
|
||||
google : [
|
||||
'material' : "com.google.android.material:material:1.6.0"
|
||||
'material' : "com.google.android.material:material:1.6.1"
|
||||
],
|
||||
dagger : [
|
||||
'dagger' : "com.google.dagger:dagger:$dagger",
|
||||
|
@ -1,64 +1,49 @@
|
||||
fastlane documentation
|
||||
----
|
||||
|
||||
================
|
||||
# Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
|
||||
```sh
|
||||
```
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||
Install _fastlane_ using
|
||||
```
|
||||
[sudo] gem install fastlane -NV
|
||||
```
|
||||
or alternatively using `brew install fastlane`
|
||||
|
||||
# Available Actions
|
||||
|
||||
## Android
|
||||
|
||||
### android test
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android test
|
||||
```
|
||||
|
||||
fastlane android test
|
||||
```
|
||||
Runs all the tests
|
||||
|
||||
### android beta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android beta
|
||||
```
|
||||
|
||||
fastlane android beta
|
||||
```
|
||||
Submit a new Beta Build to Crashlytics Beta
|
||||
|
||||
### android deploy
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deploy
|
||||
```
|
||||
|
||||
fastlane android deploy
|
||||
```
|
||||
Deploy a new version to the Google Play
|
||||
|
||||
### android deployMeta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deployMeta
|
||||
```
|
||||
|
||||
fastlane android deployMeta
|
||||
```
|
||||
Deploy Google Play metadata
|
||||
|
||||
### android getVersionCode
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane 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).
|
||||
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).
|
||||
|
2
fastlane/metadata/android/cs-CZ/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/cs-CZ/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Hlavní změny v této verzi: Vylepšena správa šifrovaných zpráv. Opravy různých chyb a vylepšení stability.
|
||||
Úplný seznam změn: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/en-US/changelogs/40104220.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/40104220.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Main changes in this version: Various bug fixes and stability improvements.
|
||||
Full changelog: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/et/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/et/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Põhilised muutused selles versioonis: krüptitud sõnumite parem haldus, lisaks pisiparandused ja stabiilsust parandavad kohendused.
|
||||
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/fa/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/fa/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
تغییرات عمده در این نگارش: مدیریت بهتر پیامهای رمزگذاشته. رفع اشکالهای مختلف و بهبودهای پایداری.
|
||||
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/fr-FR/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/fr-FR/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Principaux changements pour cette version : Meilleure gestion des messages chiffrés. Plusieurs corrections de bogues et d’améliorations de stabilité.
|
||||
Intégralité des changements : https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/id/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/id/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Perubahan utama dalam versi ini: Pengelolaan pesan terenkripsi lebih baik. Banyak perbaikan kutu dan perbaikan stabilitas.
|
||||
Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/it-IT/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/it-IT/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Modifiche principali in questa versione: migliorata la gestione dei messaggi cifrati. Varie correzioni e miglioramenti della stabilità.
|
||||
Cronologia completa: https://github.com/vector-im/element-android/releases
|
@ -1 +1 @@
|
||||
אלמנט (בעבר Riot.im)
|
||||
אלמנט - התכתבות מאובטחת
|
||||
|
2
fastlane/metadata/android/pl-PL/changelogs/40101060.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101060.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wesji: poprawki dla wesji 1.1.5
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.6
|
2
fastlane/metadata/android/pl-PL/changelogs/40101070.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101070.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Eksperymentalne wsparcie dla przestrzeni, Kompresowanie video przed wysłaniem.
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.7
|
2
fastlane/metadata/android/pl-PL/changelogs/40101080.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101080.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Poprawki w przestrzeniach
|
||||
Pełna lista zmian https://github.com/vector-im/element-android/releases/tag/v1.1.8
|
2
fastlane/metadata/android/pl-PL/changelogs/40101090.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101090.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Dodano wsparcie dla sieci gitter.im .
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.9
|
2
fastlane/metadata/android/pl-PL/changelogs/40101100.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101100.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Nowe funkcje dla przestrzeni i aktualizacja motywu i stylu.
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.10
|
2
fastlane/metadata/android/pl-PL/changelogs/40101110.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40101110.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Dodano nowe funkcje do przestrzeni i zaktualizowano motyw i styl aplikacji. (poprawki błędóœ dla wesji 1.1.10)
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.11
|
2
fastlane/metadata/android/pl-PL/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/pl-PL/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Główne zmiany w tej wersji: Lepsze zarządzanie zaszyfrowanymi wiadomościami. , Poprawki błędów i stabilności.
|
||||
Pełna lista zmian: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/pt-BR/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/pt-BR/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Principais mudanças nesta versão: Melhor gerenciamento de mensagens encriptadas. Vários consertos de bugs e melhorias de estabilidade.
|
||||
Changelog completo: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/sk/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/sk/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Hlavné zmeny v tejto verzii: Lepšia spravovanie zašifrovaných správ. Rôzne opravy chýb a vylepšenia stability.
|
||||
Úplný zoznam zmien: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/sv-SE/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/sv-SE/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Huvudsakliga ändringar i den här versionen: Bättre hantering av krypterade meddelanden. Diverse buggfixar och stabilitetsförbättringar.
|
||||
Full ändringslogg: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/uk/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/uk/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Основні зміни в цій версії: Поліпшено керування зашифрованими повідомленнями. Усунуто різні вади й поліпшено стабільність.
|
||||
Вичерпний перелік змін: https://github.com/vector-im/element-android/releases
|
2
fastlane/metadata/android/zh-TW/changelogs/40104160.txt
Normal file
2
fastlane/metadata/android/zh-TW/changelogs/40104160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
此版本中的主要變動:對於被加密的訊息有更好的管理方式。多個臭蟲修復與穩定性改善。
|
||||
完整的變更紀錄:https://github.com/vector-im/element-android/releases
|
@ -271,7 +271,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||
directionDetector.handleTouchEvent(event)
|
||||
|
||||
return when (swipeDirection) {
|
||||
SwipeDirection.Up, SwipeDirection.Down -> {
|
||||
SwipeDirection.Up, SwipeDirection.Down -> {
|
||||
if (isSwipeToDismissAllowed && !wasScaled && isImagePagerIdle) {
|
||||
swipeDismissHandler.onTouch(views.rootContainer, event)
|
||||
} else true
|
||||
@ -279,7 +279,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||
SwipeDirection.Left, SwipeDirection.Right -> {
|
||||
views.attachmentPager.dispatchTouchEvent(event)
|
||||
}
|
||||
else -> true
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,18 +42,18 @@ class AttachmentsAdapter : RecyclerView.Adapter<BaseViewHolder>() {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val itemView = inflater.inflate(viewType, parent, false)
|
||||
return when (viewType) {
|
||||
R.layout.item_image_attachment -> ZoomableImageViewHolder(itemView)
|
||||
R.layout.item_image_attachment -> ZoomableImageViewHolder(itemView)
|
||||
R.layout.item_animated_image_attachment -> AnimatedImageViewHolder(itemView)
|
||||
R.layout.item_video_attachment -> VideoViewHolder(itemView)
|
||||
else -> UnsupportedViewHolder(itemView)
|
||||
R.layout.item_video_attachment -> VideoViewHolder(itemView)
|
||||
else -> UnsupportedViewHolder(itemView)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
val info = attachmentSourceProvider!!.getAttachmentInfoAt(position)
|
||||
return when (info) {
|
||||
is AttachmentInfo.Image -> R.layout.item_image_attachment
|
||||
is AttachmentInfo.Video -> R.layout.item_video_attachment
|
||||
is AttachmentInfo.Image -> R.layout.item_image_attachment
|
||||
is AttachmentInfo.Video -> R.layout.item_video_attachment
|
||||
is AttachmentInfo.AnimatedImage -> R.layout.item_animated_image_attachment
|
||||
// is AttachmentInfo.Audio -> TODO()
|
||||
// is AttachmentInfo.File -> TODO()
|
||||
@ -68,13 +68,13 @@ class AttachmentsAdapter : RecyclerView.Adapter<BaseViewHolder>() {
|
||||
attachmentSourceProvider?.getAttachmentInfoAt(position)?.let {
|
||||
holder.bind(it)
|
||||
when (it) {
|
||||
is AttachmentInfo.Image -> {
|
||||
is AttachmentInfo.Image -> {
|
||||
attachmentSourceProvider?.loadImage((holder as ZoomableImageViewHolder).target, it)
|
||||
}
|
||||
is AttachmentInfo.AnimatedImage -> {
|
||||
attachmentSourceProvider?.loadImage((holder as AnimatedImageViewHolder).target, it)
|
||||
}
|
||||
is AttachmentInfo.Video -> {
|
||||
is AttachmentInfo.Video -> {
|
||||
attachmentSourceProvider?.loadVideo((holder as VideoViewHolder).target, it)
|
||||
}
|
||||
// else -> {
|
||||
|
@ -27,12 +27,12 @@ sealed class SwipeDirection {
|
||||
companion object {
|
||||
fun fromAngle(angle: Double): SwipeDirection {
|
||||
return when (angle) {
|
||||
in 0.0..45.0 -> Right
|
||||
in 45.0..135.0 -> Up
|
||||
in 0.0..45.0 -> Right
|
||||
in 45.0..135.0 -> Up
|
||||
in 135.0..225.0 -> Left
|
||||
in 225.0..315.0 -> Down
|
||||
in 315.0..360.0 -> Right
|
||||
else -> NotDetected
|
||||
else -> NotDetected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class SwipeDirectionDetector(
|
||||
|
||||
fun handleTouchEvent(event: MotionEvent) {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
startX = event.x
|
||||
startY = event.y
|
||||
}
|
||||
@ -45,7 +45,7 @@ class SwipeDirectionDetector(
|
||||
startX = startY
|
||||
isDetected = false
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> if (!isDetected && getEventDistance(event) > touchSlop) {
|
||||
MotionEvent.ACTION_MOVE -> if (!isDetected && getEventDistance(event) > touchSlop) {
|
||||
isDetected = true
|
||||
onDirectionDetected(getDirection(startX, startY, event.x, event.y))
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class SwipeToDismissHandler(
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
if (swipeView.hitRect.contains(event.x.toInt(), event.y.toInt())) {
|
||||
isTracking = true
|
||||
}
|
||||
@ -58,7 +58,7 @@ class SwipeToDismissHandler(
|
||||
}
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (isTracking) {
|
||||
val translationY = event.y - startY
|
||||
swipeView.translationY = translationY
|
||||
@ -66,7 +66,7 @@ class SwipeToDismissHandler(
|
||||
}
|
||||
return true
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -79,8 +79,8 @@ class SwipeToDismissHandler(
|
||||
private fun onTrackingEnd(parentHeight: Int) {
|
||||
val animateTo = when {
|
||||
swipeView.translationY < -translationLimit -> -parentHeight.toFloat()
|
||||
swipeView.translationY > translationLimit -> parentHeight.toFloat()
|
||||
else -> 0f
|
||||
swipeView.translationY > translationLimit -> parentHeight.toFloat()
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
if (animateTo != 0f && !shouldAnimateDismiss()) {
|
||||
|
@ -146,7 +146,7 @@ class VideoViewHolder constructor(itemView: View) :
|
||||
wasPaused = true
|
||||
views.videoView.pause()
|
||||
}
|
||||
is AttachmentCommands.SeekTo -> {
|
||||
is AttachmentCommands.SeekTo -> {
|
||||
val duration = views.videoView.duration
|
||||
if (duration > 0) {
|
||||
val seekDuration = duration * (commands.percentProgress / 100f)
|
||||
|
@ -43,7 +43,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
|
||||
text(async.error.localizedMessage?.toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
async.invoke()?.let {
|
||||
buildRec(it, 0, "")
|
||||
}
|
||||
@ -98,7 +98,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
|
||||
}
|
||||
}
|
||||
}
|
||||
is JSonViewerArray -> {
|
||||
is JSonViewerArray -> {
|
||||
if (model.isExpanded) {
|
||||
open(id, model.key, model.index, depth, false, model)
|
||||
model.items.forEach {
|
||||
@ -137,7 +137,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
|
||||
}
|
||||
}
|
||||
}
|
||||
is JSonViewerLeaf -> {
|
||||
is JSonViewerLeaf -> {
|
||||
valueItem {
|
||||
id(id)
|
||||
depth(depth)
|
||||
@ -172,12 +172,12 @@ internal class JSonViewerEpoxyController(private val context: Context) :
|
||||
private fun valueToSpan(leaf: JSonViewerLeaf): Span {
|
||||
val host = this
|
||||
return when (leaf.type) {
|
||||
JSONType.STRING -> {
|
||||
JSONType.STRING -> {
|
||||
span("\"${leaf.stringRes}\"") {
|
||||
textColor = host.styleProvider.stringColor
|
||||
}
|
||||
}
|
||||
JSONType.NUMBER -> {
|
||||
JSONType.NUMBER -> {
|
||||
span(leaf.stringRes) {
|
||||
textColor = host.styleProvider.numberColor
|
||||
}
|
||||
@ -187,7 +187,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
|
||||
textColor = host.styleProvider.booleanColor
|
||||
}
|
||||
}
|
||||
JSONType.NULL -> {
|
||||
JSONType.NULL -> {
|
||||
span("null") {
|
||||
textColor = host.styleProvider.booleanColor
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ internal object ModelParser {
|
||||
}
|
||||
parent.addChild(objectComposed)
|
||||
}
|
||||
is JSONArray -> {
|
||||
is JSONArray -> {
|
||||
val objectComposed = JSonViewerArray(key, index, obj)
|
||||
.apply { isExpanded = initialOpenDepth == -1 || depth <= initialOpenDepth }
|
||||
objectComposed.depth = depth
|
||||
@ -91,25 +91,25 @@ internal object ModelParser {
|
||||
}
|
||||
parent.addChild(objectComposed)
|
||||
}
|
||||
is String -> {
|
||||
is String -> {
|
||||
JSonViewerLeaf(key, index, obj, JSONType.STRING).let {
|
||||
it.depth = depth
|
||||
parent.addChild(it)
|
||||
}
|
||||
}
|
||||
is Number -> {
|
||||
is Number -> {
|
||||
JSonViewerLeaf(key, index, obj.toString(), JSONType.NUMBER).let {
|
||||
it.depth = depth
|
||||
parent.addChild(it)
|
||||
}
|
||||
}
|
||||
is Boolean -> {
|
||||
is Boolean -> {
|
||||
JSonViewerLeaf(key, index, obj.toString(), JSONType.BOOLEAN).let {
|
||||
it.depth = depth
|
||||
parent.addChild(it)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
if (obj == JSONObject.NULL) {
|
||||
JSonViewerLeaf(key, index, "null", JSONType.NULL).let {
|
||||
it.depth = depth
|
||||
|
@ -48,7 +48,7 @@ class FilePicker : Picker<MultiPickerBaseType>() {
|
||||
type.isMimeTypeVideo() -> selectedUri.toMultiPickerVideoType(context)
|
||||
type.isMimeTypeImage() -> selectedUri.toMultiPickerImageType(context)
|
||||
type.isMimeTypeAudio() -> selectedUri.toMultiPickerAudioType(context)
|
||||
else -> {
|
||||
else -> {
|
||||
// Other files
|
||||
context.contentResolver.query(selectedUri, null, null, null, null)
|
||||
?.use { cursor ->
|
||||
|
@ -31,15 +31,15 @@ class MultiPicker<T> private constructor() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> get(type: MultiPicker<T>): T {
|
||||
return when (type) {
|
||||
IMAGE -> ImagePicker() as T
|
||||
VIDEO -> VideoPicker() as T
|
||||
MEDIA -> MediaPicker() as T
|
||||
FILE -> FilePicker() as T
|
||||
AUDIO -> AudioPicker() as T
|
||||
CONTACT -> ContactPicker() as T
|
||||
CAMERA -> CameraPicker() as T
|
||||
IMAGE -> ImagePicker() as T
|
||||
VIDEO -> VideoPicker() as T
|
||||
MEDIA -> MediaPicker() as T
|
||||
FILE -> FilePicker() as T
|
||||
AUDIO -> AudioPicker() as T
|
||||
CONTACT -> ContactPicker() as T
|
||||
CAMERA -> CameraPicker() as T
|
||||
CAMERA_VIDEO -> CameraVideoPicker() as T
|
||||
else -> throw IllegalArgumentException("Unsupported type $type")
|
||||
else -> throw IllegalArgumentException("Unsupported type $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
<dimen name="text_size_body">14sp</dimen>
|
||||
<dimen name="text_size_caption">12sp</dimen>
|
||||
<dimen name="text_size_micro">10sp</dimen>
|
||||
<dimen name="text_size_nano">8sp</dimen>
|
||||
|
||||
<dimen name="text_size_button">14sp</dimen>
|
||||
|
||||
</resources>
|
||||
</resources>
|
||||
|
@ -40,4 +40,9 @@
|
||||
<item name="android:gravity">center</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Vector.TextView.Nano.Copyright">
|
||||
<!-- Static map view is always light in both light and dark theme. So we need to use a static dark color -->
|
||||
<item name="android:textColor">@color/element_content_primary_light</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -48,4 +48,9 @@
|
||||
<item name="lineHeight">16sp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
<style name="Widget.Vector.TextView.Nano">
|
||||
<item name="android:textAppearance">@style/TextAppearance.Vector.Nano</item>
|
||||
<item name="lineHeight">16sp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -85,4 +85,11 @@
|
||||
<item name="android:letterSpacing">0.02</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Vector.Nano" parent="TextAppearance.MaterialComponents.Caption">
|
||||
<item name="fontFamily">sans-serif</item>
|
||||
<item name="android:fontFamily">sans-serif</item>
|
||||
<item name="android:textSize">@dimen/text_size_nano</item>
|
||||
<item name="android:letterSpacing">0</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -88,7 +88,7 @@ class FlowSession(private val session: Session) {
|
||||
}
|
||||
|
||||
fun liveSyncState(): Flow<SyncState> {
|
||||
return session.getSyncStateLive().asFlow()
|
||||
return session.syncService().getSyncStateLive().asFlow()
|
||||
}
|
||||
|
||||
fun livePushers(): Flow<List<Pusher>> {
|
||||
|
@ -56,7 +56,7 @@ android {
|
||||
// that the app's state is completely cleared between tests.
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
|
||||
buildConfigField "String", "SDK_VERSION", "\"1.4.20\""
|
||||
buildConfigField "String", "SDK_VERSION", "\"1.4.22\""
|
||||
|
||||
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
|
||||
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""
|
||||
@ -74,6 +74,7 @@ android {
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
testCoverageEnabled true
|
||||
// Set to true to log privacy or sensible data, such as token
|
||||
buildConfigField "boolean", "LOG_PRIVATE_DATA", project.property("vector.debugPrivateData")
|
||||
// Set to BODY instead of NONE to enable logging
|
||||
@ -151,7 +152,7 @@ dependencies {
|
||||
// - https://github.com/square/okhttp/issues/3278
|
||||
// - https://github.com/square/okhttp/issues/4455
|
||||
// - https://github.com/square/okhttp/issues/3146
|
||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
|
||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0"))
|
||||
implementation 'com.squareup.okhttp3:okhttp'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor'
|
||||
|
||||
@ -175,7 +176,7 @@ dependencies {
|
||||
implementation libs.androidx.work
|
||||
|
||||
// olm lib is now hosted in MavenCentral
|
||||
implementation 'org.matrix.android:olm-sdk:3.2.11'
|
||||
implementation 'org.matrix.android:olm-sdk:3.2.12'
|
||||
|
||||
// DI
|
||||
implementation libs.dagger.dagger
|
||||
@ -192,7 +193,7 @@ dependencies {
|
||||
implementation libs.apache.commonsImaging
|
||||
|
||||
// Phone number https://github.com/google/libphonenumber
|
||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.49'
|
||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.50'
|
||||
|
||||
testImplementation libs.tests.junit
|
||||
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
|
||||
|
@ -19,10 +19,14 @@ package org.matrix.android.sdk
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import org.junit.Rule
|
||||
import org.matrix.android.sdk.common.RetryTestRule
|
||||
import org.matrix.android.sdk.test.shared.createTimberTestRule
|
||||
|
||||
interface InstrumentedTest {
|
||||
|
||||
@Rule
|
||||
fun retryTestRule() = RetryTestRule(3)
|
||||
|
||||
@Rule
|
||||
fun timberTestRule() = createTimberTestRule()
|
||||
|
||||
|
@ -137,11 +137,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis * 10) {
|
||||
val lock = CountDownLatch(1)
|
||||
coroutineScope.launch {
|
||||
session.startSync(true)
|
||||
val syncLiveData = session.getSyncStateLive()
|
||||
session.syncService().startSync(true)
|
||||
val syncLiveData = session.syncService().getSyncStateLive()
|
||||
val syncObserver = object : Observer<SyncState> {
|
||||
override fun onChanged(t: SyncState?) {
|
||||
if (session.hasAlreadySynced()) {
|
||||
if (session.syncService().hasAlreadySynced()) {
|
||||
lock.countDown()
|
||||
syncLiveData.removeObserver(this)
|
||||
}
|
||||
@ -160,10 +160,10 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) {
|
||||
waitWithLatch(timeout) { latch ->
|
||||
session.clearCache()
|
||||
val syncLiveData = session.getSyncStateLive()
|
||||
val syncLiveData = session.syncService().getSyncStateLive()
|
||||
val syncObserver = object : Observer<SyncState> {
|
||||
override fun onChanged(t: SyncState?) {
|
||||
if (session.hasAlreadySynced()) {
|
||||
if (session.syncService().hasAlreadySynced()) {
|
||||
Timber.v("Clear cache and synced")
|
||||
syncLiveData.removeObserver(this)
|
||||
latch.countDown()
|
||||
@ -171,7 +171,7 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
}
|
||||
}
|
||||
syncLiveData.observeForever(syncObserver)
|
||||
session.startSync(true)
|
||||
session.syncService().startSync(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +252,8 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
message: String,
|
||||
numberOfMessages: Int,
|
||||
rootThreadEventId: String,
|
||||
timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
||||
timeout: Long = TestConstants.timeOutMillis
|
||||
): List<TimelineEvent> {
|
||||
val timeline = room.timelineService().createTimeline(null, TimelineSettings(10))
|
||||
timeline.start()
|
||||
val sentEvents = sendTextMessagesBatched(timeline, room, message, numberOfMessages, timeout, rootThreadEventId)
|
||||
@ -272,9 +273,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
* @param testParams test params about the session
|
||||
* @return the session associated with the newly created account
|
||||
*/
|
||||
private fun createAccount(userNamePrefix: String,
|
||||
password: String,
|
||||
testParams: SessionTestParams): Session {
|
||||
private fun createAccount(
|
||||
userNamePrefix: String,
|
||||
password: String,
|
||||
testParams: SessionTestParams
|
||||
): Session {
|
||||
val session = createAccountAndSync(
|
||||
userNamePrefix + "_" + accountNumber++ + "_" + UUID.randomUUID(),
|
||||
password,
|
||||
@ -294,9 +297,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
* @param testParams test params about the session
|
||||
* @return the session associated with the existing account
|
||||
*/
|
||||
fun logIntoAccount(userId: String,
|
||||
password: String,
|
||||
testParams: SessionTestParams): Session {
|
||||
fun logIntoAccount(
|
||||
userId: String,
|
||||
password: String,
|
||||
testParams: SessionTestParams
|
||||
): Session {
|
||||
val session = logAccountAndSync(userId, password, testParams)
|
||||
assertNotNull(session)
|
||||
return session.also {
|
||||
@ -311,9 +316,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
* @param password the password
|
||||
* @param sessionTestParams parameters for the test
|
||||
*/
|
||||
private fun createAccountAndSync(userName: String,
|
||||
password: String,
|
||||
sessionTestParams: SessionTestParams): Session {
|
||||
private fun createAccountAndSync(
|
||||
userName: String,
|
||||
password: String,
|
||||
sessionTestParams: SessionTestParams
|
||||
): Session {
|
||||
val hs = createHomeServerConfig()
|
||||
|
||||
runBlockingTest {
|
||||
@ -349,9 +356,11 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
* @param password the password
|
||||
* @param sessionTestParams session test params
|
||||
*/
|
||||
private fun logAccountAndSync(userName: String,
|
||||
password: String,
|
||||
sessionTestParams: SessionTestParams): Session {
|
||||
private fun logAccountAndSync(
|
||||
userName: String,
|
||||
password: String,
|
||||
sessionTestParams: SessionTestParams
|
||||
): Session {
|
||||
val hs = createHomeServerConfig()
|
||||
|
||||
runBlockingTest {
|
||||
@ -377,8 +386,10 @@ class CommonTestHelper private constructor(context: Context) {
|
||||
* @param userName the account username
|
||||
* @param password the password
|
||||
*/
|
||||
fun logAccountWithError(userName: String,
|
||||
password: String): Throwable {
|
||||
fun logAccountWithError(
|
||||
userName: String,
|
||||
password: String
|
||||
): Throwable {
|
||||
val hs = createHomeServerConfig()
|
||||
|
||||
runBlockingTest {
|
||||
|
@ -18,8 +18,10 @@ package org.matrix.android.sdk.common
|
||||
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
||||
data class CryptoTestData(val roomId: String,
|
||||
val sessions: List<Session>) {
|
||||
data class CryptoTestData(
|
||||
val roomId: String,
|
||||
val sessions: List<Session>
|
||||
) {
|
||||
|
||||
val firstSession: Session
|
||||
get() = sessions.first()
|
||||
|
@ -73,9 +73,11 @@ class MockOkHttpInterceptor : TestInterceptor {
|
||||
/**
|
||||
* Simple rule that reply with the given body for any request that matches the match param
|
||||
*/
|
||||
class SimpleRule(match: String,
|
||||
private val code: Int = HttpsURLConnection.HTTP_OK,
|
||||
private val body: String = "{}") : Rule(match) {
|
||||
class SimpleRule(
|
||||
match: String,
|
||||
private val code: Int = HttpsURLConnection.HTTP_OK,
|
||||
private val body: String = "{}"
|
||||
) : Rule(match) {
|
||||
|
||||
override fun process(originalRequest: Request): Response? {
|
||||
return Response.Builder()
|
||||
|
@ -27,8 +27,10 @@ import java.util.concurrent.CountDownLatch
|
||||
* @param onlySuccessful true to fail if an error occurs. This is the default behavior
|
||||
* @param <T>
|
||||
*/
|
||||
open class TestMatrixCallback<T>(private val countDownLatch: CountDownLatch,
|
||||
private val onlySuccessful: Boolean = true) : MatrixCallback<T> {
|
||||
open class TestMatrixCallback<T>(
|
||||
private val countDownLatch: CountDownLatch,
|
||||
private val onlySuccessful: Boolean = true
|
||||
) : MatrixCallback<T> {
|
||||
|
||||
@CallSuper
|
||||
override fun onSuccess(data: T) {
|
||||
|
@ -47,7 +47,9 @@ internal interface TestMatrixComponent : MatrixComponent {
|
||||
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
fun create(@BindsInstance context: Context,
|
||||
@BindsInstance matrixConfiguration: MatrixConfiguration): TestMatrixComponent
|
||||
fun create(
|
||||
@BindsInstance context: Context,
|
||||
@BindsInstance matrixConfiguration: MatrixConfiguration
|
||||
): TestMatrixComponent
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
@ -40,6 +41,7 @@ import java.util.UUID
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Ignore
|
||||
class AttachmentEncryptionTest {
|
||||
|
||||
private fun checkDecryption(input: String, encryptedFileInfo: EncryptedFileInfo): String {
|
||||
|
@ -22,6 +22,7 @@ import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -37,6 +38,7 @@ import org.matrix.olm.OlmSession
|
||||
private const val DUMMY_DEVICE_KEY = "DeviceKey"
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@Ignore
|
||||
class CryptoStoreTest : InstrumentedTest {
|
||||
|
||||
@get:Rule val rule = RetryTestRule(3)
|
||||
|
@ -626,7 +626,7 @@ class E2eeSanityTests : InstrumentedTest {
|
||||
// we can release this latch?
|
||||
oldCompleteLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -653,17 +653,17 @@ class E2eeSanityTests : InstrumentedTest {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
||||
// no need to accept as there was a request first it will auto accept
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
if (matchOnce) {
|
||||
sasTx.userHasVerifiedShortCode()
|
||||
newCode = sasTx.getDecimalCodeRepresentation()
|
||||
matchOnce = false
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
newCompleteLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -21,6 +21,7 @@ import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
@ -30,6 +31,7 @@ import org.junit.runners.MethodSorters
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Ignore
|
||||
class ExportEncryptionTest {
|
||||
|
||||
@Test
|
||||
@ -83,7 +85,8 @@ class ExportEncryptionTest {
|
||||
@Test
|
||||
fun checkExportDecrypt1() {
|
||||
val password = "password"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" + "cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" +
|
||||
"cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----"
|
||||
val expectedString = "plain"
|
||||
|
||||
var decodedString: String? = null
|
||||
@ -103,7 +106,8 @@ class ExportEncryptionTest {
|
||||
@Test
|
||||
fun checkExportDecrypt2() {
|
||||
val password = "betterpassword"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" + "KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" +
|
||||
"KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----"
|
||||
val expectedString = "Hello, World"
|
||||
|
||||
var decodedString: String? = null
|
||||
@ -123,7 +127,8 @@ class ExportEncryptionTest {
|
||||
@Test
|
||||
fun checkExportDecrypt3() {
|
||||
val password = "SWORDFISH"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" + "MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----"
|
||||
val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" +
|
||||
"MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----"
|
||||
val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically"
|
||||
|
||||
var decodedString: String? = null
|
||||
@ -202,7 +207,8 @@ class ExportEncryptionTest {
|
||||
|
||||
@Test
|
||||
fun checkExportEncrypt4() {
|
||||
val password = "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword"
|
||||
val password = "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||
"passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword"
|
||||
val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically"
|
||||
var decodedString: String? = null
|
||||
|
||||
|
@ -21,6 +21,7 @@ import org.amshove.kluent.shouldBe
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
@ -59,6 +60,7 @@ import kotlin.coroutines.resume
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@Ignore
|
||||
class UnwedgingTest : InstrumentedTest {
|
||||
|
||||
private lateinit var messagesReceivedByBob: List<TimelineEvent>
|
||||
|
@ -25,6 +25,7 @@ import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
@ -47,6 +48,7 @@ import kotlin.coroutines.resume
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class XSigningTest : InstrumentedTest {
|
||||
|
||||
@Test
|
||||
|
@ -25,6 +25,7 @@ import org.amshove.kluent.internal.assertEquals
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -50,6 +51,7 @@ import org.matrix.android.sdk.mustFail
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class KeyShareTests : InstrumentedTest {
|
||||
|
||||
@get:Rule val rule = RetryTestRule(3)
|
||||
@ -422,7 +424,7 @@ class KeyShareTests : InstrumentedTest {
|
||||
|
||||
// /!\ Stop initial alice session syncing so that it can't reply
|
||||
aliceSession.cryptoService().enableKeyGossiping(false)
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
|
||||
// Let's now try to request
|
||||
aliceNewSession.cryptoService().reRequestRoomKeyForEvent(sentEvents.first().root)
|
||||
@ -445,7 +447,7 @@ class KeyShareTests : InstrumentedTest {
|
||||
|
||||
// let's wake up alice
|
||||
aliceSession.cryptoService().enableKeyGossiping(true)
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
|
||||
// We should now get a reply from first session
|
||||
commonTestHelper.waitWithLatch { latch ->
|
||||
|
@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import org.junit.Assert
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -46,6 +47,7 @@ import org.matrix.android.sdk.mustFail
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class WithHeldTests : InstrumentedTest {
|
||||
|
||||
@get:Rule val rule = RetryTestRule(3)
|
||||
|
@ -24,6 +24,7 @@ import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -55,6 +56,7 @@ import java.util.concurrent.CountDownLatch
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
@get:Rule val rule = RetryTestRule(3)
|
||||
|
@ -33,7 +33,8 @@ import java.util.concurrent.CountDownLatch
|
||||
|
||||
internal class KeysBackupTestHelper(
|
||||
private val testHelper: CommonTestHelper,
|
||||
private val cryptoTestHelper: CryptoTestHelper) {
|
||||
private val cryptoTestHelper: CryptoTestHelper
|
||||
) {
|
||||
|
||||
fun waitForKeybackUpBatching() {
|
||||
Thread.sleep(400)
|
||||
@ -96,8 +97,10 @@ internal class KeysBackupTestHelper(
|
||||
)
|
||||
}
|
||||
|
||||
fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,
|
||||
password: String? = null): PrepareKeysBackupDataResult {
|
||||
fun prepareAndCreateKeysBackupData(
|
||||
keysBackup: KeysBackupService,
|
||||
password: String? = null
|
||||
): PrepareKeysBackupDataResult {
|
||||
val stateObserver = StateObserver(keysBackup)
|
||||
|
||||
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
|
||||
@ -169,9 +172,11 @@ internal class KeysBackupTestHelper(
|
||||
* - The new device must have the same count of megolm keys
|
||||
* - Alice must have the same keys on both devices
|
||||
*/
|
||||
fun checkRestoreSuccess(testData: KeysBackupScenarioData,
|
||||
total: Int,
|
||||
imported: Int) {
|
||||
fun checkRestoreSuccess(
|
||||
testData: KeysBackupScenarioData,
|
||||
total: Int,
|
||||
imported: Int
|
||||
) {
|
||||
// - Imported keys number must be correct
|
||||
Assert.assertEquals(testData.aliceKeys.size, total)
|
||||
Assert.assertEquals(total, imported)
|
||||
|
@ -18,5 +18,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo
|
||||
|
||||
data class PrepareKeysBackupDataResult(val megolmBackupCreationInfo: MegolmBackupCreationInfo,
|
||||
val version: String)
|
||||
data class PrepareKeysBackupDataResult(
|
||||
val megolmBackupCreationInfo: MegolmBackupCreationInfo,
|
||||
val version: String
|
||||
)
|
||||
|
@ -27,9 +27,11 @@ import java.util.concurrent.CountDownLatch
|
||||
* This class observe the state change of a KeysBackup object and provide a method to check the several state change
|
||||
* It checks all state transitions and detected forbidden transition
|
||||
*/
|
||||
internal class StateObserver(private val keysBackup: KeysBackupService,
|
||||
private val latch: CountDownLatch? = null,
|
||||
private val expectedStateChange: Int = -1) : KeysBackupStateListener {
|
||||
internal class StateObserver(
|
||||
private val keysBackup: KeysBackupService,
|
||||
private val latch: CountDownLatch? = null,
|
||||
private val expectedStateChange: Int = -1
|
||||
) : KeysBackupStateListener {
|
||||
|
||||
private val allowedStateTransitions = listOf(
|
||||
KeysBackupState.BackingUp to KeysBackupState.ReadyToBackUp,
|
||||
|
@ -52,6 +52,7 @@ import java.util.concurrent.CountDownLatch
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@Ignore
|
||||
class SASTest : InstrumentedTest {
|
||||
|
||||
@Test
|
||||
@ -264,14 +265,16 @@ class SASTest : InstrumentedTest {
|
||||
assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod.value, cancelReq.code)
|
||||
}
|
||||
|
||||
private fun fakeBobStart(bobSession: Session,
|
||||
aliceUserID: String?,
|
||||
aliceDevice: String?,
|
||||
tid: String,
|
||||
protocols: List<String> = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS,
|
||||
hashes: List<String> = SASDefaultVerificationTransaction.KNOWN_HASHES,
|
||||
mac: List<String> = SASDefaultVerificationTransaction.KNOWN_MACS,
|
||||
codes: List<String> = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) {
|
||||
private fun fakeBobStart(
|
||||
bobSession: Session,
|
||||
aliceUserID: String?,
|
||||
aliceDevice: String?,
|
||||
tid: String,
|
||||
protocols: List<String> = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS,
|
||||
hashes: List<String> = SASDefaultVerificationTransaction.KNOWN_HASHES,
|
||||
mac: List<String> = SASDefaultVerificationTransaction.KNOWN_MACS,
|
||||
codes: List<String> = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES
|
||||
) {
|
||||
val startMessage = KeyVerificationStart(
|
||||
fromDevice = bobSession.cryptoService().getMyDevice().deviceId,
|
||||
method = VerificationMethod.SAS.toValue(),
|
||||
@ -412,7 +415,7 @@ class SASTest : InstrumentedTest {
|
||||
OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
aliceSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -426,7 +429,7 @@ class SASTest : InstrumentedTest {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> {
|
||||
tx.performAccept()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
if (uxState === IncomingSasVerificationTransaction.UxState.SHOW_SAS) {
|
||||
bobSASLatch.countDown()
|
||||
@ -476,7 +479,7 @@ class SASTest : InstrumentedTest {
|
||||
aliceSASLatch.countDown()
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -496,16 +499,16 @@ class SASTest : InstrumentedTest {
|
||||
tx.performAccept()
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
IncomingSasVerificationTransaction.UxState.SHOW_SAS -> {
|
||||
if (matchOnce) {
|
||||
matchOnce = false
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
IncomingSasVerificationTransaction.UxState.VERIFIED -> {
|
||||
bobSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.amshove.kluent.shouldBe
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.MethodSorters
|
||||
@ -41,6 +42,7 @@ import kotlin.coroutines.resume
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@Ignore
|
||||
class VerificationTest : InstrumentedTest {
|
||||
|
||||
data class ExpectedResult(
|
||||
@ -151,10 +153,12 @@ class VerificationTest : InstrumentedTest {
|
||||
|
||||
// TODO Add tests without SAS
|
||||
|
||||
private fun doTest(aliceSupportedMethods: List<VerificationMethod>,
|
||||
bobSupportedMethods: List<VerificationMethod>,
|
||||
expectedResultForAlice: ExpectedResult,
|
||||
expectedResultForBob: ExpectedResult) = runCryptoTest(context()) { cryptoTestHelper, testHelper ->
|
||||
private fun doTest(
|
||||
aliceSupportedMethods: List<VerificationMethod>,
|
||||
bobSupportedMethods: List<VerificationMethod>,
|
||||
expectedResultForAlice: ExpectedResult,
|
||||
expectedResultForBob: ExpectedResult
|
||||
) = runCryptoTest(context()) { cryptoTestHelper, testHelper ->
|
||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
|
@ -289,9 +289,11 @@ class MarkdownParserTest : InstrumentedTest {
|
||||
markdownParser.parse(text).expect(text, null)
|
||||
}
|
||||
|
||||
private fun testType(name: String,
|
||||
markdownPattern: String,
|
||||
htmlExpectedTag: String) {
|
||||
private fun testType(
|
||||
name: String,
|
||||
markdownPattern: String,
|
||||
htmlExpectedTag: String
|
||||
) {
|
||||
// Test simple case
|
||||
"$markdownPattern$name$markdownPattern"
|
||||
.let {
|
||||
@ -376,10 +378,12 @@ class MarkdownParserTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun testTypeNewLines(name: String,
|
||||
markdownPattern: String,
|
||||
htmlExpectedTag: String,
|
||||
softBreak: String = "<br />") {
|
||||
private fun testTypeNewLines(
|
||||
name: String,
|
||||
markdownPattern: String,
|
||||
htmlExpectedTag: String,
|
||||
softBreak: String = "<br />"
|
||||
) {
|
||||
// With new line inside the block
|
||||
"$markdownPattern$name\n$name$markdownPattern"
|
||||
.let {
|
||||
|
@ -44,7 +44,7 @@ class TestPermalinkService : PermalinkService {
|
||||
|
||||
override fun createMentionSpanTemplate(type: PermalinkService.SpanTemplateType, forceMatrixTo: Boolean): String {
|
||||
return when (type) {
|
||||
HTML -> "<a href=\"https://matrix.to/#/%1\$s\">%2\$s</a>"
|
||||
HTML -> "<a href=\"https://matrix.to/#/%1\$s\">%2\$s</a>"
|
||||
MARKDOWN -> "[%2\$s](https://matrix.to/#/%1\$s)"
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
timeline.start()
|
||||
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
@ -97,7 +97,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
timeline.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -144,7 +144,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
timeline.start()
|
||||
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
@ -156,9 +156,9 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
timeline.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
|
||||
bobSession.startSync(true)
|
||||
bobSession.syncService().startSync(true)
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
@ -170,7 +170,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
timeline.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
bobSession.stopSync()
|
||||
bobSession.syncService().stopSync()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -217,7 +217,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
timeline.start()
|
||||
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
@ -233,7 +233,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
timeline.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -314,7 +314,7 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
val timeline = aliceRoom.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
timeline.start()
|
||||
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
@ -338,6 +338,6 @@ class ThreadMessagingTest : InstrumentedTest {
|
||||
timeline.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
}
|
||||
}
|
||||
|
@ -154,9 +154,11 @@ internal class ChunkEntityTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun ChunkEntity.addAll(roomId: String,
|
||||
events: List<Event>,
|
||||
direction: PaginationDirection) {
|
||||
private fun ChunkEntity.addAll(
|
||||
roomId: String,
|
||||
events: List<Event>,
|
||||
direction: PaginationDirection
|
||||
) {
|
||||
events.forEach { event ->
|
||||
val fakeEvent = event.toEntity(roomId, SendState.SYNCED, clock.epochMillis()).let {
|
||||
realm.copyToRealm(it)
|
||||
|
@ -19,8 +19,9 @@ package org.matrix.android.sdk.session.room.timeline
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEvent
|
||||
|
||||
internal data class FakeTokenChunkEvent(override val start: String?,
|
||||
override val end: String?,
|
||||
override val events: List<Event> = emptyList(),
|
||||
override val stateEvents: List<Event> = emptyList()
|
||||
internal data class FakeTokenChunkEvent(
|
||||
override val start: String?,
|
||||
override val end: String?,
|
||||
override val events: List<Event> = emptyList(),
|
||||
override val stateEvents: List<Event> = emptyList()
|
||||
) : TokenChunkEvent
|
||||
|
@ -57,7 +57,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||
// Bob creates a poll
|
||||
roomFromBobPOV.sendService().sendPoll(PollType.DISCLOSED, pollQuestion, pollOptions)
|
||||
|
||||
aliceSession.startSync(true)
|
||||
aliceSession.syncService().startSync(true)
|
||||
val aliceTimeline = roomFromAlicePOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
aliceTimeline.start()
|
||||
|
||||
@ -77,7 +77,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
when (lock.count.toInt()) {
|
||||
TOTAL_TEST_COUNT -> {
|
||||
TOTAL_TEST_COUNT -> {
|
||||
// Poll has just been created.
|
||||
testInitialPollConditions(pollContent, pollSummary)
|
||||
lock.countDown()
|
||||
@ -119,7 +119,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||
testEndedPoll(pollSummary)
|
||||
lock.countDown()
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
fail("Lock count ${lock.count} didn't handled.")
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||
|
||||
aliceTimeline.removeAllListeners()
|
||||
|
||||
aliceSession.stopSync()
|
||||
aliceSession.syncService().stopSync()
|
||||
aliceTimeline.dispose()
|
||||
}
|
||||
|
||||
|
@ -41,11 +41,12 @@ object RoomDataHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFakeEvent(type: String,
|
||||
content: Content? = null,
|
||||
prevContent: Content? = null,
|
||||
sender: String = FAKE_TEST_SENDER,
|
||||
stateKey: String? = null
|
||||
private fun createFakeEvent(
|
||||
type: String,
|
||||
content: Content? = null,
|
||||
prevContent: Content? = null,
|
||||
sender: String = FAKE_TEST_SENDER,
|
||||
stateKey: String? = null
|
||||
): Event {
|
||||
return Event(
|
||||
type = type,
|
||||
|
@ -88,7 +88,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
// Bob stop to sync
|
||||
bobSession.stopSync()
|
||||
bobSession.syncService().stopSync()
|
||||
|
||||
val firstMessage = "First messages from Alice"
|
||||
// Alice sends 30 messages
|
||||
@ -101,7 +101,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||
.eventId
|
||||
|
||||
// Bob start to sync
|
||||
bobSession.startSync(true)
|
||||
bobSession.syncService().startSync(true)
|
||||
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
@ -125,7 +125,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
// Bob stop to sync
|
||||
bobSession.stopSync()
|
||||
bobSession.syncService().stopSync()
|
||||
|
||||
val secondMessage = "Second messages from Alice"
|
||||
// Alice sends again 30 messages
|
||||
@ -136,7 +136,7 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
||||
)
|
||||
|
||||
// Bob start to sync
|
||||
bobSession.startSync(true)
|
||||
bobSession.syncService().startSync(true)
|
||||
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
|
@ -20,6 +20,7 @@ import androidx.test.filters.LargeTest
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.amshove.kluent.internal.assertEquals
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
@ -38,6 +39,7 @@ import org.matrix.android.sdk.common.TestConstants
|
||||
@RunWith(JUnit4::class)
|
||||
@FixMethodOrder(MethodSorters.JVM)
|
||||
@LargeTest
|
||||
@Ignore
|
||||
class TimelineSimpleBackPaginationTest : InstrumentedTest {
|
||||
|
||||
@Test
|
||||
|
@ -71,7 +71,7 @@ class TimelineWithManyMembersTest : InstrumentedTest {
|
||||
val timelineForCurrentMember = roomForCurrentMember.timelineService().createTimeline(null, TimelineSettings(30))
|
||||
timelineForCurrentMember.start()
|
||||
|
||||
session.startSync(true)
|
||||
session.syncService().startSync(true)
|
||||
|
||||
run {
|
||||
val lock = CountDownLatch(1)
|
||||
@ -92,7 +92,7 @@ class TimelineWithManyMembersTest : InstrumentedTest {
|
||||
timelineForCurrentMember.addListener(eventsListener)
|
||||
commonTestHelper.await(lock, 600_000)
|
||||
}
|
||||
session.stopSync()
|
||||
session.syncService().stopSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
@ -98,6 +99,7 @@ class SpaceCreationTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun testJoinSimplePublicSpace() = runSessionTest(context()) { commonTestHelper ->
|
||||
|
||||
val aliceSession = commonTestHelper.createAccount("alice", SessionTestParams(true))
|
||||
|
@ -387,9 +387,10 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
val roomIds: List<String>
|
||||
)
|
||||
|
||||
private fun createPublicSpace(session: Session,
|
||||
spaceName: String,
|
||||
childInfo: List<Triple<String, Boolean, Boolean?>>
|
||||
private fun createPublicSpace(
|
||||
session: Session,
|
||||
spaceName: String,
|
||||
childInfo: List<Triple<String, Boolean, Boolean?>>
|
||||
/** Name, auto-join, canonical*/
|
||||
): TestSpaceCreationResult {
|
||||
var spaceId = ""
|
||||
@ -416,9 +417,10 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
return TestSpaceCreationResult(spaceId, roomIds)
|
||||
}
|
||||
|
||||
private fun createPrivateSpace(session: Session,
|
||||
spaceName: String,
|
||||
childInfo: List<Triple<String, Boolean, Boolean?>>
|
||||
private fun createPrivateSpace(
|
||||
session: Session,
|
||||
spaceName: String,
|
||||
childInfo: List<Triple<String, Boolean, Boolean?>>
|
||||
/** Name, auto-join, canonical*/
|
||||
): TestSpaceCreationResult {
|
||||
var spaceId = ""
|
||||
|
@ -26,14 +26,14 @@ internal class InlineMaths(private val delimiter: InlineDelimiter) : CustomNode(
|
||||
|
||||
override fun getOpeningDelimiter(): String {
|
||||
return when (delimiter) {
|
||||
InlineDelimiter.SINGLE_DOLLAR -> "$"
|
||||
InlineDelimiter.SINGLE_DOLLAR -> "$"
|
||||
InlineDelimiter.ROUND_BRACKET_ESCAPED -> "\\("
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClosingDelimiter(): String {
|
||||
return when (delimiter) {
|
||||
InlineDelimiter.SINGLE_DOLLAR -> "$"
|
||||
InlineDelimiter.SINGLE_DOLLAR -> "$"
|
||||
InlineDelimiter.ROUND_BRACKET_ESCAPED -> "\\)"
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,11 @@ import org.matrix.android.sdk.api.session.Session
|
||||
* This interface defines methods to authenticate or to create an account to a matrix server.
|
||||
*/
|
||||
interface AuthenticationService {
|
||||
|
||||
/**
|
||||
* Request the supported login flows for this homeserver.
|
||||
* This is the first method to call to be able to get a wizard to login or to create an account
|
||||
* This is the first method to call to be able to get a wizard to login or to create an account.
|
||||
* @param homeServerConnectionConfig contains the homeserver URL to login to, a wellKnown lookup will be attempted.
|
||||
*/
|
||||
suspend fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult
|
||||
|
||||
@ -93,14 +95,18 @@ interface AuthenticationService {
|
||||
/**
|
||||
* Create a session after a SSO successful login.
|
||||
*/
|
||||
suspend fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
credentials: Credentials): Session
|
||||
suspend fun createSessionFromSso(
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
credentials: Credentials
|
||||
): Session
|
||||
|
||||
/**
|
||||
* Perform a wellknown request, using the domain from the matrixId.
|
||||
*/
|
||||
suspend fun getWellKnownData(matrixId: String,
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult
|
||||
suspend fun getWellKnownData(
|
||||
matrixId: String,
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig?
|
||||
): WellknownResult
|
||||
|
||||
/**
|
||||
* Authenticate with a matrixId and a password.
|
||||
@ -111,9 +117,11 @@ interface AuthenticationService {
|
||||
* @param initialDeviceName the initial device name
|
||||
* @param deviceId the device id, optional. If not provided or null, the server will generate one.
|
||||
*/
|
||||
suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
matrixId: String,
|
||||
password: String,
|
||||
initialDeviceName: String,
|
||||
deviceId: String? = null): Session
|
||||
suspend fun directAuthentication(
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
matrixId: String,
|
||||
password: String,
|
||||
initialDeviceName: String,
|
||||
deviceId: String? = null
|
||||
): Session
|
||||
}
|
||||
|
@ -41,8 +41,10 @@ import org.matrix.android.sdk.api.auth.registration.TermPolicies
|
||||
* @param userLanguage the user language
|
||||
* @param defaultLanguage the default language to use if the user language is not found for a policy in registrationFlowResponse
|
||||
*/
|
||||
fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||
defaultLanguage: String = "en"): List<LocalizedFlowDataLoginTerms> {
|
||||
fun TermPolicies.toLocalizedLoginTerms(
|
||||
userLanguage: String,
|
||||
defaultLanguage: String = "en"
|
||||
): List<LocalizedFlowDataLoginTerms> {
|
||||
val result = ArrayList<LocalizedFlowDataLoginTerms>()
|
||||
|
||||
val policies = get("policies")
|
||||
@ -67,8 +69,8 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||
// Search for language
|
||||
policy.keys.forEach { policyKey ->
|
||||
when (policyKey) {
|
||||
"version" -> Unit // Ignore
|
||||
userLanguage -> {
|
||||
"version" -> Unit // Ignore
|
||||
userLanguage -> {
|
||||
// We found the data for the user language
|
||||
userLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
||||
}
|
||||
@ -76,7 +78,7 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||
// We found default language
|
||||
defaultLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
if (firstUrlAndName == null) {
|
||||
// Get at least some data
|
||||
firstUrlAndName = extractUrlAndName(policy[policyKey])
|
||||
@ -87,7 +89,7 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||
|
||||
// Copy found language data by priority
|
||||
when {
|
||||
userLanguageUrlAndName != null -> {
|
||||
userLanguageUrlAndName != null -> {
|
||||
localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url
|
||||
localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name
|
||||
}
|
||||
@ -95,7 +97,7 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||
localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url
|
||||
localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name
|
||||
}
|
||||
firstUrlAndName != null -> {
|
||||
firstUrlAndName != null -> {
|
||||
localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url
|
||||
localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name
|
||||
}
|
||||
|
@ -66,17 +66,17 @@ data class SsoIdentityProvider(
|
||||
private fun toPriority(): Int {
|
||||
return when (brand) {
|
||||
// We are on Android, so user is more likely to have a Google account
|
||||
BRAND_GOOGLE -> 5
|
||||
BRAND_GOOGLE -> 5
|
||||
// Facebook is also an important SSO provider
|
||||
BRAND_FACEBOOK -> 4
|
||||
// Twitter is more for professionals
|
||||
BRAND_TWITTER -> 3
|
||||
BRAND_TWITTER -> 3
|
||||
// Here it's very for techie people
|
||||
BRAND_GITHUB,
|
||||
BRAND_GITLAB -> 2
|
||||
BRAND_GITLAB -> 2
|
||||
// And finally, if the account has been created with an iPhone...
|
||||
BRAND_APPLE -> 1
|
||||
else -> 0
|
||||
BRAND_APPLE -> 1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,12 @@ interface LoginWizard {
|
||||
* @param deviceId the device id, optional. If not provided or null, the server will generate one.
|
||||
* @return a [Session] if the login is successful
|
||||
*/
|
||||
suspend fun login(login: String,
|
||||
password: String,
|
||||
initialDeviceName: String,
|
||||
deviceId: String? = null): Session
|
||||
suspend fun login(
|
||||
login: String,
|
||||
password: String,
|
||||
initialDeviceName: String,
|
||||
deviceId: String? = null
|
||||
): Session
|
||||
|
||||
/**
|
||||
* Exchange a login token to an access token.
|
||||
@ -63,14 +65,14 @@ interface LoginWizard {
|
||||
* [resetPasswordMailConfirmed] is successfully called.
|
||||
*
|
||||
* @param email an email previously associated to the account the user wants the password to be reset.
|
||||
* @param newPassword the desired new password
|
||||
*/
|
||||
suspend fun resetPassword(email: String,
|
||||
newPassword: String)
|
||||
suspend fun resetPassword(email: String)
|
||||
|
||||
/**
|
||||
* Confirm the new password, once the user has checked their email
|
||||
* When this method succeed, tha account password will be effectively modified.
|
||||
*
|
||||
* @param newPassword the desired new password
|
||||
*/
|
||||
suspend fun resetPasswordMailConfirmed()
|
||||
suspend fun resetPasswordMailConfirmed(newPassword: String)
|
||||
}
|
||||
|
@ -88,15 +88,15 @@ fun RegistrationFlowResponse.toFlowResult(): FlowResult {
|
||||
val isMandatory = flows?.all { type in it.stages.orEmpty() } == true
|
||||
|
||||
val stage = when (type) {
|
||||
LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(
|
||||
LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(
|
||||
isMandatory, ((params?.get(type) as? Map<*, *>)?.get("public_key") as? String)
|
||||
?: ""
|
||||
)
|
||||
LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory)
|
||||
LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>())
|
||||
LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory)
|
||||
LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>())
|
||||
LoginFlowTypes.EMAIL_IDENTITY -> Stage.Email(isMandatory)
|
||||
LoginFlowTypes.MSISDN -> Stage.Msisdn(isMandatory)
|
||||
else -> Stage.Other(isMandatory, type, (params?.get(type) as? Map<*, *>))
|
||||
LoginFlowTypes.MSISDN -> Stage.Msisdn(isMandatory)
|
||||
else -> Stage.Other(isMandatory, type, (params?.get(type) as? Map<*, *>))
|
||||
}
|
||||
|
||||
if (type in completedStages.orEmpty()) {
|
||||
|
@ -54,9 +54,11 @@ interface RegistrationWizard {
|
||||
* @param password the desired password
|
||||
* @param initialDeviceDisplayName the device display name
|
||||
*/
|
||||
suspend fun createAccount(userName: String?,
|
||||
password: String?,
|
||||
initialDeviceDisplayName: String?): RegistrationResult
|
||||
suspend fun createAccount(
|
||||
userName: String?,
|
||||
password: String?,
|
||||
initialDeviceDisplayName: String?
|
||||
): RegistrationResult
|
||||
|
||||
/**
|
||||
* Perform the "m.login.recaptcha" stage.
|
||||
|
@ -26,9 +26,11 @@ sealed class 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.
|
||||
*/
|
||||
data class Prompt(val homeServerUrl: String,
|
||||
val identityServerUrl: String?,
|
||||
val wellKnown: WellKnown) : WellknownResult()
|
||||
data class Prompt(
|
||||
val homeServerUrl: String,
|
||||
val identityServerUrl: String?,
|
||||
val wellKnown: WellKnown
|
||||
) : WellknownResult()
|
||||
|
||||
/**
|
||||
* Stop the current auto-discovery mechanism. If no more auto-discovery mechanisms are available,
|
||||
|
@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.extensions
|
||||
fun CharSequence.ensurePrefix(prefix: CharSequence): CharSequence {
|
||||
return when {
|
||||
startsWith(prefix) -> this
|
||||
else -> "$prefix$this"
|
||||
else -> "$prefix$this"
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,3 +27,8 @@ fun CharSequence.ensurePrefix(prefix: CharSequence): CharSequence {
|
||||
* Append a new line and then the provided string.
|
||||
*/
|
||||
fun StringBuilder.appendNl(str: String) = append("\n").append(str)
|
||||
|
||||
/**
|
||||
* Returns null if the string is empty.
|
||||
*/
|
||||
fun String.ensureNotEmpty() = ifEmpty { null }
|
||||
|
@ -36,7 +36,7 @@ data class Fingerprint(
|
||||
internal fun matchesCert(cert: X509Certificate): Boolean {
|
||||
val o: Fingerprint? = when (hashType) {
|
||||
HashType.SHA256 -> newSha256Fingerprint(cert)
|
||||
HashType.SHA1 -> newSha1Fingerprint(cert)
|
||||
HashType.SHA1 -> newSha1Fingerprint(cert)
|
||||
}
|
||||
return equals(o)
|
||||
}
|
||||
|
@ -17,8 +17,6 @@
|
||||
package org.matrix.android.sdk.api.session
|
||||
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.lifecycle.LiveData
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
@ -37,7 +35,6 @@ import org.matrix.android.sdk.api.session.file.FileService
|
||||
import org.matrix.android.sdk.api.session.group.GroupService
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.session.identity.IdentityService
|
||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
||||
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
|
||||
@ -55,8 +52,7 @@ import org.matrix.android.sdk.api.session.signout.SignOutService
|
||||
import org.matrix.android.sdk.api.session.space.SpaceService
|
||||
import org.matrix.android.sdk.api.session.statistics.StatisticsListener
|
||||
import org.matrix.android.sdk.api.session.sync.FilterService
|
||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
||||
import org.matrix.android.sdk.api.session.sync.SyncService
|
||||
import org.matrix.android.sdk.api.session.terms.TermsService
|
||||
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
|
||||
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
|
||||
@ -98,59 +94,11 @@ interface Session {
|
||||
@MainThread
|
||||
fun open()
|
||||
|
||||
/**
|
||||
* Requires a one time background sync.
|
||||
*/
|
||||
fun requireBackgroundSync()
|
||||
|
||||
/**
|
||||
* Launches infinite self rescheduling background syncs via the WorkManager.
|
||||
*
|
||||
* While dozing, syncs will only occur during maintenance windows.
|
||||
* For reliability it's recommended to also start a long running foreground service
|
||||
* along with disabling battery optimizations.
|
||||
*/
|
||||
fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long)
|
||||
|
||||
fun stopAnyBackgroundSync()
|
||||
|
||||
/**
|
||||
* This method start the sync thread.
|
||||
*/
|
||||
fun startSync(fromForeground: Boolean)
|
||||
|
||||
/**
|
||||
* This method stop the sync thread.
|
||||
*/
|
||||
fun stopSync()
|
||||
|
||||
/**
|
||||
* Clear cache of the session.
|
||||
*/
|
||||
suspend fun clearCache()
|
||||
|
||||
/**
|
||||
* This method allows to listen the sync state.
|
||||
* @return a [LiveData] of [SyncState].
|
||||
*/
|
||||
fun getSyncStateLive(): LiveData<SyncState>
|
||||
|
||||
/**
|
||||
* This method returns the current sync state.
|
||||
* @return the current [SyncState].
|
||||
*/
|
||||
fun getSyncState(): SyncState
|
||||
|
||||
/**
|
||||
* This method returns a flow of SyncResponse. New value will be pushed through the sync thread.
|
||||
*/
|
||||
fun syncFlow(): SharedFlow<SyncResponse>
|
||||
|
||||
/**
|
||||
* This methods return true if an initial sync has been processed.
|
||||
*/
|
||||
fun hasAlreadySynced(): Boolean
|
||||
|
||||
/**
|
||||
* This method allow to close a session. It does stop some services.
|
||||
*/
|
||||
@ -247,9 +195,9 @@ interface Session {
|
||||
fun termsService(): TermsService
|
||||
|
||||
/**
|
||||
* Returns the SyncStatusService associated with the session.
|
||||
* Returns the SyncService associated with the session.
|
||||
*/
|
||||
fun syncStatusService(): SyncStatusService
|
||||
fun syncService(): SyncService
|
||||
|
||||
/**
|
||||
* Returns the SecureStorageService associated with the session.
|
||||
|
@ -27,8 +27,10 @@ interface AccountService {
|
||||
* @param password Current password.
|
||||
* @param newPassword New password
|
||||
*/
|
||||
suspend fun changePassword(password: String,
|
||||
newPassword: String)
|
||||
suspend fun changePassword(
|
||||
password: String,
|
||||
newPassword: String
|
||||
)
|
||||
|
||||
/**
|
||||
* Deactivate the account.
|
||||
@ -46,6 +48,8 @@ interface AccountService {
|
||||
* an incomplete view of conversations
|
||||
* @param userInteractiveAuthInterceptor see [UserInteractiveAuthInterceptor]
|
||||
*/
|
||||
suspend fun deactivateAccount(eraseAllData: Boolean,
|
||||
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor)
|
||||
suspend fun deactivateAccount(
|
||||
eraseAllData: Boolean,
|
||||
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor
|
||||
)
|
||||
}
|
||||
|
@ -91,10 +91,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?,
|
||||
createCallId: String?,
|
||||
awaitCallId: String?)
|
||||
suspend fun transfer(
|
||||
targetUserId: String,
|
||||
targetRoomId: String?,
|
||||
createCallId: String?,
|
||||
awaitCallId: String?
|
||||
)
|
||||
|
||||
fun addListener(listener: StateListener)
|
||||
fun removeListener(listener: StateListener)
|
||||
|
@ -88,9 +88,11 @@ interface CryptoService {
|
||||
|
||||
fun getDeviceTrackingStatus(userId: String): Int
|
||||
|
||||
suspend fun importRoomKeys(roomKeysAsArray: ByteArray,
|
||||
password: String,
|
||||
progressListener: ProgressListener?): ImportRoomKeysResult
|
||||
suspend fun importRoomKeys(
|
||||
roomKeysAsArray: ByteArray,
|
||||
password: String,
|
||||
progressListener: ProgressListener?
|
||||
): ImportRoomKeysResult
|
||||
|
||||
suspend fun exportRoomKeys(password: String): ByteArray
|
||||
|
||||
@ -119,10 +121,12 @@ interface CryptoService {
|
||||
fun isRoomEncrypted(roomId: String): Boolean
|
||||
|
||||
// TODO This could be removed from this interface
|
||||
fun encryptEventContent(eventContent: Content,
|
||||
eventType: String,
|
||||
roomId: String,
|
||||
callback: MatrixCallback<MXEncryptEventContentResult>)
|
||||
fun encryptEventContent(
|
||||
eventContent: Content,
|
||||
eventType: String,
|
||||
roomId: String,
|
||||
callback: MatrixCallback<MXEncryptEventContentResult>
|
||||
)
|
||||
|
||||
fun discardOutboundSession(roomId: String)
|
||||
|
||||
|
@ -25,12 +25,14 @@ import org.matrix.olm.OlmException
|
||||
*/
|
||||
sealed class MXCryptoError : Throwable() {
|
||||
|
||||
data class Base(val errorType: ErrorType,
|
||||
val technicalMessage: String,
|
||||
/**
|
||||
* Describe the error with more details.
|
||||
*/
|
||||
val detailedErrorDescription: String? = null) : MXCryptoError()
|
||||
data class Base(
|
||||
val errorType: ErrorType,
|
||||
val technicalMessage: String,
|
||||
/**
|
||||
* Describe the error with more details.
|
||||
*/
|
||||
val detailedErrorDescription: String? = null
|
||||
) : MXCryptoError()
|
||||
|
||||
data class OlmError(val olmException: OlmException) : MXCryptoError()
|
||||
|
||||
|
@ -26,7 +26,7 @@ data class RequestReply(
|
||||
)
|
||||
|
||||
sealed class RequestResult {
|
||||
data class Success(val chainIndex: Int) : RequestResult()
|
||||
data class Success(val chainIndex: Int) : RequestResult()
|
||||
data class Failure(val code: WithHeldCode) : RequestResult()
|
||||
}
|
||||
|
||||
|
@ -37,14 +37,18 @@ interface CrossSigningService {
|
||||
* Initialize cross signing for this user.
|
||||
* Users needs to enter credentials
|
||||
*/
|
||||
fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?,
|
||||
callback: MatrixCallback<Unit>)
|
||||
fun initializeCrossSigning(
|
||||
uiaInterceptor: UserInteractiveAuthInterceptor?,
|
||||
callback: MatrixCallback<Unit>
|
||||
)
|
||||
|
||||
fun isCrossSigningInitialized(): Boolean = getMyCrossSigningKeys() != null
|
||||
|
||||
fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?,
|
||||
uskKeyPrivateKey: String?,
|
||||
sskPrivateKey: String?): UserTrustResult
|
||||
fun checkTrustFromPrivateKeys(
|
||||
masterKeyPrivateKey: String?,
|
||||
uskKeyPrivateKey: String?,
|
||||
sskPrivateKey: String?
|
||||
): UserTrustResult
|
||||
|
||||
fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo?
|
||||
|
||||
@ -60,20 +64,26 @@ interface CrossSigningService {
|
||||
|
||||
fun allPrivateKeysKnown(): Boolean
|
||||
|
||||
fun trustUser(otherUserId: String,
|
||||
callback: MatrixCallback<Unit>)
|
||||
fun trustUser(
|
||||
otherUserId: String,
|
||||
callback: MatrixCallback<Unit>
|
||||
)
|
||||
|
||||
fun markMyMasterKeyAsTrusted()
|
||||
|
||||
/**
|
||||
* Sign one of your devices and upload the signature.
|
||||
*/
|
||||
fun trustDevice(deviceId: String,
|
||||
callback: MatrixCallback<Unit>)
|
||||
fun trustDevice(
|
||||
deviceId: String,
|
||||
callback: MatrixCallback<Unit>
|
||||
)
|
||||
|
||||
fun checkDeviceTrust(otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
locallyTrusted: Boolean?): DeviceTrustResult
|
||||
fun checkDeviceTrust(
|
||||
otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
locallyTrusted: Boolean?
|
||||
): DeviceTrustResult
|
||||
|
||||
// FIXME Those method do not have to be in the service
|
||||
fun onSecretMSKGossip(mskPrivateKey: String)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user