Loading app/src/main/java/foundation/e/apps/data/application/data/Application.kt +3 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,9 @@ data class Application( * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 */ var filterLevel: FilterLevel = FilterLevel.UNKNOWN, var isGplayReplaced: Boolean = false var isGplayReplaced: Boolean = false, var isSystemApp: Boolean = false, ) { fun updateType() { this.type = if (this.is_pwa) Type.PWA else Type.NATIVE Loading app/src/main/java/foundation/e/apps/data/cleanapk/RetrofitModule.kt +15 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import foundation.e.apps.data.cleanapk.data.app.Application 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.SystemAppsUpdatesApi import okhttp3.Cache import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaTypeOrNull Loading Loading @@ -120,6 +121,20 @@ object RetrofitModule { .create(FdroidApiInterface::class.java) } @Singleton @Provides fun provideSystemAppsUpdatesApi( okHttpClient: OkHttpClient, moshi: Moshi, ): SystemAppsUpdatesApi { return Retrofit.Builder() .baseUrl(SystemAppsUpdatesApi.BASE_URL) .client(okHttpClient) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() .create(SystemAppsUpdatesApi::class.java) } @Singleton @Provides fun provideEcloudApi(okHttpClient: OkHttpClient, moshi: Moshi): EcloudApiInterface { Loading app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesApi.kt 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab import foundation.e.apps.data.gitlab.models.EligibleSystemApps import foundation.e.apps.data.gitlab.models.UpdateDefinition import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Path interface SystemAppsUpdatesApi { companion object { const val BASE_URL = "https://gitlab.e.foundation/e/os/update-assets/-/raw/main/" } @GET("eligible_apps.json") suspend fun getAllEligibleApps(): Response<List<EligibleSystemApps>> @GET("{packageName}/{releaseType}.json") suspend fun getSystemAppUpdateInfo( @Path("packageName") packageName: String, @Path("releaseType") releaseType: String, ): Response<UpdateDefinition> } No newline at end of file app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab import foundation.e.apps.data.application.ApplicationApi import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.gitlab.models.EligibleSystemApps import foundation.e.apps.data.gitlab.models.toApplication import javax.inject.Inject import javax.inject.Singleton import timber.log.Timber @Singleton class SystemAppsUpdatesRepository @Inject constructor( private val systemAppsUpdatesApi: SystemAppsUpdatesApi, private val applicationApi: ApplicationApi, ) { suspend fun getAllEligibleApps(): List<EligibleSystemApps>? { val response = systemAppsUpdatesApi.getAllEligibleApps() if (!response.isSuccessful) return emptyList() return response.body() } suspend fun getSystemAppUpdateInfo( packageName: String, releaseType: String, sdkLevel: Int, device: String, ): Application? { val response = systemAppsUpdatesApi.getSystemAppUpdateInfo(packageName, releaseType) if (!response.isSuccessful) { Timber.e("Failed to fetch system app update definition for: $packageName, $releaseType") return null } val updateDef = response.body() return when { updateDef == null -> { Timber.e("Null update definition: $packageName, $releaseType") null } !updateDef.eligibleAndroidPlatforms.contains(sdkLevel) -> { Timber.e("Ineligible sdk level: $packageName, $sdkLevel") null } updateDef.blacklistedDevices.contains(device) -> { Timber.e("blacklisted device: $packageName, $device") null } updateDef.blacklistedDevices.contains("${device}@${sdkLevel}") -> { // In case a device on a specific android version is blacklisted. // Eg: "redfin@31" would mean Pixel 5 on Android 12 cannot receive this update. Timber.e("blacklisted device: $packageName, ${device}@${sdkLevel}") null } else -> { val app = updateDef.toApplication() app.status = applicationApi.getFusedAppInstallationStatus(app) app } } } } No newline at end of file app/src/main/java/foundation/e/apps/data/gitlab/models/EligibleSystemApps.kt 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.squareup.moshi.Json @JsonIgnoreProperties(ignoreUnknown = true) data class EligibleSystemApps( @Json(name = "package_name") val packageName: String, @Json(name = "release_types") val releaseTypes: List<String>, ) Loading
app/src/main/java/foundation/e/apps/data/application/data/Application.kt +3 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,9 @@ data class Application( * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5720 */ var filterLevel: FilterLevel = FilterLevel.UNKNOWN, var isGplayReplaced: Boolean = false var isGplayReplaced: Boolean = false, var isSystemApp: Boolean = false, ) { fun updateType() { this.type = if (this.is_pwa) Type.PWA else Type.NATIVE Loading
app/src/main/java/foundation/e/apps/data/cleanapk/RetrofitModule.kt +15 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import foundation.e.apps.data.cleanapk.data.app.Application 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.SystemAppsUpdatesApi import okhttp3.Cache import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaTypeOrNull Loading Loading @@ -120,6 +121,20 @@ object RetrofitModule { .create(FdroidApiInterface::class.java) } @Singleton @Provides fun provideSystemAppsUpdatesApi( okHttpClient: OkHttpClient, moshi: Moshi, ): SystemAppsUpdatesApi { return Retrofit.Builder() .baseUrl(SystemAppsUpdatesApi.BASE_URL) .client(okHttpClient) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() .create(SystemAppsUpdatesApi::class.java) } @Singleton @Provides fun provideEcloudApi(okHttpClient: OkHttpClient, moshi: Moshi): EcloudApiInterface { Loading
app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesApi.kt 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab import foundation.e.apps.data.gitlab.models.EligibleSystemApps import foundation.e.apps.data.gitlab.models.UpdateDefinition import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Path interface SystemAppsUpdatesApi { companion object { const val BASE_URL = "https://gitlab.e.foundation/e/os/update-assets/-/raw/main/" } @GET("eligible_apps.json") suspend fun getAllEligibleApps(): Response<List<EligibleSystemApps>> @GET("{packageName}/{releaseType}.json") suspend fun getSystemAppUpdateInfo( @Path("packageName") packageName: String, @Path("releaseType") releaseType: String, ): Response<UpdateDefinition> } No newline at end of file
app/src/main/java/foundation/e/apps/data/gitlab/SystemAppsUpdatesRepository.kt 0 → 100644 +81 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab import foundation.e.apps.data.application.ApplicationApi import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.gitlab.models.EligibleSystemApps import foundation.e.apps.data.gitlab.models.toApplication import javax.inject.Inject import javax.inject.Singleton import timber.log.Timber @Singleton class SystemAppsUpdatesRepository @Inject constructor( private val systemAppsUpdatesApi: SystemAppsUpdatesApi, private val applicationApi: ApplicationApi, ) { suspend fun getAllEligibleApps(): List<EligibleSystemApps>? { val response = systemAppsUpdatesApi.getAllEligibleApps() if (!response.isSuccessful) return emptyList() return response.body() } suspend fun getSystemAppUpdateInfo( packageName: String, releaseType: String, sdkLevel: Int, device: String, ): Application? { val response = systemAppsUpdatesApi.getSystemAppUpdateInfo(packageName, releaseType) if (!response.isSuccessful) { Timber.e("Failed to fetch system app update definition for: $packageName, $releaseType") return null } val updateDef = response.body() return when { updateDef == null -> { Timber.e("Null update definition: $packageName, $releaseType") null } !updateDef.eligibleAndroidPlatforms.contains(sdkLevel) -> { Timber.e("Ineligible sdk level: $packageName, $sdkLevel") null } updateDef.blacklistedDevices.contains(device) -> { Timber.e("blacklisted device: $packageName, $device") null } updateDef.blacklistedDevices.contains("${device}@${sdkLevel}") -> { // In case a device on a specific android version is blacklisted. // Eg: "redfin@31" would mean Pixel 5 on Android 12 cannot receive this update. Timber.e("blacklisted device: $packageName, ${device}@${sdkLevel}") null } else -> { val app = updateDef.toApplication() app.status = applicationApi.getFusedAppInstallationStatus(app) app } } } } No newline at end of file
app/src/main/java/foundation/e/apps/data/gitlab/models/EligibleSystemApps.kt 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019-2023 E FOUNDATION * * 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.gitlab.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.squareup.moshi.Json @JsonIgnoreProperties(ignoreUnknown = true) data class EligibleSystemApps( @Json(name = "package_name") val packageName: String, @Json(name = "release_types") val releaseTypes: List<String>, )