You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FoxMagiskModuleManager/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java

226 lines
9.9 KiB
Java

package com.fox2code.mmm.repo;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.fox2code.mmm.utils.io.Http;
import com.fox2code.mmm.utils.realm.ModuleListCache;
import org.json.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmConfiguration;
public class RepoUpdater {
private static final String TAG = "RepoUpdater";
public final RepoData repoData;
public byte[] indexRaw;
private List<RepoModule> toUpdate;
private Collection<RepoModule> toApply;
public RepoUpdater(RepoData repoData) {
this.repoData = repoData;
}
@RequiresApi(api = Build.VERSION_CODES.N)
public int fetchIndex() {
if (!RepoManager.getINSTANCE().hasConnectivity()) {
this.indexRaw = null;
this.toUpdate = Collections.emptyList();
this.toApply = Collections.emptySet();
return 0;
}
if (!this.repoData.isEnabled()) {
this.indexRaw = null;
this.toUpdate = Collections.emptyList();
this.toApply = Collections.emptySet();
return 0;
}
try {
if (!this.repoData.prepare()) {
this.indexRaw = null;
this.toUpdate = Collections.emptyList();
this.toApply = this.repoData.moduleHashMap.values();
return 0;
}
this.indexRaw = Http.doHttpGet(this.repoData.getUrl(), false);
this.toUpdate = this.repoData.populate(new JSONObject(new String(this.indexRaw, StandardCharsets.UTF_8)));
// Since we reuse instances this should work
this.toApply = new HashSet<>(this.repoData.moduleHashMap.values());
this.toApply.removeAll(this.toUpdate);
// Return repo to update
return this.toUpdate.size();
} catch (
Exception e) {
Log.e(TAG, "Failed to get manifest of " + this.repoData.id, e);
this.indexRaw = null;
this.toUpdate = Collections.emptyList();
this.toApply = Collections.emptySet();
return 0;
}
}
public List<RepoModule> toUpdate() {
return this.toUpdate;
}
public Collection<RepoModule> toApply() {
return this.toApply;
}
public boolean finish() {
boolean success = this.indexRaw != null;
// If repo is not enabled we don't need to do anything, just return true
if (!this.repoData.isEnabled()) {
return true;
}
if (this.indexRaw != null) {
try {
// iterate over modules, using this.supportedProperties as a template to attempt to get each property from the module. everything that is not null is added to the module
// use realm to insert to
// props avail:
//
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ModuleListCache.realm").schemaVersion(1).deleteRealmIfMigrationNeeded().build();
// array with module info default values
// supported properties for a module
//id=<string>
//name=<string>
//version=<string>
//versionCode=<int>
//author=<string>
//description=<string>
//minApi=<int>
//maxApi=<int>
//minMagisk=<int>
//needRamdisk=<boolean>
//support=<url>
//donate=<url>
//config=<package>
//changeBoot=<boolean>
//mmtReborn=<boolean>
// extra properties only useful for the database
//repoId=<string>
//installed=<boolean>
//installedVersionCode=<int> (only if installed)
//
// all except first six can be null
for (JSONObject module : new JSONObject[]{new JSONObject(new String(this.indexRaw, StandardCharsets.UTF_8))}) {
// get module id
String id = module.getString("id");
// get module name
String name = module.getString("name");
// get module version
String version = module.getString("version");
// get module version code
int versionCode = module.getInt("versionCode");
// get module author
String author = module.getString("author");
// get module description
String description = module.getString("description");
// get module min api
int minApi = module.getInt("minApi");
// get module max api
int maxApi = module.getInt("maxApi");
// get module min magisk
int minMagisk = module.getInt("minMagisk");
// get module need ramdisk
boolean needRamdisk = module.getBoolean("needRamdisk");
// get module support
String support = module.getString("support");
// get module donate
String donate = module.getString("donate");
// get module config
String config = module.getString("config");
// get module change boot
boolean changeBoot = module.getBoolean("changeBoot");
// get module mmt reborn
boolean mmtReborn = module.getBoolean("mmtReborn");
// get module repo id
String repoId = this.repoData.id;
// get module installed
boolean installed = false;
// get module installed version code
int installedVersionCode = 0;
// insert module to realm
// first create a collection of all the properties
// then insert to realm
// then commit
// then close
Realm.getInstanceAsync(realmConfiguration, new Realm.Callback() {
@Override
public void onSuccess(@NonNull Realm realm) {
realm.executeTransactionAsync(r -> {
// create a new module
ModuleListCache moduleListCache = r.createObject(ModuleListCache.class);
// set module id
moduleListCache.setId(id);
// set module name
moduleListCache.setName(name);
// set module version
moduleListCache.setVersion(version);
// set module version code
moduleListCache.setVersionCode(versionCode);
// set module author
moduleListCache.setAuthor(author);
// set module description
moduleListCache.setDescription(description);
// set module min api
moduleListCache.setMinApi(minApi);
// set module max api
moduleListCache.setMaxApi(maxApi);
// set module min magisk
moduleListCache.setMinMagisk(minMagisk);
// set module need ramdisk
moduleListCache.setNeedRamdisk(needRamdisk);
// set module support
moduleListCache.setSupport(support);
// set module donate
moduleListCache.setDonate(donate);
// set module config
moduleListCache.setConfig(config);
// set module change boot
moduleListCache.setChangeBoot(changeBoot);
// set module mmt reborn
moduleListCache.setMmtReborn(mmtReborn);
// set module repo id
moduleListCache.setRepoId(repoId);
// set module installed
moduleListCache.setInstalled(installed);
// set module installed version code
moduleListCache.setInstalledVersionCode(installedVersionCode);
}, () -> {
// Transaction was a success.
Log.d(TAG, "onSuccess: Transaction was a success.");
// close realm
realm.close();
}, error -> {
// Transaction failed and was automatically canceled.
Log.e(TAG, "onError: Transaction failed and was automatically canceled.", error);
// close realm
realm.close();
});
}
});
}
} catch (
Exception e) {
e.printStackTrace();
}
this.indexRaw = null;
}
this.toUpdate = null;
this.toApply = null;
return success;
}
}