Update updateLatestVersion after preference change (#2182)

This commit is contained in:
Howard Wu 2022-10-18 13:54:59 +08:00 committed by GitHub
parent f4ce1b6ed2
commit 4c6d748be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 93 deletions

View File

@ -89,7 +89,7 @@ public class RepoLoader {
public static synchronized RepoLoader getInstance() {
if (instance == null) {
instance = new RepoLoader();
App.getExecutorService().submit(instance::loadRemoteData);
App.getExecutorService().submit(() -> instance.loadLocalData(true));
}
return instance;
}
@ -97,53 +97,15 @@ public class RepoLoader {
synchronized public void loadRemoteData() {
repoLoaded = false;
try {
var response = App.getOkHttpClient().newCall(new Request.Builder()
.url(repoUrl + "modules.json")
.build()).execute();
var response = App.getOkHttpClient().newCall(new Request.Builder().url(repoUrl + "modules.json").build()).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
try {
String bodyString = body.string();
Gson gson = new Gson();
Map<String, OnlineModule> modules = new HashMap<>();
OnlineModule[] repoModules = gson.fromJson(bodyString, OnlineModule[].class);
Arrays.stream(repoModules).forEach(onlineModule -> modules.put(onlineModule.getName(), onlineModule));
var channel = App.getPreferences().getString("update_channel", channels[0]);
Map<String, ModuleVersion> versions = new ConcurrentHashMap<>();
for (var module : repoModules) {
String release = module.getLatestRelease();
if (channel.equals(channels[1]) && !(module.getLatestBetaRelease() != null && module.getLatestBetaRelease().isEmpty())) {
release = module.getLatestBetaRelease();
} else if (channel.equals(channels[2])) {
if (!(module.getLatestSnapshotRelease() != null && module.getLatestSnapshotRelease().isEmpty()))
release = module.getLatestSnapshotRelease();
else if (!(module.getLatestBetaRelease() != null && module.getLatestBetaRelease().isEmpty()))
release = module.getLatestBetaRelease();
}
if (release == null || release.isEmpty()) continue;
var splits = release.split("-", 2);
if (splits.length < 2) continue;
long verCode;
String verName;
try {
verCode = Long.parseLong(splits[0]);
verName = splits[1];
} catch (NumberFormatException ignored) {
continue;
}
String pkgName = module.getName();
versions.put(pkgName, new ModuleVersion(verCode, verName));
}
latestVersion = versions;
onlineModules = modules;
Files.write(repoFile, bodyString.getBytes(StandardCharsets.UTF_8));
repoLoaded = true;
for (RepoListener listener : listeners) {
listener.onRepoLoaded();
}
loadLocalData(false);
} catch (Throwable t) {
Log.e(App.TAG, Log.getStackTraceString(t));
for (RepoListener listener : listeners) {
@ -161,11 +123,78 @@ public class RepoLoader {
repoUrl = backupRepoUrl;
loadRemoteData();
}
}
}
synchronized public void loadLocalData(boolean updateRemoteRepo) {
repoLoaded = false;
try {
if (Files.notExists(repoFile)) {
loadRemoteData();
updateRemoteRepo = false;
}
byte[] encoded = Files.readAllBytes(repoFile);
String bodyString = new String(encoded, StandardCharsets.UTF_8);
Gson gson = new Gson();
Map<String, OnlineModule> modules = new HashMap<>();
OnlineModule[] repoModules = gson.fromJson(bodyString, OnlineModule[].class);
Arrays.stream(repoModules).forEach(onlineModule -> modules.put(onlineModule.getName(), onlineModule));
var channel = App.getPreferences().getString("update_channel", channels[0]);
updateLatestVersion(repoModules, channel);
onlineModules = modules;
} catch (Throwable t) {
Log.e(App.TAG, Log.getStackTraceString(t));
for (RepoListener listener : listeners) {
listener.onThrowable(t);
}
} finally {
repoLoaded = true;
for (RepoListener listener : listeners) {
listener.onRepoLoaded();
}
if (updateRemoteRepo) loadRemoteData();
}
}
synchronized private void updateLatestVersion(OnlineModule[] onlineModules, String channel) {
repoLoaded = false;
Map<String, ModuleVersion> versions = new ConcurrentHashMap<>();
for (var module : onlineModules) {
String release = module.getLatestRelease();
if (channel.equals(channels[1]) && module.getLatestBetaRelease() != null && !module.getLatestBetaRelease().isEmpty()) {
release = module.getLatestBetaRelease();
} else if (channel.equals(channels[2])) {
if (module.getLatestSnapshotRelease() != null && !module.getLatestSnapshotRelease().isEmpty())
release = module.getLatestSnapshotRelease();
else if (module.getLatestBetaRelease() != null && !module.getLatestBetaRelease().isEmpty())
release = module.getLatestBetaRelease();
}
if (release == null || release.isEmpty()) continue;
var splits = release.split("-", 2);
if (splits.length < 2) continue;
long verCode;
String verName;
try {
verCode = Long.parseLong(splits[0]);
verName = splits[1];
} catch (NumberFormatException ignored) {
continue;
}
String pkgName = module.getName();
versions.put(pkgName, new ModuleVersion(verCode, verName));
}
latestVersion = versions;
repoLoaded = true;
for (RepoListener listener : listeners) {
listener.onRepoLoaded();
}
}
public void updateLatestVersion(String channel) {
if (repoLoaded)
updateLatestVersion(onlineModules.keySet().parallelStream().map(onlineModules::get).toArray(OnlineModule[]::new), channel);
}
@Nullable
public ModuleVersion getModuleLatestVersion(String packageName) {
return repoLoaded ? latestVersion.getOrDefault(packageName, null) : null;
@ -207,9 +236,7 @@ public class RepoLoader {
}
public void loadRemoteReleases(String packageName) {
App.getOkHttpClient().newCall(new Request.Builder()
.url(String.format(repoUrl + "module/%s.json", packageName))
.build()).enqueue(new Callback() {
App.getOkHttpClient().newCall(new Request.Builder().url(String.format(repoUrl + "module/%s.json", packageName)).build()).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.e(App.TAG, call.request().url() + e.getMessage());

View File

@ -68,10 +68,10 @@ public class OnlineModule {
private List<Release> releases = new ArrayList<>();
@SerializedName("betaReleases")
@Expose
private List<Release> betaReleases = new ArrayList<>();
private final List<Release> betaReleases = new ArrayList<>();
@SerializedName("snapshotReleases")
@Expose
private List<Release> snapshotReleases = new ArrayList<>();
private final List<Release> snapshotReleases = new ArrayList<>();
@SerializedName("readme")
@Expose
private String readme;

View File

@ -293,8 +293,8 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene
holder.appPackageName.setText(module.getName());
Instant instant;
channel = App.getPreferences().getString("update_channel", channels[0]);
instant = Instant.parse(repoLoader.getLatestReleaseTime(module.getName(), channel));
var latestReleaseTime = repoLoader.getLatestReleaseTime(module.getName(), channel);
instant = Instant.parse(latestReleaseTime != null ? latestReleaseTime : module.getLatestReleaseTime());
var formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(App.getLocale()).withZone(ZoneId.systemDefault());
holder.publishedTime.setText(String.format(getString(R.string.module_repo_updated_time), formatter.format(instant)));
@ -356,7 +356,6 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene
int sort = App.getPreferences().getInt("repo_sort", 0);
boolean upgradableFirst = App.getPreferences().getBoolean("upgradable_first", true);
ConcurrentHashMap<String, Boolean> upgradable = new ConcurrentHashMap<>();
fullList = modules.parallelStream().filter((onlineModule -> !onlineModule.isHide() && !onlineModule.getReleases().isEmpty()))
.sorted((a, b) -> {
if (upgradableFirst) {

View File

@ -384,9 +384,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.RepoLis
var name = t.getName().toLowerCase(LocaleDelegate.getDefaultLocale());
return !name.startsWith("snapshot") && !name.startsWith("nightly");
}).collect(Collectors.toList());
} else {
tmpList = releases;
}
} else tmpList = releases;
runOnUiThread(() -> {
items = tmpList;
notifyDataSetChanged();

View File

@ -36,7 +36,9 @@ import androidx.annotation.Nullable;
import androidx.core.text.HtmlCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import rikka.material.preference.MaterialSwitchPreference;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.color.DynamicColors;
@ -47,6 +49,7 @@ import org.lsposed.manager.ConfigManager;
import org.lsposed.manager.R;
import org.lsposed.manager.databinding.FragmentSettingsBinding;
import org.lsposed.manager.receivers.LSPManagerServiceHolder;
import org.lsposed.manager.repo.RepoLoader;
import org.lsposed.manager.ui.activity.MainActivity;
import org.lsposed.manager.util.BackupUtils;
import org.lsposed.manager.util.LangList;
@ -75,15 +78,12 @@ public class SettingsFragment extends BaseFragment {
setupToolbar(binding.toolbar, binding.clickView, R.string.Settings);
binding.toolbar.setNavigationIcon(null);
if (savedInstanceState == null) {
getChildFragmentManager().beginTransaction()
.add(R.id.setting_container, new PreferenceFragment()).commitNow();
getChildFragmentManager().beginTransaction().add(R.id.setting_container, new PreferenceFragment()).commitNow();
}
if (ConfigManager.isBinderAlive()) {
binding.toolbar.setSubtitle(String.format(LocaleDelegate.getDefaultLocale(), "%s (%d) - %s",
ConfigManager.getXposedVersionName(), ConfigManager.getXposedVersionCode(), ConfigManager.getApi()));
binding.toolbar.setSubtitle(String.format(LocaleDelegate.getDefaultLocale(), "%s (%d) - %s", ConfigManager.getXposedVersionName(), ConfigManager.getXposedVersionCode(), ConfigManager.getApi()));
} else {
binding.toolbar.setSubtitle(String.format(LocaleDelegate.getDefaultLocale(), "%s (%d) - %s",
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, getString(R.string.not_installed)));
binding.toolbar.setSubtitle(String.format(LocaleDelegate.getDefaultLocale(), "%s (%d) - %s", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, getString(R.string.not_installed)));
}
return binding.getRoot();
}
@ -98,30 +98,28 @@ public class SettingsFragment extends BaseFragment {
public static class PreferenceFragment extends PreferenceFragmentCompat {
private SettingsFragment parentFragment;
ActivityResultLauncher<String> backupLauncher = registerForActivityResult(new ActivityResultContracts.CreateDocument("application/gzip"),
uri -> {
if (uri == null || parentFragment == null) return;
parentFragment.runAsync(() -> {
try {
BackupUtils.backup(uri);
} catch (Exception e) {
var text = App.getInstance().getString(R.string.settings_backup_failed2, e.getMessage());
parentFragment.showHint(text, false);
}
});
});
ActivityResultLauncher<String[]> restoreLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(),
uri -> {
if (uri == null || parentFragment == null) return;
parentFragment.runAsync(() -> {
try {
BackupUtils.restore(uri);
} catch (Exception e) {
var text = App.getInstance().getString(R.string.settings_restore_failed2, e.getMessage());
parentFragment.showHint(text, false);
}
});
});
ActivityResultLauncher<String> backupLauncher = registerForActivityResult(new ActivityResultContracts.CreateDocument("application/gzip"), uri -> {
if (uri == null || parentFragment == null) return;
parentFragment.runAsync(() -> {
try {
BackupUtils.backup(uri);
} catch (Exception e) {
var text = App.getInstance().getString(R.string.settings_backup_failed2, e.getMessage());
parentFragment.showHint(text, false);
}
});
});
ActivityResultLauncher<String[]> restoreLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), uri -> {
if (uri == null || parentFragment == null) return;
parentFragment.runAsync(() -> {
try {
BackupUtils.restore(uri);
} catch (Exception e) {
var text = App.getInstance().getString(R.string.settings_restore_failed2, e.getMessage());
parentFragment.showHint(text, false);
}
});
});
@Override
public void onAttach(@NonNull Context context) {
@ -148,8 +146,7 @@ public class SettingsFragment extends BaseFragment {
if (prefVerboseLogs != null) {
prefVerboseLogs.setEnabled(!BuildConfig.DEBUG && installed);
prefVerboseLogs.setChecked(!installed || !ConfigManager.isVerboseLogEnabled());
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) ->
ConfigManager.setVerboseLogEnabled(!(boolean) newValue));
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) -> ConfigManager.setVerboseLogEnabled(!(boolean) newValue));
}
MaterialSwitchPreference prefDexObfuscate = findPreference("enable_dex_obfuscate");
@ -157,8 +154,7 @@ public class SettingsFragment extends BaseFragment {
prefDexObfuscate.setEnabled(installed);
prefDexObfuscate.setChecked(!installed || ConfigManager.isDexObfuscateEnabled());
prefDexObfuscate.setOnPreferenceChangeListener((preference, newValue) -> {
parentFragment.showHint(R.string.reboot_required, true, R.string.reboot,
v -> ConfigManager.reboot(false));
parentFragment.showHint(R.string.reboot_required, true, R.string.reboot, v -> ConfigManager.reboot(false));
return ConfigManager.setDexObfuscateEnabled((boolean) newValue);
});
}
@ -189,8 +185,7 @@ public class SettingsFragment extends BaseFragment {
backup.setOnPreferenceClickListener(preference -> {
LocalDateTime now = LocalDateTime.now();
try {
backupLauncher.launch(String.format(LocaleDelegate.getDefaultLocale(),
"LSPosed_%s.lsp", now.toString()));
backupLauncher.launch(String.format(LocaleDelegate.getDefaultLocale(), "LSPosed_%s.lsp", now.toString()));
return true;
} catch (ActivityNotFoundException e) {
parentFragment.showHint(R.string.enable_documentui, true);
@ -253,11 +248,9 @@ public class SettingsFragment extends BaseFragment {
if (prefShowHiddenIcons != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (ConfigManager.isBinderAlive()) {
prefShowHiddenIcons.setEnabled(true);
prefShowHiddenIcons.setOnPreferenceChangeListener((preference, newValue) ->
ConfigManager.setHiddenIcon(!(boolean) newValue));
prefShowHiddenIcons.setOnPreferenceChangeListener((preference, newValue) -> ConfigManager.setHiddenIcon(!(boolean) newValue));
}
prefShowHiddenIcons.setChecked(Settings.Global.getInt(
requireActivity().getContentResolver(), "show_hidden_icon_apps_enabled", 1) != 0);
prefShowHiddenIcons.setChecked(Settings.Global.getInt(requireActivity().getContentResolver(), "show_hidden_icon_apps_enabled", 1) != 0);
}
MaterialSwitchPreference prefFollowSystemAccent = findPreference("follow_system_accent");
@ -299,7 +292,7 @@ public class SettingsFragment extends BaseFragment {
}
language.setOnPreferenceChangeListener((preference, newValue) -> {
var app = App.getInstance();
var locale = App.getLocale((String)newValue);
var locale = App.getLocale((String) newValue);
var res = app.getResources();
var config = res.getConfiguration();
config.setLocale(locale);
@ -332,6 +325,14 @@ public class SettingsFragment extends BaseFragment {
translation_contributors.setSummary(translators);
}
}
SimpleMenuPreference channel = findPreference("update_channel");
if (channel != null) {
channel.setOnPreferenceChangeListener((preference, newValue) -> {
var repoLoader = RepoLoader.getInstance();
repoLoader.updateLatestVersion(String.valueOf(newValue));
return true;
});
}
}
@NonNull