0
0
mirror of https://github.com/Ishan09811/pine.git synced 2025-04-29 08:25:10 +00:00
2025-01-03 23:57:59 +05:30

239 lines
8.6 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include "common.h"
#include <jni.h>
namespace skyline {
struct DhcpInfo {
i32 ipAddress;
i32 subnet;
i32 gateway;
i32 dns1;
i32 dns2;
};
/**
* @brief A wrapper over std::string that supports construction using a JNI jstring
*/
class JniString : public std::string {
private:
static std::string GetJString(JNIEnv *env, jstring jString);
public:
JniString(JNIEnv *env, jstring jString) : std::string(GetJString(env, jString)) {}
};
/**
* @brief A wrapper over the `Settings` Kotlin class
* @note The lifetime of this class must not exceed that of the JNI environment
* @note Copy construction of this class is disallowed to avoid issues with the JNI environment lifetime
*/
class KtSettings {
private:
JNIEnv *env; //!< A pointer to the current jni environment
jclass settingsClass; //!< The settings class
jobject settingsInstance; //!< The settings instance
public:
KtSettings(JNIEnv *env, jobject settingsInstance) : env(env), settingsInstance(settingsInstance), settingsClass(env->GetObjectClass(settingsInstance)) {}
KtSettings(const KtSettings &) = delete;
void operator=(const KtSettings &) = delete;
KtSettings(KtSettings &&) = default;
/**
* @param key A null terminated string containing the key of the setting to get
*/
template<typename T>
requires std::is_integral_v<T> || std::is_enum_v<T> || std::is_floating_point_v<T>
T GetInt(const std::string_view &key) {
return static_cast<T>(env->GetIntField(settingsInstance, env->GetFieldID(settingsClass, key.data(), "I")));
}
/**
* @param key A null terminated string containing the key of the setting to get
*/
bool GetBool(const std::string_view &key) {
return env->GetBooleanField(settingsInstance, env->GetFieldID(settingsClass, key.data(), "Z")) == JNI_TRUE;
}
/**
* @param key A null terminated string containing the key of the setting to get
*/
JniString GetString(const std::string_view &key) {
return {env, static_cast<jstring>(env->GetObjectField(settingsInstance, env->GetFieldID(settingsClass, key.data(), "Ljava/lang/String;")))};
}
};
/**
* @brief The JvmManager class is used to simplify transactions with the Java component
*/
class JvmManager {
public:
using KeyboardHandle = jobject;
using KeyboardConfig = std::array<u8, 0x4C8>;
using KeyboardCloseResult = u32;
using KeyboardTextCheckResult = u32;
jobject instance; //!< A reference to the activity
jclass instanceClass; //!< The class of the activity
/**
* @param env A pointer to the JNI environment
* @param instance A reference to the activity
*/
JvmManager(JNIEnv *env, jobject instance);
~JvmManager();
/**
* @brief Returns a pointer to the JNI environment for the current thread
*/
static JNIEnv *GetEnv();
/**
* @brief Retrieves a specific field of the given type from the activity
* @tparam objectType The type of the object in the field
* @param key The name of the field in the activity class
* @return The contents of the field as objectType
*/
template<typename objectType>
objectType GetField(const char *key) {
JNIEnv *env{GetEnv()};
if constexpr(std::is_same<objectType, jboolean>())
return env->GetBooleanField(instance, env->GetFieldID(instanceClass, key, "Z"));
else if constexpr(std::is_same<objectType, jbyte>())
return env->GetByteField(instance, env->GetFieldID(instanceClass, key, "B"));
else if constexpr(std::is_same<objectType, jchar>())
return env->GetCharField(instance, env->GetFieldID(instanceClass, key, "C"));
else if constexpr(std::is_same<objectType, jshort>())
return env->GetShortField(instance, env->GetFieldID(instanceClass, key, "S"));
else if constexpr(std::is_same<objectType, jint>())
return env->GetIntField(instance, env->GetFieldID(instanceClass, key, "I"));
else if constexpr(std::is_same<objectType, jlong>())
return env->GetLongField(instance, env->GetFieldID(instanceClass, key, "J"));
else if constexpr(std::is_same<objectType, jfloat>())
return env->GetFloatField(instance, env->GetFieldID(instanceClass, key, "F"));
else if constexpr(std::is_same<objectType, jdouble>())
return env->GetDoubleField(instance, env->GetFieldID(instanceClass, key, "D"));
else
throw exception("GetField: Unhandled object type");
}
/**
* @brief Retrieves a specific field from the activity as a jobject
* @param key The name of the field in the activity class
* @param signature The signature of the field
* @return A jobject of the contents of the field
*/
jobject GetField(const char *key, const char *signature);
/**
* @brief Checks if a specific field from the activity is null or not
* @param key The name of the field in the activity class
* @param signature The signature of the field
* @return If the field is null or not
*/
bool CheckNull(const char *key, const char *signature);
/**
* @brief Checks if a specific jobject is null or not
* @param object The jobject to check
* @return If the object is null or not
*/
static bool CheckNull(jobject &object);
/**
* @brief A call to EmulationActivity.initializeControllers in Kotlin
*/
void InitializeControllers();
/**
* @brief A call to EmulationActivity.vibrateDevice in Kotlin
*/
void VibrateDevice(jint index, const span<jlong> &timings, const span<jint> &amplitudes);
/**
* @brief A call to EmulationActivity.clearVibrationDevice in Kotlin
*/
void ClearVibrationDevice(jint index);
/**
* @brief A call to EmulationActivity.showKeyboard in Kotlin
*/
KeyboardHandle ShowKeyboard(KeyboardConfig &config, std::u16string initialText);
/**
* @brief A call to EmulationActivity.waitForSubmitOrCancel in Kotlin
*/
std::pair<KeyboardCloseResult, std::u16string> WaitForSubmitOrCancel(KeyboardHandle dialog);
/**
* @brief A call to EmulationActivity.closeKeyboard in Kotlin
*/
void CloseKeyboard(KeyboardHandle dialog);
/**
* @brief A call to EmulationActivity.showValidationResult in Kotlin
*/
KeyboardCloseResult ShowValidationResult(KeyboardHandle dialog, KeyboardTextCheckResult checkResult, std::u16string message);
/**
* @brief A call to EmulationActivity.reportCrash in Kotlin
*/
void reportCrash();
/**
* @brief A call to EmulationActivity.showPipelineLoadingScreen in Kotlin
*/
void ShowPipelineLoadingScreen(u32 totalPipelineCount);
/**
* @brief A call to EmulationActivity.updatePipelineLoadingProgress in Kotlin
*/
void UpdatePipelineLoadingProgress(u32 progress);
/**
* @brief A call to EmulationActivity.hidePipelineLoadingScreen in Kotlin
*/
void HidePipelineLoadingScreen();
/**
* @brief A call to EmulationActivity.getVersionCode in Kotlin
* @return A version code in Vulkan's format with 14-bit patch + 10-bit major and minor components
*/
i32 GetVersionCode();
/**
* @brief A call to EmulationActivity.getDhcpInfo in Kotlin
*/
DhcpInfo GetDhcpInfo();
private:
jmethodID initializeControllersId;
jmethodID vibrateDeviceId;
jmethodID clearVibrationDeviceId;
jmethodID showKeyboardId;
jmethodID waitForSubmitOrCancelId;
jmethodID closeKeyboardId;
jmethodID showValidationResultId;
jmethodID getIntegerValueId;
jmethodID reportCrashId;
jmethodID showPipelineLoadingScreenId;
jmethodID updatePipelineLoadingProgressId;
jmethodID hidePipelineLoadingScreenId;
jmethodID getVersionCodeId;
jmethodID getDhcpInfoId;
};
}