Skip to content

Commit 084d167

Browse files
Pro integration (#29)
1 parent 5449aee commit 084d167

Some content is hidden

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

58 files changed

+2016
-951
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
plugins {
33
alias(libs.plugins.android.library) apply false
44
alias(libs.plugins.kotlin.android) apply false
5+
alias(libs.plugins.kotlinx.serialization) apply false
56
}

gradle/libs.versions.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
[versions]
2-
agp = "8.13.0"
3-
kotlin = "2.2.20"
2+
agp = "8.13.1"
3+
kotlin = "2.2.21"
44

55
[libraries]
66
junit = { module = "junit:junit", version = "4.13.2" }
77
androidx-test-runner = { module = "androidx.test:runner", version = "1.7.0" }
88
androidx-test-rules = { module = "androidx.test:rules", version = "1.7.0" }
99
androidx-test-ext = { module = "androidx.test.ext:junit", version = "1.3.0" }
1010
androidx-annotations = { module = "androidx.annotation:annotation", version = "1.9.1" }
11+
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version = "1.9.0" }
1112

1213
[plugins]
1314
android-library = { id = "com.android.library", version.ref = "agp" }
1415
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
15-
16+
kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

library/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
33
plugins {
44
alias(libs.plugins.android.library)
55
alias(libs.plugins.kotlin.android)
6+
alias(libs.plugins.kotlinx.serialization)
67
id("maven-publish")
78
}
89

@@ -119,4 +120,5 @@ dependencies {
119120
androidTestImplementation(libs.androidx.test.ext)
120121

121122
implementation(libs.androidx.annotations)
123+
implementation(libs.kotlinx.serialization.core)
122124
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package network.loki.messenger.libsession_util.protocol
2+
3+
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import network.loki.messenger.libsession_util.pro.BackendRequests
5+
import org.junit.Assert.assertNotNull
6+
import org.junit.Test
7+
import org.junit.runner.RunWith
8+
9+
@RunWith(AndroidJUnit4::class)
10+
class BackendRequestsTest {
11+
12+
@Test
13+
fun getProviderMetadataWorks() {
14+
val metadata = BackendRequests.getPaymentProviderMetadata(BackendRequests.PAYMENT_PROVIDER_GOOGLE_PLAY)
15+
assertNotNull(metadata)
16+
}
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package network.loki.messenger.libsession_util.protocol
2+
3+
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Test
6+
import org.junit.runner.RunWith
7+
8+
@RunWith(AndroidJUnit4::class)
9+
class SessionProtocolTest {
10+
11+
@Test
12+
fun proFeaturesForMessageWorks() {
13+
val proposedFeatures = ProFeatures.from(listOf(ProFeature.PRO_BADGE))
14+
val result = SessionProtocol.proFeaturesForMessage(
15+
messageBody = "Hello, Session Pro!",
16+
proposedFeatures
17+
)
18+
19+
assertEquals(ProFeaturesForMsg.Status.Success, result.status)
20+
assertEquals(19, result.codepointCount)
21+
assertEquals(proposedFeatures, result.features)
22+
}
23+
}

library/src/main/cpp/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ set(SOURCES
9595
attachments.cpp
9696
webp_utils.cpp
9797
gif_utils.cpp
98+
pro_backend.cpp
99+
pro_proof_util.cpp
98100

99101
${cgif_SOURCE_DIR}/src/cgif.c
100102
${cgif_SOURCE_DIR}/src/cgif_rgb.c
@@ -158,4 +160,6 @@ target_link_libraries( # Specifies the target library.
158160
webpdemux
159161
webpdecoder
160162
yuv
163+
nlohmann_json
164+
oxenc
161165
)

library/src/main/cpp/attachments.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <jni.h>
22
#include <session/attachments.hpp>
33
#include "jni_utils.h"
4+
#include "util.h"
45

56
using namespace session::attachment;
67
using namespace jni_utils;
@@ -49,7 +50,7 @@ Java_network_loki_messenger_libsession_1util_encrypt_Attachments_encryptBytes(JN
4950
);
5051

5152

52-
return util::bytes_from_span(env, std::span(reinterpret_cast<unsigned char *>(key.data()), key.size()));
53+
return util::bytes_from_span(env, std::span(reinterpret_cast<unsigned char *>(key.data()), key.size())).release();
5354
});
5455
}
5556

library/src/main/cpp/blinded_key.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionKeyPai
1717
jbyteArray ed25519_secret_key) {
1818
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
1919
const auto [pk, sk] = session::blind_version_key_pair(util::vector_from_bytes(env, ed25519_secret_key));
20-
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
20+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk).get(), util::bytes_from_span(env, sk).get());
2121
});
2222
}
2323
extern "C"
@@ -32,7 +32,7 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionSign(J
3232
session::Platform::android,
3333
timestamp
3434
);
35-
return util::bytes_from_vector(env, bytes);
35+
return util::bytes_from_vector(env, bytes).release();
3636
});
3737
}
3838

