Skip to content

Commit

Permalink
Merge branch 'release/0.7.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarty committed Oct 25, 2024
2 parents 8806275 + 69fb15b commit 159a478
Show file tree
Hide file tree
Showing 1,017 changed files with 5,706 additions and 4,009 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/maestro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
uses: actions/download-artifact@v4
with:
name: elementx-apk-maestro
- uses: mobile-dev-inc/[email protected].1
- uses: mobile-dev-inc/[email protected].2
if: (github.event_name == 'pull_request' && github.event.pull_request.fork == null) || github.event_name == 'workflow_dispatch'
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
Expand Down
25 changes: 25 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
Changes in Element X v0.7.0 (2024-10-10)
========================================

## What's Changed
### 🙌 Improvements
* Enable Login with QR code in release builds. by @bmarty in https://github.com/element-hq/element-x-android/pull/3646
* Remove unused `RoomSummary` cache by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3647
### 🐛 Bugfixes
* Add the `CallWebView` logs to our logging stack by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3637
### Dependency upgrades
* Update dependency io.element.android:emojibase-bindings to v1.3.3 by @renovate in https://github.com/element-hq/element-x-android/pull/3620
* fix(deps): update dependency androidx.compose:compose-bom to v2024.09.03 by @renovate in https://github.com/element-hq/element-x-android/pull/3583
* fix(deps): update dependency io.mockk:mockk to v1.13.13 by @renovate in https://github.com/element-hq/element-x-android/pull/3634
* chore(deps): update dependencyanalysis to v2.1.4 by @renovate in https://github.com/element-hq/element-x-android/pull/3610
* fix(deps): update dependency androidx.webkit:webkit to v1.12.1 by @renovate in https://github.com/element-hq/element-x-android/pull/3584
* fix(deps): update dependency com.posthog:posthog-android to v3.8.1 by @renovate in https://github.com/element-hq/element-x-android/pull/3638
* Upgrade Kotlin to v2.0 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3594
### Others
* Rework room summary by @ganfra in https://github.com/element-hq/element-x-android/pull/3631
* QrCode intro screen: add subtitle and fix button wording #3632 by @bmarty in https://github.com/element-hq/element-x-android/pull/3633
* Improve avatar rendering by @ganfra in https://github.com/element-hq/element-x-android/pull/3642
* Add feature flag IdentityPinningViolationNotifications. by @bmarty in https://github.com/element-hq/element-x-android/pull/3648
* Crypto copy adjustment by @bmarty in https://github.com/element-hq/element-x-android/pull/3649


Changes in Element X v0.6.5 (2024-10-09)
========================================

Expand Down
2 changes: 1 addition & 1 deletion appnav/src/main/res/values-el/translations.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Αποσύνδεση &amp;amp; Αναβάθμιση"</string>
<string name="banner_migrate_to_native_sliding_sync_action">"Αποσύνδεση &amp; Αναβάθμιση"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ο οικιακός διακομιστής σου δεν υποστηρίζει πλέον το παλιό πρωτόκολλο. Αποσυνδέσου και συνδέσου ξανά για να συνεχίσεις να χρησιμοποιείς την εφαρμογή."</string>
</resources>
2 changes: 1 addition & 1 deletion appnav/src/main/res/values-ru/translations.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Выйти и обновить"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ваш homeserver больше не поддерживает старый протокол. Пожалуйста, выйдите из системы и войдите снова, чтобы продолжить использование приложения."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ваш домашний сервер больше не поддерживает старый протокол. Пожалуйста, выйдите и войдите в свою учётную запись снова, чтобы продолжить использование приложения."</string>
</resources>
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ allprojects {
config.from(files("$rootDir/tools/detekt/detekt.yml"))
}
dependencies {
detektPlugins("io.nlopez.compose.rules:detekt:0.4.15")
detektPlugins("io.nlopez.compose.rules:detekt:0.4.16")
}

// KtLint
Expand Down
2 changes: 2 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/40007010.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Main changes in this version: bug fixes and performance improvement.
Full changelog: https://github.com/element-hq/element-x-android/releases
8 changes: 6 additions & 2 deletions fastlane/metadata/android/en-US/full_description.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Element X brings you both sovereign & seamless collaboration built on Matrix.

The collaboration capabilities include chat & video calls with the modern set of features such as:
• public & private channels
• room moderation & access conUpdatetrol
• room moderation & access control
• replies, reactions, polls, read receipts, pinned messages, etc.
• simultaneous chat & calls (picture in picture)
• decentralized & federated communication across organizations
Expand Down Expand Up @@ -32,4 +32,8 @@ Enjoy the freedom of the Matrix open standard! You have native interoperability
Enjoy your right to private conversations - free from data mining, ads and all the rest of it - and stay secure. Only the people in your conversation can read your messages.

