Skip to content

Commit 80bc727

Browse files
Merge pull request #1876 from session-foundation/release/1.31.0
Prepare for Release/1.31.0
2 parents 520c375 + 8f863aa commit 80bc727

463 files changed

Lines changed: 27968 additions & 12666 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build_and_test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
submodules: 'recursive'
3131

3232
- name: Cache Gradle
33-
uses: actions/cache@v4
33+
uses: actions/cache@v5
3434
with:
3535
path: |
3636
~/.gradle/caches
@@ -54,14 +54,14 @@ jobs:
5454

5555
- name: Upload build reports regardless
5656
if: always()
57-
uses: actions/upload-artifact@v5
57+
uses: actions/upload-artifact@v6
5858
with:
5959
name: build-reports-${{ matrix.variant }}-${{ matrix.build_type }}
6060
path: app/build/reports
6161
if-no-files-found: ignore
6262

6363
- name: Upload artifacts
64-
uses: actions/upload-artifact@v5
64+
uses: actions/upload-artifact@v6
6565
with:
6666
name: session-${{ matrix.variant }}-${{ matrix.build_type }}
6767
path: app/build/outputs/apk/${{ matrix.variant }}/${{ matrix.build_type }}/*-universal*apk

app/build.gradle.kts

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ plugins {
1212
alias(libs.plugins.hilt.android)
1313
alias(libs.plugins.dependency.analysis)
1414
alias(libs.plugins.google.services)
15-
alias(libs.plugins.protobuf.compiler)
1615

1716
id("generate-ip-country-data")
17+
id("local-snode-pool")
1818
id("rename-apk")
1919
id("witness")
2020
}
@@ -26,8 +26,8 @@ configurations.configureEach {
2626
exclude(module = "commons-logging")
2727
}
2828

29-
val canonicalVersionCode = 436
30-
val canonicalVersionName = "1.30.3"
29+
val canonicalVersionCode = 437
30+
val canonicalVersionName = "1.31.0"
3131

3232
val postFixSize = 10
3333
val abiPostFix = mapOf(
@@ -86,22 +86,7 @@ kotlin {
8686
}
8787
}
8888

89-
protobuf {
90-
protoc {
91-
artifact = libs.protoc.get().toString()
92-
}
93-
94-
plugins {
95-
generateProtoTasks {
96-
all().forEach {
97-
it.builtins {
98-
create("java") {
99-
}
100-
}
101-
}
102-
}
103-
}
104-
}
89+
val testJvmAgent = configurations.create("mockitoAgent")
10590

10691
android {
10792
namespace = "network.loki.messenger"
@@ -151,6 +136,13 @@ android {
151136
buildConfigField("String", "USER_AGENT", "\"OWA\"")
152137
buildConfigField("int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode")
153138

139+
buildConfigField("org.thoughtcrime.securesms.pro.ProBackendConfig", "PRO_BACKEND_DEV", """
140+
new org.thoughtcrime.securesms.pro.ProBackendConfig(
141+
"https://pro-backend-dev.getsession.org",
142+
"fc947730f49eb01427a66e050733294d9e520e545c7a27125a780634e0860a27"
143+
)
144+
""".trimIndent())
145+
154146
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
155147
testInstrumentationRunnerArguments["clearPackageData"] = "true"
156148
testOptions {
@@ -303,6 +295,9 @@ android {
303295

304296
testOptions {
305297
unitTests.isIncludeAndroidResources = true
298+
unitTests.all {
299+
it.jvmArgs("-javaagent:${testJvmAgent.asPath}")
300+
}
306301
}
307302

308303
lint {
@@ -332,6 +327,8 @@ android {
332327
testNamespace = "network.loki.messenger.test"
333328
}
334329

330+
331+
335332
dependencies {
336333
implementation(project(":content-descriptions"))
337334

@@ -394,28 +391,19 @@ dependencies {
394391
implementation(libs.androidx.sqlite.ktx)
395392
implementation(libs.sqlcipher.android)
396393
implementation(libs.kotlinx.serialization.json)
397-
implementation(libs.protobuf.java)
398394
implementation(libs.jackson.databind)
399395
implementation(libs.okhttp)
400396
implementation(libs.phrase)
401397
implementation(libs.copper.flow)
402398
implementation(libs.kotlinx.coroutines.android)
403399
implementation(libs.kotlinx.coroutines.guava)
404-
implementation(libs.kovenant)
405-
implementation(libs.kovenant.android)
406400
implementation(libs.opencsv)
407401
implementation(libs.androidx.work.runtime.ktx)
408402
implementation(libs.rxbinding)
409403

410-
if (hasIncludedLibSessionUtilProject) {
411-
implementation(
412-
group = libs.libsession.util.android.get().group,
413-
name = libs.libsession.util.android.get().name,
414-
version = "dev-snapshot"
415-
)
416-
} else {
417-
implementation(libs.libsession.util.android)
418-
}
404+
// If libsession_util project is included into the build, use that, otherwise use the published version
405+
findProject(":libsession-util-android")?.let(::implementation)
406+
?: implementation(libs.libsession.util.android)
419407

420408
implementation(libs.kryo)
421409
testImplementation(libs.junit)
@@ -434,8 +422,14 @@ dependencies {
434422
androidTestImplementation(libs.androidx.junit)
435423
androidTestImplementation(libs.androidx.truth)
436424
testImplementation(libs.truth)
425+
testImplementation(libs.androidx.sqlite.framework)
437426
androidTestImplementation(libs.truth)
438427
testRuntimeOnly(libs.mockito.core)
428+
testImplementation(libs.mockk)
429+
testImplementation(libs.kotlin.test)
430+
431+
// Pull in appropriate JVM agents for unit test
432+
testJvmAgent(libs.mockito.core) { isTransitive = false }
439433

440434
androidTestImplementation(libs.androidx.espresso.core)
441435
androidTestImplementation(libs.androidx.espresso.contrib)
@@ -449,7 +443,6 @@ dependencies {
449443
androidTestUtil(libs.androidx.orchestrator)
450444

451445
testImplementation(libs.robolectric)
452-
testImplementation(libs.robolectric.shadows.multidex)
453446
testImplementation(libs.conscrypt.openjdk.uber)
454447
testImplementation(libs.turbine)
455448

app/src/main/AndroidManifest.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,17 @@
218218
<data android:mimeType="text/*" />
219219
<data android:mimeType="*/*" />
220220
</intent-filter>
221+
<intent-filter>
222+
<action android:name="android.intent.action.SEND_MULTIPLE" />
223+
<category android:name="android.intent.category.DEFAULT" />
224+
<data android:mimeType="audio/*" />
225+
<data android:mimeType="image/*" />
226+
<data android:mimeType="text/plain" />
227+
<data android:mimeType="video/*" />
228+
<data android:mimeType="application/*" />
229+
<data android:mimeType="text/*" />
230+
<data android:mimeType="*/*" />
231+
</intent-filter>
221232
<meta-data
222233
android:name="android.service.chooser.chooser_target_service"
223234
android:value=".service.DirectShareService" />

