2020-06-07 00:37:49 +03:00
|
|
|
#include "JniConvertors.hpp"
|
2020-06-18 20:54:59 +03:00
|
|
|
#include "LogManagerBase.hpp"
|
2020-06-22 21:44:54 +03:00
|
|
|
#include "WrapperLogManager.hpp"
|
2020-06-19 02:25:20 +03:00
|
|
|
#include "android/log.h"
|
2020-05-31 23:50:25 +03:00
|
|
|
|
|
|
|
using namespace MAT;
|
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
template <>
|
|
|
|
ILogManager* LogManagerBase<WrapperConfig>::instance{};
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeInitializeWithoutTenantToken(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-19 02:25:20 +03:00
|
|
|
jclass /* LogManager.class */)
|
2020-06-18 20:54:59 +03:00
|
|
|
{
|
|
|
|
ILogger* logger = WrapperLogManager::Initialize();
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeInitializeWithTenantToken(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
2020-06-19 02:25:20 +03:00
|
|
|
jclass /* LogManager.class */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jstring jTenantToken)
|
|
|
|
{
|
|
|
|
auto tenantToken = JStringToStdString(env, jTenantToken);
|
|
|
|
ILogger* logger = WrapperLogManager::Initialize(tenantToken);
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
|
|
|
|
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeFlushAndTeardown(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-19 02:25:20 +03:00
|
|
|
jclass /* LogManager.class */)
|
2020-06-18 20:54:59 +03:00
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::FlushAndTeardown());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeFlush(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::Flush());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeUploadNow(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::UploadNow());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativePauseTransmission(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::PauseTransmission());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeResumeTransmission(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::ResumeTransmission());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetIntTransmitProfile(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
|
|
|
jclass /* this */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint jProfile)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetTransmitProfile(
|
2020-05-31 23:50:25 +03:00
|
|
|
static_cast<TransmitProfile>(jProfile)));
|
2020-06-18 20:54:59 +03:00
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetTransmitProfileString(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jstring jstrProfile)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetTransmitProfile(JStringToStdString(env, jstrProfile)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeLoadTransmitProfilesString(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jstring jstrProfilesJson)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::LoadTransmitProfiles(JStringToStdString(env, jstrProfilesJson)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeResetTransmitProfiles(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return static_cast<jint>(WrapperLogManager::ResetTransmitProfiles());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jstring JNICALL Java_com_microsoft_applications_events_LogManager_getTransmitProfileName(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
std::string profileName = WrapperLogManager::GetTransmitProfileName();
|
|
|
|
return static_cast<jstring>(env->NewStringUTF(profileName.c_str()));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetSemanticContext(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<jlong>(WrapperLogManager::GetSemanticContext());
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextStringValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jstring jstrValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
auto value = JStringToStdString(env, jstrValue);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, value, static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextIntValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jint jValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<int32_t>(jValue), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextLongValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jlong jValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<int64_t>(jValue), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextDoubleValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jdouble jValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<double>(jValue), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextBoolValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jboolean jValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<bool>(jValue), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextTimeTicksValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jlong jValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, time_ticks_t(static_cast<uint64_t>(jValue)), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-19 02:25:20 +03:00
|
|
|
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextGuidValue(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrName,
|
|
|
|
jstring jstrValue,
|
2020-06-18 20:54:59 +03:00
|
|
|
jint piiKind)
|
|
|
|
{
|
|
|
|
auto name = JStringToStdString(env, jstrName);
|
|
|
|
auto value = JStringToStdString(env, jstrValue);
|
|
|
|
return static_cast<jint>(WrapperLogManager::SetContext(name, GUID_t(value.c_str()), static_cast<PiiKind>(piiKind)));
|
|
|
|
}
|
|
|
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLogger(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* /* env */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jclass /* this */)
|
|
|
|
{
|
|
|
|
ILogger* logger = WrapperLogManager::GetLogger();
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
|
2020-06-18 20:54:59 +03:00
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithSource(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
2020-06-18 20:54:59 +03:00
|
|
|
jstring jstrSource)
|
|
|
|
{
|
|
|
|
auto source = JStringToStdString(env, jstrSource);
|
|
|
|
ILogger* logger = WrapperLogManager::GetLogger(source);
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
|
|
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithTenantTokenAndSource(
|
2020-05-31 23:50:25 +03:00
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* this */,
|
|
|
|
jstring jstrTenantToken,
|
2020-06-18 20:54:59 +03:00
|
|
|
jstring jstrSource)
|
|
|
|
{
|
|
|
|
auto tenantToken = JStringToStdString(env, jstrTenantToken);
|
|
|
|
auto source = JStringToStdString(env, jstrSource);
|
|
|
|
ILogger* logger = WrapperLogManager::GetLogger(tenantToken, source);
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
2020-05-31 23:50:25 +03:00
|
|
|
}
|
2020-06-19 02:25:20 +03:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* helper function: rethrow any exceptions from reverse-JNI calls
|
|
|
|
* @param env
|
|
|
|
*/
|
|
|
|
void rethrow(JNIEnv* env)
|
|
|
|
{
|
|
|
|
if (env->ExceptionCheck())
|
|
|
|
{
|
|
|
|
env->Throw(env->ExceptionOccurred());
|
|
|
|
throw std::runtime_error("JNI exception");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Smart object to manage PushLocalFrame/PopLocalFrame
|
|
|
|
*/
|
|
|
|
|
|
|
|
class FrameWrapper
|
|
|
|
{
|
|
|
|
JNIEnv* env;
|
|
|
|
size_t frameSize;
|
|
|
|
jobject* result = nullptr;
|
|
|
|
|
|
|
|
FrameWrapper() = delete;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/*
|
|
|
|
* Constructor: takes JNIEnv* and the desired LocalStack frame depth
|
|
|
|
*/
|
|
|
|
FrameWrapper(JNIEnv* e, size_t s) :
|
|
|
|
env(e),
|
|
|
|
frameSize(s)
|
|
|
|
{
|
|
|
|
env->PushLocalFrame(frameSize);
|
|
|
|
rethrow(env);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the reference that will survive PopLocalFrame (as a new
|
|
|
|
* reference in the outer frame).
|
|
|
|
* @param r Object that should survive
|
|
|
|
* @return Previous result value
|
|
|
|
*/
|
|
|
|
jobject* setResult(jobject* r)
|
|
|
|
{
|
|
|
|
jobject* t = result;
|
|
|
|
result = r;
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* On destruction, pop the frame with an optional result object.
|
|
|
|
*/
|
|
|
|
virtual ~FrameWrapper()
|
|
|
|
{
|
|
|
|
jobject localRef = nullptr;
|
|
|
|
if (!!result)
|
|
|
|
{
|
|
|
|
localRef = *result;
|
|
|
|
}
|
|
|
|
localRef = env->PopLocalFrame(localRef);
|
|
|
|
rethrow(env);
|
|
|
|
if (!!result)
|
|
|
|
{
|
|
|
|
*result = localRef;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enum of the types we know how to convert into a VariantMap or
|
|
|
|
* VariantArray.
|
|
|
|
*/
|
|
|
|
enum class ValueTypes
|
|
|
|
{
|
|
|
|
BOOLEAN,
|
|
|
|
LONG,
|
|
|
|
STRING,
|
|
|
|
VARIANT_MAP,
|
|
|
|
VARIANT_ARRAY
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* POD to record how we handle each known value type
|
|
|
|
*/
|
|
|
|
struct ValueInfo
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* JNI class reference for a known type
|
|
|
|
*/
|
|
|
|
jclass valueClass;
|
|
|
|
/**
|
|
|
|
* Method ID for the method to cast into the primitive type for
|
|
|
|
* Long or Boolean
|
|
|
|
*/
|
|
|
|
jmethodID castMethod;
|
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr char lcClassName[] =
|
|
|
|
"com/microsoft/applications/events/ILogConfiguration";
|
|
|
|
|
|
|
|
struct VariantTranslator
|
|
|
|
{
|
|
|
|
std::map<ValueTypes, ValueInfo> classCache;
|
|
|
|
|
|
|
|
JNIEnv* env;
|
|
|
|
|
|
|
|
VariantTranslator() = delete;
|
|
|
|
|
|
|
|
VariantTranslator(JNIEnv* env) :
|
|
|
|
env(env)
|
|
|
|
{
|
|
|
|
ValueInfo vi;
|
|
|
|
vi.valueClass = env->FindClass("java/lang/Boolean");
|
|
|
|
rethrow(env);
|
|
|
|
vi.castMethod =
|
|
|
|
env->GetMethodID(vi.valueClass, "booleanValue", "()Z");
|
|
|
|
rethrow(env);
|
|
|
|
classCache[ValueTypes::BOOLEAN] = vi;
|
|
|
|
vi.valueClass = env->FindClass("java/lang/Long");
|
|
|
|
rethrow(env);
|
|
|
|
vi.castMethod =
|
|
|
|
env->GetMethodID(vi.valueClass, "longValue", "()J");
|
|
|
|
rethrow(env);
|
|
|
|
classCache[ValueTypes::LONG] = vi;
|
|
|
|
vi.valueClass = env->FindClass("java/lang/String");
|
|
|
|
rethrow(env);
|
|
|
|
vi.castMethod = nullptr;
|
|
|
|
classCache[ValueTypes::STRING] = vi;
|
|
|
|
vi.valueClass = env->FindClass(lcClassName);
|
|
|
|
rethrow(env);
|
|
|
|
vi.castMethod = nullptr;
|
|
|
|
classCache[ValueTypes::VARIANT_MAP] = vi;
|
|
|
|
vi.valueClass = env->FindClass("[Ljava/lang/Object;");
|
|
|
|
vi.castMethod = nullptr;
|
|
|
|
classCache[ValueTypes::VARIANT_ARRAY] = vi;
|
|
|
|
}
|
|
|
|
|
|
|
|
void translateVariantArray(VariantArray& array, jobjectArray value)
|
|
|
|
{
|
|
|
|
jsize count = env->GetArrayLength(value);
|
|
|
|
array.clear();
|
|
|
|
array.reserve(count);
|
|
|
|
for (jsize i = 0; i < count; ++i)
|
|
|
|
{
|
|
|
|
auto element = env->GetObjectArrayElement(value, i);
|
|
|
|
rethrow(env);
|
|
|
|
array.emplace_back(std::move(translateVariant(element)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void translateVariantMap(VariantMap& variantMap, jobject configuration)
|
|
|
|
{
|
|
|
|
static std::map<ValueTypes, ValueInfo> classCache;
|
|
|
|
auto stringClass = env->FindClass("java/lang/String");
|
|
|
|
rethrow(env);
|
|
|
|
auto configClass = env->GetObjectClass(configuration);
|
|
|
|
auto gkaMethod =
|
|
|
|
env->GetMethodID(configClass,
|
|
|
|
"getKeyArray",
|
|
|
|
"()[Ljava/lang/String;");
|
|
|
|
rethrow(env);
|
|
|
|
jobjectArray keys = static_cast<jobjectArray>(env->CallObjectMethod(
|
|
|
|
configuration,
|
|
|
|
gkaMethod));
|
|
|
|
rethrow(env);
|
|
|
|
auto getMethod = env->GetMethodID(
|
|
|
|
configClass,
|
|
|
|
"getObject",
|
|
|
|
"(Ljava/lang/String;)Ljava/lang/Object;");
|
|
|
|
rethrow(env);
|
|
|
|
jsize keyCount = env->GetArrayLength(keys);
|
|
|
|
for (jsize i = 0; i < keyCount; ++i)
|
|
|
|
{
|
|
|
|
FrameWrapper wrapper(env, 32);
|
|
|
|
rethrow(env);
|
|
|
|
auto k = env->GetObjectArrayElement(keys, i);
|
|
|
|
rethrow(env);
|
|
|
|
if (k == nullptr)
|
|
|
|
{
|
|
|
|
__android_log_print(ANDROID_LOG_ERROR,
|
|
|
|
"MAE",
|
|
|
|
"Null configuration key");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!env->IsInstanceOf(k, stringClass))
|
|
|
|
{
|
|
|
|
__android_log_print(ANDROID_LOG_ERROR, "MAE",
|
|
|
|
"Configuration key is not a string");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
auto key = static_cast<jstring>(k);
|
|
|
|
auto cstringKey = env->GetStringUTFChars(key, nullptr);
|
|
|
|
rethrow(env);
|
|
|
|
std::string stringKey(cstringKey);
|
|
|
|
env->ReleaseStringUTFChars(key, cstringKey);
|
|
|
|
auto value = env->CallObjectMethod(configuration, getMethod, key);
|
|
|
|
rethrow(env);
|
|
|
|
auto v = translateVariant(value);
|
|
|
|
auto emplace = variantMap.emplace(stringKey, std::move(v));
|
|
|
|
if (!emplace.second)
|
|
|
|
{
|
|
|
|
auto& it = emplace.first;
|
|
|
|
it->second.move(std::move(v));
|
|
|
|
}
|
|
|
|
} // for (... configuration keys)
|
|
|
|
}
|
|
|
|
|
|
|
|
Variant translateVariant(jobject value)
|
|
|
|
{
|
|
|
|
for (auto& kv : classCache)
|
|
|
|
{
|
|
|
|
if (env->IsInstanceOf(value, kv.second.valueClass))
|
|
|
|
{
|
|
|
|
switch (kv.first)
|
|
|
|
{
|
|
|
|
case ValueTypes::LONG:
|
|
|
|
{
|
|
|
|
auto longValue =
|
|
|
|
env->CallLongMethod(value,
|
|
|
|
kv.second.castMethod);
|
|
|
|
rethrow(env);
|
|
|
|
return Variant(longValue);
|
|
|
|
}
|
|
|
|
case ValueTypes::BOOLEAN:
|
|
|
|
{
|
|
|
|
auto booleanValue =
|
|
|
|
env->CallBooleanMethod(value,
|
|
|
|
kv.second.castMethod);
|
|
|
|
rethrow(env);
|
|
|
|
return Variant(booleanValue);
|
|
|
|
}
|
|
|
|
case ValueTypes::STRING:
|
|
|
|
{
|
|
|
|
auto s = static_cast<jstring>(value);
|
|
|
|
auto cString = env->GetStringUTFChars(
|
|
|
|
s,
|
|
|
|
nullptr);
|
|
|
|
rethrow(env);
|
|
|
|
std::string cppString(cString);
|
|
|
|
env->ReleaseStringUTFChars(s, cString);
|
|
|
|
return Variant(std::move(cppString));
|
|
|
|
}
|
|
|
|
case ValueTypes::VARIANT_MAP:
|
|
|
|
{
|
|
|
|
VariantMap subMap;
|
|
|
|
translateVariantMap(subMap, value);
|
|
|
|
return Variant(std::move(subMap));
|
|
|
|
}
|
|
|
|
case ValueTypes::VARIANT_ARRAY:
|
|
|
|
{
|
|
|
|
VariantArray subArray;
|
|
|
|
translateVariantArray(subArray,
|
|
|
|
static_cast<jobjectArray>(value));
|
|
|
|
return Variant(std::move(subArray));
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
throw std::logic_error("Unknown enum value");
|
|
|
|
}
|
|
|
|
} // if class matches
|
|
|
|
} // for (... classCache){
|
|
|
|
auto actual = env->GetObjectClass(value);
|
|
|
|
auto meta = env->GetObjectClass(actual);
|
|
|
|
rethrow(env);
|
|
|
|
auto gnMethod =
|
|
|
|
env->GetMethodID(meta,
|
|
|
|
"getName",
|
|
|
|
"()Ljava/lang/String;");
|
|
|
|
rethrow(env);
|
|
|
|
auto jName =
|
|
|
|
static_cast<jstring>(env->CallObjectMethod(actual,
|
|
|
|
gnMethod));
|
|
|
|
auto cName = env->GetStringUTFChars(jName, nullptr);
|
|
|
|
std::string className(cName);
|
|
|
|
env->ReleaseStringUTFChars(jName, cName);
|
|
|
|
__android_log_print(ANDROID_LOG_ERROR,
|
|
|
|
"MAE",
|
|
|
|
"Unsupported class %s",
|
|
|
|
className.c_str());
|
|
|
|
auto errorClass = env->FindClass("java/lang/Error");
|
|
|
|
rethrow(env);
|
|
|
|
env->ThrowNew(errorClass, "Unsupported class");
|
|
|
|
MATSDK_THROW(std::logic_error("Unsupported class"));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ConfigConstructor
|
|
|
|
{
|
|
|
|
JNIEnv* env;
|
|
|
|
|
|
|
|
jobject boolTrue = nullptr;
|
|
|
|
jobject boolFalse = nullptr;
|
|
|
|
jclass doubleClass = nullptr;
|
|
|
|
jmethodID doubleInit = nullptr;
|
|
|
|
jclass longClass = nullptr;
|
|
|
|
jmethodID longInit = nullptr;
|
|
|
|
jclass objectClass = nullptr;
|
|
|
|
jclass configClass = nullptr;
|
|
|
|
jmethodID configInit = nullptr;
|
|
|
|
jmethodID setMethod = nullptr;
|
|
|
|
|
|
|
|
ConfigConstructor() = delete;
|
|
|
|
ConfigConstructor(JNIEnv* env)
|
|
|
|
{
|
|
|
|
this->env = env;
|
|
|
|
auto boolClass = env->FindClass("java/lang/Boolean");
|
|
|
|
rethrow(env);
|
|
|
|
auto truthField = env->GetStaticFieldID(boolClass, "TRUE", "Ljava/lang/Boolean;");
|
|
|
|
rethrow(env);
|
|
|
|
boolTrue = env->GetStaticObjectField(boolClass, truthField);
|
|
|
|
auto untruthField = env->GetStaticFieldID(boolClass, "FALSE", "Ljava/lang/Boolean;");
|
|
|
|
rethrow(env);
|
|
|
|
boolFalse = env->GetStaticObjectField(boolClass, untruthField);
|
|
|
|
doubleClass = env->FindClass("java/lang/Double");
|
|
|
|
rethrow(env);
|
|
|
|
doubleInit = env->GetMethodID(doubleClass, "<init>", "(D)V");
|
|
|
|
rethrow(env);
|
|
|
|
longClass = env->FindClass("java/lang/Long");
|
|
|
|
rethrow(env);
|
|
|
|
longInit = env->GetMethodID(longClass, "<init>", "(J)V");
|
|
|
|
rethrow(env);
|
|
|
|
objectClass = env->FindClass("java/lang/Object");
|
|
|
|
rethrow(env);
|
|
|
|
configClass = env->FindClass("com/microsoft/applications/events/LogManager$LogConfigurationImpl");
|
|
|
|
rethrow(env);
|
|
|
|
configInit = env->GetMethodID(configClass, "<init>", "()V");
|
|
|
|
rethrow(env);
|
|
|
|
setMethod = env->GetMethodID(configClass, "set", "(Ljava/lang/String;Ljava/lang/Object;)V");
|
|
|
|
rethrow(env);
|
|
|
|
}
|
|
|
|
|
|
|
|
jobject valueTranslate(Variant& variant)
|
|
|
|
{
|
|
|
|
jobject result = nullptr;
|
|
|
|
{
|
|
|
|
FrameWrapper frameWrapper(env, 8);
|
|
|
|
frameWrapper.setResult(&result);
|
|
|
|
switch (variant.type)
|
|
|
|
{
|
|
|
|
case Variant::Type::TYPE_BOOL:
|
|
|
|
{
|
|
|
|
bool const v = variant;
|
|
|
|
if (v)
|
|
|
|
{
|
|
|
|
result = boolTrue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = boolFalse;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Variant::Type::TYPE_DOUBLE:
|
|
|
|
{
|
|
|
|
jdouble const v = variant;
|
|
|
|
result = env->NewObject(doubleClass, doubleInit, v);
|
|
|
|
rethrow(env);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Variant::Type::TYPE_INT:
|
|
|
|
{
|
|
|
|
jlong const v = variant;
|
|
|
|
result = env->NewObject(longClass, longInit, v);
|
|
|
|
rethrow(env);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Variant::Type::TYPE_NULL:
|
|
|
|
break;
|
|
|
|
case Variant::Type::TYPE_OBJ:
|
|
|
|
{
|
|
|
|
VariantMap variantMap = variant;
|
|
|
|
result = mapTranslate(variantMap);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Variant::Type::TYPE_STRING:
|
|
|
|
case Variant::Type::TYPE_STRING2:
|
|
|
|
{
|
|
|
|
const char* v = variant;
|
|
|
|
result = env->NewStringUTF(v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Variant::Type::TYPE_ARR:
|
|
|
|
{
|
|
|
|
VariantArray& variantArray = variant;
|
|
|
|
{
|
|
|
|
FrameWrapper
|
|
|
|
innerWrapper(env, variantArray.size() + 4);
|
|
|
|
auto array = env->NewObjectArray(variantArray.size(),
|
|
|
|
objectClass,
|
|
|
|
nullptr);
|
|
|
|
for (size_t i = 0; i < variantArray.size(); ++i)
|
|
|
|
{
|
|
|
|
jobject element = valueTranslate(variantArray[i]);
|
|
|
|
env->SetObjectArrayElement(array, i, element);
|
|
|
|
rethrow(env);
|
|
|
|
}
|
|
|
|
result = array;
|
|
|
|
innerWrapper.setResult(&result);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
auto errorClass = env->FindClass("java/lang/Error");
|
|
|
|
rethrow(env);
|
|
|
|
env->ThrowNew(errorClass, "Unsupported class");
|
|
|
|
MATSDK_THROW(std::logic_error("Unsupported class"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
jobject mapTranslate(VariantMap& variantMap)
|
|
|
|
{
|
|
|
|
auto map = env->NewObject(configClass, configInit);
|
|
|
|
rethrow(env);
|
|
|
|
for (auto& kv : variantMap)
|
|
|
|
{
|
|
|
|
FrameWrapper frameWrapper(env, 8);
|
|
|
|
auto const& key = kv.first;
|
|
|
|
auto& value = kv.second;
|
|
|
|
auto keyString = env->NewStringUTF(key.c_str());
|
|
|
|
rethrow(env);
|
|
|
|
auto valueObject = valueTranslate(value);
|
|
|
|
env->CallVoidMethod(map, setMethod, keyString, valueObject);
|
|
|
|
rethrow(env);
|
|
|
|
}
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT jlong JNICALL
|
|
|
|
Java_com_microsoft_applications_events_LogManager_nativeInitializeConfig(JNIEnv* env,
|
|
|
|
jclass clazz,
|
|
|
|
jstring tenant_token,
|
|
|
|
jobject configuration)
|
|
|
|
{
|
|
|
|
ILogConfiguration logConfiguration;
|
|
|
|
VariantTranslator variantTranslator(env);
|
|
|
|
variantTranslator.translateVariantMap(*logConfiguration, configuration);
|
|
|
|
std::string cereal;
|
|
|
|
Variant::serialize(*logConfiguration, cereal);
|
|
|
|
__android_log_print(ANDROID_LOG_INFO, "MAE", "Translated map: %s",
|
|
|
|
cereal.c_str());
|
|
|
|
|
|
|
|
auto tokenUTF = env->GetStringUTFChars(tenant_token, nullptr);
|
|
|
|
rethrow(env);
|
|
|
|
std::string token(tokenUTF);
|
|
|
|
env->ReleaseStringUTFChars(tenant_token, tokenUTF);
|
|
|
|
auto logger = WrapperLogManager::Initialize(token, logConfiguration);
|
|
|
|
return reinterpret_cast<jlong>(logger);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT jobject JNICALL
|
|
|
|
Java_com_microsoft_applications_events_LogManager_nativeGetLogConfiguration(
|
|
|
|
JNIEnv* env,
|
|
|
|
jclass /* LogManager.class */)
|
|
|
|
{
|
|
|
|
ConfigConstructor config(env);
|
|
|
|
return config.mapTranslate(*WrapperLogManager::GetLogConfiguration());
|
|
|
|
}
|