Finish Regist JNI Bindings

This commit is contained in:
Florian Märkl 2019-10-07 19:03:02 +02:00
commit 52b8ffe976
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
9 changed files with 219 additions and 15 deletions

View file

@ -23,6 +23,7 @@
#include <chiaki/log.h>
#include <chiaki/session.h>
#include <chiaki/discoveryservice.h>
#include <chiaki/regist.h>
#include <string.h>
#include <linux/in.h>
@ -158,6 +159,40 @@ static JNIEnv *attach_thread_jni()
return NULL;
}
typedef struct android_chiaki_log_t
{
jobject java_log;
jmethodID java_log_meth;
ChiakiLog log;
} AndroidChiakiLog;
static void android_chiaki_log_cb(ChiakiLogLevel level, const char *msg, void *user)
{
log_cb_android(level, msg, NULL);
AndroidChiakiLog *log = user;
JNIEnv *env = attach_thread_jni();
if(!env)
return;
E->CallVoidMethod(env, log->java_log, log->java_log_meth, (jint)level, jnistr_from_ascii(env, msg));
(*global_vm)->DetachCurrentThread(global_vm);
}
static void android_chiaki_log_init(AndroidChiakiLog *log, JNIEnv *env, jobject java_log)
{
log->java_log = E->NewGlobalRef(env, java_log);
jclass log_class = E->GetObjectClass(env, log->java_log);
log->java_log_meth = E->GetMethodID(env, log_class, "log", "(ILjava/lang/String;)V");
log->log.level_mask = (uint32_t)E->GetIntField(env, log->java_log, E->GetFieldID(env, log_class, "levelMask", "I"));
log->log.cb = android_chiaki_log_cb;
log->log.user = log;
}
static void android_chiaki_log_fini(AndroidChiakiLog *log, JNIEnv *env)
{
E->DeleteGlobalRef(env, log->java_log);
}
static void android_chiaki_event_cb(ChiakiEvent *event, void *user)
{
AndroidChiakiSession *session = user;
@ -571,17 +606,74 @@ JNIEXPORT void JNICALL JNI_FCN(discoveryServiceFree)(JNIEnv *env, jobject obj, j
free(service);
}
typedef struct android_chiaki_regist_t
{
AndroidChiakiLog log;
jobject java_regist;
ChiakiRegist regist;
} AndroidChiakiRegist;
static void android_chiaki_regist_cb(ChiakiRegistEvent *event, void *user)
{
// TODO
}
JNIEXPORT void JNICALL JNI_FCN(registStart)(JNIEnv *env, jobject obj, jobject result, jobject regist_info_obj, jobject log_obj, jobject java_regist)
{
jclass result_class = E->GetObjectClass(env, result);
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
AndroidChiakiRegist *regist = CHIAKI_NEW(AndroidChiakiRegist);
if(!regist)
{
err = CHIAKI_ERR_MEMORY;
goto beach;
}
android_chiaki_log_init(&regist->log, env, log_obj);
regist->java_regist = E->NewGlobalRef(env, java_regist);
jclass regist_info_class = E->GetObjectClass(env, regist_info_obj);
jstring host_string = E->GetObjectField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "host", "Ljava/lang/String;"));
jboolean broadcast = E->GetBooleanField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "broadcast", "Z"));
jstring psn_id_string = E->GetObjectField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "psnId", "Ljava/lang/String;"));
jint pin = E->GetIntField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "pin", "I"));
ChiakiRegistInfo regist_info;
regist_info.host = E->GetStringUTFChars(env, host_string, NULL);
regist_info.broadcast = broadcast;
regist_info.psn_id = E->GetStringUTFChars(env, psn_id_string, NULL);
regist_info.pin = (uint32_t)pin;
err = chiaki_regist_start(&regist->regist, &regist->log.log, &regist_info, android_chiaki_regist_cb, regist);
E->ReleaseStringUTFChars(env, host_string, regist_info.host);
E->ReleaseStringUTFChars(env, psn_id_string, regist_info.psn_id);
if(err != CHIAKI_ERR_SUCCESS)
{
android_chiaki_log_fini(&regist->log, env);
E->DeleteGlobalRef(env, regist->java_regist);
free(regist);
regist = NULL;
}
beach:
E->SetIntField(env, result, E->GetFieldID(env, result_class, "errorCode", "I"), (jint)err);
E->SetLongField(env, result, E->GetFieldID(env, result_class, "ptr", "J"), (jlong)regist);
}
JNIEXPORT void JNICALL JNI_FCN(registStop)(JNIEnv *env, jobject obj, jlong ptr)
{
AndroidChiakiRegist *regist = (AndroidChiakiRegist *)ptr;
chiaki_regist_stop(&regist->regist);
}
JNIEXPORT void JNICALL JNI_FCN(registFree)(JNIEnv *env, jobject obj, jlong ptr)
{
AndroidChiakiRegist *regist = (AndroidChiakiRegist *)ptr;
chiaki_regist_fini(&regist->regist);
android_chiaki_log_fini(&regist->log, env);
E->DeleteGlobalRef(env, regist->java_regist);
free(regist);
}

View file

