Add "Show presets" option, fix backup/restore config buttons, update translations
This commit is contained in:
parent
11fc2fc206
commit
b51a3f695e
24 changed files with 380 additions and 39 deletions
|
|
@ -12,6 +12,7 @@ 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
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowInsets
|
||||
import android.widget.TextView
|
||||
import androidx.activity.addCallback
|
||||
|
|
@ -23,6 +22,7 @@ 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) {
|
||||
|
||||
|
|
@ -37,11 +37,11 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
navController.navigateUp()
|
||||
}
|
||||
|
||||
private fun applyFilter() {
|
||||
protected fun applyFilter() {
|
||||
adapter.filter.filter(search)
|
||||
}
|
||||
|
||||
private fun sortList() {
|
||||
protected open fun sortList() {
|
||||
lifecycleScope.launch {
|
||||
PackageHelper.sortList(firstComparator)
|
||||
applyFilter()
|
||||
|
|
@ -78,11 +78,13 @@ 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 = getString(R.string.title_app_select),
|
||||
title = getFragmentTitle(),
|
||||
navigationIcon = R.drawable.baseline_arrow_back_24,
|
||||
navigationOnClick = { onBack() },
|
||||
menuRes = R.menu.menu_app_list,
|
||||
|
|
@ -161,17 +163,23 @@ abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
|
|||
private val recyclerView: RecyclerView,
|
||||
private val emptyView: View
|
||||
): RecyclerView.AdapterDataObserver() {
|
||||
private val isScopeFragment = this@AppSelectFragment.javaClass == ScopeFragment::class.java
|
||||
private val fragmentType by lazy {
|
||||
when(this@AppSelectFragment.javaClass) {
|
||||
ScopeFragment::class.java -> 0
|
||||
AppPresetFragment::class.java -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIfEmpty() {
|
||||
val emptyViewVisible = recyclerView.adapter!!.itemCount < if (isScopeFragment) 1 else 2
|
||||
val emptyViewVisible = recyclerView.adapter!!.itemCount < if (fragmentType < 2) 1 else 2
|
||||
emptyView.visibility = if (emptyViewVisible) View.VISIBLE else View.GONE
|
||||
if (emptyViewVisible) {
|
||||
emptyView.findViewById<TextView>(R.id.list_empty_text).text = getString(
|
||||
if (isScopeFragment) {
|
||||
R.string.list_empty_no_enabled
|
||||
} else {
|
||||
R.string.list_empty_no_apps
|
||||
when (fragmentType) {
|
||||
0 -> R.string.list_empty_no_enabled
|
||||
1 -> R.string.list_empty_preset
|
||||
else -> R.string.list_empty_no_apps
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package icu.nullptr.hidemyapplist.ui.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
|
@ -12,7 +11,6 @@ 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
|
||||
|
|
@ -28,10 +26,12 @@ class TemplateManageFragment : Fragment(R.layout.fragment_template_manage) {
|
|||
|
||||
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?) {
|
||||
|
|
|
|||
|
|
@ -26,11 +26,15 @@ object PackageHelper {
|
|||
val icon: Bitmap
|
||||
)
|
||||
|
||||
private object Comparators {
|
||||
object Comparators {
|
||||
val byLabel = Comparator<String> { o1, o2 ->
|
||||
val n1 = loadAppLabel(o1).lowercase(Locale.getDefault())
|
||||
val n2 = loadAppLabel(o2).lowercase(Locale.getDefault())
|
||||
Collator.getInstance(Locale.getDefault()).compare(n1, n2)
|
||||
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 byPackageName = Comparator<String> { o1, o2 ->
|
||||
val n1 = o1.lowercase(Locale.getDefault())
|
||||
|
|
@ -38,14 +42,22 @@ object PackageHelper {
|
|||
Collator.getInstance(Locale.getDefault()).compare(n1, n2)
|
||||
}
|
||||
val byInstallTime = Comparator<String> { o1, o2 ->
|
||||
val n1 = loadPackageInfo(o1).firstInstallTime
|
||||
val n2 = loadPackageInfo(o2).firstInstallTime
|
||||
n2.compareTo(n1)
|
||||
try {
|
||||
val n1 = loadPackageInfo(o1).firstInstallTime
|
||||
val n2 = loadPackageInfo(o2).firstInstallTime
|
||||
n2.compareTo(n1)
|
||||
} catch (_: Throwable) {
|
||||
byPackageName.compare(o1, o2)
|
||||
}
|
||||
}
|
||||
val byUpdateTime = Comparator<String> { o1, o2 ->
|
||||
val n1 = loadPackageInfo(o1).lastUpdateTime
|
||||
val n2 = loadPackageInfo(o2).lastUpdateTime
|
||||
n2.compareTo(n1)
|
||||
try {
|
||||
val n1 = loadPackageInfo(o1).lastUpdateTime
|
||||
val n2 = loadPackageInfo(o2).lastUpdateTime
|
||||
n2.compareTo(n1)
|
||||
} catch (_: Throwable) {
|
||||
byPackageName.compare(o1, o2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,6 +111,10 @@ object PackageHelper {
|
|||
mAppList.emit(list)
|
||||
}
|
||||
|
||||
fun exists(packageName: String) = runBlocking {
|
||||
packageCache.first().contains(packageName)
|
||||
}
|
||||
|
||||
fun loadPackageInfo(packageName: String): PackageInfo = runBlocking {
|
||||
packageCache.first()[packageName]!!.info
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
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() {
|
||||
val packages by lazy { ServiceClient.getPackagesForPreset(presetName)?.toMutableList() ?: mutableListOf() }
|
||||
|
||||
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().lowercase()
|
||||
val filteredList = packages.filter {
|
||||
if (constraintLowered.isEmpty()) return@filter true
|
||||
val label = PackageHelper.loadAppLabel(it)
|
||||
label.lowercase().contains(constraintLowered) || it.lowercase().contains(constraintLowered)
|
||||
}
|
||||
|
||||
FilterResults().also { it.values = filteredList }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "NotifyDataSetChanged")
|
||||
override fun publishResults(constraint: CharSequence, results: FilterResults) {
|
||||
filteredList = results.values as List<String>
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private val mFilter = PresetFilter()
|
||||
|
||||
override fun getFilter(): Filter = mFilter
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package org.frknkrc44.hma_oss.ui.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import icu.nullptr.hidemyapplist.common.AppPresets
|
||||
import icu.nullptr.hidemyapplist.hmaApp
|
||||
import icu.nullptr.hidemyapplist.service.ConfigManager
|
||||
import icu.nullptr.hidemyapplist.ui.view.ListItemView
|
||||
import org.frknkrc44.hma_oss.BuildConfig
|
||||
import org.frknkrc44.hma_oss.R
|
||||
|
||||
class AppPresetListAdapter(
|
||||
private val onClickListener: ((ConfigManager.PresetInfo) -> Unit)?
|
||||
) : RecyclerView.Adapter<AppPresetListAdapter.ViewHolder>() {
|
||||
|
||||
private lateinit var list: List<ConfigManager.PresetInfo>
|
||||
|
||||
init {
|
||||
updateList()
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: ListItemView) : RecyclerView.ViewHolder(view) {
|
||||
init {
|
||||
view.setOnClickListener {
|
||||
onClickListener?.invoke(list[absoluteAdapterPosition])
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(presetName: String) {
|
||||
with(itemView as ListItemView) {
|
||||
setIcon(R.drawable.baseline_assignment_24)
|
||||
text = presetName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = ListItemView(parent.context)
|
||||
view.layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun getItemCount() = list.size
|
||||
|
||||
override fun getItemId(position: Int) = list[position].name.hashCode().toLong()
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(list[position].translation)
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateList() {
|
||||
val presetNames = AppPresets.instance.getAllPresetNames()
|
||||
val presetTranslations = presetNames.map { name ->
|
||||
try {
|
||||
val id = hmaApp.resources.getIdentifier(
|
||||
"preset_${name}",
|
||||
"string",
|
||||
BuildConfig.APPLICATION_ID
|
||||
)
|
||||
|
||||
return@map if (id != 0) { hmaApp.resources.getString(id) } else { name }
|
||||
} catch (_: Throwable) {}
|
||||
|
||||
name
|
||||
}
|
||||
|
||||
list = presetNames
|
||||
.map { ConfigManager.PresetInfo(it, presetTranslations[presetNames.indexOf(it)]) }
|
||||
.sortedWith { a, b -> a.translation.lowercase().compareTo(b.translation.lowercase()) }
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package org.frknkrc44.hma_oss.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import icu.nullptr.hidemyapplist.service.PrefManager
|
||||
import icu.nullptr.hidemyapplist.ui.fragment.AppSelectFragment
|
||||
import icu.nullptr.hidemyapplist.util.PackageHelper
|
||||
import icu.nullptr.hidemyapplist.util.PackageHelper.Comparators
|
||||
import kotlinx.coroutines.launch
|
||||
import org.frknkrc44.hma_oss.ui.adapter.AppPresetAdapter
|
||||
|
||||
class AppPresetFragment() : AppSelectFragment() {
|
||||
|
||||
override val firstComparator = Comparator.comparing(PackageHelper::exists).reversed()
|
||||
|
||||
override val adapter by lazy {
|
||||
val args by navArgs<AppPresetFragmentArgs>()
|
||||
AppPresetAdapter(args.presetName)
|
||||
}
|
||||
|
||||
override fun getFragmentTitle(): String {
|
||||
val args by navArgs<AppPresetFragmentArgs>()
|
||||
return args.presetTitle
|
||||
}
|
||||
|
||||
override fun sortList() {
|
||||
lifecycleScope.launch {
|
||||
sortPresetList()
|
||||
applyFilter()
|
||||
}
|
||||
}
|
||||
|
||||
fun sortPresetList() {
|
||||
var comparator = when (PrefManager.appFilter_sortMethod) {
|
||||
PrefManager.SortMethod.BY_LABEL -> Comparators.byLabel
|
||||
PrefManager.SortMethod.BY_PACKAGE_NAME -> Comparators.byPackageName
|
||||
PrefManager.SortMethod.BY_INSTALL_TIME -> Comparators.byInstallTime
|
||||
PrefManager.SortMethod.BY_UPDATE_TIME -> Comparators.byUpdateTime
|
||||
}
|
||||
if (PrefManager.appFilter_reverseOrder) comparator = comparator.reversed()
|
||||
adapter.packages.sortWith(firstComparator.then(comparator))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
// returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
}
|
||||
}
|
||||
|
|
@ -267,6 +267,14 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
|
|||
}
|
||||
}
|
||||
|
||||
with(binding.managePresets) {
|
||||
text1.text = getString(R.string.title_preset_manage)
|
||||
icon.setImageResource(R.drawable.baseline_my_location_24)
|
||||
root.setOnClickListener {
|
||||
navigate(R.id.nav_presets)
|
||||
}
|
||||
}
|
||||
|
||||
with(binding.navLogs) {
|
||||
text1.text = getString(R.string.title_logs)
|
||||
icon.setImageResource(R.drawable.outline_assignment_24)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
package org.frknkrc44.hma_oss.ui.fragment
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import icu.nullptr.hidemyapplist.service.ConfigManager
|
||||
import icu.nullptr.hidemyapplist.ui.util.navController
|
||||
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
|
||||
import org.frknkrc44.hma_oss.R
|
||||
import org.frknkrc44.hma_oss.databinding.FragmentPresetManageBinding
|
||||
import org.frknkrc44.hma_oss.ui.adapter.AppPresetListAdapter
|
||||
|
||||
class PresetManageFragment : Fragment(R.layout.fragment_preset_manage) {
|
||||
|
||||
private val binding by viewBinding<FragmentPresetManageBinding>()
|
||||
private val adapter = AppPresetListAdapter(this::navigateToPreset)
|
||||
|
||||
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,
|
||||
title = getString(R.string.title_preset_manage),
|
||||
navigationIcon = R.drawable.baseline_arrow_back_24,
|
||||
navigationOnClick = { navController.navigateUp() }
|
||||
)
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
|
||||
binding.presetList.layoutManager = LinearLayoutManager(context)
|
||||
binding.presetList.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
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToPreset(presetInfo: ConfigManager.PresetInfo) {
|
||||
val args = AppPresetFragmentArgs(presetInfo.name, presetInfo.translation)
|
||||
navController.navigate(R.id.nav_preset_inner_manage, args.toBundle())
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,10 @@
|
|||
android:id="@+id/manage_templates"
|
||||
layout="@layout/view_home_item" />
|
||||
|
||||
<include
|
||||
android:id="@+id/manage_presets"
|
||||
layout="@layout/view_home_item" />
|
||||
|
||||
<include
|
||||
android:id="@+id/nav_logs"
|
||||
layout="@layout/view_home_item" />
|
||||
|
|
@ -75,6 +79,8 @@
|
|||
android:id="@+id/backup_config"
|
||||
app:icon="@drawable/outline_backup_24"
|
||||
android:text="@string/home_backup_config"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -84,6 +90,8 @@
|
|||
android:id="@+id/restore_config"
|
||||
app:icon="@drawable/outline_settings_backup_restore_24"
|
||||
android:text="@string/home_restore_config"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
32
app/src/main/res/layout/fragment_preset_manage.xml
Normal file
32
app/src/main/res/layout/fragment_preset_manage.xml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"
|
||||
android:elevation="0dp" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/preset_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -22,6 +22,10 @@
|
|||
android:id="@+id/nav_template_manage"
|
||||
android:name="icu.nullptr.hidemyapplist.ui.fragment.TemplateManageFragment"
|
||||
android:label="@string/title_template_manage" />
|
||||
<fragment
|
||||
android:id="@+id/nav_presets"
|
||||
android:name="org.frknkrc44.hma_oss.ui.fragment.PresetManageFragment"
|
||||
android:label="@string/title_preset_manage" />
|
||||
<fragment
|
||||
android:id="@+id/nav_template_settings"
|
||||
android:name="icu.nullptr.hidemyapplist.ui.fragment.TemplateSettingsFragment"
|
||||
|
|
@ -38,6 +42,16 @@
|
|||
android:id="@+id/nav_app_manage"
|
||||
android:name="icu.nullptr.hidemyapplist.ui.fragment.AppManageFragment"
|
||||
android:label="@string/title_app_manage" />
|
||||
<fragment
|
||||
android:id="@+id/nav_preset_inner_manage"
|
||||
android:name="org.frknkrc44.hma_oss.ui.fragment.AppPresetFragment">
|
||||
<argument
|
||||
android:name="presetName"
|
||||
app:argType="string" />
|
||||
<argument
|
||||
android:name="presetTitle"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/nav_app_settings"
|
||||
android:name="icu.nullptr.hidemyapplist.ui.fragment.AppSettingsFragment"
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@
|
|||
|
||||
<dimen name="primary_elevation">6dp</dimen>
|
||||
<dimen name="secondary_elevation">1dp</dimen>
|
||||
<dimen name="text_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
<string name="list_sort_by_update_time">By update time</string>
|
||||
<string name="list_empty_no_enabled">Try enabling hiding for apps with this template\'s work mode and apps will appear here</string>
|
||||
<string name="list_empty_no_apps">No applications found, maybe you didn\'t allow this app to query all packages</string>
|
||||
<string name="list_empty_preset">No applications added in this preset</string>
|
||||
|
||||
<!-- Manage templates -->
|
||||
<string name="template_usage_hint">Establish templates for \"restless\" apps, controlling applist they can obtain.\n\nBlacklist (recommended): the apps selected in the template will be invisible to the apps applying the template.\nWhitelist: the apps not selected in the template will be invisible to the apps applying the template.</string>
|
||||
|
|
@ -106,7 +107,8 @@
|
|||
<string name="app_exclude_target_installation_source_desc">You can enable it if this app is not available at Play Store</string>
|
||||
<string name="app_force_stop_warning">Don\'t forget to force stop the target app after saving the configuration</string>
|
||||
|
||||
<!-- Preset names -->
|
||||
<!-- Presets -->
|
||||
<string name="title_preset_manage">Show presets</string>
|
||||
<string name="preset_xposed">LSPosed/Xposed modules</string>
|
||||
<string name="preset_root_apps">Root managers/Rooted apps</string>
|
||||
<string name="preset_custom_rom">Custom ROM apps</string>
|
||||
|
|
|
|||
|
|
@ -15,4 +15,6 @@ interface IHMAService {
|
|||
void clearLogs() = 5;
|
||||
|
||||
void handlePackageEvent(String eventType, String packageName) = 6;
|
||||
|
||||
String[] getPackagesForPreset(String presetName) = 7;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ abstract class BasePreset(val name: String) {
|
|||
|
||||
fun containsPackage(packageName: String) = exactPackageNames.contains(packageName) || packageNames.contains(packageName)
|
||||
|
||||
val packages get() = packageNames + exactPackageNames
|
||||
|
||||
fun addPackageInfoPreset(appInfo: ApplicationInfo): Boolean {
|
||||
val packageName = appInfo.packageName
|
||||
if (!exactPackageNames.contains(packageName) && canBeAddedIntoPreset(appInfo)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[versions]
|
||||
agp = "8.12.1"
|
||||
agp = "8.13.0"
|
||||
kotlin = "2.1.10"
|
||||
material = "1.13.0-rc01"
|
||||
rxhttp = "3.3.1"
|
||||
|
|
@ -13,7 +13,6 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi
|
|||
ksp = { id = "com.google.devtools.ksp", version = "2.1.10-1.0.31" }
|
||||
nav-safeargs-kotlin = { id = "androidx.navigation.safeargs.kotlin", version = "2.8.8" }
|
||||
autoresconfig = { id = "dev.rikka.tools.autoresconfig", version = "1.2.2" }
|
||||
materialthemebuilder = { id = "dev.rikka.tools.materialthemebuilder", version = "1.5.1" }
|
||||
refine = { id = "dev.rikka.tools.refine", version = "4.4.0" }
|
||||
|
||||
[libraries]
|
||||
|
|
|
|||
|
|
@ -277,4 +277,7 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
Intent.ACTION_PACKAGE_REMOVED -> AppPresets.instance.handlePackageRemoved(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackagesForPreset(presetName: String) =
|
||||
AppPresets.instance.getPresetByName(presetName)?.packages?.toTypedArray()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ package icu.nullptr.hidemyapplist.xposed
|
|||
import android.content.pm.IPackageManager
|
||||
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.getFieldByDesc
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookAllConstructorAfter
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
private const val TAG = "HMA-XposedEntry"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue