diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml
index b063c93530..b28dbbde69 100644
--- a/.github/ISSUE_TEMPLATE/release.yml
+++ b/.github/ISSUE_TEMPLATE/release.yml
@@ -21,6 +21,8 @@ body:
- [ ] While Weblate is locked, and after the PR from Weblate has been merged, handle all the TODOs in the main `strings.xml` file
- [ ] Run the script `./tools/release/pushPlayStoreMetaData.sh`. You can check in the GooglePlay console the Activity log to check the effect.
+ - [ ] Ensure all [the required PRs](https://github.com/vector-im/element-android/pulls?q=is%3Aopen+is%3Apr+label%3AZ-NextRelease) have been merged
+
### Do the release
- [ ] Make sure `develop` and `main` are up to date (git pull)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1c0491fda4..933c442501 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,10 +7,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
- CI_GRADLE_ARG_PROPERTIES: >
- -Porg.gradle.jvmargs=-Xmx4g
- -Porg.gradle.parallel=false
- --no-daemon
+ GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
+ CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
debug:
@@ -36,7 +34,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Assemble ${{ matrix.target }} debug apk
- run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES --stacktrace
+ run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES
- name: Upload ${{ matrix.target }} debug APKs
uses: actions/upload-artifact@v3
with:
@@ -61,7 +59,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Assemble GPlay unsigned apk
- run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES --stacktrace
+ run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload Gplay unsigned APKs
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index a1d754b4de..8a892b9b15 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -11,8 +11,10 @@ jobs:
- run: |
npm install --save-dev @babel/plugin-transform-flow-strip-types
- name: Danger
- uses: danger/danger-js@11.1.1
+ uses: danger/danger-js@11.1.2
with:
args: "--dangerfile tools/danger/dangerfile.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
+ # Fallback for forks
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 36fd225674..51c1b32e82 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -6,10 +6,8 @@ on:
- cron: "0 4 * * *"
env:
- CI_GRADLE_ARG_PROPERTIES: >
- -Porg.gradle.jvmargs=-Xmx4g
- -Porg.gradle.parallel=false
- --no-daemon
+ GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
+ CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
nightly:
@@ -40,7 +38,7 @@ jobs:
yes n | towncrier build --version nightly
- name: Build and upload Gplay Nightly APK
run: |
- ./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES --stacktrace
+ ./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
env:
ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
diff --git a/.github/workflows/post-pr.yml b/.github/workflows/post-pr.yml
index a7f1d6f204..5cde95e625 100644
--- a/.github/workflows/post-pr.yml
+++ b/.github/workflows/post-pr.yml
@@ -10,10 +10,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
- CI_GRADLE_ARG_PROPERTIES: >
- -Porg.gradle.jvmargs=-Xmx4g
- -Porg.gradle.parallel=false
- --no-daemon
+ GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
+ CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
index 56a7c8b97b..70669596bb 100644
--- a/.github/workflows/quality.yml
+++ b/.github/workflows/quality.yml
@@ -7,10 +7,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
- CI_GRADLE_ARG_PROPERTIES: >
- -Porg.gradle.jvmargs=-Xmx4g
- -Porg.gradle.parallel=false
- --no-daemon
+ GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
+ CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
check:
@@ -51,8 +49,8 @@ jobs:
- name: Run lint
# Not always, if ktlint or detekt fail, avoid running the long lint check.
run: |
- ./gradlew lintGplayRelease --stacktrace $CI_GRADLE_ARG_PROPERTIES
- ./gradlew lintFdroidRelease --stacktrace $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew lintGplayRelease $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew lintFdroidRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports
if: always()
uses: actions/upload-artifact@v3
@@ -68,11 +66,13 @@ jobs:
yarn add danger-plugin-lint-report --dev
- name: Danger lint
if: always()
- uses: danger/danger-js@11.1.1
+ uses: danger/danger-js@11.1.2
with:
args: "--dangerfile tools/danger/dangerfile-lint.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
+ # Fallback for forks
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Gradle dependency analysis using https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin
dependency-analysis:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 2b9aa1a851..2a89ed3040 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -7,10 +7,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
- CI_GRADLE_ARG_PROPERTIES: >
- -Porg.gradle.jvmargs=-Xmx4g
- -Porg.gradle.parallel=false
- --no-daemon
+ GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
+ CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
tests:
@@ -51,9 +49,9 @@ jobs:
disable-animations: true
emulator-build: 7425822
script: |
- ./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
- ./gradlew instrumentationTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
- ./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew generateCoverageReport $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
@@ -67,9 +65,9 @@ jobs:
disable-animations: true
emulator-build: 7425822
script: |
- ./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
- ./gradlew instrumentationTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
- ./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
+ ./gradlew generateCoverageReport $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:
@@ -114,5 +112,5 @@ jobs:
# restore-keys: |
# ${{ runner.os }}-gradle-
# - name: Build Android Tests
-# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
+# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES
diff --git a/.github/workflows/triage-labelled.yml b/.github/workflows/triage-labelled.yml
index 90f03779a6..f478d2bd7b 100644
--- a/.github/workflows/triage-labelled.yml
+++ b/.github/workflows/triage-labelled.yml
@@ -98,7 +98,8 @@ jobs:
# Skip in forks
if: >
github.repository == 'vector-im/element-android' &&
- (contains(github.event.issue.labels.*.name, 'Team: Delight'))
+ (contains(github.event.issue.labels.*.name, 'Team: Delight') ||
+ contains(github.event.issue.labels.*.name, 'Z-AppLayout'))
steps:
- uses: octokit/graphql-action@v2.x
with:
diff --git a/CHANGES.md b/CHANGES.md
index 2c6fc1501c..4615ec8ff0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,95 @@
+Changes in Element v1.4.34 (2022-08-23)
+=======================================
+
+Features ✨
+----------
+ - [Notification] - Handle creation of notification for live location and poll start ([#6746](https://github.com/vector-im/element-android/issues/6746))
+
+Bugfixes 🐛
+----------
+ - Fixes onboarding requiring matrix.org to be accessible on the first step, the server can now be manually changed ([#6718](https://github.com/vector-im/element-android/issues/6718))
+ - Fixing sign in/up for homeservers that rely on the SSO fallback url ([#6827](https://github.com/vector-im/element-android/issues/6827))
+ - Fixes uncaught exceptions in the SyncWorker to cause the worker to become stuck in the failure state ([#6836](https://github.com/vector-im/element-android/issues/6836))
+ - Fixes onboarding captcha crashing when no WebView is available by showing an error with information instead ([#6855](https://github.com/vector-im/element-android/issues/6855))
+ - Removes ability to continue registration after the app has been destroyed, fixes the next steps crashing due to missing information from the previous steps ([#6860](https://github.com/vector-im/element-android/issues/6860))
+ - Fixes crash when exiting the login or registration entry screens whilst they're loading ([#6861](https://github.com/vector-im/element-android/issues/6861))
+ - Fixes server selection being unable to trust certificates ([#6864](https://github.com/vector-im/element-android/issues/6864))
+ - Ensure SyncThread is started when the app is launched after a Push has been received. ([#6884](https://github.com/vector-im/element-android/issues/6884))
+ - Fixes missing firebase notifications after logging in when UnifiedPush distributor is installed ([#6891](https://github.com/vector-im/element-android/issues/6891))
+
+In development 🚧
+----------------
+ - Create DM room only on first message - Trigger the flow when the "Direct Message" action is selected from the room member details screen ([#5525](https://github.com/vector-im/element-android/issues/5525))
+ - added filter tabs for new App layout's Home screen ([#6505](https://github.com/vector-im/element-android/issues/6505))
+ - [App Layout] added dialog to configure app layout ([#6506](https://github.com/vector-im/element-android/issues/6506))
+ - Adds space list bottom sheet for new app layout ([#6749](https://github.com/vector-im/element-android/issues/6749))
+ - [App Layout] Dialpad moved from bottom navigation tab to a separate activity accessed via home screen context menu ([#6787](https://github.com/vector-im/element-android/issues/6787))
+ - Makes toolbar switch title based on space in New App Layout ([#6795](https://github.com/vector-im/element-android/issues/6795))
+ - [Devices management] Add a feature flag and empty screen for future new layout ([#6798](https://github.com/vector-im/element-android/issues/6798))
+ - Adds new chat bottom sheet as the click action of the main FAB in the new app layout ([#6801](https://github.com/vector-im/element-android/issues/6801))
+ - [Devices management] Other sessions section in new layout ([#6806](https://github.com/vector-im/element-android/issues/6806))
+ - [New Layout] Adds space settings accessible through clicking the toolbar ([#6859](https://github.com/vector-im/element-android/issues/6859))
+ - Adds New App Layout FABs (hidden behind feature flag) ([#6693](https://github.com/vector-im/element-android/issues/6693))
+
+SDK API changes ⚠️
+------------------
+ - Rename `DebugService.logDbUsageInfo` (resp. `Session.logDbUsageInfo`) to `DebugService.getDbUsageInfo` (resp. `Session.getDbUsageInfo`) and return a String instead of logging. The caller may want to log the String. ([#6884](https://github.com/vector-im/element-android/issues/6884))
+
+Other changes
+-------------
+ - Removes the Login2 proof of concept - replaced by the FTUE changes ([#5974](https://github.com/vector-im/element-android/issues/5974))
+ - Enable auto-capitalization for Room creation Title field ([#6645](https://github.com/vector-im/element-android/issues/6645))
+ - Decouples the variant logic from the vector module ([#6783](https://github.com/vector-im/element-android/issues/6783))
+ - Add a developer setting to enable LeakCanary at runtime ([#6786](https://github.com/vector-im/element-android/issues/6786))
+ - [Create Room] Reduce some boilerplate with room state event contents ([#6799](https://github.com/vector-im/element-android/issues/6799))
+ - [Call] Memory leak after a call ([#6808](https://github.com/vector-im/element-android/issues/6808))
+ - Fix some string template ([#6843](https://github.com/vector-im/element-android/issues/6843))
+
+
+Changes in Element v1.4.32 (2022-08-10)
+=======================================
+
+Features ✨
+----------
+ - [Location Share] Render fallback UI when map fails to load ([#6711](https://github.com/vector-im/element-android/issues/6711))
+
+Bugfixes 🐛
+----------
+ - Fix message content sometimes appearing in the log ([#6706](https://github.com/vector-im/element-android/issues/6706))
+ - Disable 'Enable biometrics' option if there are not biometric authenticators enrolled. ([#6713](https://github.com/vector-im/element-android/issues/6713))
+ - Fix crash when biometric key is used when coming back to foreground and KeyStore reports that the device is still locked. ([#6768](https://github.com/vector-im/element-android/issues/6768))
+ - Catch all exceptions on lockscreen system key migrations. ([#6769](https://github.com/vector-im/element-android/issues/6769))
+ - Fixes crash when entering non ascii characters during account creation ([#6735](https://github.com/vector-im/element-android/issues/6735))
+ - Fixes onboarding login/account creation errors showing after navigation ([#6737](https://github.com/vector-im/element-android/issues/6737))
+ - [Location sharing] Invisible text on map symbol ([#6687](https://github.com/vector-im/element-android/issues/6687))
+
+In development 🚧
+----------------
+ - Adds new app layout toolbar ([#6655](https://github.com/vector-im/element-android/issues/6655))
+
+Other changes
+-------------
+ - [Modularization] Provides abstraction to avoid direct usages of BuildConfig ([#6406](https://github.com/vector-im/element-android/issues/6406))
+ - Refactors SpaceStateHandler (previously AppStateHandler) and adds unit tests for it ([#6598](https://github.com/vector-im/element-android/issues/6598))
+ - Setup Danger to the project ([#6637](https://github.com/vector-im/element-android/issues/6637))
+ - [Location Share] Open maximized map on tapping on live sharing notification ([#6642](https://github.com/vector-im/element-android/issues/6642))
+ - [Location sharing] Align naming of components for live location feature ([#6647](https://github.com/vector-im/element-android/issues/6647))
+ - [Location share] Update minimum sending period to 5 seconds for a live ([#6653](https://github.com/vector-im/element-android/issues/6653))
+ - [Location sharing] - Fix the memory leaks ([#6674](https://github.com/vector-im/element-android/issues/6674))
+ - [Timeline] Memory leak in audio message playback tracker ([#6678](https://github.com/vector-im/element-android/issues/6678))
+ - [FTUE] Memory leak on FtueAuthSplashCarouselFragment ([#6680](https://github.com/vector-im/element-android/issues/6680))
+ - Link directly to DCO docs from danger message. ([#6739](https://github.com/vector-im/element-android/issues/6739))
+
+
+Changes in Element v1.4.31 (2022-08-01)
+=======================================
+
+Bugfixes 🐛
+----------
+ - Fixes crash when returning to the app after backgrounding ([#6709](https://github.com/vector-im/element-android/issues/6709))
+ - Fix message content sometimes appearing in the log ([#6706](https://github.com/vector-im/element-android/issues/6706))
+
+
Changes in Element v1.4.30 (2022-07-29)
=======================================
diff --git a/build.gradle b/build.gradle
index fccf00d579..aa8a3e2c4c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,12 +24,12 @@ buildscript {
classpath libs.gradle.gradlePlugin
classpath libs.gradle.kotlinPlugin
classpath libs.gradle.hiltPlugin
- classpath 'com.google.firebase:firebase-appdistribution-gradle:3.0.2'
+ classpath 'com.google.firebase:firebase-appdistribution-gradle:3.0.3'
classpath 'com.google.gms:google-services:4.3.13'
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.1'
+ classpath 'org.owasp:dependency-check-gradle:7.1.2'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.10"
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
// NOTE: Do not place your application dependencies here; they belong
@@ -41,10 +41,10 @@ plugins {
// ktlint Plugin
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
// Detekt
- id "io.gitlab.arturbosch.detekt" version "1.20.0"
+ id "io.gitlab.arturbosch.detekt" version "1.21.0"
// Dependency Analysis
- id 'com.autonomousapps.dependency-analysis' version "1.11.2"
+ id 'com.autonomousapps.dependency-analysis' version "1.12.0"
}
// https://github.com/jeremylong/DependencyCheck
@@ -151,6 +151,8 @@ allprojects {
"experimental:comment-wrapping",
// - A KDoc comment after any other element on the same line must be separated by a new line
"experimental:kdoc-wrapping",
+ // Ignore error "Redundant curly braces", since we use it to fix false positives, for instance in "elementLogs.${i}.txt"
+ "string-template",
]
}
diff --git a/changelog.d/6598.misc b/changelog.d/6598.misc
deleted file mode 100644
index db65a30bdc..0000000000
--- a/changelog.d/6598.misc
+++ /dev/null
@@ -1 +0,0 @@
-Refactors SpaceStateHandler (previously AppStateHandler) and adds unit tests for it
diff --git a/changelog.d/6637.misc b/changelog.d/6637.misc
deleted file mode 100644
index 7fc5ffad98..0000000000
--- a/changelog.d/6637.misc
+++ /dev/null
@@ -1 +0,0 @@
-Setup Danger to the project
diff --git a/changelog.d/6642.misc b/changelog.d/6642.misc
deleted file mode 100644
index a32b20716a..0000000000
--- a/changelog.d/6642.misc
+++ /dev/null
@@ -1 +0,0 @@
-[Location Share] Open maximized map on tapping on live sharing notification
diff --git a/changelog.d/6894.misc b/changelog.d/6894.misc
new file mode 100644
index 0000000000..abb1a69a71
--- /dev/null
+++ b/changelog.d/6894.misc
@@ -0,0 +1 @@
+Remove FragmentModule and the Fragment factory. No need to Inject the constructor on your Fragment, just add @AndroidEntryPoint annotation and @Inject class members.
diff --git a/dependencies.gradle b/dependencies.gradle
index 4b75086ba0..1ad4361b6c 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -20,16 +20,16 @@ def retrofit = "2.9.0"
def arrow = "0.8.2"
def markwon = "4.6.2"
def moshi = "1.13.0"
-def lifecycle = "2.5.0"
+def lifecycle = "2.5.1"
def flowBinding = "1.2.0"
-def flipper = "0.156.0"
+def flipper = "0.161.0"
def epoxy = "4.6.2"
def mavericks = "2.7.0"
def glide = "4.13.2"
def bigImageViewer = "1.8.1"
def jjwt = "0.11.5"
def vanniktechEmoji = "0.15.0"
-def fragment = "1.5.0"
+def fragment = "1.5.2"
// Testing
def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819
@@ -49,7 +49,7 @@ ext.libs = [
'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines"
],
androidx : [
- 'activity' : "androidx.activity:activity:1.5.0",
+ 'activity' : "androidx.activity:activity:1.5.1",
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
'biometric' : "androidx.biometric:biometric:1.1.0",
'core' : "androidx.core:core-ktx:1.8.0",
diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle
index f3f35cc88c..454d90dbbd 100644
--- a/dependencies_groups.gradle
+++ b/dependencies_groups.gradle
@@ -74,6 +74,7 @@ ext.groups = [
'com.github.javaparser',
'com.github.piasy',
'com.github.shyiko.klob',
+ 'com.github.rubensousa',
'com.google',
'com.google.android',
'com.google.api.grpc',
@@ -106,7 +107,9 @@ ext.groups = [
'com.pinterest.ktlint',
'com.posthog.android',
'com.squareup',
+ 'com.squareup.curtains',
'com.squareup.duktape',
+ 'com.squareup.leakcanary',
'com.squareup.moshi',
'com.squareup.okhttp3',
'com.squareup.okio',
@@ -125,6 +128,7 @@ ext.groups = [
'info.picocli',
'io.arrow-kt',
'io.element.android',
+ 'io.github.davidburstrom.contester',
'io.github.detekt.sarif4k',
'io.github.microutils',
'io.github.reactivecircus.flowbinding',
diff --git a/docs/danger.md b/docs/danger.md
index 19728f00e9..afa3555469 100644
--- a/docs/danger.md
+++ b/docs/danger.md
@@ -23,6 +23,7 @@ Here are the checks that Danger does so far:
- PR description is not empty
- Big PR got a warning to recommend to split
- PR contains a file for towncrier and extension is checked
+- PR does not modify frozen classes
- PR contains a Sign-Off, with exception for Element employee contributors
- PR with change on layout should include screenshot in the description
- PR which adds png file warn about the usage of vector drawables
@@ -84,6 +85,8 @@ To let Danger check all the PRs, including PRs form forks, a GitHub account have
- password: Stored on Passbolt
- GitHub token: A token with limited access has been created and added to the repository https://github.com/vector-im/element-android as secret DANGER_GITHUB_API_TOKEN. This token is not saved anywhere else. In case of problem, just delete it and create a new one, then update the secret.
+PRs from forks do not always have access to the secret `secrets.DANGER_GITHUB_API_TOKEN`, so `secrets.GITHUB_TOKEN` is also provided to the job environment. If `secrets.DANGER_GITHUB_API_TOKEN` is available, it will be used, so user `ElementBot` will comment the PR. Else `secrets.GITHUB_TOKEN` will be used, and bot `github-actions` will comment the PR.
+
## Useful links
- https://danger.systems/
diff --git a/docs/hilt_migration.md b/docs/hilt_migration.md
index 50021e9792..0556cf85dc 100644
--- a/docs/hilt_migration.md
+++ b/docs/hilt_migration.md
@@ -7,8 +7,8 @@ Hilt is built on top of Dagger 2 and simplify usage by removing needs to create
When you create a new feature, you should have the following:
Annotate your Activity with @AndroidEntryPoint
+Annotate your Fragment with @AndroidEntryPoint
If you have a BottomSheetFragment => Annotate it with @AndroidEntryPoint
-Otherwise => Add your Fragment to the FragmentModule
Add your ViewModel.Factory to the MavericksViewModelModule
Makes sure your ViewModel as the following code:
diff --git a/docs/nightly_build.md b/docs/nightly_build.md
index 91f18214c4..7750e0466a 100644
--- a/docs/nightly_build.md
+++ b/docs/nightly_build.md
@@ -48,7 +48,7 @@ mv towncrier.toml towncrier.toml.bak
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
rm towncrier.toml.bak
yes n | towncrier --version nightly
-./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES --stacktrace
+./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
```
Then you can reset the change on the codebase.
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104300.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104300.txt
new file mode 100644
index 0000000000..e74d892209
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: Umožňuje vylepšené přihlašování a registraci.
+Úplný seznam změn: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104310.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104310.txt
new file mode 100644
index 0000000000..e74d892209
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: Umožňuje vylepšené přihlašování a registraci.
+Úplný seznam změn: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/en-US/changelogs/40104310.txt b/fastlane/metadata/android/en-US/changelogs/40104310.txt
new file mode 100644
index 0000000000..c0b3284c4f
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Main changes in this version: Enables the improved sign in and sign up journeys.
+Full changelog: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/en-US/changelogs/40104320.txt b/fastlane/metadata/android/en-US/changelogs/40104320.txt
new file mode 100644
index 0000000000..61db61727a
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40104320.txt
@@ -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
diff --git a/fastlane/metadata/android/en-US/changelogs/40104340.txt b/fastlane/metadata/android/en-US/changelogs/40104340.txt
new file mode 100644
index 0000000000..61db61727a
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40104340.txt
@@ -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
diff --git a/fastlane/metadata/android/et/changelogs/40104300.txt b/fastlane/metadata/android/et/changelogs/40104300.txt
new file mode 100644
index 0000000000..e01c9b4329
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: senisest parem liitumise ja sisselogimise töövoog.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/et/changelogs/40104310.txt b/fastlane/metadata/android/et/changelogs/40104310.txt
new file mode 100644
index 0000000000..e01c9b4329
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Põhilised muutused selles versioonis: senisest parem liitumise ja sisselogimise töövoog.
+Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fa/changelogs/40104300.txt b/fastlane/metadata/android/fa/changelogs/40104300.txt
new file mode 100644
index 0000000000..7a0e87b263
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+تغییرات عمده در این نگارش: به کار انداختن ورود بهبود یافته و سفرهای ورود.
+گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fa/changelogs/40104310.txt b/fastlane/metadata/android/fa/changelogs/40104310.txt
new file mode 100644
index 0000000000..7a0e87b263
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+تغییرات عمده در این نگارش: به کار انداختن ورود بهبود یافته و سفرهای ورود.
+گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104300.txt b/fastlane/metadata/android/fr-FR/changelogs/40104300.txt
new file mode 100644
index 0000000000..328e66aaa0
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : Activation de l’authentification et du parcours d’inscription améliorés.
+Intégralité des changements : https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104310.txt b/fastlane/metadata/android/fr-FR/changelogs/40104310.txt
new file mode 100644
index 0000000000..328e66aaa0
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : Activation de l’authentification et du parcours d’inscription améliorés.
+Intégralité des changements : https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/gl/changelogs/40104160.txt b/fastlane/metadata/android/gl-ES/changelogs/40104160.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104160.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104160.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104180.txt b/fastlane/metadata/android/gl-ES/changelogs/40104180.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104180.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104180.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104190.txt b/fastlane/metadata/android/gl-ES/changelogs/40104190.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104190.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104190.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104200.txt b/fastlane/metadata/android/gl-ES/changelogs/40104200.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104200.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104200.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104220.txt b/fastlane/metadata/android/gl-ES/changelogs/40104220.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104220.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104220.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104230.txt b/fastlane/metadata/android/gl-ES/changelogs/40104230.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104230.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104230.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104240.txt b/fastlane/metadata/android/gl-ES/changelogs/40104240.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104240.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104240.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104250.txt b/fastlane/metadata/android/gl-ES/changelogs/40104250.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104250.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104250.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104260.txt b/fastlane/metadata/android/gl-ES/changelogs/40104260.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104260.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104260.txt
diff --git a/fastlane/metadata/android/gl/changelogs/40104270.txt b/fastlane/metadata/android/gl-ES/changelogs/40104270.txt
similarity index 100%
rename from fastlane/metadata/android/gl/changelogs/40104270.txt
rename to fastlane/metadata/android/gl-ES/changelogs/40104270.txt
diff --git a/fastlane/metadata/android/gl/full_description.txt b/fastlane/metadata/android/gl-ES/full_description.txt
similarity index 100%
rename from fastlane/metadata/android/gl/full_description.txt
rename to fastlane/metadata/android/gl-ES/full_description.txt
diff --git a/fastlane/metadata/android/gl/short_description.txt b/fastlane/metadata/android/gl-ES/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/gl/short_description.txt
rename to fastlane/metadata/android/gl-ES/short_description.txt
diff --git a/fastlane/metadata/android/gl/title.txt b/fastlane/metadata/android/gl-ES/title.txt
similarity index 100%
rename from fastlane/metadata/android/gl/title.txt
rename to fastlane/metadata/android/gl-ES/title.txt
diff --git a/fastlane/metadata/android/id/changelogs/40104300.txt b/fastlane/metadata/android/id/changelogs/40104300.txt
new file mode 100644
index 0000000000..3d8d13e23d
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Mengaktifkan perjalanan masuk dan keluar yang diperbaiki.
+Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/id/changelogs/40104310.txt b/fastlane/metadata/android/id/changelogs/40104310.txt
new file mode 100644
index 0000000000..3d8d13e23d
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Mengaktifkan perjalanan masuk dan keluar yang diperbaiki.
+Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt
index d3bed0bf6b..20d805c582 100644
--- a/fastlane/metadata/android/id/full_description.txt
+++ b/fastlane/metadata/android/id/full_description.txt
@@ -1,42 +1,42 @@
-Element adalah perpesanan yang aman dan aplikasi kolaborasi tim produktivitas yang ideal untuk obrolan grup saat bekerja jarak jauh. Aplikasi perpesanan ini menggunakan enkripsi ujung-ke-ujung untuk memberikan konferensi video, pembagian file, dan panggilan suara yang aman.
+Element adalah perpesanan yang aman dan aplikasi kolaborasi tim produktivitas yang ideal untuk obrolan grup saat bekerja jarak jauh. Aplikasi perpesanan ini menggunakan enkripsi ujung-ke-ujung untuk menyediakan konferensi video, pembagian berkas, dan panggilan suara yang aman.
-Fitur Element termasuk
-- Alat komunikasi online yang canggih
+Fitur Element termasuk:
+- Alat komunikasi daring yang canggih
- Pesan-pesan yang dienkripsi sepenuhnya untuk memungkinkan komunikasi perusahaan yang lebih aman, bahkan untuk pekerja jarak jauh
-- Obrolan terdesentralisasi berdasarkan kerangka Matrix yang sumber terbuka
-- Pembagian file aman dengan data terenkripsi saat mengelola proyek
+- Obrolan terdesentralisasi berdasarkan kerangka kerja Matrix yang sumber terbuka
+- Pembagian berkas aman dengan data terenkripsi saat mengelola proyek
- Obrolan video dengan VoIP dan pembagian layar
-- Integrasi yang mudah dengan alat kolaborasi online favorit Anda, alat manajemen proyek, layanan VoIP dan aplikasi perpesanan tim lainnya
+- Integrasi yang mudah dengan alat kolaborasi daring favorit Anda, alat pengelola proyek, layanan VoIP dan aplikasi perpesanan tim lainnya
-Element benar-benar berbeda dari aplikasi perpesanan dan aplikasi kolaborasi lainnya. Element beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi terdesentralisasi.
+Element benar-benar berbeda dari aplikasi perpesanan dan aplikasi kolaborasi lainnya. Element beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi yang terdesentralisasi.
Perpesanan dengan privasi dan enkripsi
-Element melindungi Anda dari iklan yang tidak diinginkan, penambangan data dan taman berdinding. Element juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu dengan enkripsi ujung-ke-ujung dan verifikasi perangkat menggunakan penandatanganan silang.
+Element melindungi Anda dari iklan yang tidak diinginkan, penambangan data, dan taman berdinding. Element juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu dengan enkripsi ujung-ke-ujung, dan verifikasi perangkat menggunakan penandatanganan silang.
-Element memberikan Anda kendali atas privasi Anda sambil memungkinkan Anda untuk berkomunikasi dengan siapa saja secara aman di jaringan Matrix, atau alat kolaborasi bisnis lainnya dengan mengintegrasikan aplikasi-aplikasi seperti Slack.
+Element memberikan Anda kendali atas privasi Anda sambil memungkinkan Anda untuk berkomunikasi dengan siapa saja secara aman di jaringan Matrix, atau alat kolaborasi bisnis lainnya dengan mengintegrasikan aplikasi seperti Slack.
-Element dapat dihost sendiri
-Untuk memungkinkan lebih banyak kendali atas data dan pesan-pesan sensitif Anda, Element dapat dihost sendiri atau Anda dapat memilih host berbasis Matrix, standar untuk komunikasi terdesentralisasi sumber terbuka. Element memberi Anda privasi, kepatuhan keamanan, dan fleksibilitas integrasi.
+Element dapat di-host sendiri
+Untuk memungkinkan lebih banyak kendali atas data dan pesan-pesan sensitif Anda, Element dapat dilayani sendiri atau Anda dapat memilih layanan berbasis Matrix, standar untuk komunikasi terdesentralisasi sumber terbuka. Element memberikan Anda privasi, kepatuhan keamanan, dan fleksibilitas integrasi.
Miliki data Anda
Anda memutuskan di mana untuk menyimpan data dan pesan-pesan Anda, tanpa risiko penambangan data atau akses dari pihak ketiga.
Element menempatkan Anda dalam kendali dengan cara yang berbeda:
-1. Dapatkan akun gratis pada server publik matrix.org yang dihost oleh pengembang Matrix, atau memilih dari ribuan server publik yang dihost oleh sukarelawan
-2. Host sendiri akun Anda dengan menjalankan server pada infrastruktur IT Anda sendiri
+1. Dapatkan akun gratis pada server publik matrix.org yang dilayani oleh pengembang Matrix, atau memilih dari ribuan server publik yang dilayani oleh sukarelawan
+2. Layani akun Anda sendiri dengan menjalankan server pada infrastruktur IT Anda sendiri
3. Daftar untuk akun di server khusus dengan berlangganan platform hosting Layanan Matrix Element
Perpesanan dan kolaborasi terbuka
-Anda dapat mengobrol dengan siapa saja di jaringan Matrix, jika mereka menggunakan Element, aplikasi Matrix lain atau bahkan menggunakan aplikasi perpesanan yang berbeda.
+Anda dapat mengobrol dengan siapa saja di jaringan Matrix, jika mereka menggunakan Element, aplikasi Matrix lain, atau bahkan menggunakan aplikasi perpesanan yang berbeda.
Sangat aman
-Enkripsi ujung-ke-ujung yang nyata (hanya mereka yang dalam obrolan dapat mendekripsi pesan), dan verifikasi perangkat menggunakan penandatanganan silang.
+Enkripsi ujung-ke-ujung yang nyata (hanya mereka yang di dalam obrolan dapat mendekripsikan pesan), dan verifikasi perangkat menggunakan penandatanganan silang.
Komunikasi dan integrasi lengkap
-Perpesanan, panggilan suara dan video, pembagian file, pembagian layar dan banyak integrasi bot dan widget. Buat ruangan dan komunitas, tetap terhubung dan selesaikan hal-hal penting.
+Perpesanan, panggilan suara dan video, pembagian berkas, pembagian layar dan banyak integrasi bot dan widget. Buat ruangan dan komunitas, tetap terhubung, dan selesaikan hal-hal penting.
Ambil di mana Anda tinggalkan
-Tetap terhubung di mana Anda berada, dengan riwayat pesan yang disinkronkan di semua perangkat Anda dan web di https://app.element.io
+Tetap terhubung di mana Anda berada, dengan riwayat pesan yang disinkronkan pada semua perangkat Anda dan pada web di https://app.element.io
Sumber terbuka
-Element Android adalah proyek sumber terbuka, dihost oleh GitHub. Silakan laporkan masalah yang Anda temukan, atau membuat kontribusi ke pengembangannya di https://github.com/vector-im/element-android
+Element Android adalah proyek sumber terbuka, dilayani oleh GitHub. Silakan laporkan masalah yang Anda temukan, atau membuat kontribusi ke pengembangannya di https://github.com/vector-im/element-android
diff --git a/fastlane/metadata/android/it-IT/changelogs/40104300.txt b/fastlane/metadata/android/it-IT/changelogs/40104300.txt
new file mode 100644
index 0000000000..40d9618137
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: introduce i percorsi migliorati di accesso e registrazione.
+Cronologia completa: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/it-IT/changelogs/40104310.txt b/fastlane/metadata/android/it-IT/changelogs/40104310.txt
new file mode 100644
index 0000000000..40d9618137
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: introduce i percorsi migliorati di accesso e registrazione.
+Cronologia completa: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104300.txt b/fastlane/metadata/android/pt-BR/changelogs/40104300.txt
new file mode 100644
index 0000000000..5f1aaf4b3d
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: Habilita as jornadas melhoradas de sign in e sign up.
+Changelog completo: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104310.txt b/fastlane/metadata/android/pt-BR/changelogs/40104310.txt
new file mode 100644
index 0000000000..5f1aaf4b3d
--- /dev/null
+++ b/fastlane/metadata/android/pt-BR/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Principais mudanças nesta versão: Habilita as jornadas melhoradas de sign in e sign up.
+Changelog completo: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sk/changelogs/40104300.txt b/fastlane/metadata/android/sk/changelogs/40104300.txt
new file mode 100644
index 0000000000..dd0f554532
--- /dev/null
+++ b/fastlane/metadata/android/sk/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Hlavné zmeny v tejto verzii: Umožňuje vylepšené postupy prihlasovania a registrácie.
+Úplný zoznam zmien: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sk/changelogs/40104310.txt b/fastlane/metadata/android/sk/changelogs/40104310.txt
new file mode 100644
index 0000000000..dd0f554532
--- /dev/null
+++ b/fastlane/metadata/android/sk/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Hlavné zmeny v tejto verzii: Umožňuje vylepšené postupy prihlasovania a registrácie.
+Úplný zoznam zmien: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/uk/changelogs/40104300.txt b/fastlane/metadata/android/uk/changelogs/40104300.txt
new file mode 100644
index 0000000000..727508a0cc
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: Поліпшені вхід і реєстрація.
+Перелік усіх змін: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/uk/changelogs/40104310.txt b/fastlane/metadata/android/uk/changelogs/40104310.txt
new file mode 100644
index 0000000000..727508a0cc
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: Поліпшені вхід і реєстрація.
+Перелік усіх змін: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104300.txt b/fastlane/metadata/android/zh-TW/changelogs/40104300.txt
new file mode 100644
index 0000000000..3055389b2b
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40104300.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:啟用改善的登入與註冊流程。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104310.txt b/fastlane/metadata/android/zh-TW/changelogs/40104310.txt
new file mode 100644
index 0000000000..3055389b2b
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40104310.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:啟用改善的登入與註冊流程。
+完整的變更紀錄:https://github.com/vector-im/element-android/releases
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ef80eb5051..f7189a776c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=97a52d145762adc241bad7fd18289bf7f6801e08ece6badf80402fe2b9f250b1
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
+distributionSha256Sum=db9c8211ed63f61f60292c69e80d89196f9eb36665e369e7f00ac4cc841c2219
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/library/ui-styles/src/main/res/drawable/ic_home_search.xml b/library/ui-styles/src/main/res/drawable/ic_home_search.xml
new file mode 100644
index 0000000000..5cb88ba1e4
--- /dev/null
+++ b/library/ui-styles/src/main/res/drawable/ic_home_search.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml
index 70d051b457..53f1044a12 100644
--- a/library/ui-styles/src/main/res/values/dimens.xml
+++ b/library/ui-styles/src/main/res/values/dimens.xml
@@ -71,4 +71,7 @@
8dp12dp22dp
+
+
+ 112dp
diff --git a/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml b/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
new file mode 100644
index 0000000000..f0807f89c6
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml b/library/ui-styles/src/main/res/values/stylable_live_location_ended_banner_view.xml
similarity index 79%
rename from library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml
rename to library/ui-styles/src/main/res/values/stylable_live_location_ended_banner_view.xml
index 81e377d39b..30ac6229c5 100644
--- a/library/ui-styles/src/main/res/values/stylable_location_live_ended_banner_view.xml
+++ b/library/ui-styles/src/main/res/values/stylable_live_location_ended_banner_view.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/library/ui-styles/src/main/res/values/stylable_map_loading_error_view.xml b/library/ui-styles/src/main/res/values/stylable_map_loading_error_view.xml
new file mode 100644
index 0000000000..911167e52a
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_map_loading_error_view.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/styles_buttons.xml b/library/ui-styles/src/main/res/values/styles_buttons.xml
index c8dcacb8ed..702f427cc0 100644
--- a/library/ui-styles/src/main/res/values/styles_buttons.xml
+++ b/library/ui-styles/src/main/res/values/styles_buttons.xml
@@ -65,4 +65,8 @@
?colorOnPrimary
+
+
diff --git a/library/ui-styles/src/main/res/values/styles_devices_management.xml b/library/ui-styles/src/main/res/values/styles_devices_management.xml
new file mode 100644
index 0000000000..2a63c2ed36
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/styles_devices_management.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/styles_location.xml b/library/ui-styles/src/main/res/values/styles_location.xml
index 41ddbc73ca..ee893046ba 100644
--- a/library/ui-styles/src/main/res/values/styles_location.xml
+++ b/library/ui-styles/src/main/res/values/styles_location.xml
@@ -1,7 +1,7 @@
-
-
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/styles_toolbar.xml b/library/ui-styles/src/main/res/values/styles_toolbar.xml
index 505419c6fe..893de92aae 100644
--- a/library/ui-styles/src/main/res/values/styles_toolbar.xml
+++ b/library/ui-styles/src/main/res/values/styles_toolbar.xml
@@ -39,4 +39,14 @@
12sp
-
\ No newline at end of file
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/text_appearances.xml b/library/ui-styles/src/main/res/values/text_appearances.xml
index 1e60e05acf..570d26fdfd 100644
--- a/library/ui-styles/src/main/res/values/text_appearances.xml
+++ b/library/ui-styles/src/main/res/values/text_appearances.xml
@@ -32,6 +32,15 @@
?vctr_content_primary
+
+
-
\ No newline at end of file
+
diff --git a/library/ui-styles/src/main/res/values/theme_dark.xml b/library/ui-styles/src/main/res/values/theme_dark.xml
index f86a05ed66..9f4e5c1e28 100644
--- a/library/ui-styles/src/main/res/values/theme_dark.xml
+++ b/library/ui-styles/src/main/res/values/theme_dark.xml
@@ -149,6 +149,9 @@
@color/vctr_live_location_dark
+
+
+ @dimen/collapsing_toolbar_layout_medium_size
diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml
index 173b502dcd..c8182abecc 100644
--- a/library/ui-styles/src/main/res/values/theme_light.xml
+++ b/library/ui-styles/src/main/res/values/theme_light.xml
@@ -150,8 +150,12 @@
@color/vctr_live_location_light
+
+
+ @dimen/collapsing_toolbar_layout_medium_size
+
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index f0d564781d..2810e36ade 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -6,7 +6,7 @@ buildscript {
}
}
dependencies {
- classpath "io.realm:realm-gradle-plugin:10.11.0"
+ classpath "io.realm:realm-gradle-plugin:10.11.1"
}
}
@@ -64,7 +64,7 @@ android {
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
- buildConfigField "String", "SDK_VERSION", "\"1.4.32\""
+ buildConfigField "String", "SDK_VERSION", "\"1.4.36\""
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""
@@ -205,7 +205,7 @@ dependencies {
implementation libs.apache.commonsImaging
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.52'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.54'
testImplementation libs.tests.junit
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt
index d0cee08831..7f5e4f2ee7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt
@@ -28,7 +28,7 @@ interface DebugService {
fun getAllRealmConfigurations(): List
/**
- * Prints out info on DB size to logcat.
+ * Get info on DB size.
*/
- fun logDbUsageInfo()
+ fun getDbUsageInfo(): String
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
index 6e198fb98c..5b41ddaaec 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
@@ -62,7 +62,10 @@ fun Throwable.isUsernameInUse() = this is Failure.ServerError &&
error.code == MatrixError.M_USER_IN_USE
fun Throwable.isInvalidUsername() = this is Failure.ServerError &&
- error.code == MatrixError.M_INVALID_USERNAME
+ (error.code == MatrixError.M_INVALID_USERNAME || usernameContainsNonAsciiCharacters())
+
+private fun Failure.ServerError.usernameContainsNonAsciiCharacters() = error.code == MatrixError.M_UNKNOWN &&
+ error.message == "Query parameter \'username\' must be ascii"
fun Throwable.isInvalidPassword() = this is Failure.ServerError &&
error.code == MatrixError.M_FORBIDDEN &&
@@ -86,10 +89,14 @@ fun Throwable.isInvalidUIAAuth() = this is Failure.ServerError &&
fun Throwable.isHomeserverUnavailable() = this is Failure.NetworkConnection &&
this.ioException is UnknownHostException
+fun Throwable.isHomeserverConnectionError() = this is Failure.NetworkConnection
+
fun Throwable.isMissingEmailVerification() = this is Failure.ServerError &&
error.code == MatrixError.M_UNAUTHORIZED &&
error.message == "Unable to get validated threepid"
+fun Throwable.isUnrecognisedCertificate() = this is Failure.UnrecognizedCertificateFailure
+
/**
* Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
index 63c1c25130..13993149f4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
@@ -323,9 +323,9 @@ interface Session {
fun getUiaSsoFallbackUrl(authenticationSessionId: String): String
/**
- * Debug API, will print out info on DB size to logcat.
+ * Debug API, will return info about the DB.
*/
- fun logDbUsageInfo()
+ fun getDbUsageInfo(): String
/**
* Debug API, return the list of all RealmConfiguration used by this session.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomGuestAccessContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomGuestAccessContent.kt
index 7dd853d75d..b229a35458 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomGuestAccessContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomGuestAccessContent.kt
@@ -29,14 +29,12 @@ data class RoomGuestAccessContent(
// Required. Whether guests can join the room. One of: ["can_join", "forbidden"]
@Json(name = "guest_access") val guestAccessStr: String? = null
) {
- val guestAccess: GuestAccess? = when (guestAccessStr) {
- "can_join" -> GuestAccess.CanJoin
- "forbidden" -> GuestAccess.Forbidden
- else -> {
- Timber.w("Invalid value for GuestAccess: `$guestAccessStr`")
- null
- }
- }
+ val guestAccess: GuestAccess? = GuestAccess.values()
+ .find { it.value == guestAccessStr }
+ ?: run {
+ Timber.w("Invalid value for GuestAccess: `$guestAccessStr`")
+ null
+ }
}
@JsonClass(generateAdapter = false)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibility.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibility.kt
index 2b0ea1d8fb..eef986ef96 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibility.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibility.kt
@@ -23,30 +23,30 @@ import com.squareup.moshi.JsonClass
* Ref: https://matrix.org/docs/spec/client_server/latest#room-history-visibility
*/
@JsonClass(generateAdapter = false)
-enum class RoomHistoryVisibility {
+enum class RoomHistoryVisibility(val value: String) {
/**
* All events while this is the m.room.history_visibility value may be shared by any
* participating homeserver with anyone, regardless of whether they have ever joined the room.
*/
- @Json(name = "world_readable") WORLD_READABLE,
+ @Json(name = "world_readable") WORLD_READABLE("world_readable"),
/**
* Previous events are always accessible to newly joined members. All events in the
* room are accessible, even those sent when the member was not a part of the room.
*/
- @Json(name = "shared") SHARED,
+ @Json(name = "shared") SHARED("shared"),
/**
* Events are accessible to newly joined members from the point they were invited onwards.
* Events stop being accessible when the member's state changes to something other than invite or join.
*/
- @Json(name = "invited") INVITED,
+ @Json(name = "invited") INVITED("invited"),
/**
* Events are accessible to newly joined members from the point they joined the room onwards.
* Events stop being accessible when the member's state changes to something other than join.
*/
- @Json(name = "joined") JOINED
+ @Json(name = "joined") JOINED("joined")
}
/**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibilityContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibilityContent.kt
index 39b4722c0c..696cd8f613 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibilityContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibilityContent.kt
@@ -24,14 +24,10 @@ import timber.log.Timber
data class RoomHistoryVisibilityContent(
@Json(name = "history_visibility") val historyVisibilityStr: String? = null
) {
- val historyVisibility: RoomHistoryVisibility? = when (historyVisibilityStr) {
- "world_readable" -> RoomHistoryVisibility.WORLD_READABLE
- "shared" -> RoomHistoryVisibility.SHARED
- "invited" -> RoomHistoryVisibility.INVITED
- "joined" -> RoomHistoryVisibility.JOINED
- else -> {
- Timber.w("Invalid value for RoomHistoryVisibility: `$historyVisibilityStr`")
- null
- }
- }
+ val historyVisibility: RoomHistoryVisibility? = RoomHistoryVisibility.values()
+ .find { it.value == historyVisibilityStr }
+ ?: run {
+ Timber.w("Invalid value for RoomHistoryVisibility: `$historyVisibilityStr`")
+ null
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt
index 6487ad947f..3ed3e2d3a6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/RoomFeaturePreset.kt
@@ -16,7 +16,6 @@
package org.matrix.android.sdk.api.session.room.model.create
-import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
@@ -30,7 +29,7 @@ interface RoomFeaturePreset {
fun updateRoomParams(params: CreateRoomParams)
- fun setupInitialStates(): List?
+ fun setupInitialStates(): List?
}
class RestrictedRoomPreset(val homeServerCapabilities: HomeServerCapabilities, val restrictedList: List) : RoomFeaturePreset {
@@ -41,9 +40,9 @@ class RestrictedRoomPreset(val homeServerCapabilities: HomeServerCapabilities, v
params.roomVersion = homeServerCapabilities.versionOverrideForFeature(HomeServerCapabilities.ROOM_CAP_RESTRICTED)
}
- override fun setupInitialStates(): List? {
+ override fun setupInitialStates(): List {
return listOf(
- Event(
+ CreateRoomStateEvent(
type = EventType.STATE_ROOM_JOIN_RULES,
stateKey = "",
content = RoomJoinRulesContent(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageBeaconLocationDataContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageBeaconLocationDataContent.kt
index e261ab5206..aa2777d0a6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageBeaconLocationDataContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageBeaconLocationDataContent.kt
@@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
/**
- * Content of the state event of type
+ * Content of the event of type
* [EventType.BEACON_LOCATION_DATA][org.matrix.android.sdk.api.session.events.model.EventType.BEACON_LOCATION_DATA]
*
* It contains location data related to a live location share.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt
index 71f7ab8494..6640b8a9af 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/SyncService.kt
@@ -53,6 +53,11 @@ interface SyncService {
*/
fun getSyncState(): SyncState
+ /**
+ * This method returns true if the sync thread is alive, i.e. started.
+ */
+ fun isSyncThreadAlive(): Boolean
+
/**
* This method allows to listen the sync state.
* @return a [LiveData] of [SyncState].
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt
index 83c8585941..1de0a36034 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/StringOrderUtils.kt
@@ -76,7 +76,7 @@ object StringOrderUtils {
}
fun stringToBase(x: String, alphabet: CharArray): BigInteger {
- if (x.isEmpty()) throw IllegalArgumentException()
+ require(x.isNotEmpty())
val len = alphabet.size.toBigInteger()
var result = BigInteger("0")
x.reversed().forEachIndexed { index, c ->
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
index 7d3cfa16c0..ab586c4bd1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
@@ -536,7 +536,7 @@ internal class MXMegolmEncryption(
@Throws
override suspend fun shareHistoryKeysWithDevice(inboundSessionWrapper: InboundGroupSessionHolder, deviceInfo: CryptoDeviceInfo) {
- if (!inboundSessionWrapper.wrapper.sessionData.sharedHistory) throw IllegalArgumentException("This key can't be shared")
+ require(inboundSessionWrapper.wrapper.sessionData.sharedHistory) { "This key can't be shared" }
Timber.tag(loggerTag.value).i("process shareHistoryKeys for ${inboundSessionWrapper.wrapper.safeSessionId} to ${deviceInfo.shortDebugString()}")
val userId = deviceInfo.userId
val deviceId = deviceInfo.deviceId
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt
index 821663bcff..8a805a5588 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt
@@ -63,7 +63,7 @@ internal class VerificationMessageProcessor @Inject constructor(
// the message should be ignored by the receiver.
if (!VerificationService.isValidRequest(event.ageLocalTs, clock.epochMillis())) return Unit.also {
- Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is outdated age:$event.ageLocalTs ms")
+ Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is outdated age:${event.ageLocalTs} ms")
}
Timber.v("## SAS Verification live observer: received msgId: ${event.eventId} type: ${event.getClearType()}")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
index 861a7a3a77..23a75d2bb3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
@@ -76,12 +76,12 @@ internal class VerificationTransportToDevice(
.configureWith(SendToDeviceTask.Params(MessageType.MSGTYPE_VERIFICATION_REQUEST, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
- Timber.v("## verification [$tx.transactionId] send toDevice request success")
+ Timber.v("## verification [${tx?.transactionId}] send toDevice request success")
callback.invoke(localId, validKeyReq)
}
override fun onFailure(failure: Throwable) {
- Timber.e("## verification [$tx.transactionId] failed to send toDevice request")
+ Timber.e("## verification [${tx?.transactionId}] failed to send toDevice request")
}
}
}
@@ -103,12 +103,12 @@ internal class VerificationTransportToDevice(
.configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_READY, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
- Timber.v("## verification [$tx.transactionId] send toDevice request success")
+ Timber.v("## verification [${tx?.transactionId}] send toDevice request success")
callback?.invoke()
}
override fun onFailure(failure: Throwable) {
- Timber.e("## verification [$tx.transactionId] failed to send toDevice request")
+ Timber.e("## verification [${tx?.transactionId}] failed to send toDevice request")
}
}
}
@@ -136,7 +136,7 @@ internal class VerificationTransportToDevice(
.configureWith(SendToDeviceTask.Params(type, contentMap)) {
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
- Timber.v("## SAS verification [$tx.transactionId] toDevice type '$type' success.")
+ Timber.v("## SAS verification [${tx.transactionId}] toDevice type '$type' success.")
if (onDone != null) {
onDone()
} else {
@@ -149,7 +149,7 @@ internal class VerificationTransportToDevice(
}
override fun onFailure(failure: Throwable) {
- Timber.e("## SAS verification [$tx.transactionId] failed to send toDevice in state : $tx.state")
+ Timber.e("## SAS verification [${tx.transactionId}] failed to send toDevice in state : ${tx.state}")
tx.cancel(onErrorReason)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmCompactOnLaunch.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmCompactOnLaunch.kt
new file mode 100644
index 0000000000..1efb2541a7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmCompactOnLaunch.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.database
+
+import io.realm.DefaultCompactOnLaunchCallback
+
+class RealmCompactOnLaunch : DefaultCompactOnLaunchCallback() {
+ /**
+ * Forces all RealmCompactOnLaunch instances to be equal.
+ * Avoids Realm throwing when multiple instances of this class are used.
+ */
+ override fun equals(other: Any?) = other is RealmCompactOnLaunch
+ override fun hashCode() = 0x1000
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
index 5b4303f5bf..01fe3411fd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
@@ -38,7 +38,7 @@ internal abstract class RealmLiveEntityObserver(protected val re
LiveEntityObserver, RealmChangeListener> {
private companion object {
- val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
+ val BACKGROUND_HANDLER = createBackgroundHandler("Matrix-LIVE_ENTITY_BACKGROUND")
}
protected val observerScope = CoroutineScope(SupervisorJob() + BACKGROUND_HANDLER.asCoroutineDispatcher())
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
index 949dd5daa1..16a55c22ac 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
@@ -64,7 +64,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
}
val realmConfiguration = RealmConfiguration.Builder()
- .compactOnLaunch()
+ .compactOnLaunch(RealmCompactOnLaunch())
.directory(directory)
.name(REALM_NAME)
.apply {
@@ -93,7 +93,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
return
}
- listOf(REALM_NAME, "$REALM_NAME.lock", "$REALM_NAME.note", "$REALM_NAME.management").forEach { file ->
+ listOf(REALM_NAME, "${REALM_NAME}.lock", "${REALM_NAME}.note", "${REALM_NAME}.management").forEach { file ->
try {
File(directory, file).deleteRecursively()
} catch (e: Exception) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/tools/RealmDebugTools.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/tools/RealmDebugTools.kt
index dc20549eb3..2e9c3303d4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/tools/RealmDebugTools.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/tools/RealmDebugTools.kt
@@ -19,16 +19,15 @@ package org.matrix.android.sdk.internal.database.tools
import io.realm.Realm
import io.realm.RealmConfiguration
import org.matrix.android.sdk.BuildConfig
-import timber.log.Timber
internal class RealmDebugTools(
private val realmConfiguration: RealmConfiguration
) {
/**
- * Log info about the DB.
+ * Get info about the DB.
*/
- fun logInfo(baseName: String) {
- buildString {
+ fun getInfo(baseName: String): String {
+ return buildString {
append("\n$baseName Realm located at : ${realmConfiguration.realmDirectory}/${realmConfiguration.realmFileName}")
if (BuildConfig.LOG_PRIVATE_DATA) {
@@ -54,7 +53,6 @@ internal class RealmDebugTools(
separator()
}
}
- .let { Timber.i(it) }
}
private fun StringBuilder.separator() = append("\n==============================================")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt
index e9a295a2a0..50586e49d8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt
@@ -33,9 +33,9 @@ internal class DefaultDebugService @Inject constructor(
// realmConfigurationGlobal
}
- override fun logDbUsageInfo() {
- // RealmDebugTools(realmConfigurationAuth).logInfo("Auth")
- // RealmDebugTools(realmConfigurationGlobal).logInfo("Global")
- sessionManager.getLastSession()?.logDbUsageInfo()
+ override fun getDbUsageInfo() = buildString {
+ //append(RealmDebugTools(realmConfigurationAuth).getInfo("Auth"))
+ //append(RealmDebugTools(realmConfigurationGlobal).getInfo("Global"))
+ append(sessionManager.getLastSession()?.getDbUsageInfo())
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt
index bfc3d1b8c1..bd5c57b5b5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt
@@ -43,7 +43,7 @@ internal object MatrixModule {
io = Dispatchers.IO,
computation = Dispatchers.Default,
main = Dispatchers.Main,
- crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
+ crypto = createBackgroundHandler("Matrix-Crypto_Thread").asCoroutineDispatcher(),
dmVerif = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
index fbae741e73..167c49aba8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
@@ -257,11 +257,11 @@ internal class DefaultSession @Inject constructor(
}
}
- override fun logDbUsageInfo() {
- RealmDebugTools(realmConfiguration).logInfo("Session")
- // RealmDebugTools(realmConfigurationCrypto).logInfo("Crypto")
- // RealmDebugTools(realmConfigurationIdentity).logInfo("Identity")
- // RealmDebugTools(realmConfigurationContentScanner).logInfo("ContentScanner")
+ override fun getDbUsageInfo() = buildString {
+ append(RealmDebugTools(realmConfiguration).getInfo("Session"))
+ //append(RealmDebugTools(realmConfigurationCrypto).getInfo("Crypto"))
+ //append(RealmDebugTools(realmConfigurationIdentity).getInfo("Identity"))
+ //append(RealmDebugTools(realmConfigurationContentScanner).getInfo("ContentScanner"))
}
override fun getRealmConfigurations(): List {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt
index faf68d538f..4105c77cc8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt
@@ -20,8 +20,13 @@ import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
+import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.identity.IdentityServiceError
import org.matrix.android.sdk.api.session.identity.toMedium
+import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
+import org.matrix.android.sdk.api.session.room.model.RoomGuestAccessContent
+import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.util.MimeTypes
import org.matrix.android.sdk.internal.crypto.DeviceListManager
@@ -78,7 +83,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
buildAvatarEvent(params),
buildGuestAccess(params)
) +
- params.featurePreset?.setupInitialStates().orEmpty() +
+ buildFeaturePresetInitialStates(params) +
buildCustomInitialStates(params)
)
.takeIf { it.isNotEmpty() }
@@ -99,6 +104,16 @@ internal class CreateRoomBodyBuilder @Inject constructor(
)
}
+ private fun buildFeaturePresetInitialStates(params: CreateRoomParams): List {
+ return params.featurePreset?.setupInitialStates().orEmpty().map {
+ Event(
+ type = it.type,
+ stateKey = it.stateKey,
+ content = it.content
+ )
+ }
+ }
+
private fun buildCustomInitialStates(params: CreateRoomParams): List {
return params.initialStates.map {
Event(
@@ -123,7 +138,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
Event(
type = EventType.STATE_ROOM_AVATAR,
stateKey = "",
- content = mapOf("url" to response.contentUri)
+ content = RoomAvatarContent(response.contentUri).toContent()
)
}
}
@@ -134,7 +149,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
Event(
type = EventType.STATE_ROOM_HISTORY_VISIBILITY,
stateKey = "",
- content = mapOf("history_visibility" to it)
+ content = RoomHistoryVisibilityContent(it.value).toContent()
)
}
}
@@ -145,7 +160,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
Event(
type = EventType.STATE_ROOM_GUEST_ACCESS,
stateKey = "",
- content = mapOf("guest_access" to it.value)
+ content = RoomGuestAccessContent(it.value).toContent()
)
}
}
@@ -167,7 +182,7 @@ internal class CreateRoomBodyBuilder @Inject constructor(
Event(
type = EventType.STATE_ROOM_ENCRYPTION,
stateKey = "",
- content = mapOf("algorithm" to it)
+ content = EncryptionEventContent(it).toContent()
)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
index 2afca6e554..801ff0ec79 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt
@@ -53,7 +53,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo
@Inject lateinit var timelineSendEventWorkCommon: TimelineSendEventWorkCommon
@Inject lateinit var localEchoRepository: LocalEchoRepository
- override fun doOnError(params: Params): Result {
+ override fun doOnError(params: Params, failureMessage: String): Result {
params.localEchoIds.forEach { localEchoIds ->
localEchoRepository.updateSendState(
eventId = localEchoIds.eventId,
@@ -63,7 +63,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo
)
}
- return super.doOnError(params)
+ return super.doOnError(params, failureMessage)
}
override fun injectWith(injector: SessionComponent) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt
index c5b13043d7..55363a7251 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt
@@ -55,7 +55,7 @@ internal class EventSenderProcessorThread @Inject constructor(
private val queuedTaskFactory: QueuedTaskFactory,
private val taskExecutor: TaskExecutor,
private val memento: QueueMemento
-) : Thread("SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
+) : Thread("Matrix-SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
private fun markAsManaged(task: QueuedTask) {
memento.track(task)
@@ -119,7 +119,7 @@ internal class EventSenderProcessorThread @Inject constructor(
override fun cancel(eventId: String, roomId: String) {
(currentTask as? SendEventQueuedTask)
- ?.takeIf { it -> it.event.eventId == eventId && it.event.roomId == roomId }
+ ?.takeIf { it.event.eventId == eventId && it.event.roomId == roomId }
?.cancel()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
index 4eaac67e5a..c380ccf14f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
@@ -76,7 +76,7 @@ internal class DefaultTimeline(
) : Timeline {
companion object {
- val BACKGROUND_HANDLER = createBackgroundHandler("DefaultTimeline_Thread")
+ val BACKGROUND_HANDLER = createBackgroundHandler("Matrix-DefaultTimeline_Thread")
}
override val timelineID = UUID.randomUUID().toString()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt
index 691dd7b20d..76c3c38abf 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/DefaultSyncService.kt
@@ -73,6 +73,8 @@ internal class DefaultSyncService @Inject constructor(
override fun getSyncState() = getSyncThread().currentState()
+ override fun isSyncThreadAlive() = getSyncThread().isAlive
+
override fun getSyncRequestStateFlow() = syncRequestStateTracker.syncRequestState
override fun hasAlreadySynced(): Boolean {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
index 24a60a80da..b47b215655 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
@@ -62,7 +62,7 @@ internal class SyncThread @Inject constructor(
private val backgroundDetectionObserver: BackgroundDetectionObserver,
private val activeCallHandler: ActiveCallHandler,
private val lightweightSettingsStorage: DefaultLightweightSettingsStorage
-) : Thread("SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
+) : Thread("Matrix-SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
private var state: SyncState = SyncState.Idle
private var liveState = MutableLiveData(state)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncWorker.kt
index 0cc7944d58..a04bc74628 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncWorker.kt
@@ -30,6 +30,7 @@ import org.matrix.android.sdk.internal.session.sync.SyncTask
import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
import org.matrix.android.sdk.internal.worker.SessionWorkerParams
import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
+import org.matrix.android.sdk.internal.worker.startChain
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@@ -136,6 +137,7 @@ internal class SyncWorker(context: Context, workerParameters: WorkerParameters,
.setConstraints(WorkManagerProvider.workConstraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
.setInputData(data)
+ .startChain(true)
.build()
workManagerProvider.workManager
.enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt
index 901d0eca8f..dea5f131b9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt
@@ -49,13 +49,13 @@ internal class DefaultBackgroundDetectionObserver : BackgroundDetectionObserver
}
override fun onStart(owner: LifecycleOwner) {
- Timber.v("App returning to foreground…")
+ Timber.d("App returning to foreground…")
isInBackground = false
listeners.forEach { it.onMoveToForeground() }
}
override fun onStop(owner: LifecycleOwner) {
- Timber.v("App going to background…")
+ Timber.d("App going to background…")
isInBackground = true
listeners.forEach { it.onMoveToBackground() }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionSafeCoroutineWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionSafeCoroutineWorker.kt
index 030f51428b..b98b61c9f0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionSafeCoroutineWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionSafeCoroutineWorker.kt
@@ -55,14 +55,16 @@ internal abstract class SessionSafeCoroutineWorker(
// Make sure to inject before handling error as you may need some dependencies to process them.
injectWith(sessionComponent)
- if (params.lastFailureMessage != null) {
- // Forward error to the next workers
- doOnError(params)
- } else {
- doSafeWork(params)
+
+ when (val lastFailureMessage = params.lastFailureMessage) {
+ null -> doSafeWork(params)
+ else -> {
+ // Forward error to the next workers
+ doOnError(params, lastFailureMessage)
+ }
}
} catch (throwable: Throwable) {
- buildErrorResult(params, throwable.localizedMessage ?: "error")
+ buildErrorResult(params, "${throwable::class.java.name}: ${throwable.localizedMessage ?: "N/A error message"}")
}
}
@@ -89,10 +91,10 @@ internal abstract class SessionSafeCoroutineWorker(
* This is called when the input parameters are correct, but contain an error from the previous worker.
*/
@CallSuper
- open fun doOnError(params: PARAM): Result {
+ open fun doOnError(params: PARAM, failureMessage: String): Result {
// Forward the error
return Result.success(inputData)
- .also { Timber.e("Work cancelled due to input error from parent") }
+ .also { Timber.e("Work cancelled due to input error from parent: $failureMessage") }
}
companion object {
diff --git a/tools/check/check_code_quality.sh b/tools/check/check_code_quality.sh
index 79a42083d3..910616176c 100755
--- a/tools/check/check_code_quality.sh
+++ b/tools/check/check_code_quality.sh
@@ -16,21 +16,6 @@
# limitations under the License.
#
-#######################################################################################################################
-# Check frozen class modification
-#######################################################################################################################
-
-echo "Check if frozen class modified"
-git diff "HEAD@{1}" --name-only | grep -e OlmInboundGroupSessionWrapper.kt -e OlmInboundGroupSessionWrapper2.kt
-FROZEN_CHANGED=$?
-if [ ${FROZEN_CHANGED} -eq 0 ]; then
- echo "❌ FROZEN CLASS CHANGED ERROR"
- exit 1
-else
- echo "Frozen check OK"
-fi
-
-
#######################################################################################################################
# Check drawable quantity
#######################################################################################################################
diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt
index b12f15fa5d..b4d7ebae1f 100755
--- a/tools/check/forbidden_strings_in_code.txt
+++ b/tools/check/forbidden_strings_in_code.txt
@@ -185,3 +185,6 @@ System\.currentTimeMillis\(\)===2
onCreateOptionsMenu
onOptionsItemSelected
onPrepareOptionsMenu
+
+### Suspicious String template. Please check that the string template will behave as expected, i.e. the class field and not the whole object will be used. For instance `Timber.d("$event.type")` is not correct, you should write `Timber.d("${event.type}")`. In the former the whole event content will be logged, since it's a data class. If this is expected (i.e. to fix false positive), please add explicit curly braces (`{` and `}`) around the variable, for instance `"elementLogs.${i}.txt"`
+\$[a-zA-Z_]\w*\??\.[a-zA-Z_]
diff --git a/tools/danger/dangerfile.js b/tools/danger/dangerfile.js
index 407cedc34b..c7db52fa19 100644
--- a/tools/danger/dangerfile.js
+++ b/tools/danger/dangerfile.js
@@ -8,9 +8,12 @@ const {danger, warn} = require('danger')
// warn(JSON.stringify(danger))
const pr = danger.github.pr
+const github = danger.github
+// User who has created the PR.
+const user = pr.user.login
const modified = danger.git.modified_files
const created = danger.git.created_files
-let editedFiles = [...modified, ...created]
+const editedFiles = [...modified, ...created]
// Check that the PR has a description
if (pr.body.length == 0) {
@@ -19,28 +22,49 @@ if (pr.body.length == 0) {
// Warn when there is a big PR
if (editedFiles.length > 50) {
- warn("This pull request seems relatively large. Please consider splitting it into multiple smaller ones.")
+ message("This pull request seems relatively large. Please consider splitting it into multiple smaller ones.")
}
// Request a changelog for each PR
-let changelogFiles = editedFiles.filter(file => file.startsWith("changelog.d/"))
+const changelogAllowList = [
+ "dependabot[bot]",
+]
-if (changelogFiles.length == 0) {
- warn("Please add a changelog. See instructions [here](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog)")
-} else {
- const validTowncrierExtensions = [
- "bugfix",
- "doc",
- "feature",
- "misc",
- "sdk",
- "wip",
- ]
- if (!changelogFiles.every(file => validTowncrierExtensions.includes(file.split(".").pop()))) {
- fail("Invalid extension for changelog. See instructions [here](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog)")
+const requiresChangelog = !changelogAllowList.includes(user)
+
+if (requiresChangelog) {
+ const changelogFiles = editedFiles.filter(file => file.startsWith("changelog.d/"))
+
+ if (changelogFiles.length == 0) {
+ warn("Please add a changelog. See instructions [here](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog)")
+ } else {
+ const validTowncrierExtensions = [
+ "bugfix",
+ "doc",
+ "feature",
+ "misc",
+ "sdk",
+ "wip",
+ ]
+ if (!changelogFiles.every(file => validTowncrierExtensions.includes(file.split(".").pop()))) {
+ fail("Invalid extension for changelog. See instructions [here](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog)")
+ }
}
}
+// check that frozen classes have not been modified
+const frozenClasses = [
+ "OlmInboundGroupSessionWrapper.kt",
+ "OlmInboundGroupSessionWrapper2.kt",
+]
+
+frozenClasses.forEach(frozen => {
+ if (editedFiles.some(file => file.endsWith(frozen))) {
+ fail("Frozen class `" + frozen + "` has been modified. Please do not modify frozen class.")
+ }
+ }
+)
+
// Check for a sign-off
const signOff = "Signed-off-by:"
@@ -50,6 +74,7 @@ const allowList = [
"BillCarsonFr",
"bmarty",
"Claire1817",
+ "dependabot[bot]",
"ericdecanini",
"fedrunov",
"Florian14",
@@ -65,18 +90,18 @@ const allowList = [
"yostyle",
]
-let requiresSignOff = !allowList.includes(pr.user.login)
+const requiresSignOff = !allowList.includes(user)
if (requiresSignOff) {
- let hasPRBodySignOff = pr.body.includes(signOff)
- let hasCommitSignOff = danger.git.commits.every(commit => commit.message.includes(signOff))
+ const hasPRBodySignOff = pr.body.includes(signOff)
+ const hasCommitSignOff = danger.git.commits.every(commit => commit.message.includes(signOff))
if (!hasPRBodySignOff && !hasCommitSignOff) {
- fail("Please add a sign-off to either the PR description or to the commits themselves.")
+ fail("Please add a sign-off to either the PR description or to the commits themselves. See instructions [here](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html#sign-off).")
}
}
// Check for screenshots on view changes
-let hasChangedViews = editedFiles.filter(file => file.includes("/layout")).length > 0
+const hasChangedViews = editedFiles.filter(file => file.includes("/layout")).length > 0
if (hasChangedViews) {
if (!pr.body.includes("user-images")) {
warn("You seem to have made changes to views. Please consider adding screenshots.")
@@ -84,12 +109,12 @@ if (hasChangedViews) {
}
// Check for pngs on resources
-let hasPngs = editedFiles.filter(file => file.toLowerCase().endsWith(".png")).length > 0
+const hasPngs = editedFiles.filter(file => file.toLowerCase().endsWith(".png")).length > 0
if (hasPngs) {
warn("You seem to have made changes to some images. Please consider using an vector drawable.")
}
// Check for reviewers
-if (pr.requested_reviewers.length == 0 && !pr.draft) {
- fail("Please add a reviewer to your PR.")
+if (github.requested_reviewers.users.length == 0 && !pr.draft) {
+ warn("Please add a reviewer to your PR.")
}
diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml
index a836edc47a..96adb3d117 100644
--- a/tools/detekt/detekt.yml
+++ b/tools/detekt/detekt.yml
@@ -23,6 +23,8 @@ style:
active: false
ProtectedMemberInFinalClass:
active: false
+ UseCheckOrError:
+ active: false
empty-blocks:
EmptyFunctionBlock:
@@ -43,6 +45,8 @@ exceptions:
active: false
TooGenericExceptionThrown:
active: false
+ InstanceOfCheckForException:
+ active: false
complexity:
TooManyFunctions:
diff --git a/tools/emojis/emoji_picker_datasource_formatted.json b/tools/emojis/emoji_picker_datasource_formatted.json
index a1b944a7eb..41465a442f 100644
--- a/tools/emojis/emoji_picker_datasource_formatted.json
+++ b/tools/emojis/emoji_picker_datasource_formatted.json
@@ -2634,7 +2634,8 @@
"mask",
"sick",
"ill",
- "disease"
+ "disease",
+ "covid"
]
},
"face-with-thermometer": {
@@ -2647,7 +2648,8 @@
"thermometer",
"temperature",
"cold",
- "fever"
+ "fever",
+ "covid"
]
},
"face-with-headbandage": {
@@ -4481,7 +4483,9 @@
"hope",
"wish",
"namaste",
- "highfive"
+ "highfive",
+ "thank you",
+ "appreciate"
]
},
"writing-hand": {
@@ -9581,7 +9585,8 @@
"amoeba",
"bacteria",
"virus",
- "germs"
+ "germs",
+ "covid"
]
},
"bouquet": {
@@ -10260,7 +10265,9 @@
"baguette",
"bread",
"food",
- "french"
+ "french",
+ "france",
+ "bakery"
]
},
"flatbread": {
@@ -10272,7 +10279,8 @@
"naan",
"pita",
"flour",
- "food"
+ "food",
+ "bakery"
]
},
"pretzel": {
@@ -10282,7 +10290,9 @@
"twisted",
"convoluted",
"food",
- "bread"
+ "bread",
+ "germany",
+ "bakery"
]
},
"bagel": {
@@ -10293,7 +10303,8 @@
"breakfast",
"schmear",
"food",
- "bread"
+ "bread",
+ "jewish"
]
},
"pancakes": {
@@ -10306,7 +10317,8 @@
"hotcake",
"pancake",
"flapjacks",
- "hotcakes"
+ "hotcakes",
+ "brunch"
]
},
"waffle": {
@@ -10316,7 +10328,8 @@
"breakfast",
"indecisive",
"iron",
- "food"
+ "food",
+ "brunch"
]
},
"cheese-wedge": {
@@ -10325,7 +10338,8 @@
"j": [
"cheese",
"food",
- "chadder"
+ "chadder",
+ "swiss"
]
},
"meat-on-bone": {
@@ -10376,7 +10390,8 @@
"food",
"meat",
"pork",
- "pig"
+ "pig",
+ "brunch"
]
},
"hamburger": {
@@ -10400,7 +10415,8 @@
"fries",
"chips",
"snack",
- "fast food"
+ "fast food",
+ "potato"
]
},
"pizza": {
@@ -10410,7 +10426,8 @@
"cheese",
"slice",
"food",
- "party"
+ "party",
+ "italy"
]
},
"hot-dog": {
@@ -10420,7 +10437,8 @@
"frankfurter",
"hotdog",
"sausage",
- "food"
+ "food",
+ "america"
]
},
"sandwich": {
@@ -10429,7 +10447,9 @@
"j": [
"bread",
"food",
- "lunch"
+ "lunch",
+ "toast",
+ "bakery"
]
},
"taco": {
@@ -10468,7 +10488,8 @@
"food",
"gyro",
"kebab",
- "stuffed"
+ "stuffed",
+ "mediterranean"
]
},
"falafel": {
@@ -10477,7 +10498,8 @@
"j": [
"chickpea",
"meatball",
- "food"
+ "food",
+ "mediterranean"
]
},
"egg": {
@@ -10498,7 +10520,8 @@
"frying",
"pan",
"food",
- "kitchen"
+ "kitchen",
+ "skillet"
]
},
"shallow-pan-of-food": {
@@ -10510,7 +10533,8 @@
"paella",
"pan",
"shallow",
- "cooking"
+ "cooking",
+ "skillet"
]
},
"pot-of-food": {
@@ -10521,7 +10545,8 @@
"stew",
"food",
"meat",
- "soup"
+ "soup",
+ "hot pot"
]
},
"fondue": {
@@ -10556,7 +10581,8 @@
"green",
"salad",
"healthy",
- "lettuce"
+ "lettuce",
+ "vegetable"
]
},
"popcorn": {
@@ -10566,7 +10592,8 @@
"food",
"movie theater",
"films",
- "snack"
+ "snack",
+ "drama"
]
},
"butter": {
@@ -10592,7 +10619,8 @@
"j": [
"can",
"food",
- "soup"
+ "soup",
+ "tomatoes"
]
},
"bento-box": {
@@ -10602,7 +10630,8 @@
"bento",
"box",
"food",
- "japanese"
+ "japanese",
+ "lunch"
]
},
"rice-cracker": {
@@ -10612,7 +10641,8 @@
"cracker",
"rice",
"food",
- "japanese"
+ "japanese",
+ "snack"
]
},
"rice-ball": {
@@ -10633,7 +10663,6 @@
"cooked",
"rice",
"food",
- "china",
"asian"
]
},
@@ -10680,7 +10709,8 @@
"roasted",
"sweet",
"food",
- "nature"
+ "nature",
+ "plant"
]
},
"oden": {
@@ -10745,7 +10775,8 @@
"autumn",
"festival",
"yuèbǐng",
- "food"
+ "food",
+ "dessert"
]
},
"dango": {
@@ -10772,7 +10803,8 @@
"jiaozi",
"pierogi",
"potsticker",
- "food"
+ "food",
+ "gyoza"
]
},
"fortune-cookie": {
@@ -10780,7 +10812,8 @@
"b": "1F960",
"j": [
"prophecy",
- "food"
+ "food",
+ "dessert"
]
},
"takeout-box": {
@@ -22169,7 +22202,9 @@
"nation",
"country",
"banner",
- "japan"
+ "japan",
+ "jp",
+ "ja"
]
},
"flag-kenya": {
diff --git a/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl
index 0f01b347c0..133faa6821 100644
--- a/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl
+++ b/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl
@@ -18,10 +18,10 @@ import javax.inject.Inject
data class ${fragmentArgsClass}() : Parcelable
#if>
-//TODO add this fragment into FragmentModule
-class ${fragmentClass} @Inject constructor(
- private val viewModelFactory: ${viewModelClass}.Factory
-) : VectorBaseFragment(), ${viewModelClass}.Factory by viewModelFactory {
+@AndroidEntryPoint
+class ${fragmentClass}() :
+ VectorBaseFragment(),
+ ${viewModelClass}.Factory by viewModelFactory {
<#if createFragmentArgs>
private val fragmentArgs: ${fragmentArgsClass} by args()
diff --git a/vector-config/src/main/java/im/vector/app/config/Analytics.kt b/vector-config/src/main/java/im/vector/app/config/Analytics.kt
new file mode 100644
index 0000000000..7fdc78dc8a
--- /dev/null
+++ b/vector-config/src/main/java/im/vector/app/config/Analytics.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.config
+
+/**
+ * The types of analytics Element currently supports.
+ */
+sealed interface Analytics {
+
+ /**
+ * Disables the analytics integrations.
+ */
+ object Disabled : Analytics
+
+ /**
+ * Analytics integration via PostHog.
+ */
+ data class PostHog(
+ /**
+ * The PostHog instance url.
+ */
+ val postHogHost: String,
+
+ /**
+ * The PostHog instance API key.
+ */
+ val postHogApiKey: String,
+
+ /**
+ * A URL to more information about the analytics collection.
+ */
+ val policyLink: String,
+ ) : Analytics
+}
diff --git a/vector-config/src/main/java/im/vector/app/config/Config.kt b/vector-config/src/main/java/im/vector/app/config/Config.kt
index 7577e6dba5..f660799d06 100644
--- a/vector-config/src/main/java/im/vector/app/config/Config.kt
+++ b/vector-config/src/main/java/im/vector/app/config/Config.kt
@@ -36,4 +36,57 @@ object Config {
* - Changing the value from `true` to `false` will force the app to return to the background sync / Firebase Push.
*/
const val ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS = true
+
+ const val ENABLE_LOCATION_SHARING = true
+ const val LOCATION_MAP_TILER_KEY = "fU3vlMsMn4Jb6dnEIFsx"
+
+ /**
+ * The maximum length of voice messages in milliseconds.
+ */
+ const val VOICE_MESSAGE_LIMIT_MS = 120_000L
+
+ /**
+ * The strategy for sharing device keys.
+ */
+ val KEY_SHARING_STRATEGY = KeySharingStrategy.WhenTyping
+
+ /**
+ * The onboarding flow.
+ */
+ val ONBOARDING_VARIANT = OnboardingVariant.FTUE_AUTH
+
+ /**
+ * If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
+ * This *must* only be set in trusted environments.
+ */
+ const val HANDLE_CALL_ASSERTED_IDENTITY_EVENTS = false
+
+ const val LOW_PRIVACY_LOG_ENABLE = false
+ const val ENABLE_STRICT_MODE_LOGS = false
+
+ /**
+ * The analytics configuration to use for the Debug build type.
+ * Can be disabled by providing Analytics.Disabled
+ */
+ val DEBUG_ANALYTICS_CONFIG = Analytics.PostHog(
+ postHogHost = "https://posthog.element.dev",
+ postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN",
+ policyLink = "https://element.io/cookie-policy",
+ )
+
+ /**
+ * The analytics configuration to use for the Release build type.
+ * Can be disabled by providing Analytics.Disabled
+ */
+ val RELEASE_ANALYTICS_CONFIG = Analytics.PostHog(
+ postHogHost = "https://posthog.hss.element.io",
+ postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
+ policyLink = "https://element.io/cookie-policy",
+ )
+
+ /**
+ * The analytics configuration to use for the Nightly build type.
+ * Can be disabled by providing Analytics.Disabled
+ */
+ val NIGHTLY_ANALYTICS_CONFIG = RELEASE_ANALYTICS_CONFIG
}
diff --git a/vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt b/vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt
new file mode 100644
index 0000000000..51f3d81151
--- /dev/null
+++ b/vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.config
+
+enum class KeySharingStrategy {
+ /**
+ * Keys will be sent for the first time when the first message is sent.
+ * This is handled by the Matrix SDK so there's no need to do it in Vector.
+ */
+ WhenSendingEvent,
+
+ /**
+ * Keys will be sent for the first time when the timeline displayed.
+ */
+ WhenEnteringRoom,
+
+ /**
+ * Keys will be sent for the first time when a typing started.
+ */
+ WhenTyping
+}
diff --git a/vector/src/main/java/im/vector/app/features/login2/SignMode2.kt b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
similarity index 77%
rename from vector/src/main/java/im/vector/app/features/login2/SignMode2.kt
rename to vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
index f3d59837e7..8821c8187e 100644
--- a/vector/src/main/java/im/vector/app/features/login2/SignMode2.kt
+++ b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 New Vector Ltd
+ * Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,9 @@
* limitations under the License.
*/
-package im.vector.app.features.login2
+package im.vector.app.config
-enum class SignMode2 {
- Unknown,
-
- // Account creation
- SignUp,
-
- // Login
- SignIn
+enum class OnboardingVariant {
+ LEGACY,
+ FTUE_AUTH
}
diff --git a/vector/build.gradle b/vector/build.gradle
index 0b7973a148..83d322946b 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -37,7 +37,7 @@ ext.versionMinor = 4
// Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release.
-ext.versionPatch = 32
+ext.versionPatch = 36
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'
@@ -156,19 +156,6 @@ android {
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
- buildConfigField "im.vector.app.features.VectorFeatures.OnboardingVariant", "ONBOARDING_VARIANT", "im.vector.app.features.VectorFeatures.OnboardingVariant.FTUE_AUTH"
-
- buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"
-
- buildConfigField "Long", "VOICE_MESSAGE_DURATION_LIMIT_MS", "120_000L"
-
- // If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
- // This *must* only be set in trusted environments.
- buildConfigField "Boolean", "handleCallAssertedIdentityEvents", "false"
-
- buildConfigField "Boolean", "enableLocationSharing", "true"
- buildConfigField "String", "mapTilerKey", "\"fU3vlMsMn4Jb6dnEIFsx\""
-
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// Keep abiFilter for the universalApk
@@ -250,10 +237,6 @@ android {
resValue "string", "app_name", "Element dbg"
resValue "color", "launcher_background", "#0DBD8B"
- buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
- // Set to true if you want to enable strict mode in debug
- buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
-
signingConfig signingConfigs.debug
if (project.hasProperty("coverage")) {
@@ -265,10 +248,6 @@ android {
resValue "string", "app_name", "Element"
resValue "color", "launcher_background", "#0DBD8B"
- buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
- buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
-
- // When updating this block, please also update the same block in the `nightly` buildType below
postprocessing {
removeUnusedCode true
removeUnusedResources true
@@ -328,8 +307,6 @@ android {
isDefault = true
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
- resValue "bool", "isGplay", "true"
- buildConfigField "boolean", "ALLOW_FCM_USE", "true"
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
}
@@ -339,8 +316,6 @@ android {
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
- resValue "bool", "isGplay", "false"
- buildConfigField "boolean", "ALLOW_FCM_USE", "false"
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
}
@@ -416,7 +391,7 @@ dependencies {
implementation libs.androidx.biometric
implementation "org.threeten:threetenbp:1.4.0:no-tzdb"
- implementation "com.gabrielittner.threetenbp:lazythreetenbp:0.10.0"
+ implementation "com.gabrielittner.threetenbp:lazythreetenbp:0.11.0"
implementation libs.squareup.moshi
kapt libs.squareup.moshiKotlin
@@ -438,7 +413,7 @@ dependencies {
implementation 'com.facebook.stetho:stetho:1.6.0'
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.52'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.54'
// FlowBinding
implementation libs.github.flowBinding
@@ -450,6 +425,9 @@ dependencies {
implementation libs.airbnb.epoxyPaging
implementation libs.airbnb.mavericks
+ // Snap Helper https://github.com/rubensousa/GravitySnapHelper
+ implementation 'com.github.rubensousa:gravitysnaphelper:2.2.2'
+
// Nightly
// API-only library
gplayImplementation libs.google.appdistributionApi
@@ -522,7 +500,7 @@ dependencies {
implementation 'com.posthog.android:posthog:1.1.2'
// UnifiedPush
- implementation 'com.github.UnifiedPush:android-connector:2.0.0'
+ implementation 'com.github.UnifiedPush:android-connector:2.0.1'
// UnifiedPush gplay flavor only
gplayImplementation('com.github.UnifiedPush:android-embedded_fcm_distributor:2.1.1') {
exclude group: 'com.google.firebase', module: 'firebase-core'
@@ -598,7 +576,7 @@ dependencies {
debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.2.0"
// Activate when you want to check for leaks, from time to time.
- //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
androidTestImplementation libs.androidx.testCore
androidTestImplementation libs.androidx.testRunner
@@ -621,4 +599,5 @@ dependencies {
androidTestImplementation libs.mockk.mockkAndroid
androidTestUtil libs.androidx.orchestrator
debugImplementation libs.androidx.fragmentTesting
+ androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:1.7.10"
}
diff --git a/vector/src/androidTest/java/im/vector/app/CantVerifyTest.kt b/vector/src/androidTest/java/im/vector/app/CantVerifyTest.kt
index ba844e56b7..e6b17c1e9e 100644
--- a/vector/src/androidTest/java/im/vector/app/CantVerifyTest.kt
+++ b/vector/src/androidTest/java/im/vector/app/CantVerifyTest.kt
@@ -27,6 +27,7 @@ import im.vector.app.features.MainActivity
import im.vector.app.ui.robot.ElementRobot
import org.junit.Rule
import org.junit.Test
+import org.junit.rules.RuleChain
import org.junit.runner.RunWith
import java.util.UUID
@@ -35,7 +36,9 @@ import java.util.UUID
class CantVerifyTest : VerificationTestBase() {
@get:Rule
- val activityRule = ActivityScenarioRule(MainActivity::class.java)
+ val testRule = RuleChain
+ .outerRule(ActivityScenarioRule(MainActivity::class.java))
+ .around(ClearCurrentSessionRule())
private val elementRobot = ElementRobot()
var userName: String = "loginTest_${UUID.randomUUID()}"
diff --git a/vector/src/androidTest/java/im/vector/app/ClearCurrentSessionRule.kt b/vector/src/androidTest/java/im/vector/app/ClearCurrentSessionRule.kt
new file mode 100644
index 0000000000..735e96c1e0
--- /dev/null
+++ b/vector/src/androidTest/java/im/vector/app/ClearCurrentSessionRule.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.test.platform.app.InstrumentationRegistry
+import im.vector.app.features.analytics.store.AnalyticsStore
+import kotlinx.coroutines.runBlocking
+import org.junit.rules.TestWatcher
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import kotlin.reflect.KClass
+
+/**
+ * A TestRule to reset and clear the current Session.
+ * If a Session is active it will be signed out and cleared from the ActiveSessionHolder.
+ * The VectorPreferences and AnalyticsDatastore are also cleared in an attempt to recreate a fresh base.
+ */
+class ClearCurrentSessionRule : TestWatcher() {
+ override fun apply(base: Statement, description: Description): Statement {
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ runBlocking {
+ reflectAnalyticDatastore(context).edit { it.clear() }
+ runCatching {
+ val holder = (context.applicationContext as VectorApplication).activeSessionHolder
+ holder.getSafeActiveSession()?.signOutService()?.signOut(true)
+ (context.applicationContext as VectorApplication).vectorPreferences.clearPreferences()
+ holder.clearActiveSession()
+ }
+ }
+ return super.apply(base, description)
+ }
+}
+
+private fun KClass<*>.asTopLevel() = Class.forName("${qualifiedName}Kt")
+
+/**
+ * Fetches the top level, private [Context.dataStore] extension property from [im.vector.app.features.analytics.store.AnalyticsStore]
+ * via reflection to avoid exposing property to all callers.
+ */
+@Suppress("UNCHECKED_CAST")
+private fun reflectAnalyticDatastore(context: Context): DataStore {
+ val klass = AnalyticsStore::class.asTopLevel()
+ val method = klass.getMethod("access\$getDataStore", Context::class.java)
+ return method.invoke(klass, context) as DataStore
+}
diff --git a/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt b/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt
index b01c1a895f..068c9fb646 100644
--- a/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt
+++ b/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt
@@ -83,7 +83,7 @@ private fun useMediaStoreScreenshotStorage(
screenshotLocation: String,
bitmap: Bitmap
) {
- contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "$screenshotName.jpeg")
+ contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "${screenshotName}.jpeg")
contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, screenshotLocation)
val uri: Uri? = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
if (uri != null) {
@@ -104,7 +104,7 @@ private fun usePublicExternalScreenshotStorage(
if (!directory.exists()) {
directory.mkdirs()
}
- val file = File(directory, "$screenshotName.jpeg")
+ val file = File(directory, "${screenshotName}.jpeg")
saveScreenshotToStream(bitmap, FileOutputStream(file))
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
}
diff --git a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelperTests.kt b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelperTests.kt
index 53c154ae30..30520dd44f 100644
--- a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelperTests.kt
+++ b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelperTests.kt
@@ -31,7 +31,6 @@ import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import im.vector.app.TestBuildVersionSdkIntProvider
import im.vector.app.features.pin.lockscreen.configuration.LockScreenConfiguration
-import im.vector.app.features.pin.lockscreen.configuration.LockScreenConfiguratorProvider
import im.vector.app.features.pin.lockscreen.configuration.LockScreenMode
import im.vector.app.features.pin.lockscreen.crypto.LockScreenCryptoConstants
import im.vector.app.features.pin.lockscreen.crypto.LockScreenKeyRepository
@@ -40,6 +39,7 @@ import im.vector.app.features.pin.lockscreen.ui.fallbackprompt.FallbackBiometric
import im.vector.app.features.pin.lockscreen.utils.DevicePromptCheck
import io.mockk.clearAllMocks
import io.mockk.every
+import io.mockk.justRun
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.mockkStatic
@@ -54,8 +54,10 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.coInvoking
import org.amshove.kluent.shouldBeFalse
import org.amshove.kluent.shouldBeTrue
+import org.amshove.kluent.shouldThrow
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
@@ -239,36 +241,35 @@ class BiometricHelperTests {
@Test
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.R) // Due to some issues with mockk and CryptoObject initialization
- fun authenticateCreatesSystemKeyIfNeededOnSuccessOnAndroidM() = runTest {
+ fun enableAuthenticationDeletesSystemKeyOnFailure() = runTest {
buildVersionSdkIntProvider.value = Build.VERSION_CODES.M
- every { lockScreenKeyRepository.isSystemKeyValid() } returns true
val mockAuthChannel = Channel(capacity = 1)
val biometricUtils = spyk(createBiometricHelper(createDefaultConfiguration(isBiometricsEnabled = true))) {
every { createAuthChannel() } returns mockAuthChannel
every { authenticateWithPromptInternal(any(), any(), any()) } returns mockk()
}
+ justRun { lockScreenKeyRepository.deleteSystemKey() }
val latch = CountDownLatch(1)
val intent = Intent(InstrumentationRegistry.getInstrumentation().targetContext, LockScreenTestActivity::class.java)
ActivityScenario.launch(intent).onActivity { activity ->
activity.lifecycleScope.launch {
+ val exception = IllegalStateException("Some error")
launch {
- mockAuthChannel.send(true)
- mockAuthChannel.close()
+ mockAuthChannel.close(exception)
}
- biometricUtils.authenticate(activity).collect()
+ coInvoking { biometricUtils.enableAuthentication(activity).collect() } shouldThrow exception
latch.countDown()
}
}
latch.await(1, TimeUnit.SECONDS)
- verify { lockScreenKeyRepository.ensureSystemKey() }
+ verify { lockScreenKeyRepository.deleteSystemKey() }
}
private fun createBiometricHelper(configuration: LockScreenConfiguration): BiometricHelper {
val context = InstrumentationRegistry.getInstrumentation().targetContext
- val configProvider = LockScreenConfiguratorProvider(configuration)
- return BiometricHelper(context, lockScreenKeyRepository, configProvider, biometricManager, buildVersionSdkIntProvider)
+ return BiometricHelper(configuration, context, lockScreenKeyRepository, biometricManager, buildVersionSdkIntProvider)
}
private fun createDefaultConfiguration(
diff --git a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/KeyStoreCryptoTests.kt b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/KeyStoreCryptoTests.kt
index 6e02cc0262..1712ec889e 100644
--- a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/KeyStoreCryptoTests.kt
+++ b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/KeyStoreCryptoTests.kt
@@ -18,6 +18,7 @@ package im.vector.app.features.pin.lockscreen.crypto
import android.os.Build
import android.security.keystore.KeyPermanentlyInvalidatedException
+import android.security.keystore.UserNotAuthenticatedException
import androidx.test.platform.app.InstrumentationRegistry
import im.vector.app.TestBuildVersionSdkIntProvider
import io.mockk.every
@@ -69,10 +70,12 @@ class KeyStoreCryptoTests {
runCatching { keyStoreCrypto.ensureKey() }
keyStoreCrypto.hasValidKey() shouldBe true
- val exception = KeyPermanentlyInvalidatedException()
- every { secretStoringUtils.getEncryptCipher(any()) } throws exception
+ val keyInvalidatedException = KeyPermanentlyInvalidatedException()
+ every { secretStoringUtils.getEncryptCipher(any()) } throws keyInvalidatedException
+ keyStoreCrypto.hasValidKey() shouldBe false
- runCatching { keyStoreCrypto.ensureKey() }
+ val userNotAuthenticatedException = UserNotAuthenticatedException()
+ every { secretStoringUtils.getEncryptCipher(any()) } throws userNotAuthenticatedException
keyStoreCrypto.hasValidKey() shouldBe false
}
diff --git a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepositoryTests.kt b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepositoryTests.kt
index 924dbfee9e..8d14ca9153 100644
--- a/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepositoryTests.kt
+++ b/vector/src/androidTest/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepositoryTests.kt
@@ -17,8 +17,6 @@
package im.vector.app.features.pin.lockscreen.crypto
import androidx.test.platform.app.InstrumentationRegistry
-import im.vector.app.features.pin.lockscreen.crypto.migrations.LegacyPinCodeMigrator
-import im.vector.app.features.settings.VectorPreferences
import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.mockk
@@ -44,8 +42,6 @@ class LockScreenKeyRepositoryTests {
}
private lateinit var lockScreenKeyRepository: LockScreenKeyRepository
- private val legacyPinCodeMigrator: LegacyPinCodeMigrator = mockk(relaxed = true)
- private val vectorPreferences: VectorPreferences = mockk(relaxed = true)
private val keyStore: KeyStore by lazy {
KeyStore.getInstance(LockScreenCryptoConstants.ANDROID_KEY_STORE).also { it.load(null) }
diff --git a/vector/src/androidTest/java/im/vector/app/features/reactions/data/EmojiDataSourceTest.kt b/vector/src/androidTest/java/im/vector/app/features/reactions/data/EmojiDataSourceTest.kt
index a880b17e0c..3517f806d6 100644
--- a/vector/src/androidTest/java/im/vector/app/features/reactions/data/EmojiDataSourceTest.kt
+++ b/vector/src/androidTest/java/im/vector/app/features/reactions/data/EmojiDataSourceTest.kt
@@ -76,7 +76,7 @@ class EmojiDataSourceTest : InstrumentedTest {
fun searchTestOneResult() {
val emojiDataSource = createEmojiDataSource()
val result = runBlocking {
- emojiDataSource.filterWith("france")
+ emojiDataSource.filterWith("flag-france")
}
assertEquals("Should have 1 result", 1, result.size)
}
diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml
index 84fa2584b9..94fdb1b389 100644
--- a/vector/src/debug/AndroidManifest.xml
+++ b/vector/src/debug/AndroidManifest.xml
@@ -9,6 +9,8 @@
+
+ () {
views.debugAnalytics.setOnClickListener {
startActivity(Intent(this, DebugAnalyticsActivity::class.java))
}
+ views.debugMemoryLeaks.setOnClickListener { openMemoryLeaksSettings() }
views.debugTestTextViewLink.setOnClickListener { testTextViewLink() }
views.debugOpenButtonStylesLight.setOnClickListener {
startActivity(Intent(this, DebugVectorButtonStylesLightActivity::class.java))
@@ -130,6 +132,10 @@ class DebugMenuActivity : VectorBaseActivity() {
startActivity(Intent(this, DebugPrivateSettingsActivity::class.java))
}
+ private fun openMemoryLeaksSettings() {
+ startActivity(Intent(this, DebugMemoryLeaksActivity::class.java))
+ }
+
private fun renderQrCode(text: String) {
views.debugQrCode.setData(text)
}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt b/vector/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
new file mode 100644
index 0000000000..d409e56349
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.di
+
+import android.content.Context
+import android.content.Intent
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import im.vector.app.core.debug.DebugNavigator
+import im.vector.app.core.debug.DebugReceiver
+import im.vector.app.core.debug.FlipperProxy
+import im.vector.app.core.debug.LeakDetector
+import im.vector.app.features.debug.DebugMenuActivity
+import im.vector.app.flipper.VectorFlipperProxy
+import im.vector.app.leakcanary.LeakCanaryLeakDetector
+import im.vector.app.receivers.VectorDebugReceiver
+
+@InstallIn(SingletonComponent::class)
+@Module
+abstract class DebugModule {
+
+ companion object {
+
+ @Provides
+ fun providesDebugNavigator() = object : DebugNavigator {
+ override fun openDebugMenu(context: Context) {
+ context.startActivity(Intent(context, DebugMenuActivity::class.java))
+ }
+ }
+ }
+
+ @Binds
+ abstract fun bindsDebugReceiver(receiver: VectorDebugReceiver): DebugReceiver
+
+ @Binds
+ abstract fun bindsFlipperProxy(flipperProxy: VectorFlipperProxy): FlipperProxy
+
+ @Binds
+ abstract fun bindsLeakDetector(leakDetector: LeakCanaryLeakDetector): LeakDetector
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
index 6ef7fe441a..ba5b8abb5e 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
@@ -24,6 +24,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.MavericksViewModelComponent
import im.vector.app.core.di.MavericksViewModelKey
import im.vector.app.features.debug.analytics.DebugAnalyticsViewModel
+import im.vector.app.features.debug.leak.DebugMemoryLeaksViewModel
import im.vector.app.features.debug.settings.DebugPrivateSettingsViewModel
@InstallIn(MavericksViewModelComponent::class)
@@ -39,4 +40,9 @@ interface MavericksViewModelDebugModule {
@IntoMap
@MavericksViewModelKey(DebugPrivateSettingsViewModel::class)
fun debugPrivateSettingsViewModelFactory(factory: DebugPrivateSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+ @Binds
+ @IntoMap
+ @MavericksViewModelKey(DebugMemoryLeaksViewModel::class)
+ fun debugMemoryLeaksViewModelFactory(factory: DebugMemoryLeaksViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
index 8fe65bd387..c127e3aed6 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
@@ -70,6 +70,11 @@ class DebugFeaturesStateFactory @Inject constructor(
key = DebugFeatureKeys.allowExternalUnifiedPushDistributors,
factory = VectorFeatures::allowExternalUnifiedPushDistributors
),
+ createBooleanFeature(
+ label = "Enable Live Location Sharing",
+ key = DebugFeatureKeys.liveLocationSharing,
+ factory = VectorFeatures::isLocationSharingEnabled
+ ),
createBooleanFeature(
label = "Force usage of OpusEncoder library",
key = DebugFeatureKeys.forceUsageOfOpusEncoder,
@@ -85,6 +90,11 @@ class DebugFeaturesStateFactory @Inject constructor(
key = DebugFeatureKeys.newAppLayoutEnabled,
factory = VectorFeatures::isNewAppLayoutEnabled
),
+ createBooleanFeature(
+ label = "Enable New Device Management",
+ key = DebugFeatureKeys.newDeviceManagementEnabled,
+ factory = VectorFeatures::isNewDeviceManagementEnabled
+ ),
)
)
}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
index 23aad65653..003b9b8084 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
@@ -24,6 +24,7 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
+import im.vector.app.config.OnboardingVariant
import im.vector.app.features.DefaultVectorFeatures
import im.vector.app.features.VectorFeatures
import kotlinx.coroutines.flow.first
@@ -39,8 +40,8 @@ class DebugVectorFeatures(
private val dataStore = context.dataStore
- override fun onboardingVariant(): VectorFeatures.OnboardingVariant {
- return readPreferences().getEnum() ?: vectorFeatures.onboardingVariant()
+ override fun onboardingVariant(): OnboardingVariant {
+ return readPreferences().getEnum() ?: vectorFeatures.onboardingVariant()
}
override fun isOnboardingAlreadyHaveAccountSplashEnabled(): Boolean = read(DebugFeatureKeys.onboardingAlreadyHaveAnAccount)
@@ -66,6 +67,9 @@ class DebugVectorFeatures(
override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing)
?: vectorFeatures.isScreenSharingEnabled()
+ override fun isLocationSharingEnabled(): Boolean = read(DebugFeatureKeys.liveLocationSharing)
+ ?: vectorFeatures.isLocationSharingEnabled()
+
override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
?: vectorFeatures.forceUsageOfOpusEncoder()
@@ -75,6 +79,9 @@ class DebugVectorFeatures(
override fun isNewAppLayoutEnabled(): Boolean = read(DebugFeatureKeys.newAppLayoutEnabled)
?: vectorFeatures.isNewAppLayoutEnabled()
+ override fun isNewDeviceManagementEnabled(): Boolean = read(DebugFeatureKeys.newDeviceManagementEnabled)
+ ?: vectorFeatures.isNewDeviceManagementEnabled()
+
fun override(value: T?, key: Preferences.Key) = updatePreferences {
if (value == null) {
it.remove(key)
@@ -135,4 +142,5 @@ object DebugFeatureKeys {
val forceUsageOfOpusEncoder = booleanPreferencesKey("force-usage-of-opus-encoder")
val startDmOnFirstMsg = booleanPreferencesKey("start-dm-on-first-msg")
val newAppLayoutEnabled = booleanPreferencesKey("new-app-layout-enabled")
+ val newDeviceManagementEnabled = booleanPreferencesKey("new-device-management-enabled")
}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
new file mode 100644
index 0000000000..226c65e3ed
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.leak
+
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.extensions.addFragment
+import im.vector.app.core.platform.VectorBaseActivity
+import im.vector.app.databinding.ActivitySimpleBinding
+
+@AndroidEntryPoint
+class DebugMemoryLeaksActivity : VectorBaseActivity() {
+
+ override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
+
+ override fun initUiAndData() {
+ if (isFirstCreation()) {
+ addFragment(
+ views.simpleFragmentContainer,
+ DebugMemoryLeaksFragment::class.java
+ )
+ }
+ }
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
new file mode 100644
index 0000000000..2abf6487e2
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.leak
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.epoxy.onClick
+import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.databinding.FragmentDebugMemoryLeaksBinding
+
+@AndroidEntryPoint
+class DebugMemoryLeaksFragment :
+ VectorBaseFragment() {
+
+ private val viewModel: DebugMemoryLeaksViewModel by fragmentViewModel()
+
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDebugMemoryLeaksBinding {
+ return FragmentDebugMemoryLeaksBinding.inflate(inflater, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ setViewListeners()
+ }
+
+ private fun setViewListeners() {
+ views.enableMemoryLeakAnalysis.onClick {
+ viewModel.handle(DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis(views.enableMemoryLeakAnalysis.isChecked))
+ }
+ }
+
+ override fun invalidate() = withState(viewModel) { viewState ->
+ views.enableMemoryLeakAnalysis.isChecked = viewState.isMemoryLeaksAnalysisEnabled
+ }
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt
new file mode 100644
index 0000000000..e1447ae345
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.leak
+
+import im.vector.app.core.platform.VectorViewModelAction
+
+sealed interface DebugMemoryLeaksViewActions : VectorViewModelAction {
+ data class EnableMemoryLeaksAnalysis(val isEnabled: Boolean) : DebugMemoryLeaksViewActions
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
new file mode 100644
index 0000000000..5432cb0888
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.leak
+
+import com.airbnb.mvrx.MavericksViewModelFactory
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import im.vector.app.core.debug.LeakDetector
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
+import im.vector.app.core.platform.EmptyViewEvents
+import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.features.settings.VectorPreferences
+import kotlinx.coroutines.launch
+
+class DebugMemoryLeaksViewModel @AssistedInject constructor(
+ @Assisted initialState: DebugMemoryLeaksViewState,
+ private val vectorPreferences: VectorPreferences,
+ private val leakDetector: LeakDetector,
+) : VectorViewModel(initialState) {
+
+ @AssistedFactory
+ interface Factory : MavericksAssistedViewModelFactory {
+ override fun create(initialState: DebugMemoryLeaksViewState): DebugMemoryLeaksViewModel
+ }
+
+ companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory()
+
+ init {
+ viewModelScope.launch {
+ refreshStateFromPreferences()
+ }
+ }
+
+ override fun handle(action: DebugMemoryLeaksViewActions) {
+ when (action) {
+ is DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis -> handleEnableMemoryLeaksAnalysis(action)
+ }
+ }
+
+ private fun handleEnableMemoryLeaksAnalysis(action: DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis) {
+ viewModelScope.launch {
+ vectorPreferences.enableMemoryLeakAnalysis(action.isEnabled)
+ leakDetector.enable(action.isEnabled)
+ refreshStateFromPreferences()
+ }
+ }
+
+ private fun refreshStateFromPreferences() {
+ setState { copy(isMemoryLeaksAnalysisEnabled = vectorPreferences.isMemoryLeakAnalysisEnabled()) }
+ }
+}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt
new file mode 100644
index 0000000000..4e9fe4b402
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.debug.leak
+
+import com.airbnb.mvrx.MavericksState
+
+data class DebugMemoryLeaksViewState(
+ val isMemoryLeaksAnalysisEnabled: Boolean = false
+) : MavericksState
diff --git a/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt b/vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
similarity index 91%
rename from vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt
rename to vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
index 76be7e1b46..2e4336c942 100644
--- a/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt
+++ b/vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
@@ -29,19 +29,19 @@ import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPl
import com.facebook.soloader.SoLoader
import com.kgurgul.flipper.RealmDatabaseDriver
import com.kgurgul.flipper.RealmDatabaseProvider
+import im.vector.app.core.debug.FlipperProxy
import io.realm.RealmConfiguration
-import okhttp3.Interceptor
import org.matrix.android.sdk.api.Matrix
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
-class FlipperProxy @Inject constructor(
+class VectorFlipperProxy @Inject constructor(
private val context: Context,
-) {
+) : FlipperProxy {
private val networkFlipperPlugin = NetworkFlipperPlugin()
- fun init(matrix: Matrix) {
+ override fun init(matrix: Matrix) {
SoLoader.init(context, false)
if (FlipperUtils.shouldEnableFlipper(context)) {
@@ -65,8 +65,5 @@ class FlipperProxy @Inject constructor(
}
}
- @Suppress("RedundantNullableReturnType")
- fun getNetworkInterceptor(): Interceptor? {
- return FlipperOkhttpInterceptor(networkFlipperPlugin)
- }
+ override fun networkInterceptor() = FlipperOkhttpInterceptor(networkFlipperPlugin)
}
diff --git a/vector/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt b/vector/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt
new file mode 100644
index 0000000000..15db71cd96
--- /dev/null
+++ b/vector/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.leakcanary
+
+import im.vector.app.core.debug.LeakDetector
+import leakcanary.LeakCanary
+import javax.inject.Inject
+
+class LeakCanaryLeakDetector @Inject constructor() : LeakDetector {
+ override fun enable(enable: Boolean) {
+ LeakCanary.config = LeakCanary.config.copy(dumpHeap = enable)
+ }
+}
diff --git a/vector/src/debug/java/im/vector/app/receivers/DebugReceiver.kt b/vector/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
similarity index 88%
rename from vector/src/debug/java/im/vector/app/receivers/DebugReceiver.kt
rename to vector/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
index 9ec475d6d3..550dc055d9 100644
--- a/vector/src/debug/java/im/vector/app/receivers/DebugReceiver.kt
+++ b/vector/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
@@ -22,14 +22,24 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import androidx.core.content.edit
+import im.vector.app.core.debug.DebugReceiver
import im.vector.app.core.di.DefaultSharedPreferences
import im.vector.app.core.utils.lsFiles
import timber.log.Timber
+import javax.inject.Inject
/**
* Receiver to handle some command from ADB
*/
-class DebugReceiver : BroadcastReceiver() {
+class VectorDebugReceiver @Inject constructor() : BroadcastReceiver(), DebugReceiver {
+
+ override fun register(context: Context) {
+ context.registerReceiver(this, getIntentFilter(context))
+ }
+
+ override fun unregister(context: Context) {
+ context.unregisterReceiver(this)
+ }
override fun onReceive(context: Context, intent: Intent) {
Timber.v("Received debug action: ${intent.action}")
diff --git a/vector/src/debug/res/layout/activity_debug_menu.xml b/vector/src/debug/res/layout/activity_debug_menu.xml
index 8b38c17b35..b5efe0302c 100644
--- a/vector/src/debug/res/layout/activity_debug_menu.xml
+++ b/vector/src/debug/res/layout/activity_debug_menu.xml
@@ -1,5 +1,6 @@
+ android:layout_height="wrap_content"
+ app:layout_anchor="@+id/scrollView2"
+ app:layout_anchorGravity="center">
+
+
-
@@ -347,8 +346,9 @@
-
+
+
diff --git a/vector/src/main/java/im/vector/app/SpaceStateHandler.kt b/vector/src/main/java/im/vector/app/SpaceStateHandler.kt
index 174b8ab3cd..d9f002be37 100644
--- a/vector/src/main/java/im/vector/app/SpaceStateHandler.kt
+++ b/vector/src/main/java/im/vector/app/SpaceStateHandler.kt
@@ -24,19 +24,19 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
/**
* Gets info about the current space the user has navigated to, any space backstack they may have
- * and handles switching to different spaces
+ * and handles switching to different spaces.
*/
interface SpaceStateHandler : DefaultLifecycleObserver {
/**
- * Gets the current space the current user has navigated to
+ * Gets the current space the current user has navigated to.
*
* @return null if the user is not in
*/
fun getCurrentSpace(): RoomSummary?
/**
- * Sets the new space the current user is navigating to
+ * Sets the new space the current user is navigating to.
*
* @param spaceId the id of the space being navigated to
* @param session the current active session
@@ -51,19 +51,19 @@ interface SpaceStateHandler : DefaultLifecycleObserver {
)
/**
- * Gets the current backstack of spaces (via their id)
+ * Gets the current backstack of spaces (via their id).
*
* null may be an entry in the ArrayDeque to indicate the root space (All Chats)
*/
fun getSpaceBackstack(): ArrayDeque
/**
- * Gets a flow of the selected space for clients to react immediately to space changes
+ * Gets a flow of the selected space for clients to react immediately to space changes.
*/
fun getSelectedSpaceFlow(): Flow