Skip to content

Commit 4e25853

Browse files
committed
feat: 4
1 parent bcf9664 commit 4e25853

2 files changed

Lines changed: 50 additions & 54 deletions

File tree

extensions/extension/src/main/java/app/revanced/extension/customfilters/TintFieldHook.java

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,72 +10,68 @@
1010
import java.lang.reflect.Method;
1111
import java.lang.reflect.Field;
1212

13+
/**
14+
* Schedule a safe install after initialization.
15+
* Call this from your smali injection.
16+
*/
1317
public class TintFieldHook {
1418
private static final String TAG = "CustomFilterHook";
19+
private static boolean installed = false;
1520

16-
// Simple ping to check injection
17-
public static void ping(Object toolTable) {
18-
try {
19-
Log.i(TAG, "ping() called. toolTable class: " + (toolTable != null ? toolTable.getClass().getName() : "null"));
20-
} catch (Throwable t) {
21-
Log.e(TAG, "ping() error", t);
22-
}
21+
/**
22+
* Schedule a safe install after initialization.
23+
* Call this from your smali injection.
24+
*/
25+
public static void scheduleInstall(final Object toolTable) {
26+
if (installed) return; // Only run once
27+
installed = true;
28+
29+
// Ensure this runs on the main thread after a short delay
30+
new Handler(Looper.getMainLooper()).postDelayed(() -> {
31+
try {
32+
installTintField(toolTable);
33+
} catch (Throwable t) {
34+
Log.e(TAG, "scheduled install failed", t);
35+
}
36+
}, 300); // 300ms delay gives initialize() time to finish
2337
}
2438

25-
// schedule the real install a little later on the main thread
26-
public static void scheduleInstall(final Object toolTable) {
27-
try {
28-
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
29-
@Override
30-
public void run() {
31-
try {
32-
installTintField(toolTable);
33-
} catch (Throwable t) {
34-
Log.e(TAG, "scheduled install failed", t);
35-
}
36-
}
37-
}, 200); // 200 ms delay
38-
} catch (Throwable t) {
39-
Log.e(TAG, "scheduleInstall failed", t);
39+
/**
40+
* Main hook: safely introspect the toolTable.
41+
*/
42+
public static void installTintField(Object toolTable) {
43+
if (toolTable == null) {
44+
Log.w(TAG, "toolTable is null, aborting hook");
45+
return;
4046
}
41-
}
4247

43-
// do minimal, defensive reflection/UI code here
44-
public static void installTintField(Object table) {
4548
try {
46-
// defensive: attempt to find context safely
47-
Object contextObj = null;
48-
try {
49-
// In a lot of these classes getModule().getContext() is the path; adapt as needed
50-
java.lang.reflect.Method getModule = table.getClass().getMethod("getModule");
51-
Object module = getModule.invoke(table);
52-
java.lang.reflect.Method getContext = module.getClass().getMethod("getContext");
53-
contextObj = getContext.invoke(module);
54-
} catch (Throwable inner) {
55-
Log.w(TAG, "couldn't get context via getModule/getContext", inner);
56-
}
49+
Log.i(TAG, "installTintField() invoked; table class: " + toolTable.getClass().getName());
5750

58-
// fallback: try table.getContext()
59-
if (contextObj == null) {
60-
try {
61-
java.lang.reflect.Method getContext2 = table.getClass().getMethod("getContext");
62-
contextObj = getContext2.invoke(table);
63-
} catch (Throwable ignored) {}
51+
// Example: safely list all fields
52+
Field[] fields = toolTable.getClass().getDeclaredFields();
53+
for (Field f : fields) {
54+
f.setAccessible(true);
55+
Object value = null;
56+
try { value = f.get(toolTable); } catch (Throwable ignored) {}
57+
Log.i(TAG, "Field: " + f.getName() + " | Type: " + f.getType().getSimpleName() + " | Value: " + value);
6458
}
6559

66-
Context context = (contextObj instanceof Context) ? (Context) contextObj : null;
67-
68-
// Show a toast safely on main thread if we have a context
69-
if (context != null) {
70-
final Context ctx = context;
71-
new Handler(Looper.getMainLooper()).post(() ->
72-
Toast.makeText(ctx, "✅ Custom filter slot installed", Toast.LENGTH_SHORT).show()
73-
);
60+
// Example: safely call a method (if exists)
61+
try {
62+
Method getContext = toolTable.getClass().getMethod("getContext");
63+
Object context = getContext.invoke(toolTable);
64+
Log.i(TAG, "Retrieved context: " + context);
65+
} catch (Throwable e) {
66+
Log.w(TAG, "getContext() method not available", e);
7467
}
7568

76-
Log.i(TAG, "installTintField() finished; table class: " + (table != null ? table.getClass().getName() : "null"));
77-
} catch (Throwable t) {
78-
Log.e(TAG, "installTintField failed", t);
69+
// === INSERT CUSTOM FILTER SLOT LOGIC BELOW ===
70+
// At this point you can add your UI components / custom slot safely
71+
Log.i(TAG, "Custom filter hook ready for adding filter slot!");
72+
73+
} catch (Throwable e) {
74+
Log.e(TAG, "installTintField failed", e);
7975
}
8076
}
8177
}

patches/src/main/kotlin/sticknodes/customFilters.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ val AddCustomFilterSlot = bytecodePatch(
4747
targetMethod.addInstruction(
4848
insertIndex,
4949
"""
50-
invoke-static/range {p0 .. p0}, Lapp/revanced/extension/customfilters/TintFieldHook;->scheduleInstall(Ljava/lang/Object;)V
50+
invoke-static {p0}, Lapp/revanced/extension/customfilters/TintFieldHook;->scheduleInstall(Ljava/lang/Object;)V
5151
""".trimIndent()
5252
)
5353

0 commit comments

Comments
 (0)