@@ -53,7 +53,7 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionSignRe
5353
jni_utils::JavaStringRef(env, path).view(),
5454
body ? std::make_optional(jni_utils::JavaByteArrayRef(env, body).get()) : std::nullopt
5555
);
56-
return util::bytes_from_vector(env, bytes);
56+
return util::bytes_from_vector(env, bytes).release();
5757
});
5858
}
5959

@@ -68,7 +68,7 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15KeyPair(JNI
6868
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
6969
jni_utils::JavaByteArrayRef(env, server_pub_key).get()
7070
);
71-
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
71+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk).get(), util::bytes_from_span(env, sk).get());
7272
});
7373
}
7474

@@ -84,7 +84,7 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15Sign(JNIEnv
8484
jni_utils::JavaStringRef(env, server_pub_key).view(),
8585
jni_utils::JavaByteArrayRef(env, message).get()
8686
);
87-
return util::bytes_from_vector(env, data);
87+
return util::bytes_from_vector(env, data).release();
8888
});
8989
}
9090

@@ -128,9 +128,9 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind25Id(JNIEnv *
128128
jstring session_id,
129129
jstring server_pub_key) {
130130
return jni_utils::run_catching_cxx_exception_or_throws<jstring>(env, [=]() -> jstring {
131-
return util::jstringFromOptional(env, session::blind25_id(
131+
return jni_utils::jstring_from_optional(env, session::blind25_id(
132132
jni_utils::JavaStringRef(env, session_id).view(),
133133
jni_utils::JavaStringRef(env, server_pub_key).view()
134-
));
134+
)).release();
135135
});
136136
}

library/src/main/cpp/config_base.cpp

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,43 @@
22
#include "util.h"
33
#include "jni_utils.h"
44

5+
6+
std::pair<std::string, std::vector<unsigned char>> extractHashAndData(JNIEnv *env, jobject kotlin_pair) {
7+
jni_utils::JavaLocalRef<jclass> pair(env, env->GetObjectClass(kotlin_pair));
8+
jfieldID first = env->GetFieldID(pair.get(), "first", "Ljava/lang/Object;");
9+
jfieldID second = env->GetFieldID(pair.get(), "second", "Ljava/lang/Object;");
10+
auto hash_as_jstring = jni_utils::JavaLocalRef(env, reinterpret_cast<jstring>(env->GetObjectField(kotlin_pair, first)));
11+
auto data_as_jbytes = jni_utils::JavaLocalRef(env, reinterpret_cast<jbyteArray>(env->GetObjectField(kotlin_pair, second)));
12+
13+
return std::make_pair(
14+
std::string(jni_utils::JavaStringRef(env, hash_as_jstring.get()).view()),
15+
jni_utils::JavaByteArrayRef(env, data_as_jbytes.get()).copy()
16+
);
17+
}
18+
19+
struct JavaConfigClassInfo : public jni_utils::JavaClassInfo {
20+
jfieldID pointer_field;
21+
22+
JavaConfigClassInfo(JNIEnv *env, jobject obj)
23+
:JavaClassInfo(env, obj),
24+
pointer_field(env->GetFieldID(java_class, "pointer", "J")) {}
25+
26+
static const JavaConfigClassInfo& get(JNIEnv *env, jobject obj) {
27+
static JavaConfigClassInfo class_info(env, obj);
28+
return class_info;
29+
}
30+
};
31+
32+
session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) {
33+
return reinterpret_cast<session::config::ConfigBase*>(
34+
env->GetLongField(obj, JavaConfigClassInfo::get(env, obj).pointer_field));
35+
}
36+
37+
session::config::ConfigSig* ptrToConfigSig(JNIEnv* env, jobject obj) {
38+
return reinterpret_cast<session::config::ConfigSig*>(
39+
env->GetLongField(obj, JavaConfigClassInfo::get(env, obj).pointer_field));
40+
}
41+
542
extern "C" {
643
JNIEXPORT jboolean JNICALL
744
Java_network_loki_messenger_libsession_1util_ConfigBase_dirty(JNIEnv *env, jobject thiz) {
@@ -33,9 +70,14 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobjec
3370

3471
jobject obsoleteHashes = jni_utils::jstring_list_from_collection(env, to_delete);
3572

36-
jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigPush");
37-
jmethodID methodId = env->GetMethodID(returnObjectClass, "<init>", "(Ljava/util/List;JLjava/util/List;)V");
38-
return env->NewObject(returnObjectClass, methodId, messages, static_cast<jlong>(seq_no), obsoleteHashes);
73+
static jni_utils::BasicJavaClassInfo class_info(
74+
env,
75+
"network/loki/messenger/libsession_util/util/ConfigPush",
76+
"(Ljava/util/List;JLjava/util/List;)V"
77+
);
78+
79+
return env->NewObject(class_info.java_class, class_info.constructor,
80+
messages, static_cast<jlong>(seq_no), obsoleteHashes);
3981
});
4082
}
4183

