diff --git a/android/app/src/main/java/com/epfl/dedis/hbt/di/HttpModule.kt b/android/app/src/main/java/com/epfl/dedis/hbt/di/HttpModule.kt new file mode 100644 index 00000000..f8a7a36f --- /dev/null +++ b/android/app/src/main/java/com/epfl/dedis/hbt/di/HttpModule.kt @@ -0,0 +1,19 @@ +package com.epfl.dedis.hbt.di + +import android.content.Context +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import org.chromium.net.CronetEngine +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class HttpModule { + @Provides + @Singleton + fun provideCronet(@ApplicationContext context: Context): CronetEngine = + CronetEngine.Builder(context).build() +} diff --git a/android/app/src/main/java/com/epfl/dedis/hbt/service/http/HttpService.kt b/android/app/src/main/java/com/epfl/dedis/hbt/service/http/HttpService.kt new file mode 100644 index 00000000..8e5e237a --- /dev/null +++ b/android/app/src/main/java/com/epfl/dedis/hbt/service/http/HttpService.kt @@ -0,0 +1,68 @@ +package com.epfl.dedis.hbt.service.http + +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.subjects.SingleSubject +import org.chromium.net.CronetEngine +import org.chromium.net.CronetException +import org.chromium.net.UrlRequest +import org.chromium.net.UrlResponseInfo +import java.nio.ByteBuffer +import java.util.concurrent.Executors +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class HttpService @Inject constructor(private val engine: CronetEngine) { + + private val executor = Executors.newSingleThreadExecutor() + + fun get(url: String): Single { + val single = SingleSubject.create() + + engine.newUrlRequestBuilder(url, Callback(single), executor) + .setHttpMethod("GET") + .build() + .start() + + return single + } + + private class Callback(private val single: SingleSubject) : UrlRequest.Callback() { + override fun onRedirectReceived( + request: UrlRequest?, + info: UrlResponseInfo?, + newLocationUrl: String? + ) { + request?.followRedirect() + } + + override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) { + request?.read(ByteBuffer.allocateDirect(BYTE_BUFFER_CAPACITY_BYTES)) + } + + override fun onReadCompleted( + request: UrlRequest?, + info: UrlResponseInfo?, + byteBuffer: ByteBuffer? + ) { + byteBuffer?.clear() + request?.read(byteBuffer) + } + + override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) { + single.onSuccess(info?.httpStatusCode.toString()) + } + + override fun onFailed( + request: UrlRequest?, + info: UrlResponseInfo?, + error: CronetException? + ) { + single.onError(error ?: Exception("Unknown error")) + } + + companion object { + private const val BYTE_BUFFER_CAPACITY_BYTES = 100 * 1024 + } + } +} \ No newline at end of file