mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-07-28 16:13:38 +00:00
app: use github api to check updates
This commit is contained in:
parent
a4b8c5e46b
commit
76962f965e
@ -14,7 +14,8 @@ class ManagerInstallDialog : MarkDownDialog() {
|
||||
private val svc get() = ServiceLocator.networkService
|
||||
|
||||
override suspend fun getMarkdownText(): String {
|
||||
val text = svc.fetchString(Info.remote.magisk.note)
|
||||
val str = Info.remote.magisk.note
|
||||
val text = if (str.startsWith("http", true)) svc.fetchString(str) else str
|
||||
// Cache the changelog
|
||||
AppContext.cacheDir.listFiles { _, name -> name.endsWith(".md") }.orEmpty().forEach {
|
||||
it.delete()
|
||||
|
@ -71,11 +71,14 @@ class InstallViewModel(svc: NetworkService, markwon: Markwon) : BaseViewModel()
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val file = File(AppContext.cacheDir, "${BuildConfig.APP_VERSION_CODE}.md")
|
||||
val note = Info.remote.magisk.note
|
||||
val text = when {
|
||||
file.exists() -> file.readText()
|
||||
Const.Url.CHANGELOG_URL.isEmpty() -> ""
|
||||
Const.APP_IS_CANARY && note.isEmpty() -> ""
|
||||
Const.APP_IS_CANARY && !note.startsWith("http", true) -> note
|
||||
else -> {
|
||||
val str = svc.fetchString(Const.Url.CHANGELOG_URL)
|
||||
val url = if (Const.APP_IS_CANARY) note else Const.Url.CHANGELOG_URL
|
||||
val str = svc.fetchString(url)
|
||||
file.writeText(str)
|
||||
str
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ object Const {
|
||||
const val PATREON_URL = "https://www.patreon.com/topjohnwu"
|
||||
const val SOURCE_CODE_URL = "https://github.com/topjohnwu/Magisk"
|
||||
|
||||
val CHANGELOG_URL = if (APP_IS_CANARY) Info.remote.magisk.note
|
||||
else "https://topjohnwu.github.io/Magisk/releases/${BuildConfig.APP_VERSION_CODE}.md"
|
||||
const val CHANGELOG_URL = "https://topjohnwu.github.io/Magisk/releases/${BuildConfig.APP_VERSION_CODE}.md"
|
||||
|
||||
const val GITHUB_RAW_URL = "https://raw.githubusercontent.com/"
|
||||
const val GITHUB_API_URL = "https://api.github.com/"
|
||||
|
@ -1,25 +1,16 @@
|
||||
package com.topjohnwu.magisk.core.data
|
||||
|
||||
import com.topjohnwu.magisk.core.model.BranchInfo
|
||||
import com.topjohnwu.magisk.core.model.ModuleJson
|
||||
import com.topjohnwu.magisk.core.model.Release
|
||||
import com.topjohnwu.magisk.core.model.UpdateInfo
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Headers
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.Streaming
|
||||
import retrofit2.http.Url
|
||||
|
||||
private const val BRANCH = "branch"
|
||||
private const val REPO = "repo"
|
||||
private const val FILE = "file"
|
||||
|
||||
interface GithubPageServices {
|
||||
|
||||
@GET
|
||||
suspend fun fetchUpdateJSON(@Url file: String): UpdateInfo
|
||||
}
|
||||
|
||||
interface RawServices {
|
||||
|
||||
@GET
|
||||
@ -32,14 +23,26 @@ interface RawServices {
|
||||
@GET
|
||||
suspend fun fetchModuleJson(@Url url: String): ModuleJson
|
||||
|
||||
@GET
|
||||
suspend fun fetchUpdateJSON(@Url url: String): UpdateInfo
|
||||
|
||||
}
|
||||
|
||||
interface GithubApiServices {
|
||||
|
||||
@GET("repos/{$REPO}/branches/{$BRANCH}")
|
||||
@Headers("Accept: application/vnd.github.v3+json")
|
||||
suspend fun fetchBranch(
|
||||
@Path(REPO, encoded = true) repo: String,
|
||||
@Path(BRANCH) branch: String
|
||||
): BranchInfo
|
||||
@GET("/repos/{owner}/{repo}/releases")
|
||||
@Headers("Accept: application/vnd.github+json")
|
||||
suspend fun fetchRelease(
|
||||
@Path("owner") owner: String = "topjohnwu",
|
||||
@Path("repo") repo: String = "Magisk",
|
||||
@Query("per_page") per: Int = 10,
|
||||
@Query("page") page: Int = 1,
|
||||
): List<Release>
|
||||
|
||||
@GET("/repos/{owner}/{repo}/releases/latest")
|
||||
@Headers("Accept: application/vnd.github+json")
|
||||
suspend fun fetchLatestRelease(
|
||||
@Path("owner") owner: String = "topjohnwu",
|
||||
@Path("repo") repo: String = "Magisk",
|
||||
): Release
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ object ServiceLocator {
|
||||
val markwon by lazy { createMarkwon(AppContext) }
|
||||
val networkService by lazy {
|
||||
NetworkService(
|
||||
createApiService(retrofit, Const.Url.GITHUB_PAGE_URL),
|
||||
createApiService(retrofit, Const.Url.GITHUB_RAW_URL),
|
||||
createApiService(retrofit, Const.Url.GITHUB_API_URL),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,16 @@ data class ModuleJson(
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CommitInfo(
|
||||
val sha: String
|
||||
data class ReleaseAssets(
|
||||
val name: String,
|
||||
val browser_download_url: String,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BranchInfo(
|
||||
val commit: CommitInfo
|
||||
data class Release(
|
||||
val tag_name: String,
|
||||
val name: String,
|
||||
val prerelease: Boolean,
|
||||
val assets: List<ReleaseAssets>,
|
||||
val body: String,
|
||||
)
|
||||
|
@ -8,15 +8,18 @@ import com.topjohnwu.magisk.core.Config.Value.DEBUG_CHANNEL
|
||||
import com.topjohnwu.magisk.core.Config.Value.DEFAULT_CHANNEL
|
||||
import com.topjohnwu.magisk.core.Config.Value.STABLE_CHANNEL
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.data.GithubPageServices
|
||||
import com.topjohnwu.magisk.core.data.GithubApiServices
|
||||
import com.topjohnwu.magisk.core.data.RawServices
|
||||
import com.topjohnwu.magisk.core.model.MagiskJson
|
||||
import com.topjohnwu.magisk.core.model.Release
|
||||
import com.topjohnwu.magisk.core.model.UpdateInfo
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
|
||||
class NetworkService(
|
||||
private val pages: GithubPageServices,
|
||||
private val raw: RawServices
|
||||
private val raw: RawServices,
|
||||
private val api: GithubApiServices,
|
||||
) {
|
||||
suspend fun fetchUpdate() = safe {
|
||||
var info = when (Config.updateChannel) {
|
||||
@ -36,11 +39,39 @@ class NetworkService(
|
||||
}
|
||||
|
||||
// UpdateInfo
|
||||
private suspend fun fetchStableUpdate() = pages.fetchUpdateJSON("stable.json")
|
||||
private suspend fun fetchBetaUpdate() = pages.fetchUpdateJSON("beta.json")
|
||||
private suspend fun fetchCanaryUpdate() = pages.fetchUpdateJSON("canary.json")
|
||||
private suspend fun fetchDebugUpdate() = pages.fetchUpdateJSON("debug.json")
|
||||
private suspend fun fetchCustomUpdate(url: String) = pages.fetchUpdateJSON(url)
|
||||
private suspend fun fetchStableUpdate(rel: Release? = null): UpdateInfo {
|
||||
val release = rel ?: api.fetchLatestRelease()
|
||||
val name = release.tag_name.drop(1)
|
||||
val info = MagiskJson(
|
||||
name, (name.toFloat() * 1000).toInt(),
|
||||
release.assets[0].browser_download_url, release.body
|
||||
)
|
||||
return UpdateInfo(info)
|
||||
}
|
||||
|
||||
private suspend fun fetchBetaUpdate(): UpdateInfo {
|
||||
val release = api.fetchRelease().find { it.tag_name[0] == 'v' && it.prerelease }
|
||||
return fetchStableUpdate(release)
|
||||
}
|
||||
|
||||
private suspend fun fetchCanaryUpdate(): UpdateInfo {
|
||||
val release = api.fetchRelease().find { it.tag_name.startsWith("canary-") }
|
||||
val info = MagiskJson(
|
||||
release!!.name.substring(8, 16),
|
||||
release.tag_name.drop(7).toInt(),
|
||||
release.assets.find { it.name == "app-release.apk" }!!.browser_download_url,
|
||||
release.body
|
||||
)
|
||||
return UpdateInfo(info)
|
||||
}
|
||||
|
||||
private suspend fun fetchDebugUpdate(): UpdateInfo {
|
||||
val release = fetchCanaryUpdate()
|
||||
val link = release.magisk.link.replace("app-release.apk", "app-debug.apk")
|
||||
return UpdateInfo(release.magisk.copy(link = link))
|
||||
}
|
||||
|
||||
private suspend fun fetchCustomUpdate(url: String) = raw.fetchUpdateJSON(url)
|
||||
|
||||
private inline fun <T> safe(factory: () -> T): T? {
|
||||
return try {
|
||||
|
@ -13,24 +13,28 @@ android {
|
||||
namespace = "com.topjohnwu.magisk"
|
||||
|
||||
val canary = !Config.version.contains(".")
|
||||
|
||||
val url = if (canary) null
|
||||
else "https://github.com/topjohnwu/Magisk/releases/download/v${Config.version}/Magisk-v${Config.version}.apk"
|
||||
val base = "https://github.com/topjohnwu/Magisk/releases/download/"
|
||||
val url = base + "v${Config.version}/Magisk-v${Config.version}.apk"
|
||||
val canaryUrl = base + "canary-${Config.versionCode}/"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.topjohnwu.magisk"
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
buildConfigField("String", "APK_URL", url?.let { "\"$it\"" } ?: "null" )
|
||||
buildConfigField("String", "APK_URL", "\"$url\"")
|
||||
buildConfigField("int", "STUB_VERSION", Config.stubVersion)
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
if (canary) buildConfigField("String", "APK_URL", "\"${canaryUrl}app-release.apk\"")
|
||||
proguardFiles("proguard-rules.pro")
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = false
|
||||
}
|
||||
debug {
|
||||
if (canary) buildConfigField("String", "APK_URL", "\"${canaryUrl}app-debug.apk\"")
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
|
@ -27,8 +27,6 @@ import com.topjohnwu.magisk.net.Networking;
|
||||
import com.topjohnwu.magisk.net.Request;
|
||||
import com.topjohnwu.magisk.utils.APKInstall;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -48,13 +46,8 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
public class DownloadActivity extends Activity {
|
||||
|
||||
private static final String APP_NAME = "Magisk";
|
||||
private static final String JSON_URL = BuildConfig.DEBUG ?
|
||||
"https://topjohnwu.github.io/magisk-files/debug.json" :
|
||||
"https://topjohnwu.github.io/magisk-files/canary.json";
|
||||
|
||||
private String apkLink = BuildConfig.APK_URL;
|
||||
private Context themed;
|
||||
private ProgressDialog dialog;
|
||||
private boolean dynLoad;
|
||||
|
||||
@Override
|
||||
@ -75,11 +68,7 @@ public class DownloadActivity extends Activity {
|
||||
ProviderInstaller.install(this);
|
||||
|
||||
if (Networking.checkNetworkStatus(this)) {
|
||||
if (BuildConfig.APK_URL == null) {
|
||||
fetchCanary();
|
||||
} else {
|
||||
showDialog();
|
||||
}
|
||||
showDialog();
|
||||
} else {
|
||||
new AlertDialog.Builder(themed)
|
||||
.setCancelable(false)
|
||||
@ -115,23 +104,10 @@ public class DownloadActivity extends Activity {
|
||||
.show();
|
||||
}
|
||||
|
||||
private void fetchCanary() {
|
||||
dialog = ProgressDialog.show(themed, "", "", true);
|
||||
request(JSON_URL).getAsJSONObject(json -> {
|
||||
dialog.dismiss();
|
||||
try {
|
||||
apkLink = json.getJSONObject("magisk").getString("link");
|
||||
showDialog();
|
||||
} catch (JSONException e) {
|
||||
error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dlAPK() {
|
||||
dialog = ProgressDialog.show(themed, getString(dling), getString(dling) + " " + APP_NAME, true);
|
||||
ProgressDialog.show(themed, getString(dling), getString(dling) + " " + APP_NAME, true);
|
||||
// Download and upgrade the app
|
||||
var request = request(apkLink).setExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
var request = request(BuildConfig.APK_URL).setExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (dynLoad) {
|
||||
request.getAsFile(StubApk.current(this), file -> StubApk.restartProcess(this));
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user