From 147d066134a7847696693650c33d622a379e5b69 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 00:05:22 +0200
Subject: [PATCH 1/8] Initial working version of CodecMod
---
CodecMod/build.gradle.kts | 15 ++++
CodecMod/src/main/AndroidManifest.xml | 29 +++++++
CodecMod/src/main/assets/xposed_init | 1 +
.../CodecMod/CodecStore.java | 72 ++++++++++++++++++
.../com/programminghoch10/CodecMod/Hook.java | 52 +++++++++++++
.../CodecMod/SettingsActivity.java | 75 +++++++++++++++++++
.../src/main/res/layout/settings_activity.xml | 9 +++
CodecMod/src/main/res/values/strings.xml | 9 +++
.../src/main/res/xml/root_preferences.xml | 8 ++
gradle/libs.versions.toml | 2 +
settings.gradle.kts | 1 +
11 files changed, 273 insertions(+)
create mode 100644 CodecMod/build.gradle.kts
create mode 100644 CodecMod/src/main/AndroidManifest.xml
create mode 100644 CodecMod/src/main/assets/xposed_init
create mode 100644 CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
create mode 100644 CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
create mode 100644 CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
create mode 100644 CodecMod/src/main/res/layout/settings_activity.xml
create mode 100644 CodecMod/src/main/res/values/strings.xml
create mode 100644 CodecMod/src/main/res/xml/root_preferences.xml
diff --git a/CodecMod/build.gradle.kts b/CodecMod/build.gradle.kts
new file mode 100644
index 0000000..787dd82
--- /dev/null
+++ b/CodecMod/build.gradle.kts
@@ -0,0 +1,15 @@
+plugins {
+ alias(libs.plugins.buildlogic.android.application)
+}
+
+android {
+ namespace = "com.programminghoch10.CodecMod"
+
+ defaultConfig {
+ minSdk = 29
+ targetSdk = 35
+ }
+}
+dependencies {
+ implementation(libs.androidx.preference)
+}
diff --git a/CodecMod/src/main/AndroidManifest.xml b/CodecMod/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0dae64a
--- /dev/null
+++ b/CodecMod/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CodecMod/src/main/assets/xposed_init b/CodecMod/src/main/assets/xposed_init
new file mode 100644
index 0000000..696169f
--- /dev/null
+++ b/CodecMod/src/main/assets/xposed_init
@@ -0,0 +1 @@
+com.programminghoch10.CodecMod.Hook
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
new file mode 100644
index 0000000..b907ae5
--- /dev/null
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
@@ -0,0 +1,72 @@
+package com.programminghoch10.CodecMod;
+
+import static android.content.Context.MODE_WORLD_READABLE;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.media.MediaCodecInfo;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.robv.android.xposed.XSharedPreferences;
+
+public class CodecStore {
+ static final boolean DEFAULT_VALUE = true;
+ private static final boolean REMOVE_DEFAULT_VALUE_FROM_CONFIG = true;
+ private static final String PREFERENCES = "codecs";
+ SharedPreferences sharedPreferences;
+ List receivers = new LinkedList<>();
+
+ CodecStore(Context context) {
+ this.sharedPreferences = context.getSharedPreferences(PREFERENCES, MODE_WORLD_READABLE);
+ }
+
+ CodecStore() {
+ this.sharedPreferences = new XSharedPreferences(BuildConfig.APPLICATION_ID, PREFERENCES);
+ }
+
+ static String getKey(MediaCodecInfo mediaCodecInfo) {
+ return "codec_" + mediaCodecInfo.getCanonicalName();
+ }
+
+ boolean getCodecPreference(MediaCodecInfo mediaCodecInfo) {
+ return sharedPreferences.getBoolean(getKey(mediaCodecInfo), DEFAULT_VALUE);
+ }
+
+ boolean setCodecPreference(MediaCodecInfo mediaCodecInfo, boolean enabled) {
+ boolean success = false;
+ if (REMOVE_DEFAULT_VALUE_FROM_CONFIG && enabled == DEFAULT_VALUE) {
+ success = sharedPreferences.edit().remove(getKey(mediaCodecInfo)).commit();
+ } else {
+ success = sharedPreferences.edit().putBoolean(getKey(mediaCodecInfo), enabled).commit();
+ }
+ if (!success)
+ return success;
+ dispatchOnCodecPreferenceChanged(mediaCodecInfo, enabled);
+ return success;
+ }
+
+ void registerOnCodecPreferenceChangedListener(MediaCodecInfo mediaCodecInfo, OnCodecPreferenceChangedListener onCodecPreferenceChangedListener) {
+ OnCodecPreferenceChangedListenerMeta listener = new OnCodecPreferenceChangedListenerMeta();
+ listener.mediaCodecInfo = mediaCodecInfo;
+ listener.callback = onCodecPreferenceChangedListener;
+ receivers.add(listener);
+ }
+
+ private void dispatchOnCodecPreferenceChanged(MediaCodecInfo mediaCodecInfo, boolean enabled) {
+ receivers.stream()
+ .filter(r -> getKey(r.mediaCodecInfo).equals(getKey(mediaCodecInfo)))
+ .forEach(r -> r.callback.onCodecPreferenceChanged(enabled));
+ }
+
+ interface OnCodecPreferenceChangedListener {
+ void onCodecPreferenceChanged(boolean value);
+ }
+
+ private class OnCodecPreferenceChangedListenerMeta {
+ MediaCodecInfo mediaCodecInfo;
+ OnCodecPreferenceChangedListener callback;
+ }
+
+}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
new file mode 100644
index 0000000..ea5e015
--- /dev/null
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
@@ -0,0 +1,52 @@
+package com.programminghoch10.CodecMod;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+
+import java.util.Arrays;
+
+import de.robv.android.xposed.IXposedHookLoadPackage;
+import de.robv.android.xposed.XC_MethodReplacement;
+import de.robv.android.xposed.XposedBridge;
+import de.robv.android.xposed.XposedHelpers;
+import de.robv.android.xposed.callbacks.XC_LoadPackage;
+
+public class Hook implements IXposedHookLoadPackage {
+ @Override
+ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
+ if (lpparam.packageName.equals(BuildConfig.APPLICATION_ID)) return;
+ if (lpparam.packageName.equals("android")) {
+ // system-wide hooking not implemented
+ return;
+ }
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfos", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ MediaCodecInfo[] mediaCodecInfos = (MediaCodecInfo[]) XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args);
+ if (mediaCodecInfos.length == 0) return mediaCodecInfos;
+ CodecStore codecStore = new CodecStore();
+ MediaCodecInfo[] filteredMediaCodecInfos = Arrays.stream(mediaCodecInfos)
+ .filter(codecStore::getCodecPreference)
+ .toArray(MediaCodecInfo[]::new);
+ return filteredMediaCodecInfos;
+ }
+ });
+
+ // reimplementations of deprecated methods for compatibility
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecCount", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos().length;
+ }
+ });
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfoAt", int.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ final int position = (int) param.args[0];
+ MediaCodecInfo[] mediaCodecInfos = (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos();
+ if (position < 0 || position >= mediaCodecInfos.length) throw new IllegalArgumentException();
+ return mediaCodecInfos[position];
+ }
+ });
+ }
+}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
new file mode 100644
index 0000000..b3afbff
--- /dev/null
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
@@ -0,0 +1,75 @@
+package com.programminghoch10.CodecMod;
+
+import android.app.ActionBar;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SwitchPreference;
+
+import java.util.Arrays;
+
+public class SettingsActivity extends FragmentActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.settings_activity);
+ if (savedInstanceState == null) {
+ getSupportFragmentManager()
+ .beginTransaction()
+ .replace(R.id.settings, new SettingsFragment())
+ .commit();
+ }
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(
+ getSupportFragmentManager().getBackStackEntryCount() > 0
+ );
+ }
+ }
+
+ public static class SettingsFragment extends PreferenceFragmentCompat {
+ private static final boolean SHOW_ALIASES = true;
+ CodecStore codecStore = null;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.root_preferences, rootKey);
+ //getPreferenceManager().setSharedPreferencesName("codecs");
+ CodecStore codecStore = new CodecStore(getContext());
+ PreferenceCategory decodersPreferenceCategory = findPreference("category_decoders");
+ PreferenceCategory encodersPreferenceCategory = findPreference("category_encoders");
+ MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
+ for (MediaCodecInfo mediaCodecInfo : mediaCodecList.getCodecInfos()) {
+ if (mediaCodecInfo.isAlias() && !SHOW_ALIASES) continue;
+ SwitchPreference preference = new SwitchPreference(getContext());
+ preference.setPersistent(false);
+ preference.setDefaultValue(CodecStore.DEFAULT_VALUE);
+ preference.setKey(CodecStore.getKey(mediaCodecInfo));
+ preference.setOnPreferenceChangeListener((p, n) -> codecStore.setCodecPreference(mediaCodecInfo, (Boolean) n));
+ codecStore.registerOnCodecPreferenceChangedListener(mediaCodecInfo, value -> {
+ if (preference.isChecked() != value) preference.setChecked(value);
+ });
+ preference.setTitle(mediaCodecInfo.getName()
+ + (mediaCodecInfo.getName().equals(mediaCodecInfo.getCanonicalName()) ? "" : " (" + mediaCodecInfo.getCanonicalName() + ")"));
+ preference.setSummary(
+ String.format(getString(R.string.hardware_accelerated), mediaCodecInfo.isHardwareAccelerated())
+ + "\n" +
+ String.format(getString(R.string.software_only), mediaCodecInfo.isSoftwareOnly())
+ + "\n" +
+ String.format(getString(R.string.supported_types), Arrays.toString(mediaCodecInfo.getSupportedTypes())) +
+ (SHOW_ALIASES ? "\n" +
+ String.format(getString(R.string.alias), mediaCodecInfo.isAlias()) : "")
+ + "\n" +
+ String.format(getString(R.string.vendor), mediaCodecInfo.isVendor())
+ );
+ PreferenceCategory preferenceCategory = mediaCodecInfo.isEncoder() ? encodersPreferenceCategory : decodersPreferenceCategory;
+ preferenceCategory.addPreference(preference);
+ preference.setChecked(codecStore.getCodecPreference(mediaCodecInfo));
+ }
+ }
+ }
+}
diff --git a/CodecMod/src/main/res/layout/settings_activity.xml b/CodecMod/src/main/res/layout/settings_activity.xml
new file mode 100644
index 0000000..3454f9f
--- /dev/null
+++ b/CodecMod/src/main/res/layout/settings_activity.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/CodecMod/src/main/res/values/strings.xml b/CodecMod/src/main/res/values/strings.xml
new file mode 100644
index 0000000..408e6f5
--- /dev/null
+++ b/CodecMod/src/main/res/values/strings.xml
@@ -0,0 +1,9 @@
+
+ CodecMod
+ CodecMod Settings
+ Hardware-accelerated: %b
+ Software-only: %b
+ Supported MIME-Types: %s
+ Alias: %b
+ Vendor: %b
+
diff --git a/CodecMod/src/main/res/xml/root_preferences.xml b/CodecMod/src/main/res/xml/root_preferences.xml
new file mode 100644
index 0000000..b4b1a7f
--- /dev/null
+++ b/CodecMod/src/main/res/xml/root_preferences.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 8fab462..e01a720 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -11,6 +11,7 @@ hiddenapibypass = "5.0"
jebrainsAnnotations = "26.0.2"
kotlin = "2.2.0"
xposed = "82"
+preference = "1.2.1"
[libraries]
android-desugarJdkLibs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
@@ -27,6 +28,7 @@ kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin" }
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" }
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
xposed-api = { module = "de.robv.android.xposed:api", version.ref = "xposed" }
+androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 931746a..f6bef72 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -48,6 +48,7 @@ include(":BetterAnimationScaling")
include(":BetterVerboseWiFiLogging")
include(":BetterBluetoothDeviceSort")
include(":ClassHunter")
+include(":CodecMod")
include(":DontResetIfBootedAndConnected")
include(":FreeNotifications")
include(":MotionEventMod")
From 060bf8c103f33feefb69def52e54f41f6a02662a Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 00:32:32 +0200
Subject: [PATCH 2/8] backport CodecMod to sdk 16
---
CodecMod/build.gradle.kts | 2 +-
CodecMod/src/main/AndroidManifest.xml | 2 +-
.../CodecMod/CodecStore.java | 27 +++--
.../com/programminghoch10/CodecMod/Hook.java | 104 +++++++++++++-----
.../CodecMod/MediaCodecInfoWrapper.java | 64 +++++++++++
.../CodecMod/SettingsActivity.java | 43 +++++---
CodecMod/src/main/res/values-v21/themes.xml | 5 +
CodecMod/src/main/res/values/themes.xml | 5 +
8 files changed, 198 insertions(+), 54 deletions(-)
create mode 100644 CodecMod/src/main/java/com/programminghoch10/CodecMod/MediaCodecInfoWrapper.java
create mode 100644 CodecMod/src/main/res/values-v21/themes.xml
create mode 100644 CodecMod/src/main/res/values/themes.xml
diff --git a/CodecMod/build.gradle.kts b/CodecMod/build.gradle.kts
index 787dd82..17d373a 100644
--- a/CodecMod/build.gradle.kts
+++ b/CodecMod/build.gradle.kts
@@ -6,7 +6,7 @@ android {
namespace = "com.programminghoch10.CodecMod"
defaultConfig {
- minSdk = 29
+ minSdk = 16
targetSdk = 35
}
}
diff --git a/CodecMod/src/main/AndroidManifest.xml b/CodecMod/src/main/AndroidManifest.xml
index 0dae64a..9fae8ca 100644
--- a/CodecMod/src/main/AndroidManifest.xml
+++ b/CodecMod/src/main/AndroidManifest.xml
@@ -6,7 +6,7 @@
android:name=".SettingsActivity"
android:exported="true"
android:label="@string/title_activity_settings"
- android:theme="@android:style/Theme.DeviceDefault.Settings">
+ android:theme="@style/AppTheme">
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
index b907ae5..de985f6 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
@@ -4,7 +4,7 @@
import android.content.Context;
import android.content.SharedPreferences;
-import android.media.MediaCodecInfo;
+import android.os.Build;
import java.util.LinkedList;
import java.util.List;
@@ -26,15 +26,15 @@ public class CodecStore {
this.sharedPreferences = new XSharedPreferences(BuildConfig.APPLICATION_ID, PREFERENCES);
}
- static String getKey(MediaCodecInfo mediaCodecInfo) {
+ static String getKey(MediaCodecInfoWrapper mediaCodecInfo) {
return "codec_" + mediaCodecInfo.getCanonicalName();
}
- boolean getCodecPreference(MediaCodecInfo mediaCodecInfo) {
+ boolean getCodecPreference(MediaCodecInfoWrapper mediaCodecInfo) {
return sharedPreferences.getBoolean(getKey(mediaCodecInfo), DEFAULT_VALUE);
}
- boolean setCodecPreference(MediaCodecInfo mediaCodecInfo, boolean enabled) {
+ boolean setCodecPreference(MediaCodecInfoWrapper mediaCodecInfo, boolean enabled) {
boolean success = false;
if (REMOVE_DEFAULT_VALUE_FROM_CONFIG && enabled == DEFAULT_VALUE) {
success = sharedPreferences.edit().remove(getKey(mediaCodecInfo)).commit();
@@ -47,17 +47,24 @@ boolean setCodecPreference(MediaCodecInfo mediaCodecInfo, boolean enabled) {
return success;
}
- void registerOnCodecPreferenceChangedListener(MediaCodecInfo mediaCodecInfo, OnCodecPreferenceChangedListener onCodecPreferenceChangedListener) {
+ void registerOnCodecPreferenceChangedListener(MediaCodecInfoWrapper mediaCodecInfo, OnCodecPreferenceChangedListener onCodecPreferenceChangedListener) {
OnCodecPreferenceChangedListenerMeta listener = new OnCodecPreferenceChangedListenerMeta();
listener.mediaCodecInfo = mediaCodecInfo;
listener.callback = onCodecPreferenceChangedListener;
receivers.add(listener);
}
- private void dispatchOnCodecPreferenceChanged(MediaCodecInfo mediaCodecInfo, boolean enabled) {
- receivers.stream()
- .filter(r -> getKey(r.mediaCodecInfo).equals(getKey(mediaCodecInfo)))
- .forEach(r -> r.callback.onCodecPreferenceChanged(enabled));
+ private void dispatchOnCodecPreferenceChanged(MediaCodecInfoWrapper mediaCodecInfo, boolean enabled) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ receivers.stream()
+ .filter(r -> getKey(r.mediaCodecInfo).equals(getKey(mediaCodecInfo)))
+ .forEach(r -> r.callback.onCodecPreferenceChanged(enabled));
+ } else {
+ for (OnCodecPreferenceChangedListenerMeta receiver : receivers) {
+ if (getKey(receiver.mediaCodecInfo).equals(getKey(mediaCodecInfo)))
+ receiver.callback.onCodecPreferenceChanged(enabled);
+ }
+ }
}
interface OnCodecPreferenceChangedListener {
@@ -65,7 +72,7 @@ interface OnCodecPreferenceChangedListener {
}
private class OnCodecPreferenceChangedListenerMeta {
- MediaCodecInfo mediaCodecInfo;
+ MediaCodecInfoWrapper mediaCodecInfo;
OnCodecPreferenceChangedListener callback;
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
index ea5e015..c3bc4af 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
@@ -1,9 +1,14 @@
package com.programminghoch10.CodecMod;
+import android.annotation.TargetApi;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
+import android.os.Build;
+import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodReplacement;
@@ -12,6 +17,34 @@
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class Hook implements IXposedHookLoadPackage {
+
+ MediaCodecInfo[] getFilteredMediaCodecInfos(MediaCodecInfo[] unfilteredMediaCodecInfos) {
+ CodecStore codecStore = new CodecStore();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ return Arrays.stream(unfilteredMediaCodecInfos)
+ .filter(mediaCodecInfo ->
+ codecStore.getCodecPreference(new MediaCodecInfoWrapper(mediaCodecInfo))
+ )
+ .toArray(MediaCodecInfo[]::new);
+ }
+ LinkedList filteredMediaCodecs = new LinkedList<>();
+ for (MediaCodecInfo mediaCodecInfo : unfilteredMediaCodecInfos) {
+ if (codecStore.getCodecPreference(new MediaCodecInfoWrapper(mediaCodecInfo)))
+ filteredMediaCodecs.add(mediaCodecInfo);
+ }
+ return filteredMediaCodecs.toArray(new MediaCodecInfo[0]);
+ }
+
+ // helper function, only to be used on mediaCodecs = new LinkedList<>();
+ final int codecCount = (int) XposedBridge.invokeOriginalMethod(XposedHelpers.findMethodExact(MediaCodecList.class, "getCodecCount"), null, null);
+ for (int i = 0; i < codecCount; i++)
+ mediaCodecs.add((MediaCodecInfo) XposedBridge.invokeOriginalMethod(XposedHelpers.findMethodExact(MediaCodecList.class, "getCodecInfoAt"), null, new Object[]{i}));
+ return getFilteredMediaCodecInfos(mediaCodecs.toArray(new MediaCodecInfo[0]));
+ }
+
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals(BuildConfig.APPLICATION_ID)) return;
@@ -19,34 +52,49 @@ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Th
// system-wide hooking not implemented
return;
}
- XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfos", new XC_MethodReplacement() {
- @Override
- protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
- MediaCodecInfo[] mediaCodecInfos = (MediaCodecInfo[]) XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args);
- if (mediaCodecInfos.length == 0) return mediaCodecInfos;
- CodecStore codecStore = new CodecStore();
- MediaCodecInfo[] filteredMediaCodecInfos = Arrays.stream(mediaCodecInfos)
- .filter(codecStore::getCodecPreference)
- .toArray(MediaCodecInfo[]::new);
- return filteredMediaCodecInfos;
- }
- });
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfos", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ MediaCodecInfo[] mediaCodecInfos = (MediaCodecInfo[]) XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args);
+ if (mediaCodecInfos.length == 0) return mediaCodecInfos;
+ return getFilteredMediaCodecInfos(mediaCodecInfos);
+ }
+ });
+
+ // reimplementations of deprecated methods for compatibility
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecCount", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos().length;
+ }
+ });
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfoAt", int.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ final int position = (int) param.args[0];
+ MediaCodecInfo[] mediaCodecInfos = (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos();
+ if (position < 0 || position >= mediaCodecInfos.length) throw new IllegalArgumentException();
+ return mediaCodecInfos[position];
+ }
+ });
+ } else {
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecCount", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return getFilteredMediaCodecInfos().length;
+ }
+ });
+ XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfoAt", int.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ final int position = (int) param.args[0];
+ MediaCodecInfo[] mediaCodecInfos = getFilteredMediaCodecInfos();
+ if (position < 0 || position >= mediaCodecInfos.length) throw new IllegalArgumentException();
+ return mediaCodecInfos[position];
+ }
+ });
+ }
- // reimplementations of deprecated methods for compatibility
- XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecCount", new XC_MethodReplacement() {
- @Override
- protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
- return (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos().length;
- }
- });
- XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfoAt", int.class, new XC_MethodReplacement() {
- @Override
- protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
- final int position = (int) param.args[0];
- MediaCodecInfo[] mediaCodecInfos = (new MediaCodecList(MediaCodecList.REGULAR_CODECS)).getCodecInfos();
- if (position < 0 || position >= mediaCodecInfos.length) throw new IllegalArgumentException();
- return mediaCodecInfos[position];
- }
- });
}
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/MediaCodecInfoWrapper.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/MediaCodecInfoWrapper.java
new file mode 100644
index 0000000..a8fe541
--- /dev/null
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/MediaCodecInfoWrapper.java
@@ -0,0 +1,64 @@
+package com.programminghoch10.CodecMod;
+
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * drop in replacement for MediaCodecInfo
+ * with compatibility checks for older SDKs
+ *
+ * @see android.media.MediaCodecInfo
+ */
+public class MediaCodecInfoWrapper {
+ private final android.media.MediaCodecInfo mediaCodecInfo;
+
+ MediaCodecInfoWrapper(android.media.MediaCodecInfo mediaCodecInfo) {
+ this.mediaCodecInfo = mediaCodecInfo;
+ }
+
+ public String getCanonicalName() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ return mediaCodecInfo.getCanonicalName();
+ }
+ return mediaCodecInfo.getName();
+ }
+
+ public boolean isAlias() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ return mediaCodecInfo.isAlias();
+ }
+ return false;
+ }
+
+ public String getName() {
+ return mediaCodecInfo.getName();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public boolean isHardwareAccelerated() {
+ return mediaCodecInfo.isHardwareAccelerated();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public boolean isSoftwareOnly() {
+ return mediaCodecInfo.isSoftwareOnly();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public boolean isVendor() {
+ return mediaCodecInfo.isVendor();
+ }
+
+ public boolean isEncoder() {
+ return mediaCodecInfo.isEncoder();
+ }
+
+ public boolean isDecoder() {
+ return !isEncoder();
+ }
+
+ public String[] getSupportedTypes() {
+ return mediaCodecInfo.getSupportedTypes();
+ }
+}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
index b3afbff..83f467f 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
@@ -1,8 +1,8 @@
package com.programminghoch10.CodecMod;
import android.app.ActionBar;
-import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
+import android.os.Build;
import android.os.Bundle;
import androidx.fragment.app.FragmentActivity;
@@ -11,6 +11,8 @@
import androidx.preference.SwitchPreference;
import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
public class SettingsActivity extends FragmentActivity {
@Override
@@ -42,8 +44,17 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
CodecStore codecStore = new CodecStore(getContext());
PreferenceCategory decodersPreferenceCategory = findPreference("category_decoders");
PreferenceCategory encodersPreferenceCategory = findPreference("category_encoders");
- MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
- for (MediaCodecInfo mediaCodecInfo : mediaCodecList.getCodecInfos()) {
+
+ List mediaCodecs = new LinkedList<>();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
+ for (android.media.MediaCodecInfo mediaCodecInfo : mediaCodecList.getCodecInfos())
+ mediaCodecs.add(new MediaCodecInfoWrapper(mediaCodecInfo));
+ } else {
+ for (int i = 0; i < MediaCodecList.getCodecCount(); i++)
+ mediaCodecs.add(new MediaCodecInfoWrapper(MediaCodecList.getCodecInfoAt(i)));
+ }
+ for (MediaCodecInfoWrapper mediaCodecInfo : mediaCodecs) {
if (mediaCodecInfo.isAlias() && !SHOW_ALIASES) continue;
SwitchPreference preference = new SwitchPreference(getContext());
preference.setPersistent(false);
@@ -55,17 +66,21 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
});
preference.setTitle(mediaCodecInfo.getName()
+ (mediaCodecInfo.getName().equals(mediaCodecInfo.getCanonicalName()) ? "" : " (" + mediaCodecInfo.getCanonicalName() + ")"));
- preference.setSummary(
- String.format(getString(R.string.hardware_accelerated), mediaCodecInfo.isHardwareAccelerated())
- + "\n" +
- String.format(getString(R.string.software_only), mediaCodecInfo.isSoftwareOnly())
- + "\n" +
- String.format(getString(R.string.supported_types), Arrays.toString(mediaCodecInfo.getSupportedTypes())) +
- (SHOW_ALIASES ? "\n" +
- String.format(getString(R.string.alias), mediaCodecInfo.isAlias()) : "")
- + "\n" +
- String.format(getString(R.string.vendor), mediaCodecInfo.isVendor())
- );
+ StringBuilder summaryBuilder = new StringBuilder();
+ summaryBuilder.append(String.format(getString(R.string.supported_types), Arrays.toString(mediaCodecInfo.getSupportedTypes())));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ summaryBuilder.append("\n");
+ summaryBuilder.append(String.format(getString(R.string.hardware_accelerated), mediaCodecInfo.isHardwareAccelerated()));
+ summaryBuilder.append("\n");
+ summaryBuilder.append(String.format(getString(R.string.software_only), mediaCodecInfo.isSoftwareOnly()));
+ if (SHOW_ALIASES) {
+ summaryBuilder.append("\n");
+ summaryBuilder.append(String.format(getString(R.string.alias), mediaCodecInfo.isAlias()));
+ }
+ summaryBuilder.append("\n");
+ summaryBuilder.append(String.format(getString(R.string.vendor), mediaCodecInfo.isVendor()));
+ }
+ preference.setSummary(summaryBuilder);
PreferenceCategory preferenceCategory = mediaCodecInfo.isEncoder() ? encodersPreferenceCategory : decodersPreferenceCategory;
preferenceCategory.addPreference(preference);
preference.setChecked(codecStore.getCodecPreference(mediaCodecInfo));
diff --git a/CodecMod/src/main/res/values-v21/themes.xml b/CodecMod/src/main/res/values-v21/themes.xml
new file mode 100644
index 0000000..ee02adb
--- /dev/null
+++ b/CodecMod/src/main/res/values-v21/themes.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/CodecMod/src/main/res/values/themes.xml b/CodecMod/src/main/res/values/themes.xml
new file mode 100644
index 0000000..8256aef
--- /dev/null
+++ b/CodecMod/src/main/res/values/themes.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
From 21cf7f13d297390e47c2b7e21707fc2a10391380 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 01:08:04 +0200
Subject: [PATCH 3/8] disable edgetoedge for CodecMod
---
CodecMod/src/main/res/values-v35/themes.xml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 CodecMod/src/main/res/values-v35/themes.xml
diff --git a/CodecMod/src/main/res/values-v35/themes.xml b/CodecMod/src/main/res/values-v35/themes.xml
new file mode 100644
index 0000000..c331e09
--- /dev/null
+++ b/CodecMod/src/main/res/values-v35/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
From bb02162a5cb856ff36f0bb748395033d07bfcc63 Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 01:11:11 +0200
Subject: [PATCH 4/8] add documentation for CodecMod
---
CodecMod/Readme.md | 5 +++++
CodecMod/src/main/AndroidManifest.xml | 2 +-
CodecMod/src/main/res/values/strings.xml | 2 ++
.../en-US/full_description.txt | 3 +++
.../en-US/short_description.txt | 1 +
metadata/com.programminghoch10.CodecMod/en-US/title.txt | 1 +
6 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 CodecMod/Readme.md
create mode 100644 metadata/com.programminghoch10.CodecMod/en-US/full_description.txt
create mode 100644 metadata/com.programminghoch10.CodecMod/en-US/short_description.txt
create mode 100644 metadata/com.programminghoch10.CodecMod/en-US/title.txt
diff --git a/CodecMod/Readme.md b/CodecMod/Readme.md
new file mode 100644
index 0000000..1beccc7
--- /dev/null
+++ b/CodecMod/Readme.md
@@ -0,0 +1,5 @@
+# CodecMod
+
+This Module allows you to selectively disable audio/video hardware/software encoders/decoders.
+
+Supports all codecs reported by Android through the MediaCodecList API.
diff --git a/CodecMod/src/main/AndroidManifest.xml b/CodecMod/src/main/AndroidManifest.xml
index 9fae8ca..dcb0552 100644
--- a/CodecMod/src/main/AndroidManifest.xml
+++ b/CodecMod/src/main/AndroidManifest.xml
@@ -20,7 +20,7 @@
android:value="true" />
+ android:value="@string/description" />
diff --git a/CodecMod/src/main/res/values/strings.xml b/CodecMod/src/main/res/values/strings.xml
index 408e6f5..ec4ae55 100644
--- a/CodecMod/src/main/res/values/strings.xml
+++ b/CodecMod/src/main/res/values/strings.xml
@@ -1,5 +1,7 @@
CodecMod
+ This Module allows you to selectively disable audio/video hardware/software encoders/decoders.
+
CodecMod Settings
Hardware-accelerated: %b
Software-only: %b
diff --git a/metadata/com.programminghoch10.CodecMod/en-US/full_description.txt b/metadata/com.programminghoch10.CodecMod/en-US/full_description.txt
new file mode 100644
index 0000000..90d04bd
--- /dev/null
+++ b/metadata/com.programminghoch10.CodecMod/en-US/full_description.txt
@@ -0,0 +1,3 @@
+This Module allows you to selectively disable codecs on your android device.
+Every encoder and decoder is listed and can be selectively disabled at choice.
+Supports all codecs reported by Android through the MediaCodecList API.
diff --git a/metadata/com.programminghoch10.CodecMod/en-US/short_description.txt b/metadata/com.programminghoch10.CodecMod/en-US/short_description.txt
new file mode 100644
index 0000000..40da116
--- /dev/null
+++ b/metadata/com.programminghoch10.CodecMod/en-US/short_description.txt
@@ -0,0 +1 @@
+This Module allows you to selectively disable audio/video hardware/software encoders/decoders.
diff --git a/metadata/com.programminghoch10.CodecMod/en-US/title.txt b/metadata/com.programminghoch10.CodecMod/en-US/title.txt
new file mode 100644
index 0000000..2826e5e
--- /dev/null
+++ b/metadata/com.programminghoch10.CodecMod/en-US/title.txt
@@ -0,0 +1 @@
+CodecMod
From 7854ed6ea36cdb765cbd3d7b41ad32d0fed1a1ed Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:11:48 +0200
Subject: [PATCH 5/8] add java desugaring to CodecMod
---
CodecMod/build.gradle.kts | 4 ++++
.../com/programminghoch10/CodecMod/Hook.java | 20 ++++++-------------
.../CodecMod/MediaCodecInfoWrapper.java | 11 +++++++---
.../CodecMod/SettingsActivity.java | 8 +++++---
4 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/CodecMod/build.gradle.kts b/CodecMod/build.gradle.kts
index 17d373a..26b5e52 100644
--- a/CodecMod/build.gradle.kts
+++ b/CodecMod/build.gradle.kts
@@ -9,7 +9,11 @@ android {
minSdk = 16
targetSdk = 35
}
+ compileOptions {
+ isCoreLibraryDesugaringEnabled = true
+ }
}
dependencies {
implementation(libs.androidx.preference)
+ coreLibraryDesugaring(libs.android.desugarJdkLibs)
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
index c3bc4af..a5af2b3 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
@@ -20,19 +20,11 @@ public class Hook implements IXposedHookLoadPackage {
MediaCodecInfo[] getFilteredMediaCodecInfos(MediaCodecInfo[] unfilteredMediaCodecInfos) {
CodecStore codecStore = new CodecStore();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- return Arrays.stream(unfilteredMediaCodecInfos)
- .filter(mediaCodecInfo ->
- codecStore.getCodecPreference(new MediaCodecInfoWrapper(mediaCodecInfo))
- )
- .toArray(MediaCodecInfo[]::new);
- }
- LinkedList filteredMediaCodecs = new LinkedList<>();
- for (MediaCodecInfo mediaCodecInfo : unfilteredMediaCodecInfos) {
- if (codecStore.getCodecPreference(new MediaCodecInfoWrapper(mediaCodecInfo)))
- filteredMediaCodecs.add(mediaCodecInfo);
- }
- return filteredMediaCodecs.toArray(new MediaCodecInfo[0]);
+ return Arrays.stream(unfilteredMediaCodecInfos)
+ .map(MediaCodecInfoWrapper::new)
+ .filter(codecStore::getCodecPreference)
+ .map(MediaCodecInfoWrapper::getOriginalMediaCodecInfo)
+ .toArray(MediaCodecInfo[]::new);
}
// helper function, only to be used on = Build.VERSION_CODES.Q) {
return mediaCodecInfo.getCanonicalName();
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
index 83f467f..40197e9 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
@@ -45,12 +45,14 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
PreferenceCategory decodersPreferenceCategory = findPreference("category_decoders");
PreferenceCategory encodersPreferenceCategory = findPreference("category_encoders");
- List mediaCodecs = new LinkedList<>();
+ List mediaCodecs;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
- for (android.media.MediaCodecInfo mediaCodecInfo : mediaCodecList.getCodecInfos())
- mediaCodecs.add(new MediaCodecInfoWrapper(mediaCodecInfo));
+ mediaCodecs = Arrays.stream(mediaCodecList.getCodecInfos())
+ .map(MediaCodecInfoWrapper::new)
+ .toList();
} else {
+ mediaCodecs = new LinkedList<>();
for (int i = 0; i < MediaCodecList.getCodecCount(); i++)
mediaCodecs.add(new MediaCodecInfoWrapper(MediaCodecList.getCodecInfoAt(i)));
}
From b6d624be66db58e524bf0454fdc440ad6d3705db Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:12:09 +0200
Subject: [PATCH 6/8] some more small CodecMod tweaks
---
.../java/com/programminghoch10/CodecMod/CodecStore.java | 4 +++-
.../src/main/java/com/programminghoch10/CodecMod/Hook.java | 6 ++----
.../com/programminghoch10/CodecMod/SettingsActivity.java | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
index de985f6..f047577 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
@@ -2,6 +2,7 @@
import static android.content.Context.MODE_WORLD_READABLE;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
@@ -18,6 +19,7 @@ public class CodecStore {
SharedPreferences sharedPreferences;
List receivers = new LinkedList<>();
+ @SuppressLint("WorldReadableFiles")
CodecStore(Context context) {
this.sharedPreferences = context.getSharedPreferences(PREFERENCES, MODE_WORLD_READABLE);
}
@@ -71,7 +73,7 @@ interface OnCodecPreferenceChangedListener {
void onCodecPreferenceChanged(boolean value);
}
- private class OnCodecPreferenceChangedListenerMeta {
+ private static class OnCodecPreferenceChangedListenerMeta {
MediaCodecInfoWrapper mediaCodecInfo;
OnCodecPreferenceChangedListener callback;
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
index a5af2b3..e84eb5b 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
@@ -1,5 +1,6 @@
package com.programminghoch10.CodecMod;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
@@ -28,6 +29,7 @@ MediaCodecInfo[] getFilteredMediaCodecInfos(MediaCodecInfo[] unfilteredMediaCode
}
// helper function, only to be used on mediaCodecs = new LinkedList<>();
@@ -40,10 +42,6 @@ MediaCodecInfo[] getFilteredMediaCodecInfos() throws InvocationTargetException,
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals(BuildConfig.APPLICATION_ID)) return;
- if (lpparam.packageName.equals("android")) {
- // system-wide hooking not implemented
- return;
- }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
XposedHelpers.findAndHookMethod(MediaCodecList.class, "getCodecInfos", new XC_MethodReplacement() {
@Override
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
index 40197e9..41a5958 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
@@ -41,7 +41,7 @@ public static class SettingsFragment extends PreferenceFragmentCompat {
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
//getPreferenceManager().setSharedPreferencesName("codecs");
- CodecStore codecStore = new CodecStore(getContext());
+ CodecStore codecStore = new CodecStore(requireContext());
PreferenceCategory decodersPreferenceCategory = findPreference("category_decoders");
PreferenceCategory encodersPreferenceCategory = findPreference("category_encoders");
@@ -58,7 +58,7 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
for (MediaCodecInfoWrapper mediaCodecInfo : mediaCodecs) {
if (mediaCodecInfo.isAlias() && !SHOW_ALIASES) continue;
- SwitchPreference preference = new SwitchPreference(getContext());
+ SwitchPreference preference = new SwitchPreference(requireContext());
preference.setPersistent(false);
preference.setDefaultValue(CodecStore.DEFAULT_VALUE);
preference.setKey(CodecStore.getKey(mediaCodecInfo));
From d00c268a71dc712e4acacd3e93f2879e0997da3f Mon Sep 17 00:00:00 2001
From: programminghoch10 <16062290+programminghoch10@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:17:33 +0200
Subject: [PATCH 7/8] add CodecMod to README
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 6a89956..b43c5f7 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ A collection of small Xposed Modules.
| [AutomaticAdvancedSettingsExpander](AutomaticAdvancedSettingsExpander) | [@binarynoise](https://github.com/binarynoise) | Automatically expands the advanced settings in the Settings app | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=AutomaticAdvancedSettingsExpander) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/de.binarynoise.AutomaticAdvancedSettingsExpander) |
| [BetterBluetoothDeviceSort](BetterBluetoothDeviceSort) | [@binarynoise](https://github.com/binarynoise) | Sorts Bluetooth devices by name | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=betterBluetoothDeviceSort) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/de.binarynoise.betterBluetoothDeviceSort) |
| [BetterVerboseWiFiLogging](BetterVerboseWiFiLogging) | [@binarynoise](https://github.com/binarynoise) | Makes the verbose Wi-Fi information more readable | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=betterVerboseWiFiLogging) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/de.binarynoise.betterVerboseWiFiLogging) |
+| [CodecMod](CodecMod) | [@programminghoch10](https://github.com/programminghoch10) | Selectively disable audio/video hardware/software encoders/decoders. | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=CodecMod) |
| [Don'tResetIfBootedAndConnected](DontResetIfBootedAndConnected) | [@binarynoise](https://github.com/binarynoise) | | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=dontResetIfBootedAndConnected) |
| [FreeNotifications](FreeNotifications) | [@binarynoise](https://github.com/binarynoise) | Enables customization for all Notification Channels again | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=freeNotifications) [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/de.binarynoise.freeNotifications) |
| [MotionEventMod](MotionEventMod) | [@programminghoch10](https://github.com/programminghoch10) | Disable touch input for some seconds after the stylus was in use | [GitHub](https://github.com/binarynoise/XposedModulets/releases?q=MotionEventMod) |
From 338380521e768472ec0f5c03172428de5160b839 Mon Sep 17 00:00:00 2001
From: binarynoise
Date: Mon, 4 Aug 2025 17:51:29 +0200
Subject: [PATCH 8/8] reformat
---
CodecMod/build.gradle.kts | 1 +
CodecMod/src/main/AndroidManifest.xml | 16 ++++++++++------
.../programminghoch10/CodecMod/CodecStore.java | 7 +++----
.../com/programminghoch10/CodecMod/Hook.java | 1 -
.../CodecMod/SettingsActivity.java | 1 -
.../src/main/res/layout/settings_activity.xml | 9 ++++++---
CodecMod/src/main/res/values-v21/themes.xml | 1 -
CodecMod/src/main/res/values-v35/themes.xml | 1 -
CodecMod/src/main/res/values/themes.xml | 1 -
CodecMod/src/main/res/xml/root_preferences.xml | 9 ++++++---
gradle/libs.versions.toml | 2 +-
11 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/CodecMod/build.gradle.kts b/CodecMod/build.gradle.kts
index 26b5e52..c99cfe2 100644
--- a/CodecMod/build.gradle.kts
+++ b/CodecMod/build.gradle.kts
@@ -13,6 +13,7 @@ android {
isCoreLibraryDesugaringEnabled = true
}
}
+
dependencies {
implementation(libs.androidx.preference)
coreLibraryDesugaring(libs.android.desugarJdkLibs)
diff --git a/CodecMod/src/main/AndroidManifest.xml b/CodecMod/src/main/AndroidManifest.xml
index dcb0552..b33a41b 100644
--- a/CodecMod/src/main/AndroidManifest.xml
+++ b/CodecMod/src/main/AndroidManifest.xml
@@ -1,12 +1,14 @@
-
+
+ android:theme="@style/AppTheme"
+ >
@@ -17,13 +19,15 @@
+ android:value="true"
+ />
+ android:value="@string/description"
+ />
+ android:value="93"
+ />
-
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
index f047577..a1d86c2 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/CodecStore.java
@@ -37,16 +37,16 @@ boolean getCodecPreference(MediaCodecInfoWrapper mediaCodecInfo) {
}
boolean setCodecPreference(MediaCodecInfoWrapper mediaCodecInfo, boolean enabled) {
- boolean success = false;
+ boolean success;
if (REMOVE_DEFAULT_VALUE_FROM_CONFIG && enabled == DEFAULT_VALUE) {
success = sharedPreferences.edit().remove(getKey(mediaCodecInfo)).commit();
} else {
success = sharedPreferences.edit().putBoolean(getKey(mediaCodecInfo), enabled).commit();
}
if (!success)
- return success;
+ return false;
dispatchOnCodecPreferenceChanged(mediaCodecInfo, enabled);
- return success;
+ return true;
}
void registerOnCodecPreferenceChangedListener(MediaCodecInfoWrapper mediaCodecInfo, OnCodecPreferenceChangedListener onCodecPreferenceChangedListener) {
@@ -77,5 +77,4 @@ private static class OnCodecPreferenceChangedListenerMeta {
MediaCodecInfoWrapper mediaCodecInfo;
OnCodecPreferenceChangedListener callback;
}
-
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
index e84eb5b..a3df051 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/Hook.java
@@ -85,6 +85,5 @@ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
}
});
}
-
}
}
diff --git a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
index 41a5958..589bff8 100644
--- a/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
+++ b/CodecMod/src/main/java/com/programminghoch10/CodecMod/SettingsActivity.java
@@ -35,7 +35,6 @@ protected void onCreate(Bundle savedInstanceState) {
public static class SettingsFragment extends PreferenceFragmentCompat {
private static final boolean SHOW_ALIASES = true;
- CodecStore codecStore = null;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
diff --git a/CodecMod/src/main/res/layout/settings_activity.xml b/CodecMod/src/main/res/layout/settings_activity.xml
index 3454f9f..89fbea7 100644
--- a/CodecMod/src/main/res/layout/settings_activity.xml
+++ b/CodecMod/src/main/res/layout/settings_activity.xml
@@ -1,9 +1,12 @@
-
+ android:layout_height="match_parent"
+ >
+ android:layout_height="match_parent"
+ />
diff --git a/CodecMod/src/main/res/values-v21/themes.xml b/CodecMod/src/main/res/values-v21/themes.xml
index ee02adb..6ee0359 100644
--- a/CodecMod/src/main/res/values-v21/themes.xml
+++ b/CodecMod/src/main/res/values-v21/themes.xml
@@ -1,5 +1,4 @@
-
diff --git a/CodecMod/src/main/res/values-v35/themes.xml b/CodecMod/src/main/res/values-v35/themes.xml
index c331e09..1cdd3f2 100644
--- a/CodecMod/src/main/res/values-v35/themes.xml
+++ b/CodecMod/src/main/res/values-v35/themes.xml
@@ -1,6 +1,5 @@
-
diff --git a/CodecMod/src/main/res/values/themes.xml b/CodecMod/src/main/res/values/themes.xml
index 8256aef..33bc3e6 100644
--- a/CodecMod/src/main/res/values/themes.xml
+++ b/CodecMod/src/main/res/values/themes.xml
@@ -1,5 +1,4 @@
-
diff --git a/CodecMod/src/main/res/xml/root_preferences.xml b/CodecMod/src/main/res/xml/root_preferences.xml
index b4b1a7f..db14437 100644
--- a/CodecMod/src/main/res/xml/root_preferences.xml
+++ b/CodecMod/src/main/res/xml/root_preferences.xml
@@ -1,8 +1,11 @@
-
+
+ app:title="Decoders"
+ />
+ app:title="Encoders"
+ />
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e01a720..f77f849 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -20,6 +20,7 @@ android-tools-common = { module = "com.android.tools:common", version.ref = "and
androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidxAnnotation" }
androidx-collection = { module = "androidx.collection:collection", version.ref = "collection" }
androidx-collection-ktx = { module = "androidx.collection:collection-ktx", version.ref = "collectionKtx" }
+androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
github-api = { module = "org.kohsuke:github-api", version.ref = "githubApi" }
hiddenapibypass = { module = "org.lsposed.hiddenapibypass:hiddenapibypass", version.ref = "hiddenapibypass" }
jebtrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jebrainsAnnotations" }
@@ -28,7 +29,6 @@ kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin" }
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" }
libsu-core = { module = "com.github.topjohnwu.libsu:core", version.ref = "libsu" }
xposed-api = { module = "de.robv.android.xposed:api", version.ref = "xposed" }
-androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }