diff --git a/CHANGES.md b/CHANGES.md index 595baee9e11..923fe8d5914 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +Changes in Element v1.6.52 (2026-03-05) +======================================= + +Other changes +------------- + - Bump `jitsi_modile_sdk` to v11.5.1 ([#9124](https://github.com/element-hq/element-android/issues/9124)). This should fix the 16KB page size incompatibility. + Changes in Element v1.6.50 (2026-02-04) ======================================= diff --git a/build.gradle b/build.gradle index 49cdb73516e..419aa9a0b7a 100644 --- a/build.gradle +++ b/build.gradle @@ -96,9 +96,9 @@ allprojects { } // Jitsi repo maven { - url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-11.4.0" + url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-11.5.1" // Note: to test Jitsi release you can use a local file like this: - // url "file:///Users/bmarty/workspaces/jitsi_libre_maven/mobile-sdk-10.2.0" + // url "file:///Users/bmarty/workspaces/jitsi_libre_maven/mobile-sdk-11.5.1" content { groups.jitsi.regex.each { includeGroupByRegex it } groups.jitsi.group.each { includeGroup it } diff --git a/dependencies.gradle b/dependencies.gradle index 784128722bf..3eaedb3617d 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -95,8 +95,8 @@ ext.libs = [ 'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger" ], element : [ - 'opusencoder' : "io.element.android:opusencoder:1.1.0", - 'wysiwyg' : "io.element.android:wysiwyg:2.38.2" + 'opusencoder' : "io.element.android:opusencoder:1.1.2", + 'wysiwyg' : "io.element.android:wysiwyg:2.41.1-classic" ], squareup : [ 'moshi' : "com.squareup.moshi:moshi:$moshi", diff --git a/docs/jitsi.md b/docs/jitsi.md index d962b1e8a3d..dd0b4dd4683 100644 --- a/docs/jitsi.md +++ b/docs/jitsi.md @@ -32,7 +32,7 @@ Update the script `./tools/jitsi/build_jitsi_libs.sh` with the tag of the projec Latest tag can be found from this page: https://github.com/jitsi/jitsi-meet-release-notes/blob/master/CHANGELOG-MOBILE-SDKS.md -Currently we are building the version with the tag `mobile-sdk-10.2.0`. +Currently we are building the version with the tag `mobile-sdk-11.5.1`. #### Run the build script @@ -49,7 +49,7 @@ It will build the Jitsi Meet Android library and put every generated files in th - Update the file `./build.gradle` to use the previously created local Maven repository. Currently we have this line: ```groovy -url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-10.2.0" +url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-11.5.1" ``` You can uncomment and update the line starting with `// url "file://...` and comment the line starting with `url`, to test the library using the locally generated Maven repository. @@ -57,7 +57,7 @@ You can uncomment and update the line starting with `// url "file://...` and com - Update the dependency of the Jitsi Meet library in the file `./vector/build.gradle`. Currently we have this line: ```groovy -api('org.jitsi.react:jitsi-meet-sdk:10.2.0') +api('org.jitsi.react:jitsi-meet-sdk:11.5.1') ``` - Perform a gradle sync and build the project @@ -82,7 +82,7 @@ If all the tests are passed, you can export the generated Jitsi library to our M - Update the file `./build.gradle` to use the previously created Maven repository. Currently we have this line: ```groovy -url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-10.2.0" +url "https://github.com/element-hq/jitsi_libre_maven/raw/main/mobile-sdk-11.5.1" ``` - Build the project and perform the sanity tests again. diff --git a/fastlane/metadata/android/en-US/changelogs/40106520.txt b/fastlane/metadata/android/en-US/changelogs/40106520.txt new file mode 100644 index 00000000000..f7bc4a582eb --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40106520.txt @@ -0,0 +1,2 @@ +Main changes in this version: updated Jitsi version. +Full changelog: https://github.com/element-hq/element-android/releases diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index ea0659195c3..2a5b7301156 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2738,6 +2738,8 @@ Review to ensure your account is safe Verify the new login accessing your account: %1$s + As of April 2026 unverified devices will not be able to send and receive messages. + Verify now Manually Verify by Text diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index f1e3f30e978..8e522bdc036 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -62,7 +62,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.6.50\"" + buildConfigField "String", "SDK_VERSION", "\"1.6.52\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" diff --git a/tools/jitsi/build_jitsi_libs.sh b/tools/jitsi/build_jitsi_libs.sh index cf5634229a7..804163c5c43 100755 --- a/tools/jitsi/build_jitsi_libs.sh +++ b/tools/jitsi/build_jitsi_libs.sh @@ -26,7 +26,7 @@ export LIBRE_BUILD=true cd jitsi-meet # Get the latest version from the changelog: https://github.com/jitsi/jitsi-meet-release-notes/blob/master/CHANGELOG-MOBILE-SDKS.md -git checkout mobile-sdk-11.4.0 +git checkout mobile-sdk-11.5.1 echo echo "##################################################" @@ -52,11 +52,11 @@ npm install # #react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output index.android.bundle --assets-dest android/app/src/main/res/ +mkdir -p /tmp/jitsi/org/webkit/ ./android/scripts/release-sdk.sh /tmp/jitsi/ # Also copy jsc -mkdir -p /tmp/jitsi/org/webkit/ cp -r ./node_modules/jsc-android/dist/org/webkit/android-jsc /tmp/jitsi/org/webkit/ echo diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index 16ba9c963ac..eab0685ce39 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -147,30 +147,30 @@ printf "\n====================================================================== printf "Uninstalling previous test app if any...\n" adb -e uninstall im.vector.app.debug.test -printf "\n================================================================================\n" -printf "Running the integration test UiAllScreensSanityTest.allScreensTest()...\n" -./gradlew connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest - -printf "\n================================================================================\n" -printf "Building the app...\n" -./gradlew assembleGplayDebug - -printf "\n================================================================================\n" -printf "Uninstalling previous debug app if any...\n" -adb -e uninstall im.vector.app.debug - -printf "\n================================================================================\n" -printf "Installing the app...\n" -adb -e install ./vector-app/build/outputs/apk/gplay/debug/vector-gplay-arm64-v8a-debug.apk - -printf "\n================================================================================\n" -printf "Running the app...\n" -# TODO This does not work, need to be fixed -adb -e shell am start -n im.vector.app.debug/im.vector.app.features.Alias -a android.intent.action.MAIN -c android.intent.category.LAUNCHER - -printf "\n================================================================================\n" -# TODO could build and deploy the APK to any emulator -read -p "Create an account on matrix.org and do some smoke tests that the sanity test does not cover like: 1-1 call, 1-1 video call, Jitsi call for instance. Press enter when it's done." +#printf "\n================================================================================\n" +#printf "Running the integration test UiAllScreensSanityTest.allScreensTest()...\n" +#./gradlew connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest +# +#printf "\n================================================================================\n" +#printf "Building the app...\n" +#./gradlew assembleGplayDebug +# +#printf "\n================================================================================\n" +#printf "Uninstalling previous debug app if any...\n" +#adb -e uninstall im.vector.app.debug +# +#printf "\n================================================================================\n" +#printf "Installing the app...\n" +#adb -e install ./vector-app/build/outputs/apk/gplay/debug/vector-gplay-arm64-v8a-debug.apk +# +#printf "\n================================================================================\n" +#printf "Running the app...\n" +## TODO This does not work, need to be fixed +#adb -e shell am start -n im.vector.app.debug/im.vector.app.features.Alias -a android.intent.action.MAIN -c android.intent.category.LAUNCHER +# +#printf "\n================================================================================\n" +## TODO could build and deploy the APK to any emulator +#read -p "Create an account on matrix.org and do some smoke tests that the sanity test does not cover like: 1-1 call, 1-1 video call, Jitsi call for instance. Press enter when it's done." printf "\n================================================================================\n" printf "Running towncrier...\n" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 5f1c5f4469a..c70094823ee 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -37,7 +37,7 @@ ext.versionMinor = 6 // 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 = 50 +ext.versionPatch = 52 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' diff --git a/vector/build.gradle b/vector/build.gradle index 561da835788..5f61566f44a 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -250,7 +250,7 @@ dependencies { implementation "androidx.emoji2:emoji2:1.3.0" // Jitsi - api('org.jitsi.react:jitsi-meet-sdk:11.4.0') { + api('org.jitsi.react:jitsi-meet-sdk:11.5.1') { exclude group: 'com.google.firebase' exclude group: 'com.google.android.gms' exclude group: 'com.android.installreferrer' diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index fe73002d9a6..0c69c905681 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -56,7 +56,7 @@ - + diff --git a/vector/src/main/java/im/vector/app/core/ui/views/VerifyDeviceBanner.kt b/vector/src/main/java/im/vector/app/core/ui/views/VerifyDeviceBanner.kt new file mode 100755 index 00000000000..249a3617ee6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/ui/views/VerifyDeviceBanner.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2026 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package im.vector.app.core.ui.views + +import android.content.Context +import android.util.AttributeSet +import androidx.constraintlayout.widget.ConstraintLayout +import im.vector.app.R +import im.vector.app.databinding.ViewVerifySessionBannerBinding + +class VerifyDeviceBanner @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + var delegate: Delegate? = null + + init { + setupView() + } + + private fun setupView() { + inflate(context, R.layout.view_verify_session_banner, this) + val views = ViewVerifySessionBannerBinding.bind(this) + views.learnMore.setOnClickListener { delegate?.onVerificationLearnMoreClicked() } + views.verifyButton.setOnClickListener { delegate?.onVerifySession() } + } + + interface Delegate { + fun onVerificationLearnMoreClicked() + fun onVerifySession() + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index ca17b95a48c..473d73ab438 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -362,11 +362,13 @@ class HomeActivityViewModel @AssistedInject constructor( // cross signing keys have been reset // Trigger a popup to re-verify // Note: user can be unknown in case of logout - session.getUserOrDefault(session.myUserId) - .toMatrixItem() - .let { user -> - _viewEvents.post(HomeActivityViewEvents.OnCrossSignedInvalidated(user)) - } + + // This is now handled by the banner in the HomeFragment + // session.getUserOrDefault(session.myUserId) + // .toMatrixItem() + // .let { user -> + // _viewEvents.post(HomeActivityViewEvents.OnCrossSignedInvalidated(user)) + // } } } @@ -441,12 +443,13 @@ class HomeActivityViewModel @AssistedInject constructor( val is4Ssetup = session.sharedSecretStorageService().isRecoverySetup() if (hasTargetDeviceToVerifyAgainst || is4Ssetup) { // New session - _viewEvents.post( - HomeActivityViewEvents.CurrentSessionNotVerified( - session.getUserOrDefault(session.myUserId).toMatrixItem(), - vectorPreferences.isOnRustCrypto() && vectorPreferences.hadExistingLegacyData() - ) - ) + // This is now handled by the banner in the HomeFragment + // _viewEvents.post( + // HomeActivityViewEvents.CurrentSessionNotVerified( + // session.getUserOrDefault(session.myUserId).toMatrixItem(), + // vectorPreferences.isOnRustCrypto() && vectorPreferences.hadExistingLegacyData() + // ) + // ) } else { _viewEvents.post( HomeActivityViewEvents.CurrentSessionCannotBeVerified( diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 0a720f29d3d..5cc55f2e781 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -93,6 +93,7 @@ class HomeDetailViewModel @AssistedInject constructor( observeRoomSummaries() updatePstnSupportFlag() observeDataStore() + observeCrossSigningState() callManager.addProtocolsCheckerListener(this) session.flow().liveUser(session.myUserId).execute { copy( @@ -101,6 +102,21 @@ class HomeDetailViewModel @AssistedInject constructor( } } + private fun observeCrossSigningState() { + session + .flow() + .liveCrossSigningInfo(session.myUserId) + .onEach { info -> + val isVerified = info.getOrNull()?.isTrusted() ?: false + setState { + copy( + isSessionVerified = isVerified, + ) + } + } + .launchIn(viewModelScope) + } + private fun observeDataStore() { vectorDataStore.pushCounterFlow.setOnEach { nbOfPush -> copy( diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt index 7b9284afc1d..352f378d5d8 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt @@ -33,7 +33,9 @@ data class HomeDetailViewState( val incrementalSyncRequestState: SyncRequestState.IncrementalSyncRequestState? = null, val pushCounter: Int = 0, val pstnSupportFlag: Boolean = false, - val forceDialPadTab: Boolean = false + val forceDialPadTab: Boolean = false, + // Set to true by default to avoid glitch + val isSessionVerified: Boolean = true, ) : MavericksState { val showDialPadTab = forceDialPadTab || pstnSupportFlag } diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt index fbc3604e58e..082e8b65244 100644 --- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt @@ -14,6 +14,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.activityViewModel @@ -33,6 +34,8 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.ui.views.CurrentCallsView import im.vector.app.core.ui.views.CurrentCallsViewPresenter import im.vector.app.core.ui.views.KeysBackupBanner +import im.vector.app.core.ui.views.VerifyDeviceBanner +import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.databinding.FragmentNewHomeDetailBinding import im.vector.app.features.call.SharedKnownCallsViewModel import im.vector.app.features.call.VectorCallActivity @@ -66,7 +69,8 @@ class NewHomeDetailFragment : KeysBackupBanner.Delegate, CurrentCallsView.Callback, OnBackPressed, - VectorMenuProvider { + VectorMenuProvider, + VerifyDeviceBanner.Delegate { @Inject lateinit var avatarRenderer: AvatarRenderer @Inject lateinit var colorProvider: ColorProvider @@ -132,6 +136,7 @@ class NewHomeDetailFragment : sharedCallActionViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java) setupToolbar() setupKeysBackupBanner() + setupVerificationBanner() setupActiveCallView() setupDebugButton() setupFabs() @@ -323,6 +328,10 @@ class NewHomeDetailFragment : views.homeKeysBackupBanner.delegate = this } + private fun setupVerificationBanner() { + views.homeVerifyDevice.delegate = this + } + private fun setupActiveCallView() { currentCallsViewPresenter.bind(views.currentCallsView, this) } @@ -355,9 +364,9 @@ class NewHomeDetailFragment : }) } -/* ========================================================================================== - * KeysBackupBanner Listener - * ========================================================================================== */ + /* ========================================================================================== + * KeysBackupBanner Listener + * ========================================================================================== */ override fun onCloseClicked() { serverBackupStatusViewModel.handle(ServerBackupStatusAction.OnBannerClosed) @@ -378,7 +387,7 @@ class NewHomeDetailFragment : it.pushCounter, vectorPreferences.developerShowDebugInfo() ) - + views.homeVerifyDevice.isGone = it.isSessionVerified refreshAvatar() hasUnreadRooms = it.hasUnreadMessages } @@ -419,6 +428,21 @@ class NewHomeDetailFragment : private fun SpaceStateHandler.isRoot() = getSpaceBackstack().isEmpty() + override fun onVerificationLearnMoreClicked() { + openUrlInChromeCustomTab( + context = requireContext(), + session = null, + url = "https://docs.element.io/latest/element-support/device-verification/how-to-verify-devices", + ) + } + + override fun onVerifySession() { + (activity as? VectorBaseActivity<*>)?.let { vectorBaseActivity -> + vectorBaseActivity.navigator + .requestSelfSessionVerification(vectorBaseActivity) + } + } + companion object { private const val HOME_ROOM_LIST_FRAGMENT_TAG = "TAG_HOME_ROOM_LIST" } diff --git a/vector/src/main/res/drawable/banner_background.xml b/vector/src/main/res/drawable/banner_background.xml new file mode 100644 index 00000000000..d66d089d918 --- /dev/null +++ b/vector/src/main/res/drawable/banner_background.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/vector/src/main/res/layout/fragment_new_home_detail.xml b/vector/src/main/res/layout/fragment_new_home_detail.xml index 32d1dfc5d21..4621156a77e 100644 --- a/vector/src/main/res/layout/fragment_new_home_detail.xml +++ b/vector/src/main/res/layout/fragment_new_home_detail.xml @@ -44,12 +44,11 @@ + android:layout_height="wrap_content"> @@ -89,13 +88,26 @@ - + android:orientation="vertical" + app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> + + + + + + diff --git a/vector/src/main/res/layout/view_verify_session_banner.xml b/vector/src/main/res/layout/view_verify_session_banner.xml new file mode 100644 index 00000000000..8d57407e1c2 --- /dev/null +++ b/vector/src/main/res/layout/view_verify_session_banner.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + +