diff --git a/android/app/build.gradle b/android/app/build.gradle index c7a72e1..a0eefca 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -50,4 +50,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + + implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0" } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 01d8172..50020f3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -20,7 +20,7 @@ - + \ No newline at end of file diff --git a/android/app/src/main/cpp/chiaki-jni.c b/android/app/src/main/cpp/chiaki-jni.c index 2d73417..d9816f0 100644 --- a/android/app/src/main/cpp/chiaki-jni.c +++ b/android/app/src/main/cpp/chiaki-jni.c @@ -215,27 +215,31 @@ JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionCreate(J JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionFree(JNIEnv *env, jobject obj, jlong ptr) { AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; + CHIAKI_LOGI(&global_log, "Free JNI Session"); if(!session) return; - E->DeleteGlobalRef(env, session->java_session); chiaki_session_fini(&session->session); free(session); + E->DeleteGlobalRef(env, session->java_session); } JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionStart(JNIEnv *env, jobject obj, jlong ptr) { AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; + CHIAKI_LOGI(&global_log, "Start JNI Session"); return chiaki_session_start(&session->session); } JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionStop(JNIEnv *env, jobject obj, jlong ptr) { AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; + CHIAKI_LOGI(&global_log, "Stop JNI Session"); return chiaki_session_stop(&session->session); } JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionJoin(JNIEnv *env, jobject obj, jlong ptr) { AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; + CHIAKI_LOGI(&global_log, "Join JNI Session"); return chiaki_session_join(&session->session); } diff --git a/android/app/src/main/java/com/metallic/chiaki/MainActivity.kt b/android/app/src/main/java/com/metallic/chiaki/MainActivity.kt index 8423c27..2cafb12 100644 --- a/android/app/src/main/java/com/metallic/chiaki/MainActivity.kt +++ b/android/app/src/main/java/com/metallic/chiaki/MainActivity.kt @@ -8,6 +8,7 @@ import android.util.Base64 import androidx.core.content.edit import androidx.core.widget.addTextChangedListener import com.metallic.chiaki.lib.* +import com.metallic.chiaki.stream.StreamActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() diff --git a/android/app/src/main/java/com/metallic/chiaki/StreamActivity.kt b/android/app/src/main/java/com/metallic/chiaki/StreamActivity.kt deleted file mode 100644 index a396bd7..0000000 --- a/android/app/src/main/java/com/metallic/chiaki/StreamActivity.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.metallic.chiaki - -import android.os.Bundle -import android.util.Log -import androidx.appcompat.app.AppCompatActivity -import com.metallic.chiaki.lib.ConnectInfo -import com.metallic.chiaki.lib.Event -import com.metallic.chiaki.lib.Session -import com.metallic.chiaki.lib.SessionCreateError -import kotlinx.android.synthetic.main.activity_stream.* - -class StreamActivity : AppCompatActivity() -{ - companion object - { - const val EXTRA_CONNECT_INFO = "connect_info" - } - - private var session: Session? = null - - override fun onCreate(savedInstanceState: Bundle?) - { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_stream) - - val connectInfo = intent.getParcelableExtra(EXTRA_CONNECT_INFO) - if(connectInfo == null) - { - finish() - return - } - - try - { - val session = Session(connectInfo) - session.eventCallback = { - Log.i("StreamActivity", "Got Event $it") - } - - session.start() - this.session = session - } - catch(e: SessionCreateError) - { - // TODO: handle error - } - - testTextView.text = "" - } - - override fun onDestroy() - { - super.onDestroy() - session?.stop() - session?.dispose() - } -} diff --git a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt new file mode 100644 index 0000000..b21d806 --- /dev/null +++ b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt @@ -0,0 +1,45 @@ +package com.metallic.chiaki.stream + +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelProviders +import com.metallic.chiaki.R +import com.metallic.chiaki.lib.ConnectInfo +import com.metallic.chiaki.lib.Session +import com.metallic.chiaki.lib.SessionCreateError +import kotlinx.android.synthetic.main.activity_stream.* + +class StreamActivity : AppCompatActivity() +{ + companion object + { + const val EXTRA_CONNECT_INFO = "connect_info" + } + + private lateinit var viewModel: StreamViewModel + + override fun onCreate(savedInstanceState: Bundle?) + { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_stream) + + viewModel = ViewModelProviders.of(this)[StreamViewModel::class.java] + if(!viewModel.isInitialized) + { + val connectInfo = intent.getParcelableExtra(EXTRA_CONNECT_INFO) + if(connectInfo == null) + { + finish() + return + } + viewModel.init(connectInfo) + } + + viewModel.state.observe(this, Observer { + stateTextView.text = "$it" + }) + } +} diff --git a/android/app/src/main/java/com/metallic/chiaki/stream/StreamViewModel.kt b/android/app/src/main/java/com/metallic/chiaki/stream/StreamViewModel.kt new file mode 100644 index 0000000..d02f3fb --- /dev/null +++ b/android/app/src/main/java/com/metallic/chiaki/stream/StreamViewModel.kt @@ -0,0 +1,57 @@ +package com.metallic.chiaki.stream + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.metallic.chiaki.lib.* + +sealed class StreamState +object StreamStateIdle: StreamState() +data class StreamStateCreateError(val error: SessionCreateError): StreamState() +data class StreamStateQuit(val reason: QuitReason, val reasonString: String?): StreamState() +data class StreamStateLoginPinRequest(val pinIncorrect: Boolean): StreamState() + +class StreamViewModel: ViewModel() +{ + var isInitialized = false + private set(value) { field = value} + + private var session: Session? = null + + private val _state = MutableLiveData(StreamStateIdle) + val state: LiveData get() = _state + + fun init(connectInfo: ConnectInfo) + { + if(isInitialized) + return + isInitialized = true + try + { + val session = Session(connectInfo) + session.eventCallback = this::eventCallback + session.start() + this.session = session + } + catch(e: SessionCreateError) + { + _state.value = StreamStateCreateError(e) + } + } + + private fun eventCallback(event: Event) + { + when(event) + { + is QuitEvent -> _state.postValue(StreamStateQuit(event.reason, event.reasonString)) + is LoginPinRequestEvent -> _state.postValue(StreamStateLoginPinRequest(event.pinIncorrect)) + } + } + + override fun onCleared() + { + super.onCleared() + session?.stop() + session?.dispose() + } +} \ No newline at end of file diff --git a/android/app/src/main/res/layout/activity_stream.xml b/android/app/src/main/res/layout/activity_stream.xml index 145e02f..2ff8f01 100644 --- a/android/app/src/main/res/layout/activity_stream.xml +++ b/android/app/src/main/res/layout/activity_stream.xml @@ -4,16 +4,20 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".stream.StreamActivity"> + + + app:layout_constraintTop_toBottomOf="@id/surfaceView" + app:layout_constraintBottom_toBottomOf="parent"/> \ No newline at end of file