Improve old layouts a bit, rename Presets to AppPresets

This commit is contained in:
frknkrc44 2025-08-26 16:37:05 +03:00
commit c2972069ba
No known key found for this signature in database
GPG key ID: 784AE1CC0DCFD34F
13 changed files with 20 additions and 30 deletions

View file

@ -1,7 +1,6 @@
package icu.nullptr.hidemyapplist.ui.fragment
import android.os.Bundle
import com.google.android.material.transition.MaterialSharedAxis
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.adapter.AppManageAdapter
import icu.nullptr.hidemyapplist.ui.util.navController

View file

@ -13,12 +13,11 @@ import androidx.navigation.fragment.navArgs
import androidx.preference.Preference
import androidx.preference.PreferenceDataStore
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import androidx.preference.SwitchPreferenceCompat
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import icu.nullptr.hidemyapplist.common.AppPresets
import icu.nullptr.hidemyapplist.common.JsonConfig
import icu.nullptr.hidemyapplist.common.Presets
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
@ -155,7 +154,7 @@ class AppSettingsFragment : Fragment(R.layout.fragment_settings) {
true
}
findPreference<Preference>("applyPresets")?.setOnPreferenceClickListener {
val presetNames = Presets.instance.getAllPresetNames()
val presetNames = AppPresets.instance.getAllPresetNames()
val presetTranslations = presetNames.map { name ->
try {
val id = resources.getIdentifier(

View file

@ -6,7 +6,6 @@ import android.view.MenuItem
import android.view.View
import android.view.WindowInsets
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.size
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration

View file

@ -1,6 +1,5 @@
package icu.nullptr.hidemyapplist.ui.fragment
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.activity.addCallback
@ -14,7 +13,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.transition.MaterialContainerTransform
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.util.setupToolbar

View file

@ -13,7 +13,6 @@ import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.navigation.NavOptions
import androidx.navigation.fragment.NavHostFragment
import org.frknkrc44.hma_oss.R
val Fragment.navController get() = NavHostFragment.findNavController(this)

View file

@ -4,14 +4,11 @@ import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.widget.ImageView
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.annotation.StyleRes
import androidx.fragment.app.Fragment
import icu.nullptr.hidemyapplist.hmaApp
import icu.nullptr.hidemyapplist.service.PrefManager
import org.frknkrc44.hma_oss.R

View file

@ -10,7 +10,6 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.marginLeft
import androidx.fragment.app.Fragment
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder

View file

@ -0,0 +1,101 @@
package icu.nullptr.hidemyapplist.common
import android.content.pm.ApplicationInfo
import android.content.pm.IPackageManager
import icu.nullptr.hidemyapplist.common.Utils.getInstalledApplicationsCompat
import icu.nullptr.hidemyapplist.common.Utils.getPackageInfoCompat
import icu.nullptr.hidemyapplist.common.app_presets.BasePreset
import icu.nullptr.hidemyapplist.common.app_presets.CustomROMPreset
import icu.nullptr.hidemyapplist.common.app_presets.RootAppsPreset
import icu.nullptr.hidemyapplist.common.app_presets.XposedModulesPreset
// TODO: Update presets when package added/removed
class AppPresets private constructor() {
private val presetList = mutableListOf<BasePreset>()
var loggerFunction: ((String) -> Unit)? = null
companion object {
private var hiddenInstance: AppPresets? = null
val instance: AppPresets
get() {
if (hiddenInstance == null) {
hiddenInstance = AppPresets()
}
return hiddenInstance!!
}
}
fun getAllPresetNames() = presetList.map { it.name }.toTypedArray()
// fun filterPresetsByName(names: Array<String>) = presetList.filter { names.contains(it.name) }
fun getPresetByName(name: String) = presetList.firstOrNull { it.name == name }
fun reloadPresetsIfEmpty(pms: IPackageManager) {
var appsList: List<ApplicationInfo>? = null
presetList.forEach {
if (it.isDynamicListEmpty()) {
if (appsList == null) {
appsList = getInstalledApplicationsCompat(pms, 0, 0)
}
for (appInfo in appsList) {
runCatching {
it.addPackageInfoPreset(appInfo)
}.onFailure { fail ->
loggerFunction?.invoke(fail.toString())
}
}
}
loggerFunction?.invoke(it.toString())
}
}
fun handlePackageAdded(pms: IPackageManager, packageName: String) {
var appInfo: ApplicationInfo? = null
var addedInAList = false
presetList.forEach {
if (!it.containsPackage(packageName)) {
if (appInfo == null)
appInfo = getPackageInfoCompat(pms, packageName, 0, 0).applicationInfo
if (appInfo != null) {
runCatching {
if (it.addPackageInfoPreset(appInfo!!)) {
loggerFunction?.invoke("Package $packageName added into ${it.name}!")
addedInAList = true
}
}.onFailure { fail ->
loggerFunction?.invoke(fail.toString())
}
}
}
}
if (addedInAList)
loggerFunction?.invoke("Package add event handled for $packageName!")
}
fun handlePackageRemoved(packageName: String) {
var itWasInAList = false
presetList.forEach {
if (it.removePackageFromPreset(packageName))
itWasInAList = true
}
if (itWasInAList)
loggerFunction?.invoke("Package remove event handled for $packageName!")
}
init {
presetList.add(CustomROMPreset())
presetList.add(RootAppsPreset())
presetList.add(XposedModulesPreset())
}
}

View file

@ -0,0 +1,34 @@
package icu.nullptr.hidemyapplist.common.app_presets
import android.content.pm.ApplicationInfo
abstract class BasePreset(val name: String) {
protected abstract val exactPackageNames: Set<String>
protected val packageNames = mutableSetOf<String>()
protected abstract fun canBeAddedIntoPreset(appInfo: ApplicationInfo): Boolean
fun isDynamicListEmpty() = packageNames.isEmpty()
fun containsPackage(packageName: String) = exactPackageNames.contains(packageName) || packageNames.contains(packageName)
fun addPackageInfoPreset(appInfo: ApplicationInfo): Boolean {
val packageName = appInfo.packageName
if (!exactPackageNames.contains(packageName) && canBeAddedIntoPreset(appInfo)) {
packageNames.add(packageName)
return true
}
return false
}
fun removePackageFromPreset(packageName: String): Boolean {
if (exactPackageNames.contains(packageName)) return false
return packageNames.remove(packageName)
}
override fun toString() = "${javaClass.simpleName} {" +
" \"exactPackageNames\": $exactPackageNames," +
" \"packageNames\": $packageNames" +
" }"
}

View file

@ -0,0 +1,35 @@
package icu.nullptr.hidemyapplist.common.app_presets
import android.content.pm.ApplicationInfo
import icu.nullptr.hidemyapplist.common.Utils
class CustomROMPreset() : BasePreset("custom_rom") {
override val exactPackageNames = setOf<String>()
override fun canBeAddedIntoPreset(appInfo: ApplicationInfo): Boolean {
val packageName = appInfo.packageName
// LineageOS apps
if (Utils.startsWithMultiple(packageName, "lineageos.", "org.lineageos.")) {
return true
}
// AOSPA
if (packageName.startsWith("co.aospa.")) {
return true
}
// OmniROM
if (packageName.startsWith("org.omnirom.")) {
return true
}
// ProtonAOSP
if (packageName.startsWith("org.protonaosp.")) {
return true
}
// TODO: Add more custom ROM apps
return false
}
}

View file

@ -0,0 +1,136 @@
package icu.nullptr.hidemyapplist.common.app_presets
import android.content.pm.ApplicationInfo
import java.util.zip.ZipFile
class RootAppsPreset() : BasePreset("root_apps") {
override val exactPackageNames = setOf(
// rooted apps
"io.github.a13e300.ksuwebui",
"io.github.muntashirakon.AppManager",
"com.fox2code.mmm",
"xzr.hkf",
"com.speedsoftware.rootexplorer",
"id.kuato.diskhealth",
"com.sunilpaulmathew.debloater",
"com.garyodernichts.downgrader",
"eu.roggstar.getmitokens",
"io.github.domi04151309.powerapp",
"eu.roggstar.luigithehunter.batterycalibrate",
"at.or.at.plugoffairplane",
"tk.giesecke.phoenix",
"com.corphish.nightlight.generic",
"com.zinaro.cachecleanerwidget",
"de.buttercookie.simbadroid",
"simple.reboot.com",
"ru.evgeniy.dpitunnel",
"me.zhanghai.android.files",
"ca.mudar.fairphone.peaceofmind",
"com.gitlab.giwiniswut.rwremount",
"com.machiav3lli.backup",
"com.bartixxx.opflashcontrol",
"dev.ukanth.ufirewall",
"org.nuntius35.wrongpinshutdown",
"ru.nsu.bobrofon.easysshfs",
"x1125io.initdlight",
// kernel managers
"flar2.exkernelmanager",
"com.franco.kernel",
"com.lybxlpsv.kernelmanager",
"com.html6405.boefflakernelconfig",
"ccc71.st.cpu",
)
override fun canBeAddedIntoPreset(appInfo: ApplicationInfo): Boolean {
val packageName = appInfo.packageName
if (packageNames.contains(packageName)) {
return false
}
// Iconify
if (packageName.startsWith("com.drdisagree.iconify")) {
return true
}
// MMRL
if (packageName.startsWith("com.dergoogler.mmrl")) {
return true
}
// MT Manager
if (packageName.startsWith("bin.mt.plus")) {
return true
}
// Magisk
if (packageName.endsWith(".magisk")) {
return true
}
// APatch
if (packageName.contains(".apatch.") || packageName.endsWith(".apatch")) {
return true
}
// DataBackup
if (packageName.startsWith("com.xayah.databackup")) {
return true
}
// SmartPack Kernel Manager + Busybox Installer
if (packageName.startsWith("com.smartpack.")) {
return true
}
// F-Droid Privileged
if (packageName.startsWith("org.fdroid.fdroid.privileged")) {
return true
}
ZipFile(appInfo.sourceDir).use { zipFile ->
if (findAppsFromLibs(zipFile) || findAppsFromAssets(zipFile)) {
return true
}
}
return false
}
private fun findAppsFromLibs(zipFile: ZipFile): Boolean {
val entryNames = listOf(
"libkernelsu.so",
"libapd.so",
"libmagisk.so",
"libmmrl-kernelsu.so",
"liblsplant.so",
)
val architectures = listOf("arm64-v8a", "armeabi-v7a")
for (entry in entryNames) {
for (arch in architectures) {
if (zipFile.getEntry("lib/$arch/$entry") != null) {
return true
}
}
}
return false
}
private fun findAppsFromAssets(zipFile: ZipFile): Boolean {
val entryNames = listOf(
"gamma_profiles.json",
"main.jar",
)
for (entry in entryNames) {
if (zipFile.getEntry("assets/$entry") != null) {
return true
}
}
return false
}
}

View file

@ -0,0 +1,26 @@
package icu.nullptr.hidemyapplist.common.app_presets
import android.content.pm.ApplicationInfo
import java.util.zip.ZipFile
class XposedModulesPreset() : BasePreset("xposed") {
override val exactPackageNames = setOf<String>()
override fun canBeAddedIntoPreset(appInfo: ApplicationInfo): Boolean {
ZipFile(appInfo.sourceDir).use { zipFile ->
val manifestFile = zipFile.getInputStream(
zipFile.getEntry("AndroidManifest.xml"))
val manifestBytes = manifestFile.use { it.readBytes() }
val manifestStr = String(manifestBytes, Charsets.US_ASCII)
// Checking with binary because the Android system sucks
if (manifestStr.contains("\u0000x\u0000p\u0000o\u0000s\u0000e\u0000d\u0000m\u0000o\u0000d\u0000u\u0000l\u0000e")) {
return true
} else if (zipFile.getEntry("META-INF/xposed")?.isDirectory ?: false) {
return true
}
}
return false
}
}

View file

@ -4,10 +4,10 @@ import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.IPackageManager
import android.os.Build
import icu.nullptr.hidemyapplist.common.AppPresets
import icu.nullptr.hidemyapplist.common.Constants
import icu.nullptr.hidemyapplist.common.IHMAService
import icu.nullptr.hidemyapplist.common.JsonConfig
import icu.nullptr.hidemyapplist.common.Presets
import icu.nullptr.hidemyapplist.common.Utils
import icu.nullptr.hidemyapplist.xposed.hook.ActivityHook
import icu.nullptr.hidemyapplist.xposed.hook.IFrameworkHook
@ -62,8 +62,8 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
instance = this
loadConfig()
installHooks()
Presets.instance.loggerFunction = { logD(TAG, it) }
Presets.instance.reloadPresetsIfEmpty(pms)
AppPresets.instance.loggerFunction = { logD(TAG, it) }
AppPresets.instance.reloadPresetsIfEmpty(pms)
logI(TAG, "HMA service initialized")
}
@ -174,7 +174,7 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
}
for (presetName in appConfig.applyPresets) {
val preset = Presets.instance.getPresetByName(presetName) ?: continue
val preset = AppPresets.instance.getPresetByName(presetName) ?: continue
if (preset.containsPackage(query)) return !appConfig.useWhitelist
}
@ -240,8 +240,8 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
if (packageName == null) return
when (eventType) {
Intent.ACTION_PACKAGE_ADDED -> Presets.instance.handlePackageAdded(pms, packageName)
Intent.ACTION_PACKAGE_REMOVED -> Presets.instance.handlePackageRemoved(packageName)
Intent.ACTION_PACKAGE_ADDED -> AppPresets.instance.handlePackageAdded(pms, packageName)
Intent.ACTION_PACKAGE_REMOVED -> AppPresets.instance.handlePackageRemoved(packageName)
}
}
}