diff --git a/app/src/main/java/foundation/e/apps/data/gitlab/ReleaseInfoApi.kt b/app/src/main/java/foundation/e/apps/data/gitlab/ReleaseInfoApi.kt new file mode 100644 index 0000000000000000000000000000000000000000..4b2a3fbf76cfc139ae6e045c1113a6b84c06fcdc --- /dev/null +++ b/app/src/main/java/foundation/e/apps/data/gitlab/ReleaseInfoApi.kt @@ -0,0 +1,37 @@ +/* + * 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 . + */ + +package foundation.e.apps.data.gitlab + +import foundation.e.apps.data.gitlab.models.ReleaseInfo +import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path + +interface ReleaseInfoApi { + + companion object { + const val BASE_URL = + "${SystemAppDefinitionApi.BASE_URL}/api/v4/projects/" + } + + @GET("{projectId}/releases") + suspend fun getReleases( + @Path("projectId") projectId: Int, + ): Response> + +} diff --git a/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppDefinitionApi.kt b/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppDefinitionApi.kt index b5f7d48b46434f420793264bada8983814335f88..3800d295b54781d1cb073fe04797fd64c6320d5f 100644 --- a/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppDefinitionApi.kt +++ b/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppDefinitionApi.kt @@ -20,19 +20,18 @@ package foundation.e.apps.data.gitlab import foundation.e.apps.data.gitlab.models.SystemAppInfo import retrofit2.Response import retrofit2.http.GET -import retrofit2.http.Path +import retrofit2.http.Url interface SystemAppDefinitionApi { companion object { const val BASE_URL = - "https://gitlab.e.foundation/api/v4/projects/" + "https://gitlab.e.foundation/" } - @GET("{projectId}/releases/permalink/latest/downloads/json/{releaseType}.json") + @GET suspend fun getSystemAppUpdateInfo( - @Path("projectId") projectId: Int, - @Path("releaseType") releaseType: String, + @Url detailsUrl: String, ): Response } diff --git a/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt b/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt index 53a642dec03164f8c3b2d2b80db9f90a84483213..c928cface437b5237011967bfef8b312da418e4d 100644 --- a/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt @@ -22,6 +22,7 @@ import android.os.Build import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.data.application.ApplicationDataManager import foundation.e.apps.data.application.data.Application +import foundation.e.apps.data.gitlab.models.OsReleaseType import foundation.e.apps.data.gitlab.models.SystemAppInfo import foundation.e.apps.data.gitlab.models.SystemAppProject import foundation.e.apps.data.gitlab.models.toApplication @@ -39,6 +40,7 @@ class SystemAppsUpdatesRepository @Inject constructor( private val systemAppDefinitionApi: SystemAppDefinitionApi, private val applicationDataManager: ApplicationDataManager, private val appLoungePackageManager: AppLoungePackageManager, + private val releaseInfoApi: ReleaseInfoApi, ) { private val systemAppProjectList = mutableListOf() @@ -93,9 +95,34 @@ class SystemAppsUpdatesRepository @Inject constructor( } } + private suspend fun getReleaseDetailsUrl( + projectId: Int, + releaseType: OsReleaseType, + ): String? { + val releaseResponse = releaseInfoApi.getReleases(projectId) + val releases = releaseResponse.body() + + if (!releaseResponse.isSuccessful || releases == null) { + Timber.e("Failed to fetch releases for project id - $projectId") + return null + } + + val sortedReleases = releases.sortedByDescending { + it.releasedAt + } + + for (release in sortedReleases) { + release.getAssetWebLink("${releaseType}.json")?.run { + return this.removePrefix(SystemAppDefinitionApi.BASE_URL) + } + } + + return null + } + private suspend fun getSystemAppUpdateInfo( packageName: String, - releaseType: String, + releaseType: OsReleaseType, sdkLevel: Int, device: String, ): Application? { @@ -103,7 +130,9 @@ class SystemAppsUpdatesRepository @Inject constructor( val projectId = systemAppProjectList.find { it.packageName == packageName }?.projectId ?: return null - val response = systemAppDefinitionApi.getSystemAppUpdateInfo(projectId, releaseType) + val detailsUrl = getReleaseDetailsUrl(projectId, releaseType) ?: return null + + val response = systemAppDefinitionApi.getSystemAppUpdateInfo(detailsUrl) val systemAppInfo = response.body() return if (systemAppInfo == null) { @@ -129,8 +158,10 @@ class SystemAppsUpdatesRepository @Inject constructor( return SystemInfoProvider.getSystemProperty(SystemInfoProvider.KEY_LINEAGE_DEVICE) ?: "" } - private fun getSystemReleaseType(): String { - return SystemInfoProvider.getSystemProperty(SystemInfoProvider.KEY_LINEAGE_RELEASE_TYPE) ?: "" + private fun getSystemReleaseType(): OsReleaseType { + return SystemInfoProvider.getSystemProperty(SystemInfoProvider.KEY_LINEAGE_RELEASE_TYPE).let { + OsReleaseType.get(it) + } } suspend fun getSystemUpdates(): List { diff --git a/app/src/main/java/foundation/e/apps/data/gitlab/models/ReleaseInfo.kt b/app/src/main/java/foundation/e/apps/data/gitlab/models/ReleaseInfo.kt new file mode 100644 index 0000000000000000000000000000000000000000..6284fe92ad511ae354ddbf62eece5432f4bd9159 --- /dev/null +++ b/app/src/main/java/foundation/e/apps/data/gitlab/models/ReleaseInfo.kt @@ -0,0 +1,59 @@ +/* + * 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 . + */ + +package foundation.e.apps.data.gitlab.models + +import com.squareup.moshi.Json + +data class ReleaseInfo( + val name: String, + @Json(name = "released_at") + val releasedAt: String, + val assets: ReleaseAssets, +) { + fun getAssetWebLink(assetName: String): String? { + return assets.links.firstOrNull { it.name == assetName }?.directAssetUrl + } +} + +data class ReleaseAssets( + val links: List, +) + +data class ReleaseLinks( + val name: String, + @Json(name = "direct_asset_url") + val directAssetUrl: String +) + +enum class OsReleaseType { + TEST, + COMMUNITY, + STABLE, + UNKNOWN, + ; + + override fun toString(): String { + return this.name.lowercase() + } + + companion object { + fun get(value: String?): OsReleaseType { + return OsReleaseType.values().find { it.name == value?.trim()?.uppercase() } ?: UNKNOWN + } + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/apps/di/network/RetrofitApiModule.kt b/app/src/main/java/foundation/e/apps/di/network/RetrofitApiModule.kt index 56914f6165379009bf6340177fd04025904b5d25..136add81108330203abad2575d74ecde0c3e9e46 100644 --- a/app/src/main/java/foundation/e/apps/di/network/RetrofitApiModule.kt +++ b/app/src/main/java/foundation/e/apps/di/network/RetrofitApiModule.kt @@ -29,6 +29,7 @@ import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.ecloud.EcloudApiInterface import foundation.e.apps.data.exodus.ExodusTrackerApi import foundation.e.apps.data.fdroid.FdroidApiInterface +import foundation.e.apps.data.gitlab.ReleaseInfoApi import foundation.e.apps.data.gitlab.UpdatableSystemAppsApi import foundation.e.apps.data.gitlab.SystemAppDefinitionApi import foundation.e.apps.data.parentalcontrol.fdroid.FDroidMonitorApi @@ -147,6 +148,20 @@ class RetrofitApiModule { .create(UpdatableSystemAppsApi::class.java) } + @Singleton + @Provides + fun provideReleaseInfoApi( + okHttpClient: OkHttpClient, + moshi: Moshi, + ): ReleaseInfoApi { + return Retrofit.Builder() + .baseUrl(ReleaseInfoApi.BASE_URL) + .client(okHttpClient) + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .build() + .create(ReleaseInfoApi::class.java) + } + @Singleton @Provides fun provideSystemAppDefinitionApi(