mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-23 19:01:32 +00:00
Removed events from modules / replaced with retrofit/rx
This commit is contained in:
parent
10e903c9fc
commit
7c755a3991
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.data.network
|
package com.topjohnwu.magisk.data.network
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.model.entity.GithubRepo
|
import com.topjohnwu.magisk.model.entity.GithubRepo
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
@ -12,7 +13,11 @@ interface GithubApiServices {
|
|||||||
fun fetchRepos(
|
fun fetchRepos(
|
||||||
@Query("page") page: Int,
|
@Query("page") page: Int,
|
||||||
@Query("per_page") count: Int = REPOS_PER_PAGE,
|
@Query("per_page") count: Int = REPOS_PER_PAGE,
|
||||||
@Query("sort") sortOrder: String = "pushed"
|
@Query("sort") sortOrder: String = when (Config.get<Int>(Config.Key.REPO_ORDER)) {
|
||||||
|
Config.Value.ORDER_DATE -> "updated"
|
||||||
|
Config.Value.ORDER_NAME -> "full_name"
|
||||||
|
else -> "updated"
|
||||||
|
}
|
||||||
): Single<List<GithubRepo>>
|
): Single<List<GithubRepo>>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -48,7 +48,7 @@ interface GithubRawApiServices {
|
|||||||
|
|
||||||
@GET("$MAGISK_MODULES/{$MODULE}/master/{$FILE}")
|
@GET("$MAGISK_MODULES/{$MODULE}/master/{$FILE}")
|
||||||
@Streaming
|
@Streaming
|
||||||
fun fetchFile(id: String, file: String): Single<ResponseBody>
|
fun fetchFile(@Path(MODULE) id: String, @Path(FILE) file: String): Single<ResponseBody>
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
|||||||
import com.topjohnwu.magisk.data.network.GithubServices
|
import com.topjohnwu.magisk.data.network.GithubServices
|
||||||
import com.topjohnwu.magisk.model.entity.GithubRepo
|
import com.topjohnwu.magisk.model.entity.GithubRepo
|
||||||
import com.topjohnwu.magisk.model.entity.toRepository
|
import com.topjohnwu.magisk.model.entity.toRepository
|
||||||
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.magisk.utils.writeToFile
|
import com.topjohnwu.magisk.utils.writeToFile
|
||||||
import com.topjohnwu.magisk.utils.writeToString
|
import com.topjohnwu.magisk.utils.writeToString
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -18,9 +19,16 @@ class ModuleRepository(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun fetchModules() = fetchAllRepos()
|
fun fetchModules() = fetchAllRepos()
|
||||||
.flattenAsFlowable { it }
|
.map {
|
||||||
.flatMapSingle { fetchProperties(it.name, it.updatedAtMillis) }
|
it.mapNotNull {
|
||||||
.toList()
|
runCatching {
|
||||||
|
fetchProperties(it.name, it.updatedAtMillis).blockingGet()
|
||||||
|
}.getOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fetchInstalledModules() = Single.fromCallable { Utils.loadModulesLeanback() }
|
||||||
|
.map { it.values.toList() }
|
||||||
|
|
||||||
fun fetchInstallFile(module: String) = apiRaw
|
fun fetchInstallFile(module: String) = apiRaw
|
||||||
.fetchFile(module, FILE_INSTALL_SH)
|
.fetchFile(module, FILE_INSTALL_SH)
|
||||||
|
@ -36,9 +36,18 @@ public abstract class BaseModule implements Comparable<BaseModule>, Parcelable {
|
|||||||
mVersionCode = p.readInt();
|
mVersionCode = p.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BaseModule(MagiskModule m) {
|
||||||
|
mId = m.getId();
|
||||||
|
mName = m.getName();
|
||||||
|
mVersion = m.getVersion();
|
||||||
|
mAuthor = m.getAuthor();
|
||||||
|
mDescription = m.getDescription();
|
||||||
|
mVersionCode = Integer.parseInt(m.getVersionCode());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(@NonNull BaseModule module) {
|
public int compareTo(@NonNull BaseModule module) {
|
||||||
return this.getName().toLowerCase().compareTo(module.getName().toLowerCase());
|
return getName().toLowerCase().compareTo(module.getName().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,7 +80,9 @@ public abstract class BaseModule implements Comparable<BaseModule>, Parcelable {
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void parseProps(List<String> props) { parseProps(props.toArray(new String[0])); }
|
protected void parseProps(List<String> props) {
|
||||||
|
parseProps(props.toArray(new String[0]));
|
||||||
|
}
|
||||||
|
|
||||||
protected void parseProps(String[] props) throws NumberFormatException {
|
protected void parseProps(String[] props) throws NumberFormatException {
|
||||||
for (String line : props) {
|
for (String line : props) {
|
||||||
|
@ -3,10 +3,14 @@ package com.topjohnwu.magisk.model.entity
|
|||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.topjohnwu.magisk.utils.timeFormatStandard
|
import com.topjohnwu.magisk.utils.timeFormatStandard
|
||||||
import com.topjohnwu.magisk.utils.toTime
|
import com.topjohnwu.magisk.utils.toTime
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
data class GithubRepo(
|
data class GithubRepo(
|
||||||
@Json(name = "name") val name: String,
|
@Json(name = "name") val name: String,
|
||||||
@Json(name = "updated_at") val updatedAt: String
|
@Json(name = "updated_at") val updatedAt: String
|
||||||
) {
|
) {
|
||||||
val updatedAtMillis by lazy { updatedAt.toTime(timeFormatStandard) }
|
val updatedAtMillis by lazy {
|
||||||
|
updatedAt.toTime(timeFormatStandard)
|
||||||
|
.apply { Timber.i("$name updated @ $this ($updatedAt)") }
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ interface MagiskModule : Parcelable {
|
|||||||
val author: String
|
val author: String
|
||||||
val version: String
|
val version: String
|
||||||
val versionCode: String
|
val versionCode: String
|
||||||
|
val description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(tableName = "repos")
|
@Entity(tableName = "repos")
|
||||||
@ -30,6 +31,7 @@ data class Repository(
|
|||||||
override val author: String,
|
override val author: String,
|
||||||
override val version: String,
|
override val version: String,
|
||||||
override val versionCode: String,
|
override val versionCode: String,
|
||||||
|
override val description: String,
|
||||||
val lastUpdate: Long
|
val lastUpdate: Long
|
||||||
) : MagiskModule
|
) : MagiskModule
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ data class Module(
|
|||||||
override val author: String,
|
override val author: String,
|
||||||
override val version: String,
|
override val version: String,
|
||||||
override val versionCode: String,
|
override val versionCode: String,
|
||||||
|
override val description: String,
|
||||||
val path: String
|
val path: String
|
||||||
) : MagiskModule
|
) : MagiskModule
|
||||||
|
|
||||||
@ -57,6 +60,7 @@ fun Map<String, String>.toModule(path: String): Module {
|
|||||||
author = get("author").orEmpty(),
|
author = get("author").orEmpty(),
|
||||||
version = get("version").orEmpty(),
|
version = get("version").orEmpty(),
|
||||||
versionCode = get("versionCode").orEmpty(),
|
versionCode = get("versionCode").orEmpty(),
|
||||||
|
description = get("description").orEmpty(),
|
||||||
path = path
|
path = path
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -77,5 +81,6 @@ fun Map<String, String>.toRepository(lastUpdate: Long) = Repository(
|
|||||||
author = get("author").orEmpty(),
|
author = get("author").orEmpty(),
|
||||||
version = get("version").orEmpty(),
|
version = get("version").orEmpty(),
|
||||||
versionCode = get("versionCode").orEmpty(),
|
versionCode = get("versionCode").orEmpty(),
|
||||||
|
description = get("description").orEmpty(),
|
||||||
lastUpdate = lastUpdate
|
lastUpdate = lastUpdate
|
||||||
)
|
)
|
@ -29,6 +29,11 @@ public class Repo extends BaseModule {
|
|||||||
mLastUpdate = new Date(p.readLong());
|
mLastUpdate = new Date(p.readLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Repo(Repository repo) {
|
||||||
|
super(repo);
|
||||||
|
mLastUpdate = new Date(repo.getLastUpdate());
|
||||||
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<Repo> CREATOR = new Parcelable.Creator<Repo>() {
|
public static final Parcelable.Creator<Repo> CREATOR = new Parcelable.Creator<Repo>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,7 +54,7 @@ public class Repo extends BaseModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update() throws IllegalRepoException {
|
public void update() throws IllegalRepoException {
|
||||||
String props[] = Utils.dlString(getPropUrl()).split("\\n");
|
String[] props = Utils.dlString(getPropUrl()).split("\\n");
|
||||||
try {
|
try {
|
||||||
parseProps(props);
|
parseProps(props);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
@ -8,6 +8,7 @@ import com.skoumal.teanity.util.KObservableField
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.model.entity.OldModule
|
import com.topjohnwu.magisk.model.entity.OldModule
|
||||||
import com.topjohnwu.magisk.model.entity.Repo
|
import com.topjohnwu.magisk.model.entity.Repo
|
||||||
|
import com.topjohnwu.magisk.model.entity.Repository
|
||||||
import com.topjohnwu.magisk.utils.get
|
import com.topjohnwu.magisk.utils.get
|
||||||
import com.topjohnwu.magisk.utils.toggle
|
import com.topjohnwu.magisk.utils.toggle
|
||||||
|
|
||||||
@ -55,6 +56,8 @@ class ModuleRvItem(val item: OldModule) : ComparableRvItem<ModuleRvItem>() {
|
|||||||
|
|
||||||
class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
|
class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
|
||||||
|
|
||||||
|
constructor(repo: Repository) : this(Repo(repo))
|
||||||
|
|
||||||
override val layoutRes: Int = R.layout.item_repo
|
override val layoutRes: Int = R.layout.item_repo
|
||||||
|
|
||||||
override fun contentSameAs(other: RepoRvItem): Boolean = item.version == other.item.version
|
override fun contentSameAs(other: RepoRvItem): Boolean = item.version == other.item.version
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.update;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.work.ListenableWorker;
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.App;
|
|
||||||
import com.topjohnwu.magisk.BuildConfig;
|
|
||||||
import com.topjohnwu.magisk.Config;
|
|
||||||
import com.topjohnwu.magisk.model.worker.DelegateWorker;
|
|
||||||
import com.topjohnwu.magisk.tasks.CheckUpdates;
|
|
||||||
import com.topjohnwu.magisk.view.Notifications;
|
|
||||||
import com.topjohnwu.superuser.Shell;
|
|
||||||
|
|
||||||
public class UpdateCheckService extends DelegateWorker {
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public ListenableWorker.Result doWork() {
|
|
||||||
if (App.foreground() == null) {
|
|
||||||
Shell.getShell();
|
|
||||||
CheckUpdates.check(this::onCheckDone);
|
|
||||||
}
|
|
||||||
return ListenableWorker.Result.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onCheckDone() {
|
|
||||||
if (BuildConfig.VERSION_CODE < Config.remoteManagerVersionCode) {
|
|
||||||
Notifications.managerUpdate();
|
|
||||||
} else if (Config.magiskVersionCode < Config.remoteMagiskVersionCode) {
|
|
||||||
Notifications.magiskUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.topjohnwu.magisk.model.update
|
||||||
|
|
||||||
|
import androidx.work.ListenableWorker
|
||||||
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
|
import com.topjohnwu.magisk.Config
|
||||||
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
|
import com.topjohnwu.magisk.model.entity.MagiskConfig
|
||||||
|
import com.topjohnwu.magisk.model.worker.DelegateWorker
|
||||||
|
import com.topjohnwu.magisk.utils.inject
|
||||||
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
|
|
||||||
|
class UpdateCheckService : DelegateWorker() {
|
||||||
|
|
||||||
|
private val magiskRepo: MagiskRepository by inject()
|
||||||
|
|
||||||
|
override fun doWork(): ListenableWorker.Result {
|
||||||
|
val config = runCatching { magiskRepo.fetchConfig().blockingGet() }
|
||||||
|
config.getOrNull()?.let { checkUpdates(it) }
|
||||||
|
return when {
|
||||||
|
config.isFailure -> ListenableWorker.Result.failure()
|
||||||
|
else -> ListenableWorker.Result.success()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkUpdates(config: MagiskConfig) {
|
||||||
|
when {
|
||||||
|
BuildConfig.VERSION_CODE < config.app.versionCode.toIntOrNull() ?: -1 -> Notifications.managerUpdate()
|
||||||
|
Config.magiskVersionCode < config.magisk.versionCode.toIntOrNull() ?: -1 -> Notifications.magiskUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,133 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.tasks;
|
|
||||||
|
|
||||||
import android.os.SystemClock;
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.Config;
|
|
||||||
import com.topjohnwu.magisk.Const;
|
|
||||||
import com.topjohnwu.magisk.utils.Event;
|
|
||||||
import com.topjohnwu.net.Networking;
|
|
||||||
import com.topjohnwu.net.Request;
|
|
||||||
import com.topjohnwu.net.ResponseListener;
|
|
||||||
import com.topjohnwu.superuser.ShellUtils;
|
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class CheckUpdates {
|
|
||||||
|
|
||||||
private static Request getRequest() {
|
|
||||||
String url;
|
|
||||||
switch ((int) Config.get(Config.Key.UPDATE_CHANNEL)) {
|
|
||||||
case Config.Value.BETA_CHANNEL:
|
|
||||||
url = Const.Url.BETA_URL;
|
|
||||||
break;
|
|
||||||
case Config.Value.CUSTOM_CHANNEL:
|
|
||||||
url = Config.get(Config.Key.CUSTOM_CHANNEL);
|
|
||||||
break;
|
|
||||||
case Config.Value.CANARY_CHANNEL:
|
|
||||||
url = Const.Url.CANARY_URL;
|
|
||||||
break;
|
|
||||||
case Config.Value.CANARY_DEBUG_CHANNEL:
|
|
||||||
url = Const.Url.CANARY_DEBUG_URL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
url = Const.Url.STABLE_URL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return Networking.get(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void check() {
|
|
||||||
check(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void check(Runnable cb) {
|
|
||||||
Request request = getRequest();
|
|
||||||
UpdateListener listener = new UpdateListener(cb);
|
|
||||||
if (ShellUtils.onMainThread()) {
|
|
||||||
request.getAsJSONObject(listener);
|
|
||||||
} else {
|
|
||||||
JSONObject json = request.execForJSONObject().getResult();
|
|
||||||
if (json != null)
|
|
||||||
listener.onResponse(json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class UpdateListener implements ResponseListener<JSONObject> {
|
|
||||||
|
|
||||||
private final Runnable cb;
|
|
||||||
private final long start;
|
|
||||||
|
|
||||||
UpdateListener(Runnable callback) {
|
|
||||||
cb = callback;
|
|
||||||
start = SystemClock.uptimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getInt(JSONObject json, String name, int defValue) {
|
|
||||||
if (json == null)
|
|
||||||
return defValue;
|
|
||||||
try {
|
|
||||||
return json.getInt(name);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getString(JSONObject json, String name, String defValue) {
|
|
||||||
if (json == null)
|
|
||||||
return defValue;
|
|
||||||
try {
|
|
||||||
return json.getString(name);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject getJson(JSONObject json, String name) {
|
|
||||||
try {
|
|
||||||
return json.getJSONObject(name);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResponse(JSONObject json) {
|
|
||||||
JSONObject magisk = getJson(json, "magisk");
|
|
||||||
Config.remoteMagiskVersionCode = getInt(magisk, "versionCode", -1);
|
|
||||||
|
|
||||||
if ((int) Config.get(Config.Key.UPDATE_CHANNEL) == Config.Value.DEFAULT_CHANNEL) {
|
|
||||||
if (Config.magiskVersionCode > Config.remoteMagiskVersionCode) {
|
|
||||||
// If we are newer than current stable channel, switch to beta
|
|
||||||
Config.set(Config.Key.UPDATE_CHANNEL, Config.Value.BETA_CHANNEL);
|
|
||||||
check(cb);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
Config.set(Config.Key.UPDATE_CHANNEL, Config.Value.STABLE_CHANNEL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Config.remoteMagiskVersionString = getString(magisk, "version", null);
|
|
||||||
Config.magiskLink = getString(magisk, "link", null);
|
|
||||||
Config.magiskNoteLink = getString(magisk, "note", null);
|
|
||||||
Config.magiskMD5 = getString(magisk, "md5", null);
|
|
||||||
|
|
||||||
JSONObject manager = getJson(json, "app");
|
|
||||||
Config.remoteManagerVersionString = getString(manager, "version", null);
|
|
||||||
Config.remoteManagerVersionCode = getInt(manager, "versionCode", -1);
|
|
||||||
Config.managerLink = getString(manager, "link", null);
|
|
||||||
Config.managerNoteLink = getString(manager, "note", null);
|
|
||||||
|
|
||||||
JSONObject uninstaller = getJson(json, "uninstaller");
|
|
||||||
Config.uninstallerLink = getString(uninstaller, "link", null);
|
|
||||||
|
|
||||||
UiThreadHandler.handler.postAtTime(() -> Event.trigger(Event.UPDATE_CHECK_DONE),
|
|
||||||
start + 1000 /* Add artificial delay to let UI behave correctly */);
|
|
||||||
|
|
||||||
if (cb != null)
|
|
||||||
cb.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import android.text.TextUtils
|
|||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.topjohnwu.magisk.*
|
import com.topjohnwu.magisk.*
|
||||||
import com.topjohnwu.magisk.tasks.CheckUpdates
|
|
||||||
import com.topjohnwu.magisk.tasks.UpdateRepos
|
import com.topjohnwu.magisk.tasks.UpdateRepos
|
||||||
import com.topjohnwu.magisk.utils.LocaleManager
|
import com.topjohnwu.magisk.utils.LocaleManager
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
@ -59,7 +58,7 @@ open class SplashActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// Schedule periodic update checks
|
// Schedule periodic update checks
|
||||||
Utils.scheduleUpdateCheck()
|
Utils.scheduleUpdateCheck()
|
||||||
CheckUpdates.check()
|
//CheckUpdates.check()
|
||||||
|
|
||||||
// Setup shortcuts
|
// Setup shortcuts
|
||||||
Shortcuts.setup(this)
|
Shortcuts.setup(this)
|
||||||
|
@ -10,28 +10,22 @@ import com.skoumal.teanity.util.DiffObservableList
|
|||||||
import com.skoumal.teanity.util.KObservableField
|
import com.skoumal.teanity.util.KObservableField
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
|
import com.topjohnwu.magisk.data.repository.ModuleRepository
|
||||||
import com.topjohnwu.magisk.model.entity.OldModule
|
|
||||||
import com.topjohnwu.magisk.model.entity.Repo
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.SectionRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.SectionRvItem
|
||||||
import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
||||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
||||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
||||||
import com.topjohnwu.magisk.tasks.UpdateRepos
|
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.utils.Event
|
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
|
||||||
import com.topjohnwu.magisk.utils.toSingle
|
import com.topjohnwu.magisk.utils.toSingle
|
||||||
import com.topjohnwu.magisk.utils.update
|
import com.topjohnwu.magisk.utils.update
|
||||||
import io.reactivex.Single
|
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||||
|
|
||||||
class ModuleViewModel(
|
class ModuleViewModel(
|
||||||
private val repoDatabase: RepoDatabaseHelper,
|
private val resources: Resources,
|
||||||
private val resources: Resources
|
private val moduleRepo: ModuleRepository
|
||||||
) : MagiskViewModel() {
|
) : MagiskViewModel() {
|
||||||
|
|
||||||
val query = KObservableField("")
|
val query = KObservableField("")
|
||||||
@ -52,36 +46,15 @@ class ModuleViewModel(
|
|||||||
queryDisposable?.dispose()
|
queryDisposable?.dispose()
|
||||||
queryDisposable = query()
|
queryDisposable = query()
|
||||||
}
|
}
|
||||||
Event.register(this)
|
|
||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getListeningEvents(): IntArray {
|
|
||||||
return intArrayOf(Event.MODULE_LOAD_DONE, Event.REPO_LOAD_DONE)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onEvent(event: Int) = when (event) {
|
|
||||||
Event.MODULE_LOAD_DONE -> updateModules(Event.getResult(event))
|
|
||||||
Event.REPO_LOAD_DONE -> updateRepos()
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fabPressed() = OpenFilePickerEvent().publish()
|
fun fabPressed() = OpenFilePickerEvent().publish()
|
||||||
fun repoPressed(item: RepoRvItem) = OpenChangelogEvent(item.item).publish()
|
fun repoPressed(item: RepoRvItem) = OpenChangelogEvent(item.item).publish()
|
||||||
fun downloadPressed(item: RepoRvItem) = InstallModuleEvent(item.item).publish()
|
fun downloadPressed(item: RepoRvItem) = InstallModuleEvent(item.item).publish()
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
state = State.LOADING
|
moduleRepo.fetchModules()
|
||||||
Utils.loadModules(true)
|
|
||||||
UpdateRepos().exec(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateModules(result: Map<String, OldModule>) = result.values
|
|
||||||
.map { ModuleRvItem(it) }
|
|
||||||
.let { itemsInstalled.update(it) }
|
|
||||||
|
|
||||||
internal fun updateRepos() {
|
|
||||||
Single.fromCallable { repoDatabase.repoCursor.toList { Repo(it) } }
|
|
||||||
.flattenAsFlowable { it }
|
.flattenAsFlowable { it }
|
||||||
.map { RepoRvItem(it) }
|
.map { RepoRvItem(it) }
|
||||||
.toList()
|
.toList()
|
||||||
@ -89,7 +62,13 @@ class ModuleViewModel(
|
|||||||
.flatMap { queryRaw() }
|
.flatMap { queryRaw() }
|
||||||
.applyViewModel(this)
|
.applyViewModel(this)
|
||||||
.subscribeK { itemsRemote.update(it.first, it.second) }
|
.subscribeK { itemsRemote.update(it.first, it.second) }
|
||||||
.add()
|
|
||||||
|
moduleRepo.fetchInstalledModules()
|
||||||
|
.flattenAsFlowable { it }
|
||||||
|
.map { ModuleRvItem(it) }
|
||||||
|
.toList()
|
||||||
|
.map { it to itemsInstalled.calculateDiff(it) }
|
||||||
|
.subscribeK { itemsInstalled.update(it.first, it.second) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun query() = queryRaw()
|
private fun query() = queryRaw()
|
||||||
|
@ -56,7 +56,7 @@ class ReposFragment : MagiskFragment<ModuleViewModel, FragmentReposBinding>(),
|
|||||||
Config.get<Int>(Config.Key.REPO_ORDER)!!
|
Config.get<Int>(Config.Key.REPO_ORDER)!!
|
||||||
) { d, which ->
|
) { d, which ->
|
||||||
Config.set(Config.Key.REPO_ORDER, which)
|
Config.set(Config.Key.REPO_ORDER, which)
|
||||||
viewModel.updateRepos()
|
viewModel.refresh()
|
||||||
d.dismiss()
|
d.dismiss()
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import com.topjohnwu.magisk.BuildConfig;
|
|||||||
import com.topjohnwu.magisk.Config;
|
import com.topjohnwu.magisk.Config;
|
||||||
import com.topjohnwu.magisk.Const;
|
import com.topjohnwu.magisk.Const;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.tasks.CheckUpdates;
|
|
||||||
import com.topjohnwu.magisk.ui.base.BasePreferenceFragment;
|
import com.topjohnwu.magisk.ui.base.BasePreferenceFragment;
|
||||||
import com.topjohnwu.magisk.utils.DownloadApp;
|
import com.topjohnwu.magisk.utils.DownloadApp;
|
||||||
import com.topjohnwu.magisk.utils.Event;
|
import com.topjohnwu.magisk.utils.Event;
|
||||||
@ -218,7 +217,7 @@ public class SettingsFragment extends BasePreferenceFragment {
|
|||||||
break;
|
break;
|
||||||
case Config.Key.UPDATE_CHANNEL:
|
case Config.Key.UPDATE_CHANNEL:
|
||||||
case Config.Key.CUSTOM_CHANNEL:
|
case Config.Key.CUSTOM_CHANNEL:
|
||||||
CheckUpdates.check();
|
//CheckUpdates.check();
|
||||||
break;
|
break;
|
||||||
case Config.Key.CHECK_UPDATES:
|
case Config.Key.CHECK_UPDATES:
|
||||||
Utils.scheduleUpdateCheck();
|
Utils.scheduleUpdateCheck();
|
||||||
|
@ -27,6 +27,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.work.Constraints;
|
import androidx.work.Constraints;
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy;
|
import androidx.work.ExistingPeriodicWorkPolicy;
|
||||||
import androidx.work.NetworkType;
|
import androidx.work.NetworkType;
|
||||||
@ -84,22 +85,16 @@ public class Utils {
|
|||||||
.replace("#", "").replace("@", "").replace("\\", "_");
|
.replace("#", "").replace("@", "").replace("\\", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static void loadModules() {
|
public static void loadModules() {
|
||||||
loadModules(true);
|
loadModules(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static void loadModules(boolean async) {
|
public static void loadModules(boolean async) {
|
||||||
Event.reset(Event.MODULE_LOAD_DONE);
|
Event.reset(Event.MODULE_LOAD_DONE);
|
||||||
Runnable run = () -> {
|
Runnable run = () -> {
|
||||||
Map<String, OldModule> moduleMap = new ValueSortedMap<>();
|
Map<String, OldModule> moduleMap = loadModulesLeanback();
|
||||||
SuFile path = new SuFile(Const.MAGISK_PATH);
|
|
||||||
SuFile[] modules = path.listFiles(
|
|
||||||
(file, name) -> !name.equals("lost+found") && !name.equals(".core"));
|
|
||||||
for (SuFile file : modules) {
|
|
||||||
if (file.isFile()) continue;
|
|
||||||
OldModule module = new OldModule(Const.MAGISK_PATH + "/" + file.getName());
|
|
||||||
moduleMap.put(module.getId(), module);
|
|
||||||
}
|
|
||||||
Event.trigger(Event.MODULE_LOAD_DONE, moduleMap);
|
Event.trigger(Event.MODULE_LOAD_DONE, moduleMap);
|
||||||
};
|
};
|
||||||
if (async)
|
if (async)
|
||||||
@ -108,6 +103,21 @@ public class Utils {
|
|||||||
run.run();
|
run.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
public static Map<String, OldModule> loadModulesLeanback() {
|
||||||
|
final Map<String, OldModule> moduleMap = new ValueSortedMap<>();
|
||||||
|
final SuFile path = new SuFile(Const.MAGISK_PATH);
|
||||||
|
final SuFile[] modules = path.listFiles((file, name) ->
|
||||||
|
!name.equals("lost+found") && !name.equals(".core")
|
||||||
|
);
|
||||||
|
for (SuFile file : modules) {
|
||||||
|
if (file.isFile()) continue;
|
||||||
|
OldModule module = new OldModule(Const.MAGISK_PATH + "/" + file.getName());
|
||||||
|
moduleMap.put(module.getId(), module);
|
||||||
|
}
|
||||||
|
return moduleMap;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean showSuperUser() {
|
public static boolean showSuperUser() {
|
||||||
return Shell.rootAccess() && (Const.USER_ID == 0 ||
|
return Shell.rootAccess() && (Const.USER_ID == 0 ||
|
||||||
(int) Config.get(Config.Key.SU_MULTIUSER_MODE) !=
|
(int) Config.get(Config.Key.SU_MULTIUSER_MODE) !=
|
||||||
|
@ -14,5 +14,5 @@ fun String.toTime(format: SimpleDateFormat) = try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val locale get() = Locale.getDefault()
|
private val locale get() = Locale.getDefault()
|
||||||
val timeFormatFull by lazy { SimpleDateFormat("YYYY/MM/DD_HH:mm:ss", locale) }
|
val timeFormatFull by lazy { SimpleDateFormat("yyyy/MM/dd_HH:mm:ss", locale) }
|
||||||
val timeFormatStandard by lazy { SimpleDateFormat("YYYY-MM-DD'T'HH:mm:ss'Z'", locale) }
|
val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", locale) }
|
Loading…
x
Reference in New Issue
Block a user