Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/build-ksu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Build KernelSU Module

on:
push:
branches: [ ksu-module ]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout source
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Install Build Tools and Platforms
run: |
sdkmanager "build-tools;33.0.0" "platforms;android-33"

- name: Build Module
run: |
cd ksu-module
chmod +x build.sh
./build.sh

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: fox_live_fps
path: ksu-module/fox_live_fps.zip
retention-days: 30
14 changes: 14 additions & 0 deletions ksu-module/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# Ensure you have the Android SDK installed for javac and d8

# 1. Compile the Java source against the Android framework
javac -cp $ANDROID_HOME/platforms/android-33/android.jar fox/fps/FpsOverlay.java

# 2. Convert to DEX bytecode
$ANDROID_HOME/build-tools/33.0.0/d8 fox/fps/FpsOverlay.class --output .

# 3. Rename and package the KSU module
mv classes.dex fps_overlay.dex
zip -r fox_live_fps.zip module.prop service.sh fps_overlay.dex

echo "Done. Flash fox_live_fps.zip in KernelSU, bitch."
74 changes: 74 additions & 0 deletions ksu-module/fox/fps/FpsOverlay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package fox.fps;

import android.app.ActivityThread;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class FpsOverlay {
public static void main(String[] args) {
Looper.prepare();
try {
// Grab the system context directly from ActivityThread
ActivityThread thread = ActivityThread.systemMain();
Context context = thread.getSystemContext();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

TextView tv = new TextView(context);
tv.setText("FPS: --");
tv.setTextColor(Color.GREEN);
tv.setTextSize(18f);
tv.setBackgroundColor(Color.argb(150, 0, 0, 0));
tv.setPadding(15, 10, 15, 10);

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
2015, // TYPE_SECURE_SYSTEM_OVERLAY - bypasses draw-over-apps permission
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 50;
params.y = 50;

wm.addView(tv, params);

Handler handler = new Handler();
Runnable updateFps = new Runnable() {
@Override
public void run() {
tv.setText("FPS: " + getFps());
handler.postDelayed(this, 500);
}
};
handler.post(updateFps);

} catch (Exception e) {
e.printStackTrace();
}
Looper.loop();
}

private static String getFps() {
try {
// Standard Qualcomm DRM sysfs node.
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "cat /sys/class/drm/sde-crtc-*/measured_fps | head -n 1"});
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
if (line != null && !line.trim().isEmpty()) {
return line.trim().split(" ")[0];
}
} catch (Exception e) {}
return "N/A";
}
}
6 changes: 6 additions & 0 deletions ksu-module/module.prop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
id=fox_live_fps
name=Live FPS Overlay
version=v1.0
versionCode=1
author=Fox
description=Displays a live FPS overlay using app_process.
11 changes: 11 additions & 0 deletions ksu-module/service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/system/bin/sh
MODDIR=${0%/*}

# Wait for boot to finish so WindowManager is ready
while [ "$(getprop sys.boot_completed)" != "1" ]; do
sleep 1
done

# Launch the app_process payload in the background
export CLASSPATH=$MODDIR/fps_overlay.dex
app_process /system/bin fox.fps.FpsOverlay &
Loading