finish room and kotlin migration
SettingsActivity.java cannot be converted right now because AS crashes silently Signed-off-by: androidacy-user <opensource@androidacy.com>pull/89/head
parent
0b05dfe29b
commit
743cd3f46d
@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 1,
|
||||||
|
"identityHash": "2abfd2dad332c887d96cdda63d92a639",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "modulelistcache",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`codename` TEXT NOT NULL, `version` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `author` TEXT NOT NULL, `description` TEXT NOT NULL, `minApi` INTEGER NOT NULL, `maxApi` INTEGER NOT NULL, `minMagisk` INTEGER NOT NULL, `needRamdisk` INTEGER NOT NULL, `support` TEXT NOT NULL, `donate` TEXT NOT NULL, `config` TEXT NOT NULL, `changeBoot` INTEGER NOT NULL, `mmtReborn` INTEGER NOT NULL, `repoId` TEXT NOT NULL, `lastUpdate` INTEGER NOT NULL, `name` TEXT NOT NULL, `safe` INTEGER NOT NULL, `stats` INTEGER NOT NULL, PRIMARY KEY(`codename`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "codename",
|
||||||
|
"columnName": "codename",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "version",
|
||||||
|
"columnName": "version",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "versionCode",
|
||||||
|
"columnName": "versionCode",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "author",
|
||||||
|
"columnName": "author",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "description",
|
||||||
|
"columnName": "description",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "minApi",
|
||||||
|
"columnName": "minApi",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "maxApi",
|
||||||
|
"columnName": "maxApi",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "minMagisk",
|
||||||
|
"columnName": "minMagisk",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "needRamdisk",
|
||||||
|
"columnName": "needRamdisk",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "support",
|
||||||
|
"columnName": "support",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "donate",
|
||||||
|
"columnName": "donate",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "config",
|
||||||
|
"columnName": "config",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "changeBoot",
|
||||||
|
"columnName": "changeBoot",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "mmtReborn",
|
||||||
|
"columnName": "mmtReborn",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "repoId",
|
||||||
|
"columnName": "repoId",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "lastUpdate",
|
||||||
|
"columnName": "lastUpdate",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "safe",
|
||||||
|
"columnName": "safe",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "stats",
|
||||||
|
"columnName": "stats",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": false,
|
||||||
|
"columnNames": [
|
||||||
|
"codename"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2abfd2dad332c887d96cdda63d92a639')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 1,
|
||||||
|
"identityHash": "5a217dbf3caa5a6b70e7eee98636866c",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "ReposList",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `url` TEXT NOT NULL, `enabled` INTEGER NOT NULL, `donate` TEXT, `support` TEXT, `submitModule` TEXT, `lastUpdate` INTEGER NOT NULL, `name` TEXT NOT NULL, `website` TEXT, PRIMARY KEY(`id`))",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "url",
|
||||||
|
"columnName": "url",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "enabled",
|
||||||
|
"columnName": "enabled",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "donate",
|
||||||
|
"columnName": "donate",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "support",
|
||||||
|
"columnName": "support",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "submitModule",
|
||||||
|
"columnName": "submitModule",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "lastUpdate",
|
||||||
|
"columnName": "lastUpdate",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "website",
|
||||||
|
"columnName": "website",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"autoGenerate": false,
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5a217dbf3caa5a6b70e7eee98636866c')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
@ -1,376 +1,430 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
package com.fox2code.mmm.module
|
||||||
|
|
||||||
package com.fox2code.mmm.module;
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.net.Uri
|
||||||
|
import android.text.Spanned
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import com.fox2code.foxcompat.app.FoxActivity
|
||||||
|
import com.fox2code.foxcompat.view.FoxDisplay
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.isShowcaseMode
|
||||||
|
import com.fox2code.mmm.R
|
||||||
|
import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.isAndroidacyLink
|
||||||
|
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskPath
|
||||||
|
import com.fox2code.mmm.manager.ModuleInfo
|
||||||
|
import com.fox2code.mmm.manager.ModuleManager.Companion.instance
|
||||||
|
import com.fox2code.mmm.utils.ExternalHelper
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openConfig
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openCustomTab
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openInstaller
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openMarkdown
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrl
|
||||||
|
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrlAndroidacy
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import io.noties.markwon.Markwon
|
||||||
|
import org.matomo.sdk.extra.TrackHelper
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
@Suppress("SENSELESS_COMPARISON")
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
|
|
||||||
import com.fox2code.foxcompat.app.FoxActivity;
|
|
||||||
import com.fox2code.foxcompat.view.FoxDisplay;
|
|
||||||
import com.fox2code.mmm.MainApplication;
|
|
||||||
import com.fox2code.mmm.R;
|
|
||||||
import com.fox2code.mmm.androidacy.AndroidacyUtil;
|
|
||||||
import com.fox2code.mmm.installer.InstallerInitializer;
|
|
||||||
import com.fox2code.mmm.manager.LocalModuleInfo;
|
|
||||||
import com.fox2code.mmm.manager.ModuleInfo;
|
|
||||||
import com.fox2code.mmm.manager.ModuleManager;
|
|
||||||
import com.fox2code.mmm.utils.ExternalHelper;
|
|
||||||
import com.fox2code.mmm.utils.IntentHelper;
|
|
||||||
import com.google.android.material.chip.Chip;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
|
|
||||||
import org.matomo.sdk.extra.TrackHelper;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import io.noties.markwon.Markwon;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
@SuppressWarnings("ReplaceNullCheck")
|
|
||||||
@SuppressLint("UseCompatLoadingForDrawables")
|
@SuppressLint("UseCompatLoadingForDrawables")
|
||||||
public enum ActionButtonType {
|
enum class ActionButtonType {
|
||||||
INFO() {
|
INFO {
|
||||||
@Override
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
button.chipIcon = button.context.getDrawable(R.drawable.ic_baseline_info_24)
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_info_24));
|
button.setText(R.string.description)
|
||||||
button.setText(R.string.description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("view_notes", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("view_notes", name).with(INSTANCE!!.getTracker())
|
||||||
String notesUrl = moduleHolder.repoModule.notesUrl;
|
val notesUrl = moduleHolder.repoModule?.notesUrl
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(notesUrl)) {
|
if (isAndroidacyLink(notesUrl)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), notesUrl, false, moduleHolder.repoModule.moduleInfo.name, moduleHolder.getMainModuleConfig());
|
openUrlAndroidacy(
|
||||||
|
button.context,
|
||||||
|
notesUrl,
|
||||||
|
false,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name,
|
||||||
|
moduleHolder.mainModuleConfig
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
IntentHelper.openMarkdown(button.getContext(), notesUrl, moduleHolder.repoModule.moduleInfo.name, moduleHolder.getMainModuleConfig(), moduleHolder.repoModule.moduleInfo.changeBoot, moduleHolder.repoModule.moduleInfo.needRamdisk, moduleHolder.repoModule.moduleInfo.minMagisk, moduleHolder.repoModule.moduleInfo.minApi, moduleHolder.repoModule.moduleInfo.maxApi);
|
openMarkdown(
|
||||||
|
button.context,
|
||||||
|
notesUrl,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name,
|
||||||
|
moduleHolder.mainModuleConfig,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.changeBoot,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.needRamdisk,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.minMagisk ?: 0,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.minApi ?: 0,
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.maxApi ?: 9999
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
val context = button.context
|
||||||
Context context = button.getContext();
|
Toast.makeText(
|
||||||
Toast.makeText(context, context.getString(R.string.module_id_prefix) + moduleHolder.moduleId, Toast.LENGTH_SHORT).show();
|
context,
|
||||||
return true;
|
context.getString(R.string.module_id_prefix) + moduleHolder.moduleId,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}, UPDATE_INSTALL() {
|
},
|
||||||
@Override
|
UPDATE_INSTALL {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
int icon;
|
val icon: Int
|
||||||
if (moduleHolder.hasUpdate()) {
|
if (moduleHolder.hasUpdate()) {
|
||||||
icon = R.drawable.ic_baseline_update_24;
|
icon = R.drawable.ic_baseline_update_24
|
||||||
button.setText(R.string.update);
|
button.setText(R.string.update)
|
||||||
} else if (moduleHolder.moduleInfo != null) {
|
} else if (moduleHolder.moduleInfo != null) {
|
||||||
icon = R.drawable.ic_baseline_refresh_24;
|
icon = R.drawable.ic_baseline_refresh_24
|
||||||
button.setText(R.string.reinstall);
|
button.setText(R.string.reinstall)
|
||||||
} else {
|
} else {
|
||||||
icon = R.drawable.ic_baseline_system_update_24;
|
icon = R.drawable.ic_baseline_system_update_24
|
||||||
button.setText(R.string.install);
|
button.setText(R.string.install)
|
||||||
}
|
}
|
||||||
button.setChipIcon(button.getContext().getDrawable(icon));
|
button.chipIcon = button.context.getDrawable(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
// if mainmoduleinfo is null, we are in repo mode
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo: ModuleInfo = if (moduleHolder.mainModuleInfo != null) {
|
||||||
if (moduleInfo == null) return;
|
moduleHolder.mainModuleInfo
|
||||||
|
|
||||||
String name;
|
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo ?: return
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("view_update_install", name).with(MainApplication.getINSTANCE().getTracker());
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
|
moduleHolder.moduleInfo!!.name
|
||||||
|
} else {
|
||||||
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
|
}
|
||||||
|
TrackHelper.track().event("view_update_install", name).with(INSTANCE!!.getTracker())
|
||||||
// if icon is reinstall, we need to uninstall first - warn the user but don't proceed
|
// if icon is reinstall, we need to uninstall first - warn the user but don't proceed
|
||||||
if (moduleHolder.moduleInfo != null) {
|
if (moduleHolder.moduleInfo != null) {
|
||||||
// get icon of the button
|
// get icon of the button
|
||||||
Drawable icon = button.getChipIcon();
|
val icon = button.chipIcon
|
||||||
if (icon != null && icon.getConstantState() != null) {
|
if (icon != null && icon.constantState != null) {
|
||||||
Drawable reinstallIcon = button.getContext().getDrawable(R.drawable.ic_baseline_refresh_24);
|
val reinstallIcon =
|
||||||
if (reinstallIcon != null && reinstallIcon.getConstantState() != null) {
|
button.context.getDrawable(R.drawable.ic_baseline_refresh_24)
|
||||||
if (icon.getConstantState().equals(reinstallIcon.getConstantState())) {
|
if (reinstallIcon != null && reinstallIcon.constantState != null) {
|
||||||
new MaterialAlertDialogBuilder(button.getContext())
|
if (icon.constantState == reinstallIcon.constantState) {
|
||||||
.setTitle(R.string.reinstall)
|
MaterialAlertDialogBuilder(button.context)
|
||||||
.setMessage(R.string.reinstall_warning)
|
.setTitle(R.string.reinstall)
|
||||||
.setPositiveButton(R.string.reinstall, null)
|
.setMessage(R.string.reinstall_warning)
|
||||||
.show();
|
.setPositiveButton(R.string.reinstall, null)
|
||||||
return;
|
.show()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String updateZipUrl = moduleHolder.getUpdateZipUrl();
|
val updateZipUrl = moduleHolder.updateZipUrl ?: return
|
||||||
if (updateZipUrl == null) return;
|
|
||||||
// Androidacy manage the selection between download and install
|
// Androidacy manage the selection between download and install
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(updateZipUrl)) {
|
if (isAndroidacyLink(updateZipUrl)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), updateZipUrl, true, moduleInfo.name, moduleInfo.config);
|
openUrlAndroidacy(
|
||||||
return;
|
button.context,
|
||||||
|
updateZipUrl,
|
||||||
|
true,
|
||||||
|
moduleInfo.name,
|
||||||
|
moduleInfo.config
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
boolean hasRoot = InstallerInitializer.peekMagiskPath() != null && !MainApplication.Companion.isShowcaseMode();
|
val hasRoot = peekMagiskPath() != null && !isShowcaseMode
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(button.getContext());
|
val builder = MaterialAlertDialogBuilder(button.context)
|
||||||
builder.setTitle(moduleInfo.name).setCancelable(true).setIcon(R.drawable.ic_baseline_extension_24);
|
builder.setTitle(moduleInfo.name).setCancelable(true)
|
||||||
CharSequence desc = moduleInfo.description;
|
.setIcon(R.drawable.ic_baseline_extension_24)
|
||||||
Markwon markwon = null;
|
var desc: CharSequence? = moduleInfo.description
|
||||||
LocalModuleInfo localModuleInfo = moduleHolder.moduleInfo;
|
var markwon: Markwon? = null
|
||||||
if (localModuleInfo != null && !localModuleInfo.updateChangeLog.isEmpty()) {
|
val localModuleInfo = moduleHolder.moduleInfo
|
||||||
markwon = MainApplication.getINSTANCE().getMarkwon();
|
if (localModuleInfo != null && localModuleInfo.updateChangeLog.isNotEmpty()) {
|
||||||
|
markwon = INSTANCE!!.getMarkwon()
|
||||||
// Re-render each time in cse of config changes
|
// Re-render each time in cse of config changes
|
||||||
desc = markwon.toMarkdown(localModuleInfo.updateChangeLog);
|
desc = markwon!!.toMarkdown(localModuleInfo.updateChangeLog)
|
||||||
}
|
}
|
||||||
|
if (desc.isNullOrEmpty()) {
|
||||||
if (desc == null || desc.length() == 0) {
|
builder.setMessage(R.string.no_desc_found)
|
||||||
builder.setMessage(R.string.no_desc_found);
|
|
||||||
} else {
|
} else {
|
||||||
builder.setMessage(desc);
|
builder.setMessage(desc)
|
||||||
|
}
|
||||||
|
Timber.i("URL: %s", updateZipUrl)
|
||||||
|
builder.setNegativeButton(R.string.download_module) { _: DialogInterface?, _: Int ->
|
||||||
|
openCustomTab(
|
||||||
|
button.context,
|
||||||
|
updateZipUrl
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Timber.i("URL: %s", updateZipUrl);
|
|
||||||
builder.setNegativeButton(R.string.download_module, (x, y) -> IntentHelper.openCustomTab(button.getContext(), updateZipUrl));
|
|
||||||
if (hasRoot) {
|
if (hasRoot) {
|
||||||
builder.setPositiveButton(moduleHolder.hasUpdate() ? R.string.update_module : R.string.install_module, (x, y) -> {
|
builder.setPositiveButton(if (moduleHolder.hasUpdate()) R.string.update_module else R.string.install_module) { _: DialogInterface?, _: Int ->
|
||||||
String updateZipChecksum = moduleHolder.getUpdateZipChecksum();
|
val updateZipChecksum = moduleHolder.updateZipChecksum
|
||||||
IntentHelper.openInstaller(button.getContext(), updateZipUrl, moduleInfo.name, moduleInfo.config, updateZipChecksum, moduleInfo.mmtReborn);
|
openInstaller(
|
||||||
});
|
button.context,
|
||||||
|
updateZipUrl,
|
||||||
|
moduleInfo.name,
|
||||||
|
moduleInfo.config,
|
||||||
|
updateZipChecksum,
|
||||||
|
moduleInfo.mmtReborn
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExternalHelper.INSTANCE.injectButton(builder, () -> Uri.parse(updateZipUrl), moduleHolder.getUpdateZipRepo());
|
ExternalHelper.INSTANCE.injectButton(
|
||||||
int dim5dp = FoxDisplay.dpToPixel(5);
|
builder,
|
||||||
builder.setBackgroundInsetStart(dim5dp).setBackgroundInsetEnd(dim5dp);
|
{ Uri.parse(updateZipUrl) },
|
||||||
AlertDialog alertDialog = builder.show();
|
moduleHolder.updateZipRepo
|
||||||
for (int i = -3; i < 0; i++) {
|
)
|
||||||
Button alertButton = alertDialog.getButton(i);
|
val dim5dp = FoxDisplay.dpToPixel(5f)
|
||||||
if (alertButton != null && alertButton.getPaddingStart() > dim5dp) {
|
builder.setBackgroundInsetStart(dim5dp).setBackgroundInsetEnd(dim5dp)
|
||||||
alertButton.setPadding(dim5dp, dim5dp, dim5dp, dim5dp);
|
val alertDialog = builder.show()
|
||||||
|
for (i in -3..-1) {
|
||||||
|
val alertButton = alertDialog.getButton(i)
|
||||||
|
if (alertButton != null && alertButton.paddingStart > dim5dp) {
|
||||||
|
alertButton.setPadding(dim5dp, dim5dp, dim5dp, dim5dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (markwon != null) {
|
if (markwon != null) {
|
||||||
TextView messageView = Objects.requireNonNull(alertDialog.getWindow()).findViewById(android.R.id.message);
|
val messageView = alertDialog.window!!.findViewById<TextView>(android.R.id.message)
|
||||||
markwon.setParsedMarkdown(messageView, (Spanned) desc);
|
markwon.setParsedMarkdown(messageView, (desc as Spanned?)!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, UNINSTALL() {
|
},
|
||||||
@Override
|
UNINSTALL {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
int icon = moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING) ? R.drawable.ic_baseline_delete_outline_24 : (!moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING) || moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE)) ? R.drawable.ic_baseline_delete_24 : R.drawable.ic_baseline_delete_forever_24;
|
val icon =
|
||||||
button.setChipIcon(button.getContext().getDrawable(icon));
|
if (moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING)) R.drawable.ic_baseline_delete_outline_24 else if (!moduleHolder.hasFlag(
|
||||||
button.setText(R.string.uninstall);
|
ModuleInfo.FLAG_MODULE_UPDATING
|
||||||
|
) || moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE)
|
||||||
|
) R.drawable.ic_baseline_delete_24 else R.drawable.ic_baseline_delete_forever_24
|
||||||
|
button.chipIcon = button.context.getDrawable(icon)
|
||||||
|
button.setText(R.string.uninstall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
if (!moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE or ModuleInfo.FLAG_MODULE_UNINSTALLING) && moduleHolder.hasFlag(
|
||||||
if (!moduleHolder.hasFlag(ModuleInfo.FLAGS_MODULE_ACTIVE | ModuleInfo.FLAG_MODULE_UNINSTALLING) && moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING)) {
|
ModuleInfo.FLAG_MODULE_UPDATING
|
||||||
doActionLong(button, moduleHolder);
|
)
|
||||||
return;
|
) {
|
||||||
|
doActionLong(button, moduleHolder)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
String name;
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
if (moduleHolder.moduleInfo != null) {
|
moduleHolder.moduleInfo!!.name
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("uninstall_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("uninstall_module", name).with(INSTANCE!!.getTracker())
|
||||||
Timber.i(Integer.toHexString(moduleHolder.moduleInfo.flags));
|
Timber.i(Integer.toHexString(moduleHolder.moduleInfo?.flags ?: 0))
|
||||||
if (!Objects.requireNonNull(ModuleManager.getInstance()).setUninstallState(moduleHolder.moduleInfo, !moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UNINSTALLING))) {
|
if (!instance!!.setUninstallState(
|
||||||
Timber.e("Failed to switch uninstalled state!");
|
moduleHolder.moduleInfo!!, !moduleHolder.hasFlag(
|
||||||
|
ModuleInfo.FLAG_MODULE_UNINSTALLING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Timber.e("Failed to switch uninstalled state!")
|
||||||
}
|
}
|
||||||
update(button, moduleHolder);
|
update(button, moduleHolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
if (moduleHolder.moduleInfo == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// Actually a module having mount is the only issue when deleting module
|
// Actually a module having mount is the only issue when deleting module
|
||||||
if (moduleHolder.moduleInfo.hasFlag(ModuleInfo.FLAG_MODULE_HAS_ACTIVE_MOUNT))
|
if (moduleHolder.moduleInfo!!.hasFlag(ModuleInfo.FLAG_MODULE_HAS_ACTIVE_MOUNT)) return false // We can't trust active flag on first boot
|
||||||
return false; // We can't trust active flag on first boot
|
val builder = MaterialAlertDialogBuilder(button.context)
|
||||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(button.getContext());
|
builder.setTitle(R.string.master_delete)
|
||||||
builder.setTitle(R.string.master_delete);
|
builder.setPositiveButton(R.string.master_delete_yes) { _: DialogInterface?, _: Int ->
|
||||||
builder.setPositiveButton(R.string.master_delete_yes, (dialog, which) -> {
|
val moduleId = moduleHolder.moduleInfo!!.id
|
||||||
String moduleId = moduleHolder.moduleInfo.id;
|
if (!instance!!.masterClear(moduleHolder.moduleInfo!!)) {
|
||||||
if (!Objects.requireNonNull(ModuleManager.getInstance()).masterClear(moduleHolder.moduleInfo)) {
|
Toast.makeText(button.context, R.string.master_delete_fail, Toast.LENGTH_SHORT)
|
||||||
Toast.makeText(button.getContext(), R.string.master_delete_fail, Toast.LENGTH_SHORT).show();
|
.show()
|
||||||
} else {
|
} else {
|
||||||
moduleHolder.moduleInfo = null;
|
moduleHolder.moduleInfo = null
|
||||||
FoxActivity.getFoxActivity(button).refreshUI();
|
FoxActivity.getFoxActivity(button).refreshUI()
|
||||||
Timber.e("Cleared: %s", moduleId);
|
Timber.e("Cleared: %s", moduleId)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
builder.setNegativeButton(R.string.master_delete_no, (v, i) -> {
|
builder.setNegativeButton(R.string.master_delete_no) { _: DialogInterface?, _: Int -> }
|
||||||
});
|
builder.create()
|
||||||
builder.create();
|
builder.show()
|
||||||
builder.show();
|
return true
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}, CONFIG() {
|
},
|
||||||
@Override
|
CONFIG {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_app_settings_alt_24));
|
button.chipIcon =
|
||||||
button.setText(R.string.config);
|
button.context.getDrawable(R.drawable.ic_baseline_app_settings_alt_24)
|
||||||
|
button.setText(R.string.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
if (moduleHolder.moduleInfo == null) {
|
||||||
String config = moduleHolder.getMainModuleConfig();
|
return
|
||||||
if (config == null) return;
|
}
|
||||||
|
val config = moduleHolder.mainModuleConfig ?: return
|
||||||
String name;
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
if (moduleHolder.moduleInfo != null) {
|
moduleHolder.moduleInfo!!.name
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("config_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("config_module", name).with(INSTANCE!!.getTracker())
|
||||||
if (AndroidacyUtil.Companion.isAndroidacyLink(config)) {
|
if (isAndroidacyLink(config)) {
|
||||||
IntentHelper.openUrlAndroidacy(button.getContext(), config, true);
|
openUrlAndroidacy(button.context, config, true)
|
||||||
} else {
|
} else {
|
||||||
IntentHelper.openConfig(button.getContext(), config);
|
openConfig(button.context, config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, SUPPORT() {
|
},
|
||||||
@Override
|
SUPPORT {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo = moduleHolder.mainModuleInfo
|
||||||
button.setChipIcon(button.getContext().getDrawable(supportIconForUrl(moduleInfo.support)));
|
button.chipIcon = button.context.getDrawable(
|
||||||
button.setText(R.string.support);
|
supportIconForUrl(moduleInfo.support)
|
||||||
|
)
|
||||||
|
button.setText(R.string.support)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
|
moduleHolder.moduleInfo!!.name
|
||||||
String name;
|
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("support_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("support_module", name).with(INSTANCE!!.getTracker())
|
||||||
IntentHelper.Companion.openUrl(button.getContext(), Objects.requireNonNull(moduleHolder.getMainModuleInfo().support));
|
openUrl(button.context, Objects.requireNonNull(moduleHolder.mainModuleInfo.support))
|
||||||
}
|
}
|
||||||
}, DONATE() {
|
},
|
||||||
@Override
|
DONATE {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
|
val moduleInfo = moduleHolder.mainModuleInfo
|
||||||
button.setChipIcon(button.getContext().getDrawable(donateIconForUrl(moduleInfo.donate)));
|
button.chipIcon = button.context.getDrawable(
|
||||||
button.setText(R.string.donate);
|
donateIconForUrl(moduleInfo.donate)
|
||||||
|
)
|
||||||
|
button.setText(R.string.donate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("donate_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("donate_module", name).with(INSTANCE!!.getTracker())
|
||||||
IntentHelper.Companion.openUrl(button.getContext(), moduleHolder.getMainModuleInfo().donate);
|
openUrl(button.context, moduleHolder.mainModuleInfo.donate)
|
||||||
}
|
}
|
||||||
}, WARNING() {
|
},
|
||||||
@Override
|
WARNING {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.ic_baseline_warning_24));
|
button.chipIcon = button.context.getDrawable(R.drawable.ic_baseline_warning_24)
|
||||||
button.setText(R.string.warning);
|
button.setText(R.string.warning)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("warning_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("warning_module", name).with(INSTANCE!!.getTracker())
|
||||||
new MaterialAlertDialogBuilder(button.getContext()).setTitle(R.string.warning).setMessage(R.string.warning_message).setPositiveButton(R.string.understand, (v, i) -> {
|
MaterialAlertDialogBuilder(button.context).setTitle(R.string.warning)
|
||||||
}).create().show();
|
.setMessage(R.string.warning_message).setPositiveButton(
|
||||||
|
R.string.understand
|
||||||
|
) { _: DialogInterface?, _: Int -> }
|
||||||
|
.create().show()
|
||||||
}
|
}
|
||||||
}, SAFE() {
|
},
|
||||||
|
SAFE {
|
||||||
// SAFE is for modules that the api says are clean. only supported by androidacy currently
|
// SAFE is for modules that the api says are clean. only supported by androidacy currently
|
||||||
@Override
|
override fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
button.chipIcon =
|
||||||
button.setChipIcon(button.getContext().getDrawable(R.drawable.baseline_verified_user_24));
|
button.context.getDrawable(R.drawable.baseline_verified_user_24)
|
||||||
button.setText(R.string.safe);
|
button.setText(R.string.safe)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public void doAction(Chip button, ModuleHolder moduleHolder) {
|
val name: String? = if (moduleHolder.moduleInfo != null) {
|
||||||
String name;
|
moduleHolder.moduleInfo!!.name
|
||||||
if (moduleHolder.moduleInfo != null) {
|
|
||||||
name = moduleHolder.moduleInfo.name;
|
|
||||||
} else {
|
} else {
|
||||||
name = moduleHolder.repoModule.moduleInfo.name;
|
moduleHolder.repoModule?.moduleInfo?.name
|
||||||
}
|
}
|
||||||
TrackHelper.track().event("safe_module", name).with(MainApplication.getINSTANCE().getTracker());
|
TrackHelper.track().event("safe_module", name).with(INSTANCE!!.getTracker())
|
||||||
new MaterialAlertDialogBuilder(button.getContext()).setTitle(R.string.safe_module).setMessage(R.string.safe_message).setPositiveButton(R.string.understand, (v, i) -> {
|
MaterialAlertDialogBuilder(button.context).setTitle(R.string.safe_module)
|
||||||
}).create().show();
|
.setMessage(R.string.safe_message).setPositiveButton(
|
||||||
|
R.string.understand
|
||||||
|
) { _: DialogInterface?, _: Int -> }
|
||||||
|
.create().show()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
private final int iconId;
|
private val iconId: Int
|
||||||
|
|
||||||
ActionButtonType() {
|
constructor() {
|
||||||
this.iconId = 0;
|
iconId = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@Suppress("unused")
|
||||||
ActionButtonType(int iconId) {
|
constructor(iconId: Int) {
|
||||||
this.iconId = iconId;
|
this.iconId = iconId
|
||||||
}
|
}
|
||||||
|
|
||||||
@DrawableRes
|
open fun update(button: Chip, moduleHolder: ModuleHolder) {
|
||||||
public static int supportIconForUrl(String url) {
|
button.chipIcon = button.context.getDrawable(iconId)
|
||||||
int icon = R.drawable.ic_baseline_support_24;
|
|
||||||
if (url == null) {
|
|
||||||
return icon;
|
|
||||||
} else if (url.startsWith("https://t.me/")) {
|
|
||||||
icon = R.drawable.ic_baseline_telegram_24;
|
|
||||||
} else if (url.startsWith("https://discord.gg/") || url.startsWith("https://discord.com/invite/")) {
|
|
||||||
icon = R.drawable.ic_baseline_discord_24;
|
|
||||||
} else if (url.startsWith("https://github.com/")) {
|
|
||||||
icon = R.drawable.ic_github;
|
|
||||||
} else if (url.startsWith("https://gitlab.com/")) {
|
|
||||||
icon = R.drawable.ic_gitlab;
|
|
||||||
} else if (url.startsWith("https://forum.xda-developers.com/")) {
|
|
||||||
icon = R.drawable.ic_xda;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DrawableRes
|
abstract fun doAction(button: Chip, moduleHolder: ModuleHolder)
|
||||||
public static int donateIconForUrl(String url) {
|
open fun doActionLong(button: Chip, moduleHolder: ModuleHolder): Boolean {
|
||||||
int icon = R.drawable.ic_baseline_monetization_on_24;
|
return false
|
||||||
if (url == null) {
|
|
||||||
return icon;
|
|
||||||
} else if (url.startsWith("https://www.paypal.me/") || url.startsWith("https://www.paypal.com/paypalme/") || url.startsWith("https://www.paypal.com/donate/")) {
|
|
||||||
icon = R.drawable.ic_baseline_paypal_24;
|
|
||||||
} else if (url.startsWith("https://patreon.com/") || url.startsWith("https://www.patreon.com/")) {
|
|
||||||
icon = R.drawable.ic_patreon;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(Chip button, ModuleHolder moduleHolder) {
|
|
||||||
button.setChipIcon(button.getContext().getDrawable(this.iconId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void doAction(Chip button, ModuleHolder moduleHolder);
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@DrawableRes
|
||||||
|
fun supportIconForUrl(url: String?): Int {
|
||||||
|
var icon = R.drawable.ic_baseline_support_24
|
||||||
|
if (url == null) {
|
||||||
|
return icon
|
||||||
|
} else if (url.startsWith("https://t.me/")) {
|
||||||
|
icon = R.drawable.ic_baseline_telegram_24
|
||||||
|
} else if (url.startsWith("https://discord.gg/") || url.startsWith("https://discord.com/invite/")) {
|
||||||
|
icon = R.drawable.ic_baseline_discord_24
|
||||||
|
} else if (url.startsWith("https://github.com/")) {
|
||||||
|
icon = R.drawable.ic_github
|
||||||
|
} else if (url.startsWith("https://gitlab.com/")) {
|
||||||
|
icon = R.drawable.ic_gitlab
|
||||||
|
} else if (url.startsWith("https://forum.xda-developers.com/")) {
|
||||||
|
icon = R.drawable.ic_xda
|
||||||
|
}
|
||||||
|
return icon
|
||||||
|
}
|
||||||
|
|
||||||
public boolean doActionLong(Chip button, ModuleHolder moduleHolder) {
|
@JvmStatic
|
||||||
return false;
|
@DrawableRes
|
||||||
|
fun donateIconForUrl(url: String?): Int {
|
||||||
|
var icon = R.drawable.ic_baseline_monetization_on_24
|
||||||
|
if (url == null) {
|
||||||
|
return icon
|
||||||
|
} else if (url.startsWith("https://www.paypal.me/") || url.startsWith("https://www.paypal.com/paypalme/") || url.startsWith(
|
||||||
|
"https://www.paypal.com/donate/"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
icon = R.drawable.ic_baseline_paypal_24
|
||||||
|
} else if (url.startsWith("https://patreon.com/") || url.startsWith("https://www.patreon.com/")) {
|
||||||
|
icon = R.drawable.ic_patreon
|
||||||
|
}
|
||||||
|
return icon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,374 +1,420 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||||
*/
|
*/
|
||||||
|
package com.fox2code.mmm.module
|
||||||
package com.fox2code.mmm.module;
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Context;
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager;
|
import android.view.View
|
||||||
import android.view.View;
|
import androidx.annotation.StringRes
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
|
||||||
import androidx.annotation.NonNull;
|
import com.fox2code.mmm.MainApplication.Companion.formatTime
|
||||||
import androidx.annotation.StringRes;
|
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
|
||||||
|
import com.fox2code.mmm.MainApplication.Companion.isDisableLowQualityModuleFilter
|
||||||
import com.fox2code.mmm.MainApplication;
|
import com.fox2code.mmm.NotificationType
|
||||||
import com.fox2code.mmm.NotificationType;
|
import com.fox2code.mmm.R
|
||||||
import com.fox2code.mmm.R;
|
import com.fox2code.mmm.XHooks.Companion.checkConfigTargetExists
|
||||||
import com.fox2code.mmm.XHooks;
|
import com.fox2code.mmm.manager.LocalModuleInfo
|
||||||
import com.fox2code.mmm.manager.LocalModuleInfo;
|
import com.fox2code.mmm.manager.ModuleInfo
|
||||||
import com.fox2code.mmm.manager.ModuleInfo;
|
import com.fox2code.mmm.repo.RepoModule
|
||||||
import com.fox2code.mmm.repo.RepoModule;
|
import com.fox2code.mmm.utils.IntentHelper.Companion.getPackageOfConfig
|
||||||
import com.fox2code.mmm.utils.IntentHelper;
|
import com.fox2code.mmm.utils.io.PropUtils.Companion.isLowQualityModule
|
||||||
import com.fox2code.mmm.utils.io.PropUtils;
|
import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView
|
||||||
import com.fox2code.mmm.utils.io.net.Http;
|
import timber.log.Timber
|
||||||
|
import java.util.Objects
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashSet;
|
@Suppress("unused", "KotlinConstantConditions")
|
||||||
import java.util.List;
|
class ModuleHolder : Comparable<ModuleHolder?> {
|
||||||
import java.util.Locale;
|
val moduleId: String
|
||||||
import java.util.Objects;
|
val notificationType: NotificationType?
|
||||||
import java.util.Set;
|
val separator: Type?
|
||||||
|
var footerPx: Int
|
||||||
import timber.log.Timber;
|
var onClickListener: View.OnClickListener? = null
|
||||||
|
var moduleInfo: LocalModuleInfo? = null
|
||||||
public final class ModuleHolder implements Comparable<ModuleHolder> {
|
var repoModule: RepoModule? = null
|
||||||
|
var filterLevel = 0
|
||||||
public final String moduleId;
|
|
||||||
public final NotificationType notificationType;
|
constructor(moduleId: String) {
|
||||||
public final Type separator;
|
this.moduleId = Objects.requireNonNull(moduleId)
|
||||||
public int footerPx;
|
notificationType = null
|
||||||
public View.OnClickListener onClickListener;
|
separator = null
|
||||||
|
footerPx = -1
|
||||||
public LocalModuleInfo moduleInfo;
|
|
||||||
public RepoModule repoModule;
|
|
||||||
public int filterLevel;
|
|
||||||
|
|
||||||
public ModuleHolder(String moduleId) {
|
|
||||||
this.moduleId = Objects.requireNonNull(moduleId);
|
|
||||||
this.notificationType = null;
|
|
||||||
this.separator = null;
|
|
||||||
this.footerPx = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleHolder(NotificationType notificationType) {
|
|
||||||
this.moduleId = "";
|
|
||||||
this.notificationType = Objects.requireNonNull(notificationType);
|
|
||||||
this.separator = null;
|
|
||||||
this.footerPx = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleHolder(Type separator) {
|
|
||||||
this.moduleId = "";
|
|
||||||
this.notificationType = null;
|
|
||||||
this.separator = separator;
|
|
||||||
this.footerPx = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
constructor(notificationType: NotificationType) {
|
||||||
public ModuleHolder(int footerPx, boolean header) {
|
moduleId = ""
|
||||||
this.moduleId = "";
|
this.notificationType = Objects.requireNonNull(notificationType)
|
||||||
this.notificationType = null;
|
separator = null
|
||||||
this.separator = null;
|
footerPx = -1
|
||||||
this.footerPx = footerPx;
|
|
||||||
this.filterLevel = header ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModuleHolder() {
|
constructor(separator: Type?) {
|
||||||
return this.notificationType == null && this.separator == null && this.footerPx == -1;
|
moduleId = ""
|
||||||
|
notificationType = null
|
||||||
|
this.separator = separator
|
||||||
|
footerPx = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleInfo getMainModuleInfo() {
|
@Suppress("unused")
|
||||||
return this.repoModule != null && (this.moduleInfo == null || this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.moduleInfo : this.moduleInfo;
|
constructor(footerPx: Int, header: Boolean) {
|
||||||
|
moduleId = ""
|
||||||
|
notificationType = null
|
||||||
|
separator = null
|
||||||
|
this.footerPx = footerPx
|
||||||
|
filterLevel = if (header) 1 else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUpdateZipUrl() {
|
val isModuleHolder: Boolean
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.zipUrl : this.moduleInfo.updateZipUrl;
|
get() = notificationType == null && separator == null && footerPx == -1
|
||||||
}
|
val mainModuleInfo: ModuleInfo
|
||||||
|
get() = if (repoModule != null && (moduleInfo == null || moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode)) repoModule!!.moduleInfo else moduleInfo!!
|
||||||
public String getUpdateZipRepo() {
|
val updateZipUrl: String?
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.repoData.preferenceId : "update_json";
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.zipUrl else moduleInfo!!.updateZipUrl
|
||||||
}
|
val updateZipRepo: String?
|
||||||
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.repoData.preferenceId else "update_json"
|
||||||
public String getUpdateZipChecksum() {
|
val updateZipChecksum: String?
|
||||||
return this.moduleInfo == null || (this.repoModule != null && this.moduleInfo.updateVersionCode < this.repoModule.moduleInfo.versionCode) ? this.repoModule.checksum : this.moduleInfo.updateChecksum;
|
get() = if (moduleInfo == null || repoModule != null && moduleInfo!!.updateVersionCode < repoModule!!.moduleInfo.versionCode) repoModule!!.checksum else moduleInfo!!.updateChecksum
|
||||||
}
|
val mainModuleName: String?
|
||||||
|
get() {
|
||||||
public String getMainModuleName() {
|
val moduleInfo = mainModuleInfo
|
||||||
ModuleInfo moduleInfo = this.getMainModuleInfo();
|
if (moduleInfo.name == null) throw Error("Error for " + type.name + " id " + moduleId)
|
||||||
if (moduleInfo == null || moduleInfo.name == null)
|
return moduleInfo.name
|
||||||
throw new Error("Error for " + this.getType().name() + " id " + this.moduleId);
|
|
||||||
return moduleInfo.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMainModuleNameLowercase() {
|
|
||||||
return this.getMainModuleName().toLowerCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMainModuleConfig() {
|
|
||||||
if (this.moduleInfo == null) return null;
|
|
||||||
String config = this.moduleInfo.config;
|
|
||||||
if (config == null && this.repoModule != null) {
|
|
||||||
config = this.repoModule.moduleInfo.config;
|
|
||||||
}
|
}
|
||||||
return config;
|
val mainModuleNameLowercase: String
|
||||||
}
|
get() = mainModuleName!!.lowercase()
|
||||||
|
val mainModuleConfig: String?
|
||||||
public String getUpdateTimeText() {
|
get() {
|
||||||
if (this.repoModule == null) return "";
|
if (moduleInfo == null) return null
|
||||||
long timeStamp = this.repoModule.lastUpdated;
|
var config = moduleInfo!!.config
|
||||||
return timeStamp <= 0 ? "" : MainApplication.formatTime(timeStamp);
|
if (config == null && repoModule != null) {
|
||||||
}
|
config = repoModule!!.moduleInfo.config
|
||||||
|
}
|
||||||
public String getRepoName() {
|
return config
|
||||||
if (this.repoModule == null) return "";
|
}
|
||||||
return this.repoModule.repoName;
|
val updateTimeText: String
|
||||||
}
|
get() {
|
||||||
|
if (repoModule == null) return ""
|
||||||
|
val timeStamp = repoModule!!.lastUpdated
|
||||||
|
return if (timeStamp <= 0) "" else formatTime(timeStamp)
|
||||||
|
}
|
||||||
|
val repoName: String?
|
||||||
|
get() = if (repoModule == null) "" else repoModule!!.repoName
|
||||||
|
|
||||||
public boolean hasFlag(int flag) {
|
fun hasFlag(flag: Int): Boolean {
|
||||||
return this.moduleInfo != null && this.moduleInfo.hasFlag(flag);
|
return moduleInfo != null && moduleInfo!!.hasFlag(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
val type: Type
|
||||||
if (this.footerPx != -1) {
|
get() = if (footerPx != -1) {
|
||||||
Timber.i("Module %s is footer", this.moduleId);
|
Timber.i("Module %s is footer", moduleId)
|
||||||
return Type.FOOTER;
|
Type.FOOTER
|
||||||
} else if (this.separator != null) {
|
} else if (separator != null) {
|
||||||
Timber.i("Module %s is separator", this.moduleId);
|
Timber.i("Module %s is separator", moduleId)
|
||||||
return Type.SEPARATOR;
|
Type.SEPARATOR
|
||||||
} else if (this.notificationType != null) {
|
} else if (notificationType != null) {
|
||||||
Timber.i("Module %s is notification", this.moduleId);
|
Timber.i("Module %s is notification", moduleId)
|
||||||
return Type.NOTIFICATION;
|
Type.NOTIFICATION
|
||||||
} else if (this.moduleInfo == null) {
|
} else if (moduleInfo == null) {
|
||||||
return Type.INSTALLABLE;
|
Type.INSTALLABLE
|
||||||
} else if (this.moduleInfo.versionCode < this.moduleInfo.updateVersionCode || (this.repoModule != null && this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode)) {
|
} else if (moduleInfo!!.versionCode < moduleInfo!!.updateVersionCode || repoModule != null && moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode) {
|
||||||
boolean ignoreUpdate = false;
|
var ignoreUpdate = false
|
||||||
try {
|
try {
|
||||||
if (Objects.requireNonNull(Objects.requireNonNull(MainApplication.getSharedPreferences("mmm")).getStringSet("pref_background_update_check_excludes", new HashSet<>())).contains(moduleInfo.id))
|
if (getSharedPreferences("mmm")?.getStringSet("pref_background_update_check_excludes", HashSet())!!
|
||||||
ignoreUpdate = true;
|
.contains(
|
||||||
} catch (Exception ignored) {
|
moduleInfo!!.id
|
||||||
|
)
|
||||||
|
) ignoreUpdate = true
|
||||||
|
} catch (ignored: Exception) {
|
||||||
}
|
}
|
||||||
// now, we just had to make it more fucking complicated, didn't we?
|
// now, we just had to make it more fucking complicated, didn't we?
|
||||||
// we now have pref_background_update_check_excludes_version, which is a id:version stringset of versions the user may want to "skip"
|
// we now have pref_background_update_check_excludes_version, which is a id:version stringset of versions the user may want to "skip"
|
||||||
// oh, and because i hate myself, i made ^ at the beginning match that version and newer, and $ at the end match that version and older
|
// oh, and because i hate myself, i made ^ at the beginning match that version and newer, and $ at the end match that version and older
|
||||||
Set<String> stringSetT = Objects.requireNonNull(MainApplication.getSharedPreferences("mmm")).getStringSet("pref_background_update_check_excludes_version", new HashSet<>());
|
val stringSetT = getSharedPreferences("mmm")?.getStringSet("pref_background_update_check_excludes_version", HashSet())
|
||||||
String version = "";
|
var version = ""
|
||||||
Timber.d(stringSetT.toString());
|
Timber.d(stringSetT.toString())
|
||||||
// unfortunately, stringset.contains() doesn't work for partial matches
|
// unfortunately, stringset.contains() doesn't work for partial matches
|
||||||
// so we have to iterate through the set
|
// so we have to iterate through the set
|
||||||
for (String s : stringSetT) {
|
for (s in stringSetT!!) {
|
||||||
if (s.startsWith(this.moduleInfo.id)) {
|
if (s.startsWith(moduleInfo!!.id)) {
|
||||||
version = s;
|
version = s
|
||||||
Timber.d("igV: %s", version);
|
Timber.d("igV: %s", version)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String remoteVersionCode = String.valueOf(moduleInfo.updateVersionCode);
|
var remoteVersionCode = moduleInfo!!.updateVersionCode.toString()
|
||||||
if (repoModule != null) {
|
if (repoModule != null) {
|
||||||
remoteVersionCode = String.valueOf(repoModule.moduleInfo.versionCode);
|
remoteVersionCode = repoModule!!.moduleInfo.versionCode.toString()
|
||||||
}
|
}
|
||||||
if (!version.isEmpty()) {
|
if (version.isNotEmpty()) {
|
||||||
// now, coerce everything into an int
|
// now, coerce everything into an int
|
||||||
int remoteVersionCodeInt = Integer.parseInt(remoteVersionCode);
|
val remoteVersionCodeInt = remoteVersionCode.toInt()
|
||||||
int wantsVersion = Integer.parseInt(version.split(":")[1].replaceAll("[^0-9]", ""));
|
val wantsVersion = version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
|
||||||
|
.toTypedArray()[1].replace("[^0-9]".toRegex(), "").toInt()
|
||||||
// now find out if user wants up to and including this version, or this version and newer
|
// now find out if user wants up to and including this version, or this version and newer
|
||||||
Timber.d("igV start with");
|
Timber.d("igV start with")
|
||||||
version = version.split(":")[1];
|
version =
|
||||||
|
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||||
// this version and newer
|
// this version and newer
|
||||||
if (version.startsWith("^")) {
|
if (version.startsWith("^")) {
|
||||||
Timber.d("igV: newer");
|
Timber.d("igV: newer")
|
||||||
// the wantsversion and newer
|
// the wantsversion and newer
|
||||||
if (remoteVersionCodeInt >= wantsVersion) {
|
if (remoteVersionCodeInt >= wantsVersion) {
|
||||||
Timber.d("igV: skipping");
|
Timber.d("igV: skipping")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
} else if (version.endsWith("$")) {
|
} else if (version.endsWith("$")) {
|
||||||
Timber.d("igV: older");
|
Timber.d("igV: older")
|
||||||
// this wantsversion and older
|
// this wantsversion and older
|
||||||
if (remoteVersionCodeInt <= wantsVersion) {
|
if (remoteVersionCodeInt <= wantsVersion) {
|
||||||
Timber.d("igV: skipping");
|
Timber.d("igV: skipping")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
} else if (wantsVersion == remoteVersionCodeInt) {
|
} else if (wantsVersion == remoteVersionCodeInt) {
|
||||||
Timber.d("igV: equal");
|
Timber.d("igV: equal")
|
||||||
// if it is, we skip it
|
// if it is, we skip it
|
||||||
ignoreUpdate = true;
|
ignoreUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ignoreUpdate) {
|
if (ignoreUpdate) {
|
||||||
Timber.d("Module %s has update, but is ignored", this.moduleId);
|
Timber.d("Module %s has update, but is ignored", moduleId)
|
||||||
return Type.INSTALLABLE;
|
Type.INSTALLABLE
|
||||||
} else {
|
} else {
|
||||||
Objects.requireNonNull(MainApplication.getINSTANCE()).modulesHaveUpdates = true;
|
INSTANCE!!.modulesHaveUpdates = true
|
||||||
if (!MainApplication.getINSTANCE().updateModules.contains(this.moduleId)) {
|
if (!INSTANCE!!.updateModules.contains(moduleId)) {
|
||||||
MainApplication.getINSTANCE().updateModules.add(this.moduleId);
|
INSTANCE!!.updateModules += moduleId
|
||||||
MainApplication.getINSTANCE().updateModuleCount++;
|
INSTANCE!!.updateModuleCount++
|
||||||
}
|
}
|
||||||
Timber.d("modulesHaveUpdates = %s, updateModuleCount = %s", MainApplication.getINSTANCE().modulesHaveUpdates, MainApplication.getINSTANCE().updateModuleCount);
|
Timber.d(
|
||||||
Timber.d("Module %s has update", this.moduleId);
|
"modulesHaveUpdates = %s, updateModuleCount = %s",
|
||||||
return Type.UPDATABLE;
|
INSTANCE!!.modulesHaveUpdates,
|
||||||
|
INSTANCE!!.updateModuleCount
|
||||||
|
)
|
||||||
|
Timber.d("Module %s has update", moduleId)
|
||||||
|
Type.UPDATABLE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Type.INSTALLED;
|
Type.INSTALLED
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Type getCompareType(Type type) {
|
fun getCompareType(type: Type?): Type? {
|
||||||
if (this.separator != null) {
|
return separator
|
||||||
return this.separator;
|
?: if (notificationType != null && notificationType.special) {
|
||||||
} else if (this.notificationType != null && this.notificationType.special) {
|
Type.SPECIAL_NOTIFICATIONS
|
||||||
return Type.SPECIAL_NOTIFICATIONS;
|
} else {
|
||||||
} else {
|
type
|
||||||
return type;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldRemove() {
|
fun shouldRemove(): Boolean {
|
||||||
if (this.repoModule != null && this.moduleInfo != null && !hasUpdate()) {
|
if (repoModule != null && moduleInfo != null && !hasUpdate()) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
return this.notificationType != null ? this.notificationType.shouldRemove() : this.footerPx == -1 && this.moduleInfo == null && (this.repoModule == null || !this.repoModule.repoData.isEnabled() || (PropUtils.isLowQualityModule(this.repoModule.moduleInfo) && !MainApplication.Companion.isDisableLowQualityModuleFilter()));
|
return notificationType?.shouldRemove()
|
||||||
|
?: (footerPx == -1 && moduleInfo == null && (repoModule == null || !repoModule!!.repoData.isEnabled || isLowQualityModule(
|
||||||
|
repoModule!!.moduleInfo
|
||||||
|
) && !isDisableLowQualityModuleFilter))
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getButtons(Context context, List<ActionButtonType> buttonTypeList, boolean showcaseMode) {
|
fun getButtons(
|
||||||
if (!this.isModuleHolder()) return;
|
context: Context?,
|
||||||
LocalModuleInfo localModuleInfo = this.moduleInfo;
|
buttonTypeList: MutableList<ActionButtonType?>,
|
||||||
|
showcaseMode: Boolean
|
||||||
|
) {
|
||||||
|
if (!isModuleHolder) return
|
||||||
|
val localModuleInfo = moduleInfo
|
||||||
// Add warning button if module id begins with a dot - this is a hidden module which could indicate malware
|
// Add warning button if module id begins with a dot - this is a hidden module which could indicate malware
|
||||||
if (this.moduleId.startsWith(".") || !this.moduleId.matches("^[a-zA-Z][a-zA-Z0-9._-]+$")) {
|
if (moduleId.startsWith(".") || !moduleId.matches("^[a-zA-Z][a-zA-Z0-9._-]+$".toRegex())) {
|
||||||
buttonTypeList.add(ActionButtonType.WARNING);
|
buttonTypeList.add(ActionButtonType.WARNING)
|
||||||
}
|
}
|
||||||
if (localModuleInfo != null && !showcaseMode) {
|
if (localModuleInfo != null && !showcaseMode) {
|
||||||
buttonTypeList.add(ActionButtonType.UNINSTALL);
|
buttonTypeList.add(ActionButtonType.UNINSTALL)
|
||||||
}
|
}
|
||||||
if (this.repoModule != null && this.repoModule.notesUrl != null) {
|
if (repoModule != null && repoModule!!.notesUrl != null) {
|
||||||
buttonTypeList.add(ActionButtonType.INFO);
|
buttonTypeList.add(ActionButtonType.INFO)
|
||||||
}
|
}
|
||||||
if ((this.repoModule != null || (localModuleInfo != null && localModuleInfo.updateZipUrl != null))) {
|
if (repoModule != null || localModuleInfo?.updateZipUrl != null) {
|
||||||
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL);
|
buttonTypeList.add(ActionButtonType.UPDATE_INSTALL)
|
||||||
}
|
}
|
||||||
String config = this.getMainModuleConfig();
|
val config = mainModuleConfig
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
if (config.startsWith("https://www.androidacy.com/") && Http.hasWebView()) {
|
if (config.startsWith("https://www.androidacy.com/") && hasWebView()) {
|
||||||
buttonTypeList.add(ActionButtonType.CONFIG);
|
buttonTypeList.add(ActionButtonType.CONFIG)
|
||||||
} else {
|
} else {
|
||||||
String pkg = IntentHelper.getPackageOfConfig(config);
|
val pkg = getPackageOfConfig(config)
|
||||||
try {
|
try {
|
||||||
XHooks.checkConfigTargetExists(context, pkg, config);
|
checkConfigTargetExists(context!!, pkg, config)
|
||||||
buttonTypeList.add(ActionButtonType.CONFIG);
|
buttonTypeList.add(ActionButtonType.CONFIG)
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
Timber.w("Config package \"" + pkg + "\" missing for module \"" + this.moduleId + "\"");
|
Timber.w("Config package \"$pkg\" missing for module \"$moduleId\"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleInfo moduleInfo = this.getMainModuleInfo();
|
var moduleInfo: ModuleInfo? = mainModuleInfo
|
||||||
if (moduleInfo == null) { // Avoid concurrency NPE
|
if (moduleInfo == null) { // Avoid concurrency NPE
|
||||||
if (localModuleInfo == null) return;
|
if (localModuleInfo == null) return
|
||||||
moduleInfo = localModuleInfo;
|
moduleInfo = localModuleInfo
|
||||||
}
|
}
|
||||||
if (moduleInfo.support != null) {
|
if (moduleInfo.support != null) {
|
||||||
buttonTypeList.add(ActionButtonType.SUPPORT);
|
buttonTypeList.add(ActionButtonType.SUPPORT)
|
||||||
}
|
}
|
||||||
if (moduleInfo.donate != null) {
|
if (moduleInfo.donate != null) {
|
||||||
buttonTypeList.add(ActionButtonType.DONATE);
|
buttonTypeList.add(ActionButtonType.DONATE)
|
||||||
}
|
}
|
||||||
if (moduleInfo.safe) {
|
if (moduleInfo.safe) {
|
||||||
buttonTypeList.add(ActionButtonType.SAFE);
|
buttonTypeList.add(ActionButtonType.SAFE)
|
||||||
} else {
|
} else {
|
||||||
Timber.d("Module %s is not safe", this.moduleId);
|
Timber.d("Module %s is not safe", moduleId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasUpdate() {
|
fun hasUpdate(): Boolean {
|
||||||
return this.moduleInfo != null && this.repoModule != null && this.moduleInfo.versionCode < this.repoModule.moduleInfo.versionCode;
|
return moduleInfo != null && repoModule != null && moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override operator fun compareTo(other: ModuleHolder?): Int {
|
||||||
public int compareTo(ModuleHolder o) {
|
|
||||||
// Compare depend on type, also allow type spoofing
|
// Compare depend on type, also allow type spoofing
|
||||||
Type selfTypeReal = this.getType();
|
val selfTypeReal = type
|
||||||
Type otherTypeReal = o.getType();
|
val otherTypeReal = other!!.type
|
||||||
Type selfType = this.getCompareType(selfTypeReal);
|
val selfType = getCompareType(selfTypeReal)
|
||||||
Type otherType = o.getCompareType(otherTypeReal);
|
val otherType = other.getCompareType(otherTypeReal)
|
||||||
int compare = selfType.compareTo(otherType);
|
val compare = selfType!!.compareTo(otherType!!)
|
||||||
return compare != 0 ? compare : selfTypeReal == otherTypeReal ? selfTypeReal.compare(this, o) : selfTypeReal.compareTo(otherTypeReal);
|
return if (compare != 0) compare else if (selfTypeReal === otherTypeReal) selfTypeReal.compare(
|
||||||
|
this,
|
||||||
|
other
|
||||||
|
) else selfTypeReal.compareTo(otherTypeReal)
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
override fun toString(): String {
|
||||||
@Override
|
return "ModuleHolder{moduleId='$moduleId', notificationType=$notificationType, separator=$separator, footerPx=$footerPx}"
|
||||||
public String toString() {
|
|
||||||
return "ModuleHolder{" + "moduleId='" + moduleId + '\'' + ", notificationType=" + notificationType + ", separator=" + separator + ", footerPx=" + footerPx + '}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type implements Comparator<ModuleHolder> {
|
enum class Type(
|
||||||
HEADER(R.string.loading, false, false), SEPARATOR(R.string.loading, false, false) {
|
@field:StringRes @param:StringRes val title: Int,
|
||||||
@Override
|
val hasBackground: Boolean,
|
||||||
@SuppressWarnings("ConstantConditions")
|
val moduleHolder: Boolean
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
) : Comparator<ModuleHolder?> {
|
||||||
return o1.separator.compareTo(o2.separator);
|
HEADER(R.string.loading, false, false) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
return o1.separator!!.compareTo(o2.separator!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, NOTIFICATION(R.string.loading, true, false) {
|
}, SEPARATOR(R.string.loading, false, false) {
|
||||||
@Override
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
@SuppressWarnings("ConstantConditions")
|
if (o1 != null && o2 != null) {
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
return o1.separator!!.compareTo(o2.separator!!)
|
||||||
return o1.notificationType.compareTo(o2.notificationType);
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, UPDATABLE(R.string.updatable, true, true) {
|
},
|
||||||
@Override
|
NOTIFICATION(R.string.loading, true, false) {
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
if (o1 != null && o2 != null) {
|
||||||
if (cmp != 0) return cmp;
|
return o1.notificationType!!.compareTo(o2.notificationType!!)
|
||||||
long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated;
|
} else if (o1 != null) {
|
||||||
long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated;
|
return -1
|
||||||
cmp = Long.compare(lastUpdated2, lastUpdated1);
|
} else if (o2 != null) {
|
||||||
if (cmp != 0) return cmp;
|
return 1
|
||||||
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, INSTALLED(R.string.installed, true, true) {
|
},
|
||||||
|
UPDATABLE(R.string.updatable, true, true) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
|
if (cmp != 0) return cmp
|
||||||
|
val lastUpdated1 =
|
||||||
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
|
val lastUpdated2 =
|
||||||
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
INSTALLED(R.string.installed, true, true) {
|
||||||
// get stacktrace for debugging
|
// get stacktrace for debugging
|
||||||
@Override
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
if (o1 != null && o2 != null) {
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
val cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
if (cmp != 0) return cmp;
|
return if (cmp != 0) cmp else o1.mainModuleNameLowercase.compareTo(o2.mainModuleNameLowercase)
|
||||||
return o1.getMainModuleNameLowercase().compareTo(o2.getMainModuleNameLowercase());
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, SPECIAL_NOTIFICATIONS(R.string.loading, true, false), INSTALLABLE(R.string.online_repo, true, true) {
|
},
|
||||||
@Override
|
SPECIAL_NOTIFICATIONS(R.string.loading, true, false) {
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
|
if (o1 != null && o2 != null) {
|
||||||
if (cmp != 0) return cmp;
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
long lastUpdated1 = o1.repoModule == null ? 0L : o1.repoModule.lastUpdated;
|
if (cmp != 0) return cmp
|
||||||
long lastUpdated2 = o2.repoModule == null ? 0L : o2.repoModule.lastUpdated;
|
val lastUpdated1 =
|
||||||
cmp = Long.compare(lastUpdated2, lastUpdated1);
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
if (cmp != 0) return cmp;
|
val lastUpdated2 =
|
||||||
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}, FOOTER(R.string.loading, false, false);
|
}, INSTALLABLE(
|
||||||
|
R.string.online_repo,
|
||||||
@StringRes
|
true,
|
||||||
public final int title;
|
true
|
||||||
public final boolean hasBackground;
|
) {
|
||||||
public final boolean moduleHolder;
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
Type(@StringRes int title, boolean hasBackground, boolean moduleHolder) {
|
var cmp = o1.filterLevel.compareTo(o2.filterLevel)
|
||||||
this.title = title;
|
if (cmp != 0) return cmp
|
||||||
this.hasBackground = hasBackground;
|
val lastUpdated1 =
|
||||||
this.moduleHolder = moduleHolder;
|
if (o1.repoModule == null) 0L else o1.repoModule!!.lastUpdated
|
||||||
}
|
val lastUpdated2 =
|
||||||
|
if (o2.repoModule == null) 0L else o2.repoModule!!.lastUpdated
|
||||||
// Note: This method should only be called if both element have the same type
|
cmp = lastUpdated2.compareTo(lastUpdated1)
|
||||||
@Override
|
return if (cmp != 0) cmp else o1.mainModuleName!!.compareTo(o2.mainModuleName!!)
|
||||||
public int compare(ModuleHolder o1, ModuleHolder o2) {
|
} else if (o1 != null) {
|
||||||
if (o1 == o2) {
|
return -1
|
||||||
return 0;
|
} else if (o2 != null) {
|
||||||
} else if (o1 == null) {
|
return 1
|
||||||
return -1;
|
}
|
||||||
} else if (o2 == null) {
|
return 0
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return o1.moduleId.compareTo(o2.moduleId);
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
FOOTER(R.string.loading, false, false) {
|
||||||
|
override fun compare(o1: ModuleHolder?, o2: ModuleHolder?): Int {
|
||||||
|
if (o1 != null && o2 != null) {
|
||||||
|
return o1.footerPx.compareTo(o2.footerPx)
|
||||||
|
} else if (o1 != null) {
|
||||||
|
return -1
|
||||||
|
} else if (o2 != null) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue