From b21e660eb1230e0f0a80800498876fb1ed1a56f6 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sat, 16 Aug 2025 13:49:47 +0200
Subject: [PATCH 1/7] Implement VolumeStepsIncrease
---
VolumeStepsIncrease/build.gradle.kts | 17 +++++++
.../src/main/AndroidManifest.xml | 34 ++++++++++++++
.../src/main/assets/xposed_init | 1 +
.../VolumeStepsIncrease/Common.kt | 24 ++++++++++
.../VolumeStepsIncrease/Hook.kt | 37 +++++++++++++++
.../VolumeStepsIncrease/SettingsActivity.kt | 46 +++++++++++++++++++
.../src/main/res/layout/settings_activity.xml | 14 ++++++
.../src/main/res/values-v21/themes.xml | 4 ++
.../src/main/res/values/arrays.xml | 6 +++
.../src/main/res/values/strings.xml | 5 ++
.../src/main/res/values/themes.xml | 8 ++++
.../src/main/res/xml/root_preferences.xml | 4 ++
modules.gradle.kts | 1 +
13 files changed, 201 insertions(+)
create mode 100644 VolumeStepsIncrease/build.gradle.kts
create mode 100644 VolumeStepsIncrease/src/main/AndroidManifest.xml
create mode 100644 VolumeStepsIncrease/src/main/assets/xposed_init
create mode 100644 VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
create mode 100644 VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
create mode 100644 VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
create mode 100644 VolumeStepsIncrease/src/main/res/layout/settings_activity.xml
create mode 100644 VolumeStepsIncrease/src/main/res/values-v21/themes.xml
create mode 100644 VolumeStepsIncrease/src/main/res/values/arrays.xml
create mode 100644 VolumeStepsIncrease/src/main/res/values/strings.xml
create mode 100644 VolumeStepsIncrease/src/main/res/values/themes.xml
create mode 100644 VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
diff --git a/VolumeStepsIncrease/build.gradle.kts b/VolumeStepsIncrease/build.gradle.kts
new file mode 100644
index 0000000..352aa6a
--- /dev/null
+++ b/VolumeStepsIncrease/build.gradle.kts
@@ -0,0 +1,17 @@
+plugins {
+ alias(libs.plugins.buildlogic.android.application)
+ alias(libs.plugins.buildlogic.kotlin.android)
+}
+
+android {
+ namespace = "com.programminghoch10.VolumeStepsIncrease"
+
+ defaultConfig {
+ minSdk = 23
+ targetSdk = 35
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.preference)
+}
diff --git a/VolumeStepsIncrease/src/main/AndroidManifest.xml b/VolumeStepsIncrease/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6958021
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VolumeStepsIncrease/src/main/assets/xposed_init b/VolumeStepsIncrease/src/main/assets/xposed_init
new file mode 100644
index 0000000..2d70ba7
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/assets/xposed_init
@@ -0,0 +1 @@
+com.programminghoch10.VolumeStepsIncrease.Hook
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
new file mode 100644
index 0000000..224c86a
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
@@ -0,0 +1,24 @@
+package com.programminghoch10.VolumeStepsIncrease
+
+class Common {
+ companion object {
+ val streams = arrayOf(
+ "ro.config.vc_call_vol_steps",
+ "ro.config.media_vol_steps",
+ "ro.config.alarm_vol_steps",
+ "ro.config.system_vol_steps",
+ )
+
+ val defaultStreamValues = mapOf(
+ // default volumes from AudioService
+ "ro.config.vc_call_vol_steps" to 5,
+ "ro.config.media_vol_steps" to 15,
+ "ro.config.alarm_vol_steps" to 7,
+ "ro.config.system_vol_steps" to 7,
+ ).mapValues { it.value * 2 }
+
+ fun getMaxVolumeSteps(): Int {
+ return defaultStreamValues.values.maxOf { it } * 3
+ }
+ }
+}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
new file mode 100644
index 0000000..9fd0bc5
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
@@ -0,0 +1,37 @@
+package com.programminghoch10.VolumeStepsIncrease
+
+import android.util.Log
+import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.XSharedPreferences
+import de.robv.android.xposed.XposedHelpers
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+import de.robv.android.xposed.XC_MethodHook as MethodHook
+
+class Hook : IXposedHookLoadPackage {
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
+ if (lpparam.packageName == BuildConfig.APPLICATION_ID) return
+
+ val SystemPropertiesClass = XposedHelpers.findClass("android.os.SystemProperties", lpparam.classLoader)
+
+ XposedHelpers.findAndHookMethod(SystemPropertiesClass, "getInt", String::class.java, Int::class.java, object : MethodHook() {
+ override fun afterHookedMethod(param: MethodHookParam) {
+ val key = param.args[0] as String
+ param.args[1] as Int
+ val result = param.result as Int
+ if (!streams.contains(key)) return
+ val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, "streams")
+ if (!preferences.contains(key)) return
+ param.result = preferences.getInt(key, result)
+ Log.d("Logger", "beforeHookedMethod: replace $key with ${param.result}")
+ }
+ })
+
+ XposedHelpers.findAndHookMethod(SystemPropertiesClass, "getBoolean", String::class.java, Boolean::class.java, object : MethodHook() {
+ override fun beforeHookedMethod(param: MethodHookParam) {
+ val key = param.args[0] as String
+ if (key == "audio.safemedia.bypass") param.result = true
+ }
+ })
+ }
+}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
new file mode 100644
index 0000000..3c090cb
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
@@ -0,0 +1,46 @@
+package com.programminghoch10.VolumeStepsIncrease
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import androidx.fragment.app.FragmentActivity
+import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.SeekBarPreference
+import com.programminghoch10.VolumeStepsIncrease.Common.Companion.defaultStreamValues
+import com.programminghoch10.VolumeStepsIncrease.Common.Companion.getMaxVolumeSteps
+import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
+
+class SettingsActivity : FragmentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.settings_activity)
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment()).commit()
+ }
+ actionBar?.setDisplayHomeAsUpEnabled(
+ supportFragmentManager.backStackEntryCount > 0
+ )
+ }
+
+ class SettingsFragment : PreferenceFragmentCompat() {
+ @SuppressLint("WorldReadableFiles")
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ setPreferencesFromResource(R.xml.root_preferences, rootKey)
+ preferenceManager.sharedPreferencesName = "streams"
+ preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
+
+ for (stream in streams) {
+ val defaultValue = defaultStreamValues[stream]!!
+ val preference = SeekBarPreference(requireContext())
+ preference.key = stream
+ preference.title = stream
+ preference.min = 1
+ preference.max = getMaxVolumeSteps()
+ preference.setDefaultValue(defaultValue)
+ preference.showSeekBarValue = true
+ //preference.summary = "default = ${defaultValue / 2}"
+ preferenceScreen.addPreference(preference)
+ }
+ }
+ }
+}
diff --git a/VolumeStepsIncrease/src/main/res/layout/settings_activity.xml b/VolumeStepsIncrease/src/main/res/layout/settings_activity.xml
new file mode 100644
index 0000000..620409c
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/layout/settings_activity.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/VolumeStepsIncrease/src/main/res/values-v21/themes.xml b/VolumeStepsIncrease/src/main/res/values-v21/themes.xml
new file mode 100644
index 0000000..6ee0359
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/values-v21/themes.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/VolumeStepsIncrease/src/main/res/values/arrays.xml b/VolumeStepsIncrease/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..db6e46a
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/values/arrays.xml
@@ -0,0 +1,6 @@
+
+
+
+ - android
+
+
diff --git a/VolumeStepsIncrease/src/main/res/values/strings.xml b/VolumeStepsIncrease/src/main/res/values/strings.xml
new file mode 100644
index 0000000..81e8057
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+ VolumeStepsIncrease
+ Volume Steps Configuration
+
diff --git a/VolumeStepsIncrease/src/main/res/values/themes.xml b/VolumeStepsIncrease/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1b28f45
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/values/themes.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml b/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
new file mode 100644
index 0000000..37f6c5a
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/modules.gradle.kts b/modules.gradle.kts
index 352f7fa..b1f4cf1 100644
--- a/modules.gradle.kts
+++ b/modules.gradle.kts
@@ -19,3 +19,4 @@ include(":ResetAllNotificationChannels")
include(":RotationControl")
include(":SensorMod")
include(":UpsideWifi")
+include(":VolumeStepsIncrease")
From 2360164dadf77a6f8c83662e344a5b51df27d7d0 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sat, 16 Aug 2025 22:58:50 +0200
Subject: [PATCH 2/7] flatten companion object in VolumeStepsIncrease
---
.../VolumeStepsIncrease/Common.kt | 38 +++++++++----------
.../VolumeStepsIncrease/Hook.kt | 2 +-
.../VolumeStepsIncrease/SettingsActivity.kt | 6 +--
3 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
index 224c86a..234b5ce 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
@@ -1,24 +1,22 @@
package com.programminghoch10.VolumeStepsIncrease
-class Common {
- companion object {
- val streams = arrayOf(
- "ro.config.vc_call_vol_steps",
- "ro.config.media_vol_steps",
- "ro.config.alarm_vol_steps",
- "ro.config.system_vol_steps",
- )
-
- val defaultStreamValues = mapOf(
- // default volumes from AudioService
- "ro.config.vc_call_vol_steps" to 5,
- "ro.config.media_vol_steps" to 15,
- "ro.config.alarm_vol_steps" to 7,
- "ro.config.system_vol_steps" to 7,
- ).mapValues { it.value * 2 }
-
- fun getMaxVolumeSteps(): Int {
- return defaultStreamValues.values.maxOf { it } * 3
- }
+object Common {
+ val streams = arrayOf(
+ "ro.config.vc_call_vol_steps",
+ "ro.config.media_vol_steps",
+ "ro.config.alarm_vol_steps",
+ "ro.config.system_vol_steps",
+ )
+
+ val defaultStreamValues = mapOf(
+ // default volumes from AudioService
+ "ro.config.vc_call_vol_steps" to 5,
+ "ro.config.media_vol_steps" to 15,
+ "ro.config.alarm_vol_steps" to 7,
+ "ro.config.system_vol_steps" to 7,
+ ).mapValues { it.value * 2 }
+
+ fun getMaxVolumeSteps(): Int {
+ return defaultStreamValues.values.maxOf { it } * 3
}
}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
index 9fd0bc5..4347cdc 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
@@ -1,7 +1,7 @@
package com.programminghoch10.VolumeStepsIncrease
import android.util.Log
-import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
+import com.programminghoch10.VolumeStepsIncrease.Common.streams
import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.XSharedPreferences
import de.robv.android.xposed.XposedHelpers
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
index 3c090cb..b9d8dbf 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
@@ -5,9 +5,9 @@ import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SeekBarPreference
-import com.programminghoch10.VolumeStepsIncrease.Common.Companion.defaultStreamValues
-import com.programminghoch10.VolumeStepsIncrease.Common.Companion.getMaxVolumeSteps
-import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
+import com.programminghoch10.VolumeStepsIncrease.Common.defaultStreamValues
+import com.programminghoch10.VolumeStepsIncrease.Common.getMaxVolumeSteps
+import com.programminghoch10.VolumeStepsIncrease.Common.streams
class SettingsActivity : FragmentActivity() {
From 69806211d7a053579435dcb55a3507904159b0d0 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sat, 16 Aug 2025 22:59:35 +0200
Subject: [PATCH 3/7] remove appinfo settings access for VolumeStepsIncrease
* the module has to be enabled for this to work,
forcing the user to go through Xposed Manager makes it more likely they enable it first
---
VolumeStepsIncrease/src/main/AndroidManifest.xml | 2 --
1 file changed, 2 deletions(-)
diff --git a/VolumeStepsIncrease/src/main/AndroidManifest.xml b/VolumeStepsIncrease/src/main/AndroidManifest.xml
index 6958021..13292ab 100644
--- a/VolumeStepsIncrease/src/main/AndroidManifest.xml
+++ b/VolumeStepsIncrease/src/main/AndroidManifest.xml
@@ -10,8 +10,6 @@
android:theme="@style/AppTheme"
>
-
-
From 74c9b8fc6d99f973a682b20b4f2aa776c6703fc5 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sun, 17 Aug 2025 22:42:04 +0200
Subject: [PATCH 4/7] add metadata for IncreaseVolumeSteps
---
README.md | 1 +
VolumeStepsIncrease/Readme.md | 3 +++
VolumeStepsIncrease/src/main/AndroidManifest.xml | 4 ++++
VolumeStepsIncrease/src/main/res/values/strings.xml | 1 +
.../en-US/full_description.txt | 1 +
.../en-US/short_description.txt | 1 +
.../com.programminghoch10.VolumeStepsIncrease/en-US/title.txt | 1 +
7 files changed, 12 insertions(+)
create mode 100644 VolumeStepsIncrease/Readme.md
create mode 100644 metadata/com.programminghoch10.VolumeStepsIncrease/en-US/full_description.txt
create mode 100644 metadata/com.programminghoch10.VolumeStepsIncrease/en-US/short_description.txt
create mode 100644 metadata/com.programminghoch10.VolumeStepsIncrease/en-US/title.txt
diff --git a/README.md b/README.md
index 9bc9877..8867bb8 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ A collection of small Xposed Modules.
| [ResetAllNotificationChannels](ResetAllNotificationChannels) | [@binarynoise](https://github.com/binarynoise) | Reset all Notification Channels: vibrations, ringtones, importance etc. | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=resetAllNotificationChannels) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/de.binarynoise.resetAllNotificationChannels) |
| [RotationControl](RotationControl) | [@programminghoch10](https://github.com/programminghoch10) | Force rotation for selected packages | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=RotationControl) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/com.programminghoch10.RotationControl) |
| [UpsideWifi](UpsideWifi) | [@programminghoch10](https://github.com/programminghoch10) | Turn the WiFi icon upside down | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=UpsideWifi) |
+| [VolumeStepsIncrease](VolumeStepsIncrease) | [@programminghoch10](https://github.com/programminghoch10) | Increase the amount of volume steps | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=VolumeStepsIncrease) |
## License
diff --git a/VolumeStepsIncrease/Readme.md b/VolumeStepsIncrease/Readme.md
new file mode 100644
index 0000000..cfe8bb2
--- /dev/null
+++ b/VolumeStepsIncrease/Readme.md
@@ -0,0 +1,3 @@
+# VolumeStepsIncrease
+
+Increase the amount of volume steps.
diff --git a/VolumeStepsIncrease/src/main/AndroidManifest.xml b/VolumeStepsIncrease/src/main/AndroidManifest.xml
index 13292ab..7cf0327 100644
--- a/VolumeStepsIncrease/src/main/AndroidManifest.xml
+++ b/VolumeStepsIncrease/src/main/AndroidManifest.xml
@@ -19,6 +19,10 @@
android:name="xposedmodule"
android:value="true"
/>
+
VolumeStepsIncrease
Volume Steps Configuration
+ Increase the amount of volume steps.
diff --git a/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/full_description.txt b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/full_description.txt
new file mode 100644
index 0000000..4977cfb
--- /dev/null
+++ b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/full_description.txt
@@ -0,0 +1 @@
+Increase the amount of volume steps.
diff --git a/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/short_description.txt b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/short_description.txt
new file mode 100644
index 0000000..4977cfb
--- /dev/null
+++ b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/short_description.txt
@@ -0,0 +1 @@
+Increase the amount of volume steps.
diff --git a/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/title.txt b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/title.txt
new file mode 100644
index 0000000..ac5f80f
--- /dev/null
+++ b/metadata/com.programminghoch10.VolumeStepsIncrease/en-US/title.txt
@@ -0,0 +1 @@
+VolumeStepsIncrease
\ No newline at end of file
From 2d669b58d5eff9334c94a6ef142cd6a6f6f80420 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sun, 24 Aug 2025 16:22:55 +0200
Subject: [PATCH 5/7] improve VolumeStepsIncrease
* settings activity
* hooking AudioService
---
VolumeStepsIncrease/build.gradle.kts | 2 +-
.../VolumeStepsIncrease/Common.kt | 58 +++++++++---
.../VolumeStepsIncrease/Hook.kt | 23 ++++-
.../VolumeStepsIncrease/SettingsActivity.kt | 55 ++++++++---
.../VolumeStepsIncrease/StockValues.kt | 94 +++++++++++++++++++
.../src/main/res/values/strings.xml | 1 +
.../src/main/res/xml/root_preferences.xml | 6 +-
7 files changed, 205 insertions(+), 34 deletions(-)
create mode 100644 VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/StockValues.kt
diff --git a/VolumeStepsIncrease/build.gradle.kts b/VolumeStepsIncrease/build.gradle.kts
index 352aa6a..48b1ab2 100644
--- a/VolumeStepsIncrease/build.gradle.kts
+++ b/VolumeStepsIncrease/build.gradle.kts
@@ -13,5 +13,5 @@ android {
}
dependencies {
- implementation(libs.androidx.preference)
+ implementation(libs.androidx.preference.ktx)
}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
index 234b5ce..ddb8552 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
@@ -1,22 +1,52 @@
package com.programminghoch10.VolumeStepsIncrease
+import com.programminghoch10.VolumeStepsIncrease.StockValues.MAX_STREAM_VOLUME
+import com.programminghoch10.VolumeStepsIncrease.StockValues.MIN_STREAM_VOLUME
+import com.programminghoch10.VolumeStepsIncrease.StockValues.STREAM_ALARM
+import com.programminghoch10.VolumeStepsIncrease.StockValues.STREAM_MUSIC
+import com.programminghoch10.VolumeStepsIncrease.StockValues.STREAM_SYSTEM
+import com.programminghoch10.VolumeStepsIncrease.StockValues.STREAM_VOICE_CALL
+
object Common {
- val streams = arrayOf(
- "ro.config.vc_call_vol_steps",
- "ro.config.media_vol_steps",
- "ro.config.alarm_vol_steps",
- "ro.config.system_vol_steps",
+ val SHARED_PREFERENCES_NAME = "streams"
+
+ val STREAMS = StockValues::class.java.declaredFields.filter { it.name.startsWith("STREAM_") }.associate { it.name to it.getInt(null) }
+
+ val STREAM_NAMES = STREAMS.keys
+
+ val systemPropertyToStream = mapOf(
+ "ro.config.vc_call_vol_steps" to STREAM_VOICE_CALL,
+ "ro.config.media_vol_steps" to STREAM_MUSIC,
+ "ro.config.alarm_vol_steps" to STREAM_ALARM,
+ "ro.config.system_vol_steps" to STREAM_SYSTEM,
)
- val defaultStreamValues = mapOf(
- // default volumes from AudioService
- "ro.config.vc_call_vol_steps" to 5,
- "ro.config.media_vol_steps" to 15,
- "ro.config.alarm_vol_steps" to 7,
- "ro.config.system_vol_steps" to 7,
- ).mapValues { it.value * 2 }
+ val moduleDefaultVolumeSteps = mapOf(
+ STREAM_MUSIC to MAX_STREAM_VOLUME[STREAM_MUSIC] * 2,
+ STREAM_VOICE_CALL to MAX_STREAM_VOLUME[STREAM_VOICE_CALL] * 2,
+ )
+
+ fun getSystemMaxVolumeSteps(stream: Int): Int {
+ return MAX_STREAM_VOLUME[stream]
+ }
+
+ fun getModuleDefaultVolumeSteps(stream: Int): Int {
+ return moduleDefaultVolumeSteps[stream] ?: getSystemMaxVolumeSteps(stream)
+ }
+
+ fun getModuleMaxVolumeSteps(stream: Int): Int {
+ return getSystemMaxVolumeSteps(stream) * 3
+ }
+
+ fun getSystemMinVolumeSteps(stream: Int): Int {
+ return MIN_STREAM_VOLUME[stream]
+ }
+
+ fun getModuleMinVolumeSteps(stream: Int): Int {
+ return getSystemMinVolumeSteps((stream))
+ }
- fun getMaxVolumeSteps(): Int {
- return defaultStreamValues.values.maxOf { it } * 3
+ fun getPreferenceKey(stream: Int): String {
+ return "STREAM_${stream}"
}
}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
index 4347cdc..de64cfc 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Hook.kt
@@ -1,9 +1,13 @@
package com.programminghoch10.VolumeStepsIncrease
import android.util.Log
-import com.programminghoch10.VolumeStepsIncrease.Common.streams
+import com.programminghoch10.VolumeStepsIncrease.Common.SHARED_PREFERENCES_NAME
+import com.programminghoch10.VolumeStepsIncrease.Common.STREAMS
+import com.programminghoch10.VolumeStepsIncrease.Common.getPreferenceKey
+import com.programminghoch10.VolumeStepsIncrease.Common.systemPropertyToStream
import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.XSharedPreferences
+import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers
import de.robv.android.xposed.callbacks.XC_LoadPackage
import de.robv.android.xposed.XC_MethodHook as MethodHook
@@ -19,9 +23,9 @@ class Hook : IXposedHookLoadPackage {
val key = param.args[0] as String
param.args[1] as Int
val result = param.result as Int
- if (!streams.contains(key)) return
- val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, "streams")
- if (!preferences.contains(key)) return
+ val streamInt = systemPropertyToStream[key] ?: return
+ val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
+ if (!preferences.contains(getPreferenceKey(streamInt))) return
param.result = preferences.getInt(key, result)
Log.d("Logger", "beforeHookedMethod: replace $key with ${param.result}")
}
@@ -33,5 +37,16 @@ class Hook : IXposedHookLoadPackage {
if (key == "audio.safemedia.bypass") param.result = true
}
})
+
+ val AudioServiceClass = XposedHelpers.findClass("com.android.server.audio.AudioService", lpparam.classLoader)
+ XposedBridge.hookAllConstructors(AudioServiceClass, object : MethodHook() {
+ override fun afterHookedMethod(param: MethodHookParam) {
+ val MAX_STREAM_VOLUME = XposedHelpers.getObjectField(param.thisObject, "MAX_STREAM_VOLUME") as Array
+ val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
+ STREAMS.filter { preferences.contains(getPreferenceKey(it.value)) }
+ .map { it.value to preferences.getInt(getPreferenceKey(it.value), MAX_STREAM_VOLUME[it.value]) }
+ .forEach { MAX_STREAM_VOLUME[it.first] = it.second }
+ }
+ })
}
}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
index b9d8dbf..33ffc4e 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
@@ -1,13 +1,22 @@
package com.programminghoch10.VolumeStepsIncrease
+import kotlin.math.round
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
+import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.PreferenceGroup
import androidx.preference.SeekBarPreference
-import com.programminghoch10.VolumeStepsIncrease.Common.defaultStreamValues
-import com.programminghoch10.VolumeStepsIncrease.Common.getMaxVolumeSteps
-import com.programminghoch10.VolumeStepsIncrease.Common.streams
+import androidx.preference.children
+import com.programminghoch10.VolumeStepsIncrease.Common.SHARED_PREFERENCES_NAME
+import com.programminghoch10.VolumeStepsIncrease.Common.STREAMS
+import com.programminghoch10.VolumeStepsIncrease.Common.STREAM_NAMES
+import com.programminghoch10.VolumeStepsIncrease.Common.getModuleDefaultVolumeSteps
+import com.programminghoch10.VolumeStepsIncrease.Common.getModuleMaxVolumeSteps
+import com.programminghoch10.VolumeStepsIncrease.Common.getModuleMinVolumeSteps
+import com.programminghoch10.VolumeStepsIncrease.Common.getPreferenceKey
+import com.programminghoch10.VolumeStepsIncrease.Common.getSystemMaxVolumeSteps
class SettingsActivity : FragmentActivity() {
@@ -26,21 +35,43 @@ class SettingsActivity : FragmentActivity() {
@SuppressLint("WorldReadableFiles")
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
- preferenceManager.sharedPreferencesName = "streams"
+ preferenceManager.sharedPreferencesName = SHARED_PREFERENCES_NAME
preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
- for (stream in streams) {
- val defaultValue = defaultStreamValues[stream]!!
+ for (stream in STREAM_NAMES) {
+ val streamInt = STREAMS[stream]!!
val preference = SeekBarPreference(requireContext())
- preference.key = stream
- preference.title = stream
- preference.min = 1
- preference.max = getMaxVolumeSteps()
- preference.setDefaultValue(defaultValue)
+ preference.key = getPreferenceKey(streamInt)
+ preference.title = stream.replace("STREAM_", "")
+ preference.min = getModuleMinVolumeSteps(streamInt)
+ preference.max = getModuleMaxVolumeSteps(streamInt)
+ preference.setDefaultValue(getModuleDefaultVolumeSteps(streamInt))
preference.showSeekBarValue = true
- //preference.summary = "default = ${defaultValue / 2}"
+ preference.updatesContinuously = true
+ preference.setOnPreferenceChangeListener { preference, newValue ->
+ val factor = (newValue as Int).toDouble() / getSystemMaxVolumeSteps(streamInt)
+ preference.summary = arrayOf(
+ "factor=${factor.round(1)}x ",
+ //"systemMin=${getSystemMinVolumeSteps(streamInt)} ",
+ "systemMax=${getSystemMaxVolumeSteps(streamInt)} ",
+ ).joinToString(" ")
+ true
+ }
preferenceScreen.addPreference(preference)
+ preference.onPreferenceChangeListener?.onPreferenceChange(preference, preference.value)
}
+ preferenceScreen.setIconSpaceReservedRecursive(false)
+ }
+
+ fun Preference.setIconSpaceReservedRecursive(iconSpaceReserved: Boolean) {
+ this.isIconSpaceReserved = iconSpaceReserved
+ if (this is PreferenceGroup) children.forEach { it.setIconSpaceReservedRecursive(iconSpaceReserved) }
+ }
+
+ fun Double.round(decimals: Int = 0): Double {
+ var multiplier = 1.0
+ repeat(decimals) { multiplier *= 10 }
+ return round(this * multiplier) / multiplier
}
}
}
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/StockValues.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/StockValues.kt
new file mode 100644
index 0000000..6bbfce1
--- /dev/null
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/StockValues.kt
@@ -0,0 +1,94 @@
+package com.programminghoch10.VolumeStepsIncrease
+
+import android.media.AudioManager
+import androidx.annotation.Keep
+
+@Keep
+object StockValues {
+
+ // from com.android.server.media.AudioService
+
+ /** Maximum volume index values for audio streams */
+ var MAX_STREAM_VOLUME: IntArray = intArrayOf(
+ 5, // STREAM_VOICE_CALL
+ 7, // STREAM_SYSTEM
+ 7, // STREAM_RING
+ 15, // STREAM_MUSIC
+ 7, // STREAM_ALARM
+ 7, // STREAM_NOTIFICATION
+ 15, // STREAM_BLUETOOTH_SCO
+ 7, // STREAM_SYSTEM_ENFORCED
+ 15, // STREAM_DTMF
+ 15, // STREAM_TTS
+ 15, // STREAM_ACCESSIBILITY
+ 15, // STREAM_ASSISTANT
+ )
+
+ /** Minimum volume index values for audio streams */
+ var MIN_STREAM_VOLUME: IntArray = intArrayOf(
+ 1, // STREAM_VOICE_CALL
+ 0, // STREAM_SYSTEM
+ 0, // STREAM_RING
+ 0, // STREAM_MUSIC
+ 1, // STREAM_ALARM
+ 0, // STREAM_NOTIFICATION
+ 0, // STREAM_BLUETOOTH_SCO
+ 0, // STREAM_SYSTEM_ENFORCED
+ 0, // STREAM_DTMF
+ 0, // STREAM_TTS
+ 1, // STREAM_ACCESSIBILITY
+ 0, // STREAM_ASSISTANT
+ )
+
+ // from android.media.AudioSystem
+
+ const val STREAM_VOICE_CALL: Int = AudioManager.STREAM_VOICE_CALL
+
+ /** @hide Used to identify the volume of audio streams for system sounds
+ */
+ const val STREAM_SYSTEM: Int = AudioManager.STREAM_SYSTEM
+
+ /** @hide Used to identify the volume of audio streams for the phone ring and message alerts
+ */
+ const val STREAM_RING: Int = AudioManager.STREAM_RING
+
+ /** @hide Used to identify the volume of audio streams for music playback
+ */
+ const val STREAM_MUSIC: Int = AudioManager.STREAM_MUSIC
+
+ /** @hide Used to identify the volume of audio streams for alarms
+ */
+ const val STREAM_ALARM: Int = AudioManager.STREAM_ALARM
+
+ /** @hide Used to identify the volume of audio streams for notifications
+ */
+ const val STREAM_NOTIFICATION: Int = AudioManager.STREAM_NOTIFICATION
+
+ /** @hide
+ * Used to identify the volume of audio streams for phone calls when connected on bluetooth
+ */
+ @Deprecated("use {@link #STREAM_VOICE_CALL} instead ")
+ const val STREAM_BLUETOOTH_SCO: Int = 6
+
+ /** @hide Used to identify the volume of audio streams for enforced system sounds in certain
+ * countries (e.g camera in Japan)
+ */
+ const val STREAM_SYSTEM_ENFORCED: Int = 7
+
+ /** @hide Used to identify the volume of audio streams for DTMF tones
+ */
+ const val STREAM_DTMF: Int = AudioManager.STREAM_DTMF
+
+ /** @hide Used to identify the volume of audio streams exclusively transmitted through the
+ * speaker (TTS) of the device
+ */
+ const val STREAM_TTS: Int = 9
+
+ /** @hide Used to identify the volume of audio streams for accessibility prompts
+ */
+ const val STREAM_ACCESSIBILITY: Int = AudioManager.STREAM_ACCESSIBILITY
+
+ /** @hide Used to identify the volume of audio streams for virtual assistant
+ */
+ const val STREAM_ASSISTANT: Int = 11
+}
diff --git a/VolumeStepsIncrease/src/main/res/values/strings.xml b/VolumeStepsIncrease/src/main/res/values/strings.xml
index ddde23b..d239e46 100644
--- a/VolumeStepsIncrease/src/main/res/values/strings.xml
+++ b/VolumeStepsIncrease/src/main/res/values/strings.xml
@@ -3,4 +3,5 @@
VolumeStepsIncrease
Volume Steps Configuration
Increase the amount of volume steps.
+ A restart is required to apply the new values!
diff --git a/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml b/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
index 37f6c5a..bdbca14 100644
--- a/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
+++ b/VolumeStepsIncrease/src/main/res/xml/root_preferences.xml
@@ -1,4 +1,4 @@
-
-
+
+
+
From 57843ba051065e61459f98d9424308a4e224e958 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Sun, 24 Aug 2025 16:26:12 +0200
Subject: [PATCH 6/7] inline redundant variable
---
.../VolumeStepsIncrease/Common.kt | 2 --
.../VolumeStepsIncrease/SettingsActivity.kt | 20 +++++++++----------
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
index ddb8552..b8f37a5 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/Common.kt
@@ -12,8 +12,6 @@ object Common {
val STREAMS = StockValues::class.java.declaredFields.filter { it.name.startsWith("STREAM_") }.associate { it.name to it.getInt(null) }
- val STREAM_NAMES = STREAMS.keys
-
val systemPropertyToStream = mapOf(
"ro.config.vc_call_vol_steps" to STREAM_VOICE_CALL,
"ro.config.media_vol_steps" to STREAM_MUSIC,
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
index 33ffc4e..9928322 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
@@ -11,7 +11,6 @@ import androidx.preference.SeekBarPreference
import androidx.preference.children
import com.programminghoch10.VolumeStepsIncrease.Common.SHARED_PREFERENCES_NAME
import com.programminghoch10.VolumeStepsIncrease.Common.STREAMS
-import com.programminghoch10.VolumeStepsIncrease.Common.STREAM_NAMES
import com.programminghoch10.VolumeStepsIncrease.Common.getModuleDefaultVolumeSteps
import com.programminghoch10.VolumeStepsIncrease.Common.getModuleMaxVolumeSteps
import com.programminghoch10.VolumeStepsIncrease.Common.getModuleMinVolumeSteps
@@ -38,22 +37,21 @@ class SettingsActivity : FragmentActivity() {
preferenceManager.sharedPreferencesName = SHARED_PREFERENCES_NAME
preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
- for (stream in STREAM_NAMES) {
- val streamInt = STREAMS[stream]!!
+ for (stream in STREAMS) {
val preference = SeekBarPreference(requireContext())
- preference.key = getPreferenceKey(streamInt)
- preference.title = stream.replace("STREAM_", "")
- preference.min = getModuleMinVolumeSteps(streamInt)
- preference.max = getModuleMaxVolumeSteps(streamInt)
- preference.setDefaultValue(getModuleDefaultVolumeSteps(streamInt))
+ preference.key = getPreferenceKey(stream.value)
+ preference.title = stream.key.replace("STREAM_", "")
+ preference.min = getModuleMinVolumeSteps(stream.value)
+ preference.max = getModuleMaxVolumeSteps(stream.value)
+ preference.setDefaultValue(getModuleDefaultVolumeSteps(stream.value))
preference.showSeekBarValue = true
preference.updatesContinuously = true
preference.setOnPreferenceChangeListener { preference, newValue ->
- val factor = (newValue as Int).toDouble() / getSystemMaxVolumeSteps(streamInt)
+ val factor = (newValue as Int).toDouble() / getSystemMaxVolumeSteps(stream.value)
preference.summary = arrayOf(
"factor=${factor.round(1)}x ",
- //"systemMin=${getSystemMinVolumeSteps(streamInt)} ",
- "systemMax=${getSystemMaxVolumeSteps(streamInt)} ",
+ //"systemMin=${getSystemMinVolumeSteps(stream.value)} ",
+ "systemMax=${getSystemMaxVolumeSteps(stream.value)} ",
).joinToString(" ")
true
}
From ce0316cb051704cf058d331ae3d6d19f49988200 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Thu, 28 Aug 2025 14:58:23 +0200
Subject: [PATCH 7/7] set activity properties properly
---
VolumeStepsIncrease/src/main/AndroidManifest.xml | 1 +
.../VolumeStepsIncrease/SettingsActivity.kt | 9 ++++++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/VolumeStepsIncrease/src/main/AndroidManifest.xml b/VolumeStepsIncrease/src/main/AndroidManifest.xml
index 7cf0327..b8980a2 100644
--- a/VolumeStepsIncrease/src/main/AndroidManifest.xml
+++ b/VolumeStepsIncrease/src/main/AndroidManifest.xml
@@ -8,6 +8,7 @@
android:exported="true"
android:label="@string/title_activity_settings"
android:theme="@style/AppTheme"
+ android:excludeFromRecents="true"
>
diff --git a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
index 9928322..d683375 100644
--- a/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
+++ b/VolumeStepsIncrease/src/main/java/com/programminghoch10/VolumeStepsIncrease/SettingsActivity.kt
@@ -25,9 +25,12 @@ class SettingsActivity : FragmentActivity() {
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment()).commit()
}
- actionBar?.setDisplayHomeAsUpEnabled(
- supportFragmentManager.backStackEntryCount > 0
- )
+ actionBar?.setDisplayHomeAsUpEnabled(true)
+ }
+
+ override fun onNavigateUp(): Boolean {
+ finish()
+ return super.onNavigateUp()
}
class SettingsFragment : PreferenceFragmentCompat() {