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/danger.yml b/.github/workflows/danger.yml index a1d754b4de..d36f2d0765 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -16,3 +16,5 @@ jobs: 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/quality.yml b/.github/workflows/quality.yml index 6e5e2e4d67..544d9081f8 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -71,6 +71,8 @@ jobs: 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/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 829b1a0caa..4615ec8ff0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,51 @@ +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) ======================================= diff --git a/build.gradle b/build.gradle index afe51cc734..38cbc3af0f 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ 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' @@ -44,7 +44,7 @@ plugins { 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/dependencies.gradle b/dependencies.gradle index 783169406f..8a7260294b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -22,7 +22,7 @@ def markwon = "4.6.2" def moshi = "1.13.0" def lifecycle = "2.5.1" def flowBinding = "1.2.0" -def flipper = "0.156.0" +def flipper = "0.157.0" def epoxy = "4.6.2" def mavericks = "2.7.0" def glide = "4.13.2" @@ -30,7 +30,7 @@ def bigImageViewer = "1.8.1" def jjwt = "0.11.5" def vanniktechEmoji = "0.15.0" -def fragment = "1.5.1" +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 diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index ea5777960a..db9e05f620 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -108,7 +108,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', 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/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/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/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/styles_buttons.xml b/library/ui-styles/src/main/res/values/styles_buttons.xml index 21d51c4901..993ff134ea 100644 --- a/library/ui-styles/src/main/res/values/styles_buttons.xml +++ b/library/ui-styles/src/main/res/values/styles_buttons.xml @@ -62,4 +62,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_tablayout.xml b/library/ui-styles/src/main/res/values/styles_tablayout.xml new file mode 100644 index 0000000000..ab26972995 --- /dev/null +++ b/library/ui-styles/src/main/res/values/styles_tablayout.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 45a962f12c..aa8731da2a 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -17,7 +17,7 @@ buildscript { } } dependencies { - classpath "io.realm:realm-gradle-plugin:10.11.0" + classpath "io.realm:realm-gradle-plugin:10.11.1" } } @@ -60,7 +60,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.34\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" @@ -199,7 +199,7 @@ dependencies { implementation libs.apache.commonsImaging // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.53' + 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 68b931b33c..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 @@ -89,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/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 f2f88e216b..020b42b3b8 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 r 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 3f2e6fafc8..46479c3db6 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 @@ -36,9 +36,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 49713a1d7f..f2f8a5dc04 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 @@ -40,7 +40,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 57db187bdc..679c5085ef 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 @@ -263,11 +263,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 51107c9655..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) 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 7f5181c6f7..7551af8492 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 @@ -80,7 +80,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 000b9e8d40..fbbb5b4b16 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 4efd236419..c7db52fa19 100644 --- a/tools/danger/dangerfile.js +++ b/tools/danger/dangerfile.js @@ -52,6 +52,19 @@ if (requiresChangelog) { } } +// 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:" 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/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt index ae8cfd1172..8821c8187e 100644 --- a/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt +++ b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt @@ -18,6 +18,5 @@ package im.vector.app.config enum class OnboardingVariant { LEGACY, - LOGIN_2, FTUE_AUTH } diff --git a/vector/build.gradle b/vector/build.gradle index aa9df54975..6d13ced9e4 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 = 34 ext.scVersion = 57 @@ -312,7 +312,6 @@ android { versionName "1.4.32.sc57" - resValue "bool", "isGplay", "true" buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\"" buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\"" } @@ -322,7 +321,6 @@ android { versionName "1.4.32.sc57" - resValue "bool", "isGplay", "false" buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\"" buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\"" } @@ -403,7 +401,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 implementation libs.squareup.moshiKt @@ -426,7 +424,7 @@ dependencies { implementation 'com.facebook.stetho:stetho:1.6.0' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.53' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.54' // FlowBinding implementation libs.github.flowBinding @@ -514,7 +512,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' @@ -590,7 +588,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 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/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 d7e402c4dc..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 @@ -90,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 031ff11d59..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 @@ -79,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) @@ -139,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..d3e70e26e6 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt @@ -0,0 +1,54 @@ +/* + * 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 4dcd114f83..964b7e5386 100644 --- a/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt +++ b/vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt @@ -30,19 +30,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) { // https://github.com/facebook/flipper/issues/3572 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) return SoLoader.init(context, false) @@ -68,8 +68,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"> +