<b>Chat across multiple devices</b>
Stay in touch wherever you are with fully synchronized message history across all your devices, even those running Element legacy app, and on the web at https://app.element.io
Stay in touch wherever you are with fully synchronized message history across all your devices, even those running Element legacy app, and on the web at https://app.element.io

The application requires the android.permission.REQUEST_INSTALL_PACKAGES permission to enable the installation of applications received as attachments, ensuring seamless and convenient access to new software within the app.

The application requires the USE_FULL_SCREEN_INTENT permission to ensure our users can effectively receive call notifications even when their devices are locked.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"Предоставлять анонимные данные об использовании, чтобы помочь нам выявить проблемы."</string>
<string name="screen_analytics_settings_help_us_improve">"Предоставьте разработчикам анонимные данные об использовании, чтобы помочь им выявлять проблемы эффективнее."</string>
<string name="screen_analytics_settings_read_terms">"Вы можете ознакомиться со всеми нашими условиями %1$s."</string>
<string name="screen_analytics_settings_read_terms_content_link">"здесь"</string>
<string name="screen_analytics_settings_share_data">"Делитесь данными аналитики"</string>
<string name="screen_analytics_settings_share_data">"Отправлять аналитические данные"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<string name="screen_analytics_prompt_help_us_improve">"Partilhe dados de utilização anónimos para nos ajudar a identificar problemas."</string>
<string name="screen_analytics_prompt_read_terms">"Podes ler todos os nossos termos %1$s."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"aqui"</string>
<string name="screen_analytics_prompt_settings">"Podes desligar qualquer momento"</string>
<string name="screen_analytics_prompt_settings">"Pode desactivar a qualquer momento"</string>
<string name="screen_analytics_prompt_third_party_sharing">"Não partilharemos os teus dados com terceiros"</string>
<string name="screen_analytics_prompt_title">"Ajude a melhorar a %1$s"</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"Мы не будем записывать или профилировать какие-либо персональные данные"</string>
<string name="screen_analytics_prompt_help_us_improve">"Предоставлять анонимные данные об использовании, чтобы помочь нам выявить проблемы."</string>
<string name="screen_analytics_prompt_help_us_improve">"Предоставьте разработчикам анонимные данные об использовании, чтобы помочь им выявлять проблемы эффективнее."</string>
<string name="screen_analytics_prompt_read_terms">"Вы можете ознакомиться со всеми нашими условиями %1$s."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"здесь"</string>
<string name="screen_analytics_prompt_settings">"Вы можете отключить эту функцию в любое время"</string>
Expand Down
6 changes: 3 additions & 3 deletions features/call/impl/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

<!-- Permissions for call foreground services -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />

<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

<application>
Expand Down Expand Up @@ -80,7 +80,7 @@
android:name=".services.CallForegroundService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="phoneCall" />
android:foregroundServiceType="microphone" />

<receiver
android:name=".receivers.DeclineCallBroadcastReceiver"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

package io.element.android.features.call.impl.services

