Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
493 changes: 493 additions & 0 deletions app/schemas/app.revanced.manager.data.room.AppDatabase/4.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ import kotlin.random.Random

@Database(
entities = [PatchBundleEntity::class, PatchSelection::class, SelectedPatch::class, DownloadedApp::class, InstalledApp::class, AppliedPatch::class, InstalledPatchBundle::class, OptionGroup::class, Option::class, DownloaderEntity::class],
version = 3,
version = 4,
exportSchema = true,
autoMigrations = [
AutoMigration(from = 1, to = 2),
AutoMigration(
from = 2,
to = 3,
spec = AppDatabase.DeleteTrustedDownloaders::class
)
),
AutoMigration(from = 3, to = 4)
]
)
@TypeConverters(Converters::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface PatchBundleDao {
@Query("DELETE FROM patch_bundles WHERE uid = :uid")
suspend fun remove(uid: Int)

@Query("SELECT name, version, auto_update, source FROM patch_bundles WHERE uid = :uid")
@Query("SELECT name, version, auto_update, source, released_at FROM patch_bundles WHERE uid = :uid")
suspend fun getProps(uid: Int): SourceProperties?

@Upsert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ data class PatchBundleEntity(
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "version") val versionHash: String? = null,
@ColumnInfo(name = "source") val source: Source,
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean,
@ColumnInfo(name = "released_at") val releasedAt: Long? = null,
) : SourceManager.DatabaseEntity
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface DownloaderDao {
@Query("DELETE FROM downloaders WHERE uid = :uid")
suspend fun remove(uid: Int)

@Query("SELECT name, version, auto_update, source FROM downloaders WHERE uid = :uid")
@Query("SELECT name, version, auto_update, source, released_at FROM downloaders WHERE uid = :uid")
suspend fun getProps(uid: Int): SourceProperties?

@Upsert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ data class DownloaderEntity(
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "version") val versionHash: String? = null,
@ColumnInfo(name = "source") val source: Source,
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean,
@ColumnInfo(name = "released_at") val releasedAt: Long? = null
) : SourceManager.DatabaseEntity
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ data class SourceProperties(
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "version") val versionHash: String? = null,
@ColumnInfo(name = "source") val source: Source,
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean
@ColumnInfo(name = "auto_update") val autoUpdate: Boolean,
@ColumnInfo(name = "released_at") val releasedAt: Long? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.withContext
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.io.File
Expand Down Expand Up @@ -114,7 +117,12 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
val newName = src.loaded?.let(::realNameOf).takeIf { it != src.name }
?: return@syncName

updateDb(uid) { it.copy(name = newName) }
updateDb(uid) {
it.copy(
name = newName,
releasedAt = (src as? RemoteSource)?.releasedAt?.toEpochMillis()
)
}
sources[uid] = src.copy(name = newName)
}

Expand All @@ -141,7 +149,7 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
private suspend fun createEntity(
name: String,
source: SourceInfo,
autoUpdate: Boolean = false
autoUpdate: Boolean = false,
) =
entityFromProps(
uid = generateUid(),
Expand All @@ -150,6 +158,7 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
versionHash = null,
source = source,
autoUpdate = autoUpdate,
releasedAt = null,
)
).also {
dbUpsert(it)
Expand All @@ -172,6 +181,7 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
versionHash = new.versionHash,
source = new.source,
autoUpdate = new.autoUpdate,
releasedAt = new.releasedAt,
)
)
)
Expand Down Expand Up @@ -238,7 +248,7 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
this@SourceManager.store.state.value.sources.values.filterIsInstance<APISource<LOADED>>()
.forEach { src ->
with(src) { deleteLocalFile() }
updateDb(src.uid) { it.copy(versionHash = null) }
updateDb(src.uid) { it.copy(versionHash = null, releasedAt = null) }
}