@ -46,7 +46,7 @@ private class ChiakiNative
@JvmStatic external fun sessionSetLoginPin(ptr: Long, pin: String)
@JvmStatic external fun discoveryServiceCreate(result: CreateResult, options: DiscoveryServiceOptions, javaService: DiscoveryService)
@JvmStatic external fun discoveryServiceFree(ptr: Long)
@JvmStatic external fun registStart(result: CreateResult, registInfo: RegistInfo, javaLog: Log, javaRegist: Regist)
@JvmStatic external fun registStart(result: CreateResult, registInfo: RegistInfo, javaLog: ChiakiLog, javaRegist: Regist)
@JvmStatic external fun registStop(ptr: Long)
@JvmStatic external fun registFree(ptr: Long)
}
@ -58,7 +58,7 @@ class ErrorCode(val value: Int)
var isSuccess = value == 0
}
class Log(val levelMask: Int)
class ChiakiLog(val levelMask: Int)
{
enum class Level(val value: Int)
{
@ -66,7 +66,8 @@ class Log(val levelMask: Int)
VERBOSE(1 shl 3),
INFO(1 shl 2),
WARNING(1 shl 1),
ERROR(1 shl 0)
ERROR(1 shl 0),
ALL(0.inv())
}
private fun log(level: Int, text: String)
@ -286,11 +287,11 @@ data class RegistHost(
sealed class RegistEvent
object RegistEventCanceled: RegistEvent()
object RegistEventFailed: RegistEvent()
class RegistEventSuccess(val host: RegistHost)
class RegistEventSuccess(val host: RegistHost): RegistEvent()
class Regist(
info: RegistInfo,
log: Log,
log: ChiakiLog,
val callback: (RegistEvent) -> Unit
)
{
@ -318,4 +319,9 @@ class Regist(
ChiakiNative.registFree(nativePtr)
nativePtr = 0L
}
private fun event(event: RegistEvent)
{
callback(event)
}
}

View file

@ -73,7 +73,7 @@ class RegistActivity: AppCompatActivity(), RevealActivity
it.putExtra(RegistExecuteActivity.EXTRA_HOST, host)
it.putExtra(RegistExecuteActivity.EXTRA_BROADCAST, broadcast)
it.putExtra(RegistExecuteActivity.EXTRA_PSN_ID, psnId)
it.putExtra(RegistExecuteActivity.EXTRA_PIN, pin)
it.putExtra(RegistExecuteActivity.EXTRA_PIN, pin.toUInt().toInt())
startActivity(it)
}
}

View file

@ -19,7 +19,9 @@ package com.metallic.chiaki.regist
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProviders
import com.metallic.chiaki.R
import com.metallic.chiaki.lib.RegistInfo
class RegistExecuteActivity: AppCompatActivity()
{
@ -31,9 +33,28 @@ class RegistExecuteActivity: AppCompatActivity()
const val EXTRA_PIN = "regist_pin"
}
private lateinit var viewModel: RegistExecuteViewModel
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_regist_execute)
viewModel = ViewModelProviders.of(this).get(RegistExecuteViewModel::class.java)
val registInfo = RegistInfo(
intent.getStringExtra(EXTRA_HOST) ?: return,
intent.getBooleanExtra(EXTRA_BROADCAST, false) ?: return,
intent.getStringExtra(EXTRA_PSN_ID) ?: return,
intent.getIntExtra(EXTRA_PIN, 0).toUInt()
)
viewModel.start(registInfo)
}
override fun onStop()
{
super.onStop()
viewModel.stop()
}
}

View file

@ -0,0 +1,85 @@
/*
* This file is part of Chiaki.
*
* Chiaki is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chiaki is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
*/
package com.metallic.chiaki.regist
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.metallic.chiaki.lib.*
class RegistExecuteViewModel: ViewModel()
{
enum class State
{
IDLE,
RUNNING,
STOPPED,
FAILED,
SUCCESSFUL
}
private val _state = MutableLiveData<State>(State.IDLE)
val state: LiveData<State> get() = _state
private val log = ChiakiLog(ChiakiLog.Level.ALL.value/* and ChiakiLog.Level.VERBOSE.value.inv()*/)
private var regist: Regist? = null
fun start(info: RegistInfo)
{
if(regist != null)
return
try
{
regist = Regist(info, log, this::registEvent)
_state.value = State.RUNNING
}
catch(error: CreateError)
{
// TODO: log about error
_state.value = State.FAILED
}
}
fun stop()
{
regist?.stop()
}
private fun registEvent(event: RegistEvent)
{
when(event)
{
is RegistEventCanceled -> {
_state.postValue(State.STOPPED)
}
is RegistEventFailed -> {
_state.postValue(State.FAILED)
}
is RegistEventSuccess -> {
// TODO: save event.host into db
_state.postValue(State.SUCCESSFUL)
}
}
}
override fun onCleared()
{
super.onCleared()
regist?.dispose()
}
}

View file

@ -41,7 +41,7 @@ set(SOURCE_FILES
src/thread.c
src/base64.c
src/http.c
src/sessionlog.c
src/log.c
src/ctrl.c
src/rpcrypt.c
src/takion.c

View file

@ -31,9 +31,9 @@ extern "C" {
typedef struct chiaki_regist_info_t
{
char *host;
const char *host;
bool broadcast;
char *psn_id;
const char *psn_id;
uint32_t pin;
} ChiakiRegistInfo;

View file

@ -75,9 +75,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_start(ChiakiRegist *regist, ChiakiLo
error_stop_pipe:
chiaki_stop_pipe_fini(&regist->stop_pipe);
error_psn_id:
free(regist->info.psn_id);
free((char *)regist->info.psn_id);
error_host:
free(regist->info.host);
free((char *)regist->info.host);
return err;
}
@ -85,8 +85,8 @@ CHIAKI_EXPORT void chiaki_regist_fini(ChiakiRegist *regist)
{
chiaki_thread_join(&regist->thread, NULL);
chiaki_stop_pipe_fini(&regist->stop_pipe);
free(regist->info.psn_id);
free(regist->info.host);
free((char *)regist->info.psn_id);
free((char *)regist->info.host);
}
CHIAKI_EXPORT void chiaki_regist_stop(ChiakiRegist *regist)