@@ -49,8 +91,7 @@ JNIEXPORT jbyteArray JNICALL
4991
Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) {
5092
auto config = ptrToConfigBase(env, thiz);
5193
auto dumped = config->dump();
52-
jbyteArray bytes = util::bytes_from_vector(env, dumped);
53-
return bytes;
94+
return util::bytes_from_vector(env, dumped).release();
5495
}
5596

5697
JNIEXPORT jstring JNICALL
@@ -96,34 +137,6 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(
96137

97138
#pragma clang diagnostic pop
98139
}
99-
extern "C"
100-
JNIEXPORT jint JNICALL
101-
Java_network_loki_messenger_libsession_1util_ConfigBase_configNamespace(JNIEnv *env, jobject thiz) {
102-
auto conf = ptrToConfigBase(env, thiz);
103-
return (std::int16_t) conf->storage_namespace();
104-
}
105-
extern "C"
106-
JNIEXPORT jclass JNICALL
107-
Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(JNIEnv *env,
108-
jobject thiz,
109-
jint config_namespace) {
110-
auto user_class = env->FindClass("network/loki/messenger/libsession_util/UserProfile");
111-
auto contact_class = env->FindClass("network/loki/messenger/libsession_util/Contacts");
112-
auto convo_volatile_class = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig");
113-
auto group_list_class = env->FindClass("network/loki/messenger/libsession_util/UserGroupsConfig");
114-
switch (config_namespace) {
115-
case (int)session::config::Namespace::UserProfile:
116-
return user_class;
117-
case (int)session::config::Namespace::Contacts:
118-
return contact_class;
119-
case (int)session::config::Namespace::ConvoInfoVolatile:
120-
return convo_volatile_class;
121-
case (int)session::config::Namespace::UserGroups:
122-
return group_list_class;
123-
default:
124-
return nullptr;
125-
}
126-
}
127140

128141
extern "C"
129142
JNIEXPORT jobject JNICALL

library/src/main/cpp/config_base.h

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,11 @@
11
#ifndef SESSION_ANDROID_CONFIG_BASE_H
22
#define SESSION_ANDROID_CONFIG_BASE_H
33

4-
#include "session/config/base.hpp"
5-
#include "util.h"
6-
#include "jni_utils.h"
7-
#include <jni.h>
8-
#include <string>
9-
#include <vector>
10-
11-
inline session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) {
12-
auto baseClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/ConfigBase"));
13-
jfieldID pointerField = env->GetFieldID(baseClass.get(), "pointer", "J");
14-
return (session::config::ConfigBase*) env->GetLongField(obj, pointerField);
15-
}
4+
#include <session/config/base.hpp>
165

17-
inline std::pair<std::string, std::vector<unsigned char>> extractHashAndData(JNIEnv *env, jobject kotlin_pair) {
18-
auto pair = jni_utils::JavaLocalRef(env, env->FindClass("kotlin/Pair"));
19-
jfieldID first = env->GetFieldID(pair.get(), "first", "Ljava/lang/Object;");
20-
jfieldID second = env->GetFieldID(pair.get(), "second", "Ljava/lang/Object;");
21-
auto hash_as_jstring = jni_utils::JavaLocalRef(env, reinterpret_cast<jstring>(env->GetObjectField(kotlin_pair, first)));
22-
auto data_as_jbytes = jni_utils::JavaLocalRef(env, reinterpret_cast<jbyteArray>(env->GetObjectField(kotlin_pair, second)));
23-
24-
return std::make_pair(
25-
std::string(jni_utils::JavaStringRef(env, hash_as_jstring.get()).view()),
26-
jni_utils::JavaByteArrayRef(env, data_as_jbytes.get()).copy()
27-
);
28-
}
6+
#include <jni.h>
297

30-
inline session::config::ConfigSig* ptrToConfigSig(JNIEnv* env, jobject obj) {
31-
auto sigClass = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/ConfigSig"));
32-
jfieldID pointerField = env->GetFieldID(sigClass.get(), "pointer", "J");
33-
return (session::config::ConfigSig*) env->GetLongField(obj, pointerField);
34-
}
8+
session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj);
9+
session::config::ConfigSig* ptrToConfigSig(JNIEnv* env, jobject obj);
3510

3611
#endif

0 commit comments

Comments
 (0)