doReload(state)
Expand Down Expand Up @@ -308,15 +318,15 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
async update@{
Log.d(tag, "Updating: ${it.name}")

val newVersion = it.runCatching {
val updateResult = it.runCatching {
when {
redownload -> downloadLatest()
checkOnly -> getUpdateInfo()?.version
checkOnly -> getUpdateInfo()?.let { info -> RemoteSource.UpdateResult(info.version, info.createdAt) }
else -> update()
} ?: return@update null
}

it to newVersion
it to updateResult
}
}
.awaitAll()
Expand All @@ -332,15 +342,19 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(

var hasErrors = false
results.forEach { (src, result) ->
result.getOrNull()?.let { newVersionHash ->
result.getOrNull()?.let { updateResult ->
if (checkOnly) {
outdated.add(src.uid)
return@let
}

val name = src.loaded?.let(::realNameOf) ?: src.name
updateDb(src.uid) {
it.copy(versionHash = newVersionHash, name = name)
it.copy(
versionHash = updateResult.versionHash,
name = name,
releasedAt = updateResult.releasedAt.toEpochMillis()
)
}
}
result.exceptionOrNull()?.let {
Expand Down Expand Up @@ -378,4 +392,6 @@ abstract class SourceManager<DB : SourceManager.DatabaseEntity, LOADED, OUTPUT>(
interface DatabaseEntity {
val uid: Int
}
}
}

private fun LocalDateTime.toEpochMillis() = toInstant(TimeZone.UTC).toEpochMilliseconds()
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import app.revanced.manager.network.downloader.DownloaderPackage
import app.revanced.manager.util.PM
import dalvik.system.PathClassLoader
import kotlinx.coroutines.flow.map
import kotlinx.datetime.toLocalDateTime
import java.io.File
import java.lang.ref.WeakReference
import java.lang.reflect.Modifier
import kotlin.time.Instant
import app.revanced.manager.data.room.sources.Source as SourceInfo

@OptIn(DownloaderHostApi::class)
Expand Down Expand Up @@ -61,14 +63,20 @@ class DownloaderRepository(
override fun loadEntity(entity: DownloaderEntity): Source<DownloaderPackage> = with(entity) {
val file = directoryOf(uid).resolve("downloader.jar")
val actualName =
entity.name.ifEmpty { app.getString(if (uid == 0) R.string.auto_updates_dialog_downloaders else R.string.source_name_fallback) }
name.ifEmpty { app.getString(if (uid == 0) R.string.auto_updates_dialog_downloaders else R.string.source_name_fallback) }

val releasedAt = entity.releasedAt?.let {
Instant.fromEpochMilliseconds(it)
.toLocalDateTime(kotlinx.datetime.TimeZone.UTC)
}

return when (source) {
is SourceInfo.Local -> LocalSource(actualName, uid, null, file, loader)
is SourceInfo.API -> APISource(
actualName,
uid,
versionHash,
releasedAt,
null,
file,
SourceInfo.API.SENTINEL,
Expand All @@ -80,6 +88,7 @@ class DownloaderRepository(
actualName,
uid,
versionHash,
releasedAt,
null,
file,
source.url.toString(),
Expand All @@ -97,7 +106,8 @@ class DownloaderRepository(
name = props.name,
versionHash = props.versionHash,
source = props.source,
autoUpdate = props.autoUpdate
autoUpdate = props.autoUpdate,
releasedAt = props.releasedAt
)

override fun realNameOf(loaded: DownloaderPackage) = loaded.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import app.revanced.manager.domain.sources.LocalPatchBundle
import app.revanced.manager.domain.sources.PatchBundleSource
import app.revanced.manager.domain.manager.SourceManager
import app.revanced.manager.domain.sources.Loader
import app.revanced.manager.domain.sources.RemotePatchBundle
import app.revanced.manager.domain.sources.Source
import app.revanced.manager.patcher.patch.PatchInfo
import app.revanced.manager.patcher.patch.PatchBundle
Expand All @@ -27,9 +28,13 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runInterruptible
import kotlinx.coroutines.withContext
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import java.io.File
import kotlin.collections.map
import kotlin.text.ifEmpty
import kotlin.time.Instant

private typealias Info = PersistentMap<Int, PatchBundleInfo.Global>

Expand Down Expand Up @@ -58,12 +63,18 @@ class PatchBundleRepository(
val actualName =
entity.name.ifEmpty { app.getString(if (uid == 0) R.string.patches_name_default else R.string.source_name_fallback) }

val releasedAt = entity.releasedAt?.let {
Instant.fromEpochMilliseconds(it)
.toLocalDateTime(TimeZone.UTC)
}

return when (source) {
is SourceInfo.Local -> LocalPatchBundle(actualName, uid, null, file, PatchBundleLoader)
is SourceInfo.API -> APIPatchBundle(
actualName,
uid,
versionHash,
releasedAt,
null,
file,
SourceInfo.API.SENTINEL,
Expand All @@ -75,6 +86,7 @@ class PatchBundleRepository(
actualName,
uid,
versionHash,
releasedAt,
null,
file,
source.url.toString(),
Expand All @@ -92,7 +104,8 @@ class PatchBundleRepository(
name = props.name,
versionHash = props.versionHash,
source = props.source,
autoUpdate = props.autoUpdate
autoUpdate = props.autoUpdate,
releasedAt = props.releasedAt
)

override fun realNameOf(loaded: PatchBundle) = loaded.manifestAttributes?.name
Expand Down Expand Up @@ -173,6 +186,7 @@ class PatchBundleRepository(
this[src.uid] = PatchBundleInfo.Global(
src.name,
bundle.manifestAttributes?.version,
(src as? RemotePatchBundle)?.releasedAt,
src.uid,
result.getOrThrow().toList()
)
Expand Down
Loading
Loading