import android.Manifest
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
Expand All @@ -33,8 +35,12 @@ import timber.log.Timber
class CallForegroundService : Service() {
companion object {
fun start(context: Context) {
val intent = Intent(context, CallForegroundService::class.java)
ContextCompat.startForegroundService(context, intent)
if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
val intent = Intent(context, CallForegroundService::class.java)
ContextCompat.startForegroundService(context, intent)
} else {
Timber.w("Microphone permission is not granted, cannot start the call foreground service")
}
}

fun stop(context: Context) {
Expand Down Expand Up @@ -67,8 +73,8 @@ class CallForegroundService : Service() {
.setContentIntent(pendingIntent)
.build()
val notificationId = NotificationIdProvider.getForegroundServiceNotificationId(ForegroundServiceType.ONGOING_CALL)
val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
} else {
0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class CallScreenPresenter @AssistedInject constructor(
urlState = urlState.value,
webViewError = webViewError,
userAgent = userAgent,
isCallActive = isJoinedCall,
isInWidgetMode = isInWidgetMode,
eventSink = { handleEvents(it) },
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ data class CallScreenState(
val urlState: AsyncData<String>,
val webViewError: String?,
val userAgent: String,
val isCallActive: Boolean,
val isInWidgetMode: Boolean,
val eventSink: (CallScreenEvents) -> Unit,
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ internal fun aCallScreenState(
urlState: AsyncData<String> = AsyncData.Success("https://call.element.io/some-actual-call?with=parameters"),
webViewError: String? = null,
userAgent: String = "",
isCallActive: Boolean = true,
isInWidgetMode: Boolean = false,
eventSink: (CallScreenEvents) -> Unit = {},
): CallScreenState {
return CallScreenState(
urlState = urlState,
webViewError = webViewError,
userAgent = userAgent,
isCallActive = isCallActive,
isInWidgetMode = isInWidgetMode,
eventSink = eventSink,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberUpdatedState
Expand Down Expand Up @@ -95,14 +96,19 @@ class ElementCallActivity :
pictureInPicturePresenter.setPipView(this)

audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
requestAudioFocus()

setContent {
val pipState = pictureInPicturePresenter.present()
ListenToAndroidEvents(pipState)
ElementThemeApp(appPreferencesStore) {
val state = presenter.present()
eventSink = state.eventSink
LaunchedEffect(state.isCallActive, state.isInWidgetMode) {
// Note when not in WidgetMode, isCallActive will never be true, so consider the call is active
if (state.isCallActive || !state.isInWidgetMode) {
setCallIsActive()
}
}
CallScreenView(
state = state,
pipState = pipState,
Expand All @@ -115,6 +121,11 @@ class ElementCallActivity :
}
}

private fun setCallIsActive() {
requestAudioFocus()
CallForegroundService.start(this)
}

@Composable
private fun ListenToAndroidEvents(pipState: PictureInPictureState) {
val pipEventSink by rememberUpdatedState(pipState.eventSink)
Expand Down Expand Up @@ -156,18 +167,6 @@ class ElementCallActivity :
setCallType(intent)
}

override fun onStart() {
super.onStart()
CallForegroundService.stop(this)
}

override fun onStop() {
super.onStop()
if (!isFinishing && !isChangingConfigurations) {
CallForegroundService.start(this)
}
}

override fun onDestroy() {
super.onDestroy()
releaseAudioFocus()
Expand Down Expand Up @@ -231,10 +230,10 @@ class ElementCallActivity :

@Suppress("DEPRECATION")
private fun requestAudioFocus() {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build()
val request = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build()
Expand All @@ -247,7 +246,6 @@ class ElementCallActivity :
AudioManager.STREAM_VOICE_CALL,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE,
)

audioFocusChangeListener = listener
}
}
Expand Down
1 change: 1 addition & 0 deletions features/call/impl/src/main/res/values-nl/translations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
<string name="call_foreground_service_channel_title_android">"Actieve oproep"</string>
<string name="call_foreground_service_message_android">"Tik om terug te gaan naar het gesprek"</string>
<string name="call_foreground_service_title_android">"☎️ In gesprek"</string>
<string name="screen_incoming_call_subtitle_android">"Inkomende Element-oproep"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class CallScreenPresenterTest {
assertThat(initialState.urlState).isEqualTo(AsyncData.Success("https://call.element.io"))
assertThat(initialState.webViewError).isNull()
assertThat(initialState.isInWidgetMode).isFalse()
assertThat(initialState.isCallActive).isFalse()
analyticsLambda.assertions().isNeverCalled()
joinedCallLambda.assertions().isCalledOnce()
}
Expand Down Expand Up @@ -106,6 +107,7 @@ class CallScreenPresenterTest {
joinedCallLambda.assertions().isCalledOnce()
val initialState = awaitItem()
assertThat(initialState.urlState).isInstanceOf(AsyncData.Success::class.java)
assertThat(initialState.isCallActive).isFalse()
assertThat(initialState.isInWidgetMode).isTrue()
assertThat(widgetProvider.getWidgetCalled).isTrue()
assertThat(widgetDriver.runCalledCount).isEqualTo(1)
Expand Down Expand Up @@ -203,6 +205,44 @@ class CallScreenPresenterTest {
}
}

@Test
fun `present - a received room member message makes the call to be active`() = runTest {
val navigator = FakeCallScreenNavigator()
val widgetDriver = FakeMatrixWidgetDriver()
val presenter = createCallScreenPresenter(
callType = CallType.RoomCall(A_SESSION_ID, A_ROOM_ID),
widgetDriver = widgetDriver,
navigator = navigator,
dispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true),
screenTracker = FakeScreenTracker {},
)
val messageInterceptor = FakeWidgetMessageInterceptor()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
assertThat(initialState.isCallActive).isFalse()
initialState.eventSink(CallScreenEvents.SetupMessageChannels(messageInterceptor))
messageInterceptor.givenInterceptedMessage(
"""
{
"action":"send_event",
"api":"fromWidget",
"widgetId":"1",
"requestId":"1",
"data":{
"type":"org.matrix.msc3401.call.member"
}
}
""".trimIndent()
)
skipItems(1)
val finalState = awaitItem()
assertThat(finalState.isCallActive).isTrue()
}
}

@Test
fun `present - automatically starts the Matrix client sync when on RoomCall`() = runTest {
val navigator = FakeCallScreenNavigator()
Expand Down
Loading

0 comments on commit 159a478

Please sign in to comment.