Skip to content

Commit

Permalink
fix: bundles not loading on Android 14
Browse files Browse the repository at this point in the history
  • Loading branch information
Axelen123 committed Oct 20, 2023
1 parent 4b12ae1 commit 18cfb56
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import java.nio.file.StandardCopyOption
class LocalPatchBundle(name: String, id: Int, directory: File) : PatchBundleSource(name, id, directory) {
suspend fun replace(patches: InputStream? = null, integrations: InputStream? = null) {
withContext(Dispatchers.IO) {
patches?.let {
Files.copy(it, patchesFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
patches?.let { inputStream ->
patchBundleOutputStream().use { outputStream ->
inputStream.copyTo(outputStream)
}
}
integrations?.let {
Files.copy(it, this@LocalPatchBundle.integrationsFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flowOf
import java.io.File
import java.io.OutputStream

/**
* A [PatchBundle] source.
Expand All @@ -23,6 +24,16 @@ sealed class PatchBundleSource(val name: String, val uid: Int, directory: File)
*/
fun hasInstalled() = patchesFile.exists()

protected fun patchBundleOutputStream(): OutputStream = with(patchesFile) {
// Android 14+ requires dex containers to be readonly.
try {
setWritable(true, true)
outputStream()
} finally {
setReadOnly()
}
}

private fun load(): State {
if (!hasInstalled()) return State.Missing

Expand All @@ -40,7 +51,7 @@ sealed class PatchBundleSource(val name: String, val uid: Int, directory: File)
sealed interface State {
fun patchBundleOrNull(): PatchBundle? = null

object Missing : State
data object Missing : State
data class Failed(val throwable: Throwable) : State
data class Loaded(val bundle: PatchBundle) : State {
override fun patchBundleOrNull() = bundle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@ sealed class RemotePatchBundle(name: String, id: Int, directory: File, val endpo
private suspend fun download(info: BundleInfo) = withContext(Dispatchers.IO) {
val (patches, integrations) = info
coroutineScope {
mapOf(
patches.url to patchesFile,
integrations.url to integrationsFile
).forEach { (asset, file) ->
launch {
http.download(file) {
url(asset)
launch {
patchBundleOutputStream().use {
http.streamTo(it) {
url(patches.url)
}
}
}

launch {
http.download(integrationsFile) {
url(integrations.url)
}
}
}

saveVersion(patches.version, integrations.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.isNotEmpty
import io.ktor.utils.io.core.readBytes
import it.skrape.core.htmlDocument
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import java.io.File
import java.io.OutputStream

/**
* @author Aliucord Authors, DiamondMiner88
Expand Down Expand Up @@ -49,7 +52,10 @@ class HttpService(
null
}

Log.e(tag, "Failed to fetch: API error, http status: ${response.status}, body: $body")
Log.e(
tag,
"Failed to fetch: API error, http status: ${response.status}, body: $body"
)
APIResponse.Error(APIError(response.status, body))
}
} catch (t: Throwable) {
Expand All @@ -59,20 +65,19 @@ class HttpService(
return response
}

suspend fun download(
saveLocation: File,
suspend fun streamTo(
outputStream: OutputStream,
builder: HttpRequestBuilder.() -> Unit
) {
http.prepareGet(builder).execute { httpResponse ->
if (httpResponse.status.isSuccess()) {

saveLocation.outputStream().use { stream ->
val channel: ByteReadChannel = httpResponse.body()
val channel: ByteReadChannel = httpResponse.body()
withContext(Dispatchers.IO) {
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
while (packet.isNotEmpty) {
val bytes = packet.readBytes()
stream.write(bytes)
outputStream.write(bytes)
}
}
}
Expand All @@ -83,6 +88,11 @@ class HttpService(
}
}

suspend fun download(
saveLocation: File,
builder: HttpRequestBuilder.() -> Unit
) = saveLocation.outputStream().use { streamTo(it, builder) }

suspend fun getHtml(builder: HttpRequestBuilder.() -> Unit) = htmlDocument(
html = http.get(builder).bodyAsText()
)
Expand Down

0 comments on commit 18cfb56

Please sign in to comment.