Add loop
some devices may crash when using JNI callback in that way...
This commit is contained in:
parent
9fede70bec
commit
91dea41ca2
@ -4,6 +4,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
extern JavaVM* g_javaVM;
|
extern JavaVM* g_javaVM;
|
||||||
extern jclass g_gakumasHookMainClass;
|
extern jclass g_gakumasHookMainClass;
|
||||||
@ -24,9 +25,13 @@ extern jmethodID showToastMethodId;
|
|||||||
|
|
||||||
|
|
||||||
namespace GakumasLocal::Log {
|
namespace GakumasLocal::Log {
|
||||||
|
namespace {
|
||||||
|
std::queue<std::string> showingToasts{};
|
||||||
|
}
|
||||||
|
|
||||||
std::string StringFormat(const char* fmt, ...) {
|
std::string StringFormat(const char* fmt, ...) {
|
||||||
GetParamStringResult(result);
|
GetParamStringResult(result);
|
||||||
return result.c_str();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log(int prio, const char* msg) {
|
void Log(int prio, const char* msg) {
|
||||||
@ -70,38 +75,7 @@ namespace GakumasLocal::Log {
|
|||||||
__android_log_write(prio, "GakumasLog", result.c_str());
|
__android_log_write(prio, "GakumasLog", result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowToast(const std::string& text) {
|
void ShowToastJNI(const char* text) {
|
||||||
DebugFmt("Toast: %s", text.c_str());
|
|
||||||
|
|
||||||
std::thread([text](){
|
|
||||||
auto env = Misc::GetJNIEnv();
|
|
||||||
if (!env) {
|
|
||||||
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.c_str());
|
|
||||||
env->CallStaticVoidMethod(kotlinClass, methodId, param);
|
|
||||||
|
|
||||||
g_javaVM->DetachCurrentThread();
|
|
||||||
}).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowToastFmt(const char* fmt, ...) {
|
|
||||||
GetParamStringResult(result);
|
|
||||||
ShowToast(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowToast(const char* text) {
|
|
||||||
DebugFmt("Toast: %s", text);
|
DebugFmt("Toast: %s", text);
|
||||||
|
|
||||||
std::thread([text](){
|
std::thread([text](){
|
||||||
@ -126,4 +100,44 @@ namespace GakumasLocal::Log {
|
|||||||
g_javaVM->DetachCurrentThread();
|
g_javaVM->DetachCurrentThread();
|
||||||
}).detach();
|
}).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);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetQueuedToast() {
|
||||||
|
if (showingToasts.empty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const auto ret = showingToasts.front();
|
||||||
|
showingToasts.pop();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToastLoop(JNIEnv *env, jclass clazz) {
|
||||||
|
const auto toastString = GetQueuedToast();
|
||||||
|
if (toastString.empty()) return;
|
||||||
|
|
||||||
|
static auto _showToastMethodId = env->GetStaticMethodID(clazz, "showToast", "(Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GAKUMAS_LOCALIFY_LOG_H
|
#define GAKUMAS_LOCALIFY_LOG_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
namespace GakumasLocal::Log {
|
namespace GakumasLocal::Log {
|
||||||
std::string StringFormat(const char* fmt, ...);
|
std::string StringFormat(const char* fmt, ...);
|
||||||
@ -16,6 +17,8 @@ namespace GakumasLocal::Log {
|
|||||||
|
|
||||||
void ShowToast(const char* text);
|
void ShowToast(const char* text);
|
||||||
void ShowToastFmt(const char* fmt, ...);
|
void ShowToastFmt(const char* fmt, ...);
|
||||||
|
|
||||||
|
void ToastLoop(JNIEnv *env, jclass clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //GAKUMAS_LOCALIFY_LOG_H
|
#endif //GAKUMAS_LOCALIFY_LOG_H
|
||||||
|
@ -111,4 +111,11 @@ Java_io_github_chinosk_gakumas_localify_GakumasHookMain_loadConfig(JNIEnv *env,
|
|||||||
const auto configJsonStrChars = env->GetStringUTFChars(config_json_str, nullptr);
|
const auto configJsonStrChars = env->GetStringUTFChars(config_json_str, nullptr);
|
||||||
const std::string configJson = configJsonStrChars;
|
const std::string configJson = configJsonStrChars;
|
||||||
GakumasLocal::Config::LoadConfig(configJson);
|
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);
|
||||||
}
|
}
|
@ -25,8 +25,14 @@ import android.widget.Toast
|
|||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import io.github.chinosk.gakumas.localify.models.GakumasConfig
|
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.io.File
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
val TAG = "GakumasLocalify"
|
val TAG = "GakumasLocalify"
|
||||||
|
|
||||||
@ -42,6 +48,20 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||||||
private var getConfigError: Exception? = null
|
private var getConfigError: Exception? = null
|
||||||
|
|
||||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
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) {
|
if (lpparam.packageName != targetPackageName) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -175,6 +195,21 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||||||
alreadyInitialized = true
|
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) {
|
fun initGkmsConfig(activity: Activity) {
|
||||||
@ -337,6 +372,9 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||||||
Log.e(TAG, "showToast: $message failed: applicationContext is null")
|
Log.e(TAG, "showToast: $message failed: applicationContext is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
external fun pluginCallbackLooper()
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user