Skip to content

Commit

Permalink
Add loop
Browse files Browse the repository at this point in the history
some devices may crash when using JNI callback in that way...
  • Loading branch information
chinosk6 committed Jun 24, 2024
1 parent 9fede70 commit 91dea41
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 25 deletions.
64 changes: 39 additions & 25 deletions app/src/main/cpp/GakumasLocalify/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <sstream>
#include <string>
#include <thread>
#include <queue>

extern JavaVM* g_javaVM;
extern jclass g_gakumasHookMainClass;
Expand All @@ -24,9 +25,13 @@ extern jmethodID showToastMethodId;


namespace GakumasLocal::Log {
namespace {
std::queue<std::string> showingToasts{};
}

std::string StringFormat(const char* fmt, ...) {
GetParamStringResult(result);
return result.c_str();
return result;
}

void Log(int prio, const char* msg) {
Expand Down Expand Up @@ -70,8 +75,8 @@ namespace GakumasLocal::Log {
__android_log_write(prio, "GakumasLog", result.c_str());
}

void ShowToast(const std::string& text) {
DebugFmt("Toast: %s", text.c_str());
void ShowToastJNI(const char* text) {
DebugFmt("Toast: %s", text);

std::thread([text](){
auto env = Misc::GetJNIEnv();
Expand All @@ -89,41 +94,50 @@ namespace GakumasLocal::Log {
g_javaVM->DetachCurrentThread();
return;
}
jstring param = env->NewStringUTF(text.c_str());
jstring param = env->NewStringUTF(text);
env->CallStaticVoidMethod(kotlinClass, methodId, param);

g_javaVM->DetachCurrentThread();
}).detach();
}


void ShowToast(const std::string& text) {
showingToasts.push(text);
}

void ShowToast(const char* text) {
DebugFmt("Toast: %s", text);
return ShowToast(std::string(text));
}

void ShowToastFmt(const char* fmt, ...) {
GetParamStringResult(result);
ShowToast(result);
}

void ShowToast(const char* text) {
DebugFmt("Toast: %s", text);
std::string GetQueuedToast() {
if (showingToasts.empty()) {
return "";
}
const auto ret = showingToasts.front();
showingToasts.pop();
return ret;
}

std::thread([text](){
auto env = Misc::GetJNIEnv();
if (!env) {
return;
}
void ToastLoop(JNIEnv *env, jclass clazz) {
const auto toastString = GetQueuedToast();
if (toastString.empty()) return;

jclass& kotlinClass = g_gakumasHookMainClass;
if (!kotlinClass) {
g_javaVM->DetachCurrentThread();
return;
}
jmethodID& methodId = showToastMethodId;
if (!methodId) {
g_javaVM->DetachCurrentThread();
return;
}
jstring param = env->NewStringUTF(text);
env->CallStaticVoidMethod(kotlinClass, methodId, param);
static auto _showToastMethodId = env->GetStaticMethodID(clazz, "showToast", "(Ljava/lang/String;)V");

g_javaVM->DetachCurrentThread();
}).detach();
if (env && clazz && _showToastMethodId) {
jstring param = env->NewStringUTF(toastString.c_str());
env->CallStaticVoidMethod(clazz, _showToastMethodId, param);
env->DeleteLocalRef(param);
}
else {
_showToastMethodId = env->GetStaticMethodID(clazz, "showToast", "(Ljava/lang/String;)V");
}
}
}
3 changes: 3 additions & 0 deletions app/src/main/cpp/GakumasLocalify/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GAKUMAS_LOCALIFY_LOG_H

#include <string>
#include <jni.h>

namespace GakumasLocal::Log {
std::string StringFormat(const char* fmt, ...);
Expand All @@ -16,6 +17,8 @@ namespace GakumasLocal::Log {

void ShowToast(const char* text);
void ShowToastFmt(const char* fmt, ...);

void ToastLoop(JNIEnv *env, jclass clazz);
}

#endif //GAKUMAS_LOCALIFY_LOG_H
7 changes: 7 additions & 0 deletions app/src/main/cpp/libMarryKotone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,11 @@ Java_io_github_chinosk_gakumas_localify_GakumasHookMain_loadConfig(JNIEnv *env,
const auto configJsonStrChars = env->GetStringUTFChars(config_json_str, nullptr);
const std::string configJson = configJsonStrChars;
GakumasLocal::Config::LoadConfig(configJson);
}

extern "C"
JNIEXPORT void JNICALL
Java_io_github_chinosk_gakumas_localify_GakumasHookMain_pluginCallbackLooper(JNIEnv *env,
jclass clazz) {
GakumasLocal::Log::ToastLoop(env, clazz);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ import android.widget.Toast
import com.google.gson.Gson
import de.robv.android.xposed.XposedBridge
import io.github.chinosk.gakumas.localify.models.GakumasConfig
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.File
import java.util.Locale
import kotlin.system.measureTimeMillis

val TAG = "GakumasLocalify"

Expand All @@ -42,6 +48,20 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
private var getConfigError: Exception? = null

override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
// if (lpparam.packageName == "io.github.chinosk.gakumas.localify") {
// XposedHelpers.findAndHookMethod(
// "io.github.chinosk.gakumas.localify.MainActivity",
// lpparam.classLoader,
// "showToast",
// String::class.java,
// object : XC_MethodHook() {
// override fun beforeHookedMethod(param: MethodHookParam) {
// Log.d(TAG, "beforeHookedMethod hooked: ${param.args}")
// }
// }
// )
// }

if (lpparam.packageName != targetPackageName) {
return
}
Expand Down Expand Up @@ -175,6 +195,21 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
alreadyInitialized = true
}
})

startLoop()
}

@OptIn(DelicateCoroutinesApi::class)
private fun startLoop() {
GlobalScope.launch {
val interval = 1000L / 30
while (isActive) {
val timeTaken = measureTimeMillis {
pluginCallbackLooper()
}
delay(interval - timeTaken)
}
}
}

fun initGkmsConfig(activity: Activity) {
Expand Down Expand Up @@ -337,6 +372,9 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
Log.e(TAG, "showToast: $message failed: applicationContext is null")
}
}

@JvmStatic
external fun pluginCallbackLooper()
}

init {
Expand Down

0 comments on commit 91dea41

Please sign in to comment.