app/src/main/java/org/session/libsession/database/StorageProtocol.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ interface StorageProtocol {
5757
// Servers
5858
fun setServerCapabilities(server: String, capabilities: List<String>)
5959
fun getServerCapabilities(server: String): List<String>?
60+
fun clearServerCapabilities(server: String)
6061

6162
// Open Groups
6263
suspend fun addOpenGroup(urlAsString: String)

app/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import org.session.libsession.database.MessageDataProvider
77
import org.session.libsession.database.StorageProtocol
88
import org.session.libsession.messaging.groups.GroupManagerV2
99
import org.session.libsession.messaging.groups.LegacyGroupDeprecationManager
10-
import org.session.libsession.messaging.jobs.MessageSendJob
1110
import org.session.libsession.messaging.notifications.TokenFetcher
12-
import org.session.libsession.snode.SnodeClock
11+
import org.session.libsession.network.SnodeClock
12+
import org.session.libsession.network.onion.PathManager
1313
import org.session.libsession.utilities.ConfigFactoryProtocol
1414
import org.session.libsession.utilities.Device
1515
import org.session.libsession.utilities.TextSecurePreferences
@@ -28,14 +28,14 @@ class MessagingModuleConfiguration @Inject constructor(
2828
val configFactory: ConfigFactoryProtocol,
2929
val tokenFetcher: TokenFetcher,
3030
val groupManagerV2: GroupManagerV2,
31-
val clock: SnodeClock,
3231
val preferences: TextSecurePreferences,
3332
val deprecationManager: LegacyGroupDeprecationManager,
3433
val recipientRepository: RecipientRepository,
3534
val avatarUtils: AvatarUtils,
3635
val proStatusManager: ProStatusManager,
37-
val messageSendJobFactory: MessageSendJob.Factory,
3836
val json: Json,
37+
val snodeClock: SnodeClock,
38+
val pathManager: PathManager
3939
) {
4040

4141
companion object {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.session.libsession.messaging.file_server
2+
3+
import dagger.assisted.Assisted
4+
import dagger.assisted.AssistedFactory
5+
import dagger.assisted.AssistedInject
6+
import okhttp3.HttpUrl.Companion.toHttpUrl
7+
import org.thoughtcrime.securesms.api.server.ServerApiErrorManager
8+
import org.thoughtcrime.securesms.api.ApiExecutorContext
9+
import org.thoughtcrime.securesms.api.http.HttpBody
10+
import org.thoughtcrime.securesms.api.http.HttpRequest
11+
import org.thoughtcrime.securesms.api.http.HttpResponse
12+
import org.thoughtcrime.securesms.api.server.ServerApi
13+
import java.time.ZonedDateTime
14+
import java.time.format.DateTimeFormatter
15+
16+
class FileDownloadApi @AssistedInject constructor(
17+
@Assisted private val fileId: String,
18+
errorManager: ServerApiErrorManager,
19+
) : ServerApi<FileDownloadApi.Response>(errorManager) {
20+
override fun buildRequest(
21+
baseUrl: String,
22+
x25519PubKeyHex: String
23+
): HttpRequest {
24+
return HttpRequest(
25+
url = "$baseUrl/file/$fileId".toHttpUrl(),
26+
method = "GET",
27+
headers = emptyMap(),
28+
body = null
29+
)
30+
}
31+
32+
override suspend fun handleSuccessResponse(
33+
executorContext: ApiExecutorContext,
34+
baseUrl: String,
35+
response: HttpResponse
36+
): Response {
37+
return Response(
38+
data = response.body,
39+
expires = response.parseFileServerExpiresHeader()
40+
)
41+
}
42+
43+
class Response(
44+
val data: HttpBody,
45+
val expires: ZonedDateTime?
46+
)
47+
48+
@AssistedFactory
49+
interface Factory {
50+
fun create(fileId: String): FileDownloadApi
51+
}
52+
53+
companion object {
54+
fun HttpResponse.parseFileServerExpiresHeader(): ZonedDateTime? {
55+
return headers["expires"]?.let {
56+
ZonedDateTime.parse(it, DateTimeFormatter.RFC_1123_DATE_TIME)
57+
}
58+
}
59+
}
60+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.session.libsession.messaging.file_server
2+
3+
import dagger.assisted.Assisted
4+
import dagger.assisted.AssistedFactory
5+
import dagger.assisted.AssistedInject
6+
import okhttp3.HttpUrl.Companion.toHttpUrl
7+
import org.thoughtcrime.securesms.api.server.ServerApiErrorManager
8+
import org.thoughtcrime.securesms.api.ApiExecutorContext
9+
import org.thoughtcrime.securesms.api.http.HttpRequest
10+
import org.thoughtcrime.securesms.api.http.HttpResponse
11+
import org.thoughtcrime.securesms.api.server.ServerApi
12+
13+
class FileRenewApi @AssistedInject constructor(
14+
@Assisted private val fileId: String,
15+
errorManager: ServerApiErrorManager,
16+
) : ServerApi<Unit>(errorManager) {
17+
18+
override fun buildRequest(
19+
baseUrl: String,
20+
x25519PubKeyHex: String
21+
): HttpRequest {
22+
return HttpRequest(
23+
url = "$baseUrl/file/$fileId/extend".toHttpUrl(),
24+
method = "POST",
25+
headers = emptyMap(),
26+
body = null,
27+
)
28+
}
29+
30+
override suspend fun handleSuccessResponse(
31+
executorContext: ApiExecutorContext,
32+
baseUrl: String,
33+
response: HttpResponse
34+
) = Unit
35+
36+
@AssistedFactory
37+
interface Factory {
38+
fun create(fileId: String): FileRenewApi
39+
}
40+
}

app/src/main/java/org/session/libsession/messaging/file_server/FileServer.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.session.libsession.messaging.file_server
22

33
import kotlinx.serialization.Serializable
4+
import network.loki.messenger.libsession_util.Curve25519
45
import okhttp3.HttpUrl
56
import okhttp3.HttpUrl.Companion.toHttpUrl
67
import org.session.libsession.utilities.serializable.HttpUrlSerializer
8+
import org.session.libsignal.utilities.Hex
79

810
@Serializable
911
data class FileServer(
@@ -12,6 +14,12 @@ data class FileServer(
1214
val ed25519PublicKeyHex: String
1315
) {
1416
constructor(url: String, ed25519PublicKeyHex: String) : this(url.toHttpUrl(), ed25519PublicKeyHex)
17+
18+
val x25519PubKeyHex: String by lazy {
19+
Hex.toStringCondensed(
20+
Curve25519.pubKeyFromED25519(Hex.fromStringCondensed(ed25519PublicKeyHex))
21+
)
22+
}
1523
}
1624

1725
val HttpUrl.isOfficial: Boolean

0 commit comments

Comments
 (0)