Skip to content

Commit 6781ce5

Browse files
Implement VolumeStepsIncrease
1 parent dfb7a76 commit 6781ce5

File tree

13 files changed

+201
-0
lines changed

13 files changed

+201
-0
lines changed

VolumeStepsIncrease/build.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
plugins {
2+
alias(libs.plugins.buildlogic.android.application)
3+
alias(libs.plugins.buildlogic.kotlin.android)
4+
}
5+
6+
android {
7+
namespace = "com.programminghoch10.VolumeStepsIncrease"
8+
9+
defaultConfig {
10+
minSdk = 23
11+
targetSdk = 35
12+
}
13+
}
14+
15+
dependencies {
16+
implementation(libs.androidx.preference)
17+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest
3+
xmlns:android="http://schemas.android.com/apk/res/android">
4+
5+
<application android:label="@string/app_name">
6+
<activity
7+
android:name=".SettingsActivity"
8+
android:exported="true"
9+
android:label="@string/title_activity_settings"
10+
android:theme="@style/AppTheme"
11+
>
12+
<intent-filter>
13+
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
14+
<category android:name="android.intent.category.DEFAULT" />
15+
<action android:name="android.intent.action.MAIN" />
16+
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
17+
</intent-filter>
18+
</activity>
19+
20+
<meta-data
21+
android:name="xposedmodule"
22+
android:value="true"
23+
/>
24+
<meta-data
25+
android:name="xposedminversion"
26+
android:value="93"
27+
/>
28+
<meta-data
29+
android:name="xposedscope"
30+
android:resource="@array/scope"
31+
/>
32+
</application>
33+
34+
</manifest>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.programminghoch10.VolumeStepsIncrease.Hook
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.programminghoch10.VolumeStepsIncrease
2+
3+
class Common {
4+
companion object {
5+
val streams = arrayOf(
6+
"ro.config.vc_call_vol_steps",
7+
"ro.config.media_vol_steps",
8+
"ro.config.alarm_vol_steps",
9+
"ro.config.system_vol_steps",
10+
)
11+
12+
val defaultStreamValues = mapOf<String, Int>(
13+
// default volumes from AudioService
14+
"ro.config.vc_call_vol_steps" to 5,
15+
"ro.config.media_vol_steps" to 15,
16+
"ro.config.alarm_vol_steps" to 7,
17+
"ro.config.system_vol_steps" to 7,
18+
).mapValues { it.value * 2 }
19+
20+
fun getMaxVolumeSteps(): Int {
21+
return defaultStreamValues.values.maxOf { it } * 3
22+
}
23+
}
24+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.programminghoch10.VolumeStepsIncrease
2+
3+
import android.util.Log
4+
import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
5+
import de.robv.android.xposed.IXposedHookLoadPackage
6+
import de.robv.android.xposed.XSharedPreferences
7+
import de.robv.android.xposed.XposedHelpers
8+
import de.robv.android.xposed.callbacks.XC_LoadPackage
9+
import de.robv.android.xposed.XC_MethodHook as MethodHook
10+
11+
class Hook : IXposedHookLoadPackage {
12+
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
13+
if (lpparam.packageName == BuildConfig.APPLICATION_ID) return
14+
15+
val SystemPropertiesClass = XposedHelpers.findClass("android.os.SystemProperties", lpparam.classLoader)
16+
17+
XposedHelpers.findAndHookMethod(SystemPropertiesClass, "getInt", String::class.java, Int::class.java, object : MethodHook() {
18+
override fun afterHookedMethod(param: MethodHookParam) {
19+
val key = param.args[0] as String
20+
param.args[1] as Int
21+
val result = param.result as Int
22+
if (!streams.contains(key)) return
23+
val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, "streams")
24+
if (!preferences.contains(key)) return
25+
param.result = preferences.getInt(key, result)
26+
Log.d("Logger", "beforeHookedMethod: replace $key with ${param.result}")
27+
}
28+
})
29+
30+
XposedHelpers.findAndHookMethod(SystemPropertiesClass, "getBoolean", String::class.java, Boolean::class.java, object : MethodHook() {
31+
override fun beforeHookedMethod(param: MethodHookParam) {
32+
val key = param.args[0] as String
33+
if (key == "audio.safemedia.bypass") param.result = true
34+
}
35+
})
36+
}
37+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.programminghoch10.VolumeStepsIncrease
2+
3+
import android.annotation.SuppressLint
4+
import android.os.Bundle
5+
import androidx.fragment.app.FragmentActivity
6+
import androidx.preference.PreferenceFragmentCompat
7+
import androidx.preference.SeekBarPreference
8+
import com.programminghoch10.VolumeStepsIncrease.Common.Companion.defaultStreamValues
9+
import com.programminghoch10.VolumeStepsIncrease.Common.Companion.getMaxVolumeSteps
10+
import com.programminghoch10.VolumeStepsIncrease.Common.Companion.streams
11+
12+
class SettingsActivity : FragmentActivity() {
13+
14+
override fun onCreate(savedInstanceState: Bundle?) {
15+
super.onCreate(savedInstanceState)
16+
setContentView(R.layout.settings_activity)
17+
if (savedInstanceState == null) {
18+
supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment()).commit()
19+
}
20+
actionBar?.setDisplayHomeAsUpEnabled(
21+
supportFragmentManager.backStackEntryCount > 0
22+
)
23+
}
24+
25+
class SettingsFragment : PreferenceFragmentCompat() {
26+
@SuppressLint("WorldReadableFiles")
27+
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
28+
setPreferencesFromResource(R.xml.root_preferences, rootKey)
29+
preferenceManager.sharedPreferencesName = "streams"
30+
preferenceManager.sharedPreferencesMode = MODE_WORLD_READABLE
31+
32+
for (stream in streams) {
33+
val defaultValue = defaultStreamValues[stream]!!
34+
val preference = SeekBarPreference(requireContext())
35+
preference.key = stream
36+
preference.title = stream
37+
preference.min = 1
38+
preference.max = getMaxVolumeSteps()
39+
preference.setDefaultValue(defaultValue)
40+
preference.showSeekBarValue = true
41+
//preference.summary = "default = ${defaultValue / 2}"
42+
preferenceScreen.addPreference(preference)
43+
}
44+
}
45+
}
46+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent"
6+
style="@style/AppTheme.Edge2EdgeFix"
7+
>
8+
9+
<FrameLayout
10+
android:id="@+id/settings"
11+
android:layout_width="match_parent"
12+
android:layout_height="match_parent"
13+
/>
14+
</LinearLayout>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<style name="AppTheme" parent="@android:style/Theme.DeviceDefault.Settings" />
4+
</resources>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string-array name="scope">
4+
<item>android</item>
5+
</string-array>
6+
</resources>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string name="app_name">VolumeStepsIncrease</string>
4+
<string name="title_activity_settings">Volume Steps Configuration</string>
5+
</resources>

0 commit comments

Comments
 (0)