Compare commits
67 changed files with 595 additions and 1696 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# HMAL-OSS
|
||||
|
||||
Forked from [HMA-OSS](https://github.com/frknkrc44/HMA-OSS)
|
||||
Forked from [HMA-OSS]https://github.com/frknkrc44/HMA-OSS)
|
||||
|
||||
[](https://choosealicense.com/licenses/gpl-3.0/)
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ dependencies {
|
|||
android.applicationVariants.all {
|
||||
outputs.all {
|
||||
(this as BaseVariantOutputImpl).apply {
|
||||
outputFileName = "${rootProject.name.replace(" ", "_")}-${versionName}-${buildType.name}.apk"
|
||||
outputFileName = "${rootProject.name.replace(" ", "_")}-v${versionName}-${buildType.name}.apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
app/proguard-rules.pro
vendored
5
app/proguard-rules.pro
vendored
|
|
@ -1,3 +1,8 @@
|
|||
# Xposed
|
||||
-keepclassmembers class icu.nullptr.hidemyapplist.MyApp {
|
||||
boolean isHooked;
|
||||
}
|
||||
|
||||
# Enum class
|
||||
-keepclassmembers,allowoptimization enum * {
|
||||
public static **[] values();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="PackageVisibilityPolicy,QueryAllPackagesPermission" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name="icu.nullptr.hidemyapplist.MyApp"
|
||||
android:allowBackup="true"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ import kotlin.system.exitProcess
|
|||
lateinit var hmaApp: MyApp
|
||||
|
||||
class MyApp : Application() {
|
||||
|
||||
@JvmField
|
||||
var isHooked = false
|
||||
|
||||
val globalScope = CoroutineScope(Dispatchers.Default)
|
||||
val appIconLoader by lazy {
|
||||
val iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import java.io.File
|
|||
object ConfigManager {
|
||||
|
||||
data class TemplateInfo(val name: String?, val isWhiteList: Boolean)
|
||||
data class PresetInfo(val name: String, val translation: String)
|
||||
|
||||
private const val TAG = "ConfigManager"
|
||||
private lateinit var config: JsonConfig
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ object PrefManager {
|
|||
private const val PREF_THEME_COLOR = "theme_color"
|
||||
|
||||
private const val PREF_HIDE_ICON = "hide_icon"
|
||||
private const val PREF_BYPASS_RISKY_PACKAGE_WARNING = "bypass_risky_package_warning"
|
||||
|
||||
private const val PREF_APP_FILTER_SHOW_SYSTEM = "app_filter_show_system"
|
||||
private const val PREF_APP_FILTER_SORT_METHOD = "app_filter_sort_method"
|
||||
|
|
@ -68,10 +67,6 @@ object PrefManager {
|
|||
hmaApp.packageManager.setComponentEnabledSetting(component, status, PackageManager.DONT_KILL_APP)
|
||||
}
|
||||
|
||||
var bypassRiskyPackageWarning: Boolean
|
||||
get() = pref.getBoolean(PREF_BYPASS_RISKY_PACKAGE_WARNING, false)
|
||||
set(value) = pref.edit().putBoolean(PREF_BYPASS_RISKY_PACKAGE_WARNING, value).apply()
|
||||
|
||||
var appFilter_showSystem: Boolean
|
||||
get() = pref.getBoolean(PREF_APP_FILTER_SHOW_SYSTEM, false)
|
||||
set(value) = pref.edit().putBoolean(PREF_APP_FILTER_SHOW_SYSTEM, value).apply()
|
||||
|
|
|
|||
|
|
@ -88,9 +88,6 @@ object ServiceClient : IHMAService, IBinder.DeathRecipient {
|
|||
getServiceLegacy()?.handlePackageEvent(eventType, packageName)
|
||||
}
|
||||
|
||||
override fun getPackagesForPreset(presetName: String) =
|
||||
getServiceLegacy()?.getPackagesForPreset(presetName)
|
||||
|
||||
override fun syncConfig(json: String) {
|
||||
getServiceLegacy()?.syncConfig(json)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@ class AboutActivity : AbsAboutActivity() {
|
|||
}
|
||||
|
||||
override fun onItemsCreated(items: MutableList<Any>) {
|
||||
|
||||
items.add(Category(getString(R.string.about_mychanges_title)))
|
||||
items.add(Card(getString(R.string.about_mychanges_summary)))
|
||||
|
||||
items.add(Category(getString(R.string.title_about_fork)))
|
||||
items.add(Card(getString(R.string.about_fork_description)))
|
||||
|
||||
|
|
@ -50,12 +46,10 @@ class AboutActivity : AbsAboutActivity() {
|
|||
items.add(Line())
|
||||
items.add(Contributor(R.drawable.cont_cpp_master, "LoveSy", "Idea provider", "https://github.com/yujincheng08"))
|
||||
|
||||
|
||||
items.add(Category(getString(R.string.about_fakedev)))
|
||||
items.add(Contributor(R.drawable.cont_cuynu, "Cuynu", "another loser with no coding skills", "https://git.disroot.org/cuynu"))
|
||||
|
||||
items.add(Category(getString(R.string.about_support)))
|
||||
items.add(Card("Disroot\nhttps://git.disroot.org/cuynu/HMAL-OSS"))
|
||||
items.add(Card("Github\nhttps://github.com/frknkrc44/HMA-OSS"))
|
||||
items.add(Line())
|
||||
items.add(Card("Telegram\nhttps://t.me/aerathfuns"))
|
||||
|
||||
items.add(Category(getString(R.string.about_open_source)))
|
||||
items.add(License("MultiType", "drakeet", License.APACHE_2, "https://github.com/drakeet/MultiType"))
|
||||
|
|
|
|||
|
|
@ -1,35 +1,16 @@
|
|||
package icu.nullptr.hidemyapplist.ui.adapter
|
||||
|
||||
import android.view.ViewGroup
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import icu.nullptr.hidemyapplist.common.Constants.GMS_PACKAGE_NAME
|
||||
import icu.nullptr.hidemyapplist.common.Constants.GSF_PACKAGE_NAME
|
||||
import icu.nullptr.hidemyapplist.service.ConfigManager
|
||||
import icu.nullptr.hidemyapplist.service.PrefManager
|
||||
import icu.nullptr.hidemyapplist.ui.view.AppItemView
|
||||
import org.frknkrc44.hma_oss.R
|
||||
|
||||
class AppManageAdapter(
|
||||
private val onItemClickListener: (String) -> Unit
|
||||
) : AppSelectAdapter() {
|
||||
private val riskyPackages = arrayOf(GMS_PACKAGE_NAME, GSF_PACKAGE_NAME)
|
||||
|
||||
inner class ViewHolder(view: AppItemView) : AppSelectAdapter.ViewHolder(view) {
|
||||
init {
|
||||
view.setOnClickListener {
|
||||
if (!PrefManager.bypassRiskyPackageWarning && riskyPackages.contains(view.binding.packageName.text)) {
|
||||
MaterialAlertDialogBuilder(view.context)
|
||||
.setTitle(R.string.app_warning_risky_package_title)
|
||||
.setMessage(R.string.app_warning_risky_package_desc)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
onItemClickListener.invoke(filteredList[absoluteAdapterPosition])
|
||||
}
|
||||
.show()
|
||||
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
onItemClickListener.invoke(filteredList[absoluteAdapterPosition])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import icu.nullptr.hidemyapplist.ui.view.AppItemView
|
|||
import icu.nullptr.hidemyapplist.util.PackageHelper
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.frknkrc44.hma_oss.BuildConfig
|
||||
|
||||
abstract class AppSelectAdapter(
|
||||
private val firstFilter: ((String) -> Boolean)? = null
|
||||
|
|
@ -21,15 +20,13 @@ abstract class AppSelectAdapter(
|
|||
private inner class AppFilter : Filter() {
|
||||
override fun performFiltering(constraint: CharSequence): FilterResults {
|
||||
return runBlocking {
|
||||
val constraintLowered = constraint.toString().trim().lowercase()
|
||||
val constraintLowered = constraint.toString().lowercase()
|
||||
val filteredList = PackageHelper.appList.first().filter {
|
||||
if (firstFilter?.invoke(it) == false) return@filter false
|
||||
if (!PrefManager.appFilter_showSystem && PackageHelper.isSystem(it)) return@filter false
|
||||
if (it == BuildConfig.APPLICATION_ID &&
|
||||
(this@AppSelectAdapter.javaClass == AppManageAdapter::class.java ||
|
||||
(this@AppSelectAdapter.javaClass == AppScopeAdapter::class.java && firstFilter != null))) return@filter false
|
||||
val label = PackageHelper.loadAppLabel(it)
|
||||
label.lowercase().contains(constraintLowered) || it.lowercase().contains(constraintLowered)
|
||||
val packageInfo = PackageHelper.loadPackageInfo(it)
|
||||
label.lowercase().contains(constraintLowered) || packageInfo.packageName.lowercase().contains(constraintLowered)
|
||||
}
|
||||
|
||||
FilterResults().also { it.values = filteredList }
|
||||
|
|
@ -38,11 +35,8 @@ abstract class AppSelectAdapter(
|
|||
|
||||
@Suppress("UNCHECKED_CAST", "NotifyDataSetChanged")
|
||||
override fun publishResults(constraint: CharSequence, results: FilterResults) {
|
||||
val values = results.values
|
||||
if (values != null) {
|
||||
filteredList = values as List<String>
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
filteredList = results.values as List<String>
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,12 @@ import android.os.Bundle
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.widget.TextView
|
||||
import androidx.activity.addCallback
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.flowWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import icu.nullptr.hidemyapplist.service.PrefManager
|
||||
import icu.nullptr.hidemyapplist.ui.adapter.AppSelectAdapter
|
||||
|
|
@ -22,11 +20,10 @@ import icu.nullptr.hidemyapplist.util.PackageHelper
|
|||
import kotlinx.coroutines.launch
|
||||
import org.frknkrc44.hma_oss.R
|
||||
import org.frknkrc44.hma_oss.databinding.FragmentAppSelectBinding
|
||||
import org.frknkrc44.hma_oss.ui.fragment.AppPresetFragment
|
||||
|
||||
abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
||||
|
||||
protected val binding by viewBinding<FragmentAppSelectBinding>()
|
||||
private val binding by viewBinding<FragmentAppSelectBinding>()
|
||||
|
||||
protected abstract val firstComparator: Comparator<String>
|
||||
protected abstract val adapter: AppSelectAdapter
|
||||
|
|
@ -37,21 +34,17 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
navController.navigateUp()
|
||||
}
|
||||
|
||||
protected fun applyFilter() {
|
||||
private fun applyFilter() {
|
||||
adapter.filter.filter(search)
|
||||
}
|
||||
|
||||
protected open fun sortList() {
|
||||
private fun sortList() {
|
||||
lifecycleScope.launch {
|
||||
PackageHelper.sortList(firstComparator)
|
||||
applyFilter()
|
||||
}
|
||||
}
|
||||
|
||||
open fun invalidateCache() {
|
||||
PackageHelper.invalidateCache()
|
||||
}
|
||||
|
||||
private fun onMenuOptionSelected(item: MenuItem) {
|
||||
when (item.itemId) {
|
||||
R.id.menu_show_system -> {
|
||||
|
|
@ -82,13 +75,11 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
sortList()
|
||||
}
|
||||
|
||||
open fun getFragmentTitle() = getString(R.string.title_app_select)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { onBack() }
|
||||
setupToolbar(
|
||||
toolbar = binding.toolbar,
|
||||
title = getFragmentTitle(),
|
||||
title = getString(R.string.title_app_select),
|
||||
navigationIcon = R.drawable.baseline_arrow_back_24,
|
||||
navigationOnClick = { onBack() },
|
||||
menuRes = R.menu.menu_app_list,
|
||||
|
|
@ -119,16 +110,9 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
binding.list.layoutManager = LinearLayoutManager(context)
|
||||
binding.list.adapter = adapter
|
||||
binding.swipeRefresh.setOnRefreshListener {
|
||||
invalidateCache()
|
||||
PackageHelper.invalidateCache()
|
||||
}
|
||||
|
||||
adapter.registerAdapterDataObserver(
|
||||
EmptyDataObserver(
|
||||
binding.list,
|
||||
binding.listEmptyContainer
|
||||
)
|
||||
)
|
||||
|
||||
lifecycleScope.launch {
|
||||
PackageHelper.isRefreshing
|
||||
.flowWithLifecycle(lifecycle)
|
||||
|
|
@ -139,66 +123,23 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
|
||||
sortList()
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
}
|
||||
}
|
||||
|
||||
// Credit: https://medium.com/nerd-for-tech/empty-dataset-in-recyclerview-ad86833dd5c6
|
||||
inner class EmptyDataObserver(
|
||||
private val recyclerView: RecyclerView,
|
||||
private val emptyView: View
|
||||
): RecyclerView.AdapterDataObserver() {
|
||||
private val fragmentType by lazy {
|
||||
when(this@AppSelectFragment.javaClass) {
|
||||
ScopeFragment::class.java -> 0
|
||||
AppPresetFragment::class.java -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
val atLeastEntryCount: Int get() {
|
||||
if (!search.isBlank()) return 0
|
||||
|
||||
return if (fragmentType < 2) 1 else 2
|
||||
}
|
||||
|
||||
private fun checkIfEmpty() {
|
||||
val emptyViewVisible = recyclerView.adapter!!.itemCount < atLeastEntryCount
|
||||
emptyView.visibility = if (emptyViewVisible) View.VISIBLE else View.GONE
|
||||
if (emptyViewVisible) {
|
||||
emptyView.findViewById<TextView>(R.id.list_empty_text).text = getString(
|
||||
when (fragmentType) {
|
||||
0 -> R.string.list_empty_no_enabled
|
||||
1 -> R.string.list_empty_preset
|
||||
else -> R.string.list_empty_no_apps
|
||||
}
|
||||
)
|
||||
}
|
||||
recyclerView.visibility = if (emptyViewVisible) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
override fun onChanged() {
|
||||
super.onChanged()
|
||||
checkIfEmpty()
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.widget.Toast
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.fragment.app.Fragment
|
||||
|
|
@ -77,26 +76,23 @@ class AppSettingsFragment : Fragment(R.layout.fragment_settings) {
|
|||
.commit()
|
||||
}
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,9 +103,6 @@ class AppSettingsFragment : Fragment(R.layout.fragment_settings) {
|
|||
"enableHide" -> pack.enabled
|
||||
"useWhiteList" -> pack.config.useWhitelist
|
||||
"excludeSystemApps" -> pack.config.excludeSystemApps
|
||||
"hideInstallationSource" -> pack.config.hideInstallationSource
|
||||
"hideSystemInstallationSource" -> pack.config.hideSystemInstallationSource
|
||||
"excludeTargetInstallationSource" -> pack.config.excludeTargetInstallationSource
|
||||
else -> throw IllegalArgumentException("Invalid key: $key")
|
||||
}
|
||||
}
|
||||
|
|
@ -119,9 +112,6 @@ class AppSettingsFragment : Fragment(R.layout.fragment_settings) {
|
|||
"enableHide" -> pack.enabled = value
|
||||
"useWhiteList" -> pack.config.useWhitelist = value
|
||||
"excludeSystemApps" -> pack.config.excludeSystemApps = value
|
||||
"hideInstallationSource" -> pack.config.hideInstallationSource = value
|
||||
"hideSystemInstallationSource" -> pack.config.hideSystemInstallationSource = value
|
||||
"excludeTargetInstallationSource" -> pack.config.excludeTargetInstallationSource = value
|
||||
else -> throw IllegalArgumentException("Invalid key: $key")
|
||||
}
|
||||
}
|
||||
|
|
@ -162,21 +152,6 @@ class AppSettingsFragment : Fragment(R.layout.fragment_settings) {
|
|||
it.title = PackageHelper.loadAppLabel(pack.app)
|
||||
it.summary = PackageHelper.loadPackageInfo(pack.app).packageName
|
||||
}
|
||||
findPreference<SwitchPreferenceCompat>("hideInstallationSource")?.setOnPreferenceChangeListener { _, newValue ->
|
||||
Toast.makeText(requireContext(),
|
||||
R.string.app_force_stop_warning, Toast.LENGTH_LONG).show()
|
||||
true
|
||||
}
|
||||
findPreference<SwitchPreferenceCompat>("hideSystemInstallationSource")?.setOnPreferenceChangeListener { _, newValue ->
|
||||
Toast.makeText(requireContext(),
|
||||
R.string.app_force_stop_warning, Toast.LENGTH_LONG).show()
|
||||
true
|
||||
}
|
||||
findPreference<SwitchPreferenceCompat>("excludeTargetInstallationSource")?.setOnPreferenceChangeListener { _, newValue ->
|
||||
Toast.makeText(requireContext(),
|
||||
R.string.app_force_stop_warning, Toast.LENGTH_LONG).show()
|
||||
true
|
||||
}
|
||||
findPreference<SwitchPreferenceCompat>("useWhiteList")?.setOnPreferenceChangeListener { _, newValue ->
|
||||
pack.config.applyTemplates.clear()
|
||||
pack.config.extraAppList.clear()
|
||||
|
|
|
|||
|
|
@ -143,26 +143,23 @@ class LogsFragment : Fragment(R.layout.fragment_logs) {
|
|||
binding.list.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))
|
||||
updateLogs()
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,26 +57,23 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
.commit()
|
||||
}
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +94,6 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
"blackDarkTheme" -> PrefManager.blackDarkTheme
|
||||
"detailLog" -> ConfigManager.detailLog
|
||||
"hideIcon" -> PrefManager.hideIcon
|
||||
"bypassRiskyPackageWarning" -> PrefManager.bypassRiskyPackageWarning
|
||||
"appDataIsolation" -> CommonUtils.isAppDataIsolationEnabled
|
||||
"voldAppDataIsolation" -> CommonUtils.isVoldAppDataIsolationEnabled
|
||||
"forceMountData" -> ConfigManager.forceMountData
|
||||
|
|
@ -122,7 +118,6 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
"detailLog" -> ConfigManager.detailLog = value
|
||||
"forceMountData" -> ConfigManager.forceMountData = value
|
||||
"hideIcon" -> PrefManager.hideIcon = value
|
||||
"bypassRiskyPackageWarning" -> PrefManager.bypassRiskyPackageWarning = value
|
||||
"appDataIsolation" -> Unit
|
||||
"voldAppDataIsolation" -> Unit
|
||||
else -> throw IllegalArgumentException("Invalid key: $key")
|
||||
|
|
@ -269,11 +264,6 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
|
||||
configureDataIsolation()
|
||||
|
||||
findPreference<SwitchPreferenceCompat>("bypassRiskyPackageWarning")?.setOnPreferenceChangeListener { _, newValue ->
|
||||
activity?.recreate()
|
||||
true
|
||||
}
|
||||
|
||||
findPreference<Preference>("stopSystemService")?.setOnPreferenceClickListener {
|
||||
if (ServiceClient.serviceVersion != 0) {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package icu.nullptr.hidemyapplist.ui.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
|
@ -11,6 +12,7 @@ import androidx.fragment.app.setFragmentResultListener
|
|||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import icu.nullptr.hidemyapplist.common.JsonConfig
|
||||
import icu.nullptr.hidemyapplist.service.ConfigManager
|
||||
import icu.nullptr.hidemyapplist.ui.adapter.TemplateAdapter
|
||||
|
|
@ -24,6 +26,14 @@ class TemplateManageFragment : Fragment(R.layout.fragment_template_manage) {
|
|||
private val binding by viewBinding<FragmentTemplateManageBinding>()
|
||||
private val adapter = TemplateAdapter(this::navigateToSettings)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.nav_host_fragment
|
||||
scrimColor = Color.TRANSPARENT
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setupToolbar(
|
||||
toolbar = binding.toolbar,
|
||||
|
|
@ -43,26 +53,23 @@ class TemplateManageFragment : Fragment(R.layout.fragment_template_manage) {
|
|||
binding.templateList.layoutManager = LinearLayoutManager(context)
|
||||
binding.templateList.adapter = adapter
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,16 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
|
|||
navController.navigateUp()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
/*
|
||||
sharedElementEnterTransition = MaterialContainerTransform().apply {
|
||||
drawingViewId = R.id.nav_host_fragment
|
||||
scrimColor = Color.TRANSPARENT
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { onBack(false) }
|
||||
setupToolbar(
|
||||
|
|
@ -70,7 +80,6 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
|
|||
)
|
||||
|
||||
binding.templateName.setText(viewModel.name)
|
||||
binding.workMode.setText(if (viewModel.isWhiteList) R.string.whitelist else R.string.blacklist)
|
||||
binding.templateName.addTextChangedListener { viewModel.name = it.toString() }
|
||||
binding.targetApps.setOnClickListener {
|
||||
setFragmentResultListener("app_select") { _, bundle ->
|
||||
|
|
@ -110,26 +119,23 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
|
|||
}
|
||||
}
|
||||
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
val insets = binding.root.rootWindowInsets
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val barInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
binding.root.setPadding(
|
||||
barInsets.left,
|
||||
barInsets.top,
|
||||
barInsets.right,
|
||||
barInsets.bottom,
|
||||
)
|
||||
} else {
|
||||
@Suppress("deprecation")
|
||||
binding.root.setPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class AppItemView @JvmOverloads constructor(
|
|||
defStyleRes: Int = 0
|
||||
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
|
||||
|
||||
val binding by viewBinding<AppItemViewBinding>(createMethod = CreateMethod.INFLATE)
|
||||
private val binding by viewBinding<AppItemViewBinding>(createMethod = CreateMethod.INFLATE)
|
||||
|
||||
var showEnabled: Boolean
|
||||
get() = binding.enabled.visibility == VISIBLE
|
||||
|
|
@ -35,12 +35,7 @@ class AppItemView @JvmOverloads constructor(
|
|||
|
||||
fun load(packageName: String) {
|
||||
binding.packageName.text = packageName
|
||||
try {
|
||||
binding.label.text = PackageHelper.loadAppLabel(packageName)
|
||||
binding.icon.setImageBitmap(PackageHelper.loadAppIcon(packageName))
|
||||
} catch (e: Throwable) {
|
||||
binding.label.text = packageName
|
||||
binding.icon.setImageResource(android.R.drawable.sym_def_app_icon)
|
||||
}
|
||||
binding.label.text = PackageHelper.loadAppLabel(packageName)
|
||||
binding.icon.setImageBitmap(PackageHelper.loadAppIcon(packageName))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,15 +26,11 @@ object PackageHelper {
|
|||
val icon: Bitmap
|
||||
)
|
||||
|
||||
object Comparators {
|
||||
private object Comparators {
|
||||
val byLabel = Comparator<String> { o1, o2 ->
|
||||
try {
|
||||
val n1 = loadAppLabel(o1).lowercase(Locale.getDefault())
|
||||
val n2 = loadAppLabel(o2).lowercase(Locale.getDefault())
|
||||
Collator.getInstance(Locale.getDefault()).compare(n1, n2)
|
||||
} catch (_: Throwable) {
|
||||
byPackageName.compare(o1, o2)
|
||||
}
|
||||
val n1 = loadAppLabel(o1).lowercase(Locale.getDefault())
|
||||
val n2 = loadAppLabel(o2).lowercase(Locale.getDefault())
|
||||
Collator.getInstance(Locale.getDefault()).compare(n1, n2)
|
||||
}
|
||||
val byPackageName = Comparator<String> { o1, o2 ->
|
||||
val n1 = o1.lowercase(Locale.getDefault())
|
||||
|
|
@ -42,22 +38,14 @@ object PackageHelper {
|
|||
Collator.getInstance(Locale.getDefault()).compare(n1, n2)
|
||||
}
|
||||
val byInstallTime = Comparator<String> { o1, o2 ->
|
||||
try {
|
||||
val n1 = loadPackageInfo(o1).firstInstallTime
|
||||
val n2 = loadPackageInfo(o2).firstInstallTime
|
||||
n2.compareTo(n1)
|
||||
} catch (_: Throwable) {
|
||||
byPackageName.compare(o1, o2)
|
||||
}
|
||||
val n1 = loadPackageInfo(o1).firstInstallTime
|
||||
val n2 = loadPackageInfo(o2).firstInstallTime
|
||||
n2.compareTo(n1)
|
||||
}
|
||||
val byUpdateTime = Comparator<String> { o1, o2 ->
|
||||
try {
|
||||
val n1 = loadPackageInfo(o1).lastUpdateTime
|
||||
val n2 = loadPackageInfo(o2).lastUpdateTime
|
||||
n2.compareTo(n1)
|
||||
} catch (_: Throwable) {
|
||||
byPackageName.compare(o1, o2)
|
||||
}
|
||||
val n1 = loadPackageInfo(o1).lastUpdateTime
|
||||
val n2 = loadPackageInfo(o2).lastUpdateTime
|
||||
n2.compareTo(n1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,10 +99,6 @@ object PackageHelper {
|
|||
mAppList.emit(list)
|
||||
}
|
||||
|
||||
fun exists(packageName: String) = runBlocking {
|
||||
packageCache.first().contains(packageName)
|
||||
}
|
||||
|
||||
fun loadPackageInfo(packageName: String): PackageInfo = runBlocking {
|
||||
packageCache.first()[packageName]!!.info
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
package org.frknkrc44.hma_oss.ui.adapter
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Filter
|
||||
import icu.nullptr.hidemyapplist.service.ServiceClient
|
||||
import icu.nullptr.hidemyapplist.ui.adapter.AppSelectAdapter
|
||||
import icu.nullptr.hidemyapplist.ui.view.AppItemView
|
||||
import icu.nullptr.hidemyapplist.util.PackageHelper
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class AppPresetAdapter(
|
||||
private val presetName: String
|
||||
) : AppSelectAdapter() {
|
||||
var packages = mutableListOf<String>()
|
||||
|
||||
fun updateList() {
|
||||
packages.clear()
|
||||
packages += ServiceClient.getPackagesForPreset(presetName)?.toList() ?: listOf()
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: AppItemView) : AppSelectAdapter.ViewHolder(view) {
|
||||
override fun bind(packageName: String) {
|
||||
(itemView as AppItemView).let {
|
||||
it.load(packageName)
|
||||
it.alpha = if (!PackageHelper.exists(packageName)) 0.5f else 1.0f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = AppItemView(parent.context, false)
|
||||
view.layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
private inner class PresetFilter : Filter() {
|
||||
|
||||
override fun performFiltering(constraint: CharSequence): FilterResults {
|
||||
return runBlocking {
|
||||
val constraintLowered = constraint.toString().trim().lowercase()
|
||||
val filteredList = packages.filter {
|
||||
if (constraintLowered.isEmpty()) return@filter true
|
||||
|
||||
if (it.lowercase().contains(constraintLowered)) return@filter true
|
||||
|
||||
try {
|
||||
val label = PackageHelper.loadAppLabel(it)
|
||||
return@filter label.lowercase().contains(constraintLowered)
|
||||
} catch (e: Throwable) {
|
||||
return@filter false
|
||||
}
|
||||
}
|
||||
|
||||
FilterResults().also { it.values = filteredList }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "NotifyDataSetChanged")
|
||||
override fun publishResults(constraint: CharSequence, results: FilterResults) {
|
||||
val values = results.values
|
||||
if (values != null) {
|
||||
filteredList = values as List<String>
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val mFilter = PresetFilter()
|
||||
|
||||
override fun getFilter(): Filter = mFilter
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue