Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Verified Commit 7ebe73b3 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

refactor: split network modules into smaller modules

No more complaints from detekt about TooManyFunctions!
parent 13b79f06
Loading
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.data.cleanapk

import android.os.Build
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.BuildConfig
import java.util.Locale
import javax.inject.Singleton
import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor

@Module
@InstallIn(SingletonComponent::class)
class InterceptorModule {

    companion object {
        private const val HEADER_USER_AGENT = "User-Agent"
        private const val HEADER_ACCEPT_LANGUAGE = "Accept-Language"
    }

    @Singleton
    @Provides
    fun provideInterceptor(): Interceptor {
        return Interceptor { chain ->
            val builder =
                chain
                    .request()
                    .newBuilder()
                    .header(
                        HEADER_USER_AGENT,
                        "Dalvik/2.1.0 (Linux; U; Android ${Build.VERSION.RELEASE};)")
                    .header(HEADER_ACCEPT_LANGUAGE, Locale.getDefault().language)

            val response = chain.proceed(builder.build())

            return@Interceptor response
        }
    }

    @Provides
    @Singleton
    fun provideLoggingInterceptor(): HttpLoggingInterceptor {
        val interceptor = HttpLoggingInterceptor()

        interceptor.level =
            when {
                BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY
                else -> HttpLoggingInterceptor.Level.NONE
            }

        return interceptor
    }
}
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021-2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.data.cleanapk

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.data.cleanapk.data.app.Application
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.converter.jackson.JacksonConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    private const val HTTP_TIMEOUT_IN_SECOND = 10L

    @Singleton
    @Provides
    fun getMoshi(): Moshi {
        return Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
    }

    @Singleton
    @Provides
    @Named("gsonCustomAdapter")
    fun getGson(): Gson {
        return GsonBuilder()
            .registerTypeAdapter(Application::class.java, ApplicationDeserializer())
            .enableComplexMapKeySerialization()
            .create()
    }

    /**
     * Used in [RetrofitApiModule.provideFdroidApi].
     * Reference: https://stackoverflow.com/a/69859687
     */
    @Singleton
    @Provides
    @Named("yamlFactory")
    fun getYamlFactory(): JacksonConverterFactory {
        return JacksonConverterFactory.create(ObjectMapper(YAMLFactory()))
    }

    @Singleton
    @Provides
    fun provideOkHttpClient(
        cache: Cache,
        interceptor: Interceptor,
        httpLoggingInterceptor: HttpLoggingInterceptor
    ): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .addInterceptor(httpLoggingInterceptor) // Put logging interceptor last
            .callTimeout(HTTP_TIMEOUT_IN_SECOND, TimeUnit.SECONDS)
            .cache(cache)
            .build()
    }
}
+115 −205
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021-2024 MURENA SAS
 * Copyright (C) 2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -18,44 +18,27 @@

package foundation.e.apps.data.cleanapk

import android.os.Build
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.BuildConfig
import foundation.e.apps.data.cleanapk.data.app.Application
import foundation.e.apps.data.cleanapk.NetworkModule.getYamlFactory
import foundation.e.apps.data.ecloud.EcloudApiInterface
import foundation.e.apps.data.exodus.ExodusTrackerApi
import foundation.e.apps.data.fdroid.FdroidApiInterface
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.jackson.JacksonConverterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.Locale
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton


@Module
@InstallIn(SingletonComponent::class)
object RetrofitModule {

    private const val HTTP_TIMEOUT_IN_SECOND = 10L
    private const val HEADER_USER_AGENT = "User-Agent"
    private const val HEADER_ACCEPT_LANGUAGE = "Accept-Language"

class RetrofitApiModule {
    /**
     * Provides an instance of Retrofit to work with CleanAPK API
     * @return instance of [CleanApkRetrofit]
@@ -129,77 +112,4 @@ object RetrofitModule {
            .build()
            .create(EcloudApiInterface::class.java)
    }

    @Singleton
    @Provides
    fun getMoshi(): Moshi {
        return Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
    }

    @Singleton
    @Provides
    @Named("gsonCustomAdapter")
    fun getGson(): Gson {
        return GsonBuilder()
            .registerTypeAdapter(Application::class.java, ApplicationDeserializer())
            .enableComplexMapKeySerialization()
            .create()
    }

    /**
     * Used in above [provideFdroidApi].
     * Reference: https://stackoverflow.com/a/69859687
     */
    @Singleton
    @Provides
    @Named("yamlFactory")
    fun getYamlFactory(): JacksonConverterFactory {
        return JacksonConverterFactory.create(ObjectMapper(YAMLFactory()))
    }

    @Singleton
    @Provides
    fun provideInterceptor(): Interceptor {
        return Interceptor { chain ->
            val builder = chain.request().newBuilder()
                .header(
                    HEADER_USER_AGENT, "Dalvik/2.1.0 (Linux; U; Android ${Build.VERSION.RELEASE};)"
                )
                .header(HEADER_ACCEPT_LANGUAGE, Locale.getDefault().language)

            val response = chain.proceed(builder.build())

            return@Interceptor response
        }
    }

    @Provides
    @Singleton
    fun provideLoggingInterceptor(): HttpLoggingInterceptor {
        val interceptor = HttpLoggingInterceptor()

        interceptor.level = when {
            BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY
            else -> HttpLoggingInterceptor.Level.NONE
        }

        return interceptor
    }

    @Singleton
    @Provides
    fun provideOkHttpClient(
        cache: Cache,
        interceptor: Interceptor,
        httpLoggingInterceptor: HttpLoggingInterceptor
    ): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .addInterceptor(httpLoggingInterceptor) // Put logging interceptor last
            .callTimeout(HTTP_TIMEOUT_IN_SECOND, TimeUnit.SECONDS)
            .cache(cache)
            .build()
    }
}
+19 −1
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.data.fdroid

import foundation.e.apps.data.fdroid.models.FdroidApiModel
@@ -7,7 +25,7 @@ import retrofit2.http.Path

/**
 * Interface for retrofit calls.
 * Created from [foundation.e.apps.data.cleanapk.RetrofitModule.provideFdroidApi].
 * Created from [foundation.e.apps.data.cleanapk.RetrofitApiModule.provideFdroidApi].
 */
interface FdroidApiInterface {