From 9575db64fd18c4083b333e862885d107162d3fd5 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:12:53 +1100 Subject: [PATCH] Add github action workflow (#1016) * Add build steps for github action * Fix build commands * Checkout submodule recursively and don't fail fast * Fix mention view model tests * Upload test result when failed * Temporarily disable variants * Fix tests * Fix tests * Fix tests * Fix tests * Remove deprecated properties * Fixes up artifact uploading * Fixes tests * Fixes tests * Huawei artifact matching and gradle caching * PR trigger --- .github/workflows/build_and_test.yml | 63 +++++++++++++++++++ .../v2/mention/MentionViewModel.kt | 5 +- .../securesms/database/Storage.kt | 8 +++ .../securesms/BaseCoroutineTest.kt | 14 ++--- .../securesms/CoroutineTestRule.kt | 50 --------------- .../securesms/MainCoroutineRule.kt | 25 +++++--- .../DisappearingMessagesViewModelTest.kt | 5 +- .../v2/ConversationViewModelTest.kt | 28 ++++++--- .../conversation/v2/MentionViewModelTest.kt | 35 +++++++---- .../MessageRequestsViewModelTest.kt | 5 ++ gradle.properties | 6 +- .../libsession/database/StorageProtocol.kt | 1 + .../org/session/libsession/snode/SnodeAPI.kt | 3 +- libsignal/build.gradle | 5 ++ 14 files changed, 155 insertions(+), 98 deletions(-) create mode 100644 .github/workflows/build_and_test.yml delete mode 100644 app/src/sharedTest/java/org/thoughtcrime/securesms/CoroutineTestRule.kt diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml new file mode 100644 index 0000000000..4a1807fdaf --- /dev/null +++ b/.github/workflows/build_and_test.yml @@ -0,0 +1,63 @@ +name: Build and test + +on: + push: + branches: [ "dev", "master" ] + pull_request: + types: [synchronize] + + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_and_test: + runs-on: ubuntu-latest + strategy: + fail-fast: false # Continue with other matrix items if one fails + matrix: + variant: [ 'play', 'website', 'huawei' ] + build_type: [ 'debug' ] + include: + - variant: 'huawei' + extra_build_command_options: '-Phuawei=1' + steps: + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + .gradle + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'gradle.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: '17' + + - name: Build and test with Gradle + id: build + run: ./gradlew assemble${{ matrix.variant }}${{ matrix.build_type }} test${{ matrix.variant }}${{ matrix.build_type }}UnitTest ${{ matrix.extra_build_command_options }} + + - name: Upload build reports regardless + if: always() + uses: actions/upload-artifact@v4 + with: + name: build-reports-${{ matrix.variant }}-${{ matrix.build_type }} + path: app/build/reports + if-no-files-found: ignore + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: session-${{ matrix.variant }}-${{ matrix.build_type }} + path: app/build/outputs/apk/${{ matrix.variant }}/${{ matrix.build_type }}/*-universal*apk + if-no-files-found: error + compression-level: 0 diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/mention/MentionViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/mention/MentionViewModel.kt index f48adcfb8e..b9dbea6681 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/mention/MentionViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/mention/MentionViewModel.kt @@ -141,10 +141,7 @@ class MentionViewModel( } val myId = if (openGroup != null) { - AccountId(IdPrefix.BLINDED, - SodiumUtilities.blindedKeyPair(openGroup.publicKey, - requireNotNull(storage.getUserED25519KeyPair()))!!.publicKey.asBytes) - .hexString + requireNotNull(storage.getUserBlindedAccountId(openGroup.publicKey)).hexString } else { requireNotNull(storage.getUserPublicKey()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 3a50f72638..0bf9426761 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -228,6 +228,14 @@ open class Storage @Inject constructor( override fun getUserED25519KeyPair(): KeyPair? { return KeyPairUtilities.getUserED25519KeyPair(context) } + override fun getUserBlindedAccountId(serverPublicKey: String): AccountId? { + val userKeyPair = getUserED25519KeyPair() ?: return null + return AccountId( + IdPrefix.BLINDED, + SodiumUtilities.blindedKeyPair(serverPublicKey, userKeyPair)!!.publicKey.asBytes + ) + } + override fun getUserProfile(): Profile { val displayName = usernameUtils.getCurrentUsername() val profileKey = ProfileKeyUtil.getProfileKey(context) diff --git a/app/src/sharedTest/java/org/thoughtcrime/securesms/BaseCoroutineTest.kt b/app/src/sharedTest/java/org/thoughtcrime/securesms/BaseCoroutineTest.kt index 60d10cbbb5..c98fbed42e 100644 --- a/app/src/sharedTest/java/org/thoughtcrime/securesms/BaseCoroutineTest.kt +++ b/app/src/sharedTest/java/org/thoughtcrime/securesms/BaseCoroutineTest.kt @@ -1,15 +1,11 @@ package org.thoughtcrime.securesms -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Rule +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest open class BaseCoroutineTest { - @get:Rule - var coroutinesTestRule = CoroutineTestRule() - - protected fun runBlockingTest(test: suspend TestCoroutineScope.() -> Unit) = - coroutinesTestRule.runBlockingTest { test() } - + protected fun runBlockingTest(test: suspend TestScope.() -> Unit) = runTest { + test() + } } \ No newline at end of file diff --git a/app/src/sharedTest/java/org/thoughtcrime/securesms/CoroutineTestRule.kt b/app/src/sharedTest/java/org/thoughtcrime/securesms/CoroutineTestRule.kt deleted file mode 100644 index 04ca0ac523..0000000000 --- a/app/src/sharedTest/java/org/thoughtcrime/securesms/CoroutineTestRule.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.thoughtcrime.securesms - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.test.TestCoroutineDispatcher -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.resetMain -import kotlinx.coroutines.test.setMain -import org.junit.rules.TestWatcher -import org.junit.runner.Description - -/** - * Sets the main coroutines dispatcher to a [TestCoroutineScope] for unit testing. A - * [TestCoroutineScope] provides control over the execution of coroutines. - * - * Declare it as a JUnit Rule: - * - * ``` - * @get:Rule - * var coroutineTestRule = CoroutineTestRule() - * ``` - * - * Use it directly as a [TestCoroutineScope]: - * - * ``` - * coroutineTestRule.pauseDispatcher() - * ... - * coroutineTestRule.resumeDispatcher() - * ... - * coroutineTestRule.runBlockingTest { } - * ... - * - */ - -class CoroutineTestRule( - val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher() -) : TestWatcher(), TestCoroutineScope by TestCoroutineScope(dispatcher) { - - override fun starting(description: Description?) { - super.starting(description) - Dispatchers.setMain(dispatcher) - - } - - override fun finished(description: Description?) { - super.finished(description) - cleanupTestCoroutines() - Dispatchers.resetMain() - } - -} \ No newline at end of file diff --git a/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt b/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt index 2e13ce1df6..2afe9e1fba 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt @@ -2,24 +2,33 @@ package org.thoughtcrime.securesms import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestCoroutineScheduler import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain import org.junit.rules.TestWatcher import org.junit.runner.Description +import java.util.concurrent.atomic.AtomicBoolean -@ExperimentalCoroutinesApi -class MainCoroutineRule(private val dispatcher: TestDispatcher = StandardTestDispatcher()) : +@OptIn(ExperimentalCoroutinesApi::class) +class MainCoroutineRule() : TestWatcher() { + companion object { + private val dispatcherSet = AtomicBoolean(false) + } + override fun starting(description: Description) { super.starting(description) - Dispatchers.setMain(dispatcher) - } - override fun finished(description: Description) { - super.finished(description) - Dispatchers.resetMain() + // Set the main dispatcher to test dispatcher, however we shouldn't reset the main dispatcher + // as some coroutine tasks spawn during the testing may try to resume on the main dispatcher, + // which will cause an exception if it has been reset. + // Right now there aren't good ways to force the coroutines run on other threads to behave + // correctly everytime so we'll just keep the main dispatcher as the test dispatcher globally. + if (dispatcherSet.compareAndSet(false, true)) { + Dispatchers.setMain(UnconfinedTestDispatcher(TestCoroutineScheduler())) + } } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt index 0fb458a0d5..c462938dda 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessagesViewModelTest.kt @@ -23,6 +23,8 @@ import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.guava.Optional +import org.thoughtcrime.securesms.BaseCoroutineTest +import org.thoughtcrime.securesms.BaseViewModelTest import org.thoughtcrime.securesms.MainCoroutineRule import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.ExpiryRadioOption import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCardData @@ -44,9 +46,8 @@ private val GROUP_ADDRESS = Address.fromSerialized(GROUP_NUMBER) @OptIn(ExperimentalCoroutinesApi::class) @RunWith(MockitoJUnitRunner::class) -class DisappearingMessagesViewModelTest { +class DisappearingMessagesViewModelTest : BaseViewModelTest() { - @ExperimentalCoroutinesApi @get:Rule var mainCoroutineRule = MainCoroutineRule() diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModelTest.kt index c4b6a26842..50aa48c6d8 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModelTest.kt @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.conversation.v2 import android.app.Application import com.goterl.lazysodium.utils.KeyPair +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.first import org.hamcrest.CoreMatchers.equalTo @@ -9,21 +10,29 @@ import org.hamcrest.CoreMatchers.notNullValue import org.hamcrest.CoreMatchers.nullValue import org.hamcrest.MatcherAssert.assertThat import org.junit.Before +import org.junit.Rule import org.junit.Test import org.mockito.Mockito import org.mockito.Mockito.anyLong import org.mockito.Mockito.verify import org.mockito.kotlin.any +import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever +import org.session.libsession.messaging.groups.LegacyGroupDeprecationManager import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.BaseViewModelTest +import org.thoughtcrime.securesms.MainCoroutineRule import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.repository.ConversationRepository +import java.time.ZonedDateTime class ConversationViewModelTest: BaseViewModelTest() { + @get:Rule + val rule = MainCoroutineRule() + private val repository = mock() private val storage = mock() private val application = mock() @@ -49,7 +58,10 @@ class ConversationViewModelTest: BaseViewModelTest() { configFactory = mock(), groupManagerV2 = mock(), callManager = mock(), - legacyGroupDeprecationManager = mock(), + legacyGroupDeprecationManager = mock { + on { deprecationState } doReturn MutableStateFlow(LegacyGroupDeprecationManager.DeprecationState.DEPRECATED) + on { deprecatedTime } doReturn MutableStateFlow(ZonedDateTime.now()) + }, expiredGroupManager = mock(), usernameUtils = mock() ) @@ -66,7 +78,7 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `should save draft message`() { + fun `should save draft message`() = runBlockingTest { val draft = "Hi there" viewModel.saveDraft(draft) @@ -76,7 +88,7 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `should retrieve draft message`() { + fun `should retrieve draft message`() = runBlockingTest { val draft = "Hi there" whenever(repository.getDraft(anyLong())).thenReturn(draft) @@ -87,7 +99,7 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `should invite contacts`() { + fun `should invite contacts`() = runBlockingTest { val contacts = listOf() viewModel.inviteContacts(contacts) @@ -96,7 +108,7 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `should unblock contact recipient`() { + fun `should unblock contact recipient`() = runBlockingTest { whenever(recipient.isContactRecipient).thenReturn(true) viewModel.unblock() @@ -167,7 +179,7 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `open group recipient should have no blinded recipient`() { + fun `open group recipient should have no blinded recipient`() = runBlockingTest { whenever(recipient.isCommunityRecipient).thenReturn(true) whenever(recipient.isCommunityOutboxRecipient).thenReturn(false) whenever(recipient.isCommunityInboxRecipient).thenReturn(false) @@ -175,14 +187,14 @@ class ConversationViewModelTest: BaseViewModelTest() { } @Test - fun `local recipient should have input and no blinded recipient`() { + fun `local recipient should have input and no blinded recipient`() = runBlockingTest { whenever(recipient.isLocalNumber).thenReturn(true) assertThat(viewModel.shouldHideInputBar(), equalTo(false)) assertThat(viewModel.blindedRecipient, nullValue()) } @Test - fun `contact recipient should hide input bar if not accepting requests`() { + fun `contact recipient should hide input bar if not accepting requests`() = runBlockingTest { whenever(recipient.isCommunityInboxRecipient).thenReturn(true) val blinded = mock { whenever(it.blocksCommunityMessageRequests).thenReturn(true) diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt index da1b678fbd..a0cfd9d691 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt @@ -21,11 +21,13 @@ import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.open_groups.GroupMemberRole import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.utilities.recipients.Recipient +import org.session.libsignal.utilities.AccountId +import org.thoughtcrime.securesms.BaseViewModelTest import org.thoughtcrime.securesms.MainCoroutineRule import org.thoughtcrime.securesms.conversation.v2.mention.MentionViewModel @RunWith(RobolectricTestRunner::class) -class MentionViewModelTest { +class MentionViewModelTest : BaseViewModelTest() { @OptIn(ExperimentalCoroutinesApi::class) @get:Rule val mainCoroutineRule = MainCoroutineRule() @@ -37,16 +39,22 @@ class MentionViewModelTest { private data class MemberInfo( val name: String, val pubKey: String, - val roles: List + val roles: List, + val isMe: Boolean ) + private val myId = AccountId.fromString( + "151234567890123456789012345678901234567890123456789012345678901234" + )!! + private val threadMembers = listOf( - MemberInfo("Alice", "pubkey1", listOf(GroupMemberRole.ADMIN)), - MemberInfo("Bob", "pubkey2", listOf(GroupMemberRole.STANDARD)), - MemberInfo("Charlie", "pubkey3", listOf(GroupMemberRole.MODERATOR)), - MemberInfo("David", "pubkey4", listOf(GroupMemberRole.HIDDEN_ADMIN)), - MemberInfo("Eve", "pubkey5", listOf(GroupMemberRole.HIDDEN_MODERATOR)), - MemberInfo("李云海", "pubkey6", listOf(GroupMemberRole.ZOOMBIE)), + MemberInfo("You", myId.hexString, listOf(GroupMemberRole.STANDARD), isMe = true), + MemberInfo("Alice", "pubkey1", listOf(GroupMemberRole.ADMIN), isMe = false), + MemberInfo("Bob", "pubkey2", listOf(GroupMemberRole.STANDARD), isMe = false), + MemberInfo("Charlie", "pubkey3", listOf(GroupMemberRole.MODERATOR), isMe = false), + MemberInfo("David", "pubkey4", listOf(GroupMemberRole.HIDDEN_ADMIN), isMe = false), + MemberInfo("Eve", "pubkey5", listOf(GroupMemberRole.HIDDEN_MODERATOR), isMe = false), + MemberInfo("李云海", "pubkey6", listOf(GroupMemberRole.ZOOMBIE), isMe = false), ) private val memberContacts = threadMembers.map { m -> @@ -106,7 +114,8 @@ class MentionViewModelTest { }, storage = mock { on { getOpenGroup(threadID) } doReturn openGroup - }, + on { getUserBlindedAccountId(any()) } doReturn myId + }, dispatcher = StandardTestDispatcher(), configFactory = mock(), threadID = threadID, @@ -135,11 +144,11 @@ class MentionViewModelTest { result as MentionViewModel.AutoCompleteState.Result assertThat(result.members).isEqualTo(threadMembers.mapIndexed { index, m -> - val name = + val name = if (m.isMe) "You" else memberContacts[index].displayName(Contact.ContactContext.OPEN_GROUP) MentionViewModel.Candidate( - MentionViewModel.Member(m.pubKey, name, m.roles.any { it.isModerator }, isMe = false), + MentionViewModel.Member(m.pubKey, name, m.roles.any { it.isModerator }, isMe = m.isMe), name, 0 ) @@ -157,8 +166,8 @@ class MentionViewModelTest { .isInstanceOf(MentionViewModel.AutoCompleteState.Result::class.java) result as MentionViewModel.AutoCompleteState.Result - assertThat(result.members[0].member.name).isEqualTo("Alice (pubk...key1)") - assertThat(result.members[1].member.name).isEqualTo("Charlie (pubk...key3)") + assertThat(result.members[0].member.name).isEqualTo("Alice (pubkey1)") + assertThat(result.members[1].member.name).isEqualTo("Charlie (pubkey3)") } } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsViewModelTest.kt index 8cdb36b6b3..62814b387c 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsViewModelTest.kt @@ -1,14 +1,19 @@ package org.thoughtcrime.securesms.messagerequests +import org.junit.Rule import org.junit.Test import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.thoughtcrime.securesms.BaseViewModelTest +import org.thoughtcrime.securesms.MainCoroutineRule import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.repository.ConversationRepository class MessageRequestsViewModelTest : BaseViewModelTest() { + @get:Rule + val rule = MainCoroutineRule() + private val repository = mock(ConversationRepository::class.java) private val viewModel: MessageRequestsViewModel by lazy { diff --git a/gradle.properties b/gradle.properties index 2a9f1bd997..512f282004 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ navVersion=2.8.0-beta05 android.useAndroidX=true appcompatVersion=1.6.1 coreVersion=1.13.1 -coroutinesVersion=1.6.4 +coroutinesVersion=1.9.0 curve25519Version=0.6.0 jetpackHiltVersion=1.2.0 daggerHiltVersion=2.55 @@ -42,6 +42,8 @@ preferenceVersion=1.2.0 protobufVersion=4.29.3 testCoreVersion=1.5.0 zxingVersion=3.5.3 -android.defaults.buildfeatures.buildconfig=true android.nonTransitiveRClass=false android.nonFinalResIds=false + +# Enable fast service loader to fix a crash in coroutine's test dispatcher set up +kotlinx.coroutines.fast.service.loader=true \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index 44b97b941e..06ea703253 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -46,6 +46,7 @@ interface StorageProtocol { fun getUserPublicKey(): String? fun getUserED25519KeyPair(): KeyPair? fun getUserX25519KeyPair(): ECKeyPair + fun getUserBlindedAccountId(serverPublicKey: String): AccountId? fun getUserProfile(): Profile fun setProfilePicture(recipient: Recipient, newProfilePicture: String?, newProfileKey: ByteArray?) fun setBlocksCommunityMessageRequests(recipient: Recipient, blocksMessageRequests: Boolean) diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index b1edf6e939..775428f1fb 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -4,8 +4,6 @@ package org.session.libsession.snode import android.os.SystemClock import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode import com.goterl.lazysodium.exceptions.SodiumException import com.goterl.lazysodium.interfaces.GenericHash import com.goterl.lazysodium.interfaces.PwHash @@ -18,6 +16,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.launch +import kotlinx.coroutines.selects.onTimeout import kotlinx.coroutines.selects.select import nl.komponents.kovenant.Promise import nl.komponents.kovenant.all diff --git a/libsignal/build.gradle b/libsignal/build.gradle index 0d0c67b1c3..74801dfac9 100644 --- a/libsignal/build.gradle +++ b/libsignal/build.gradle @@ -17,6 +17,11 @@ android { kotlinOptions { jvmTarget = '11' } + + buildFeatures { + buildConfig = true + } + namespace 'org.session.libsignal' }