Add StreamSession

This commit is contained in:
Florian Märkl 2019-09-16 18:13:04 +02:00
commit 2d3531e3fc
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
3 changed files with 140 additions and 62 deletions

View file

@ -0,0 +1,99 @@
/*
* 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
import android.graphics.SurfaceTexture
import android.view.Surface
import android.view.TextureView
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
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 StreamSession(connectInfo: ConnectInfo)
{
var session: Session? = null
private set(value) { field = value }
private val _state = MutableLiveData<StreamState>(StreamStateIdle)
val state: LiveData<StreamState> get() = _state
var surfaceTexture: SurfaceTexture? = null
init
{
try
{
val session = Session(connectInfo)
session.eventCallback = this::eventCallback
session.start()
this.session = session
}
catch(e: SessionCreateError)
{
_state.value = StreamStateCreateError(e)
}
}
fun shutdown()
{
session?.stop()
session?.dispose()
surfaceTexture?.release()
}
private fun eventCallback(event: Event)
{
when(event)
{
is QuitEvent -> _state.postValue(StreamStateQuit(event.reason, event.reasonString))
is LoginPinRequestEvent -> _state.postValue(StreamStateLoginPinRequest(event.pinIncorrect))
}
}
fun attachToTextureView(textureView: TextureView)
{
textureView.surfaceTextureListener = object: TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int)
{
if(surfaceTexture != null)
return
surfaceTexture = surface
session?.setSurface(Surface(surface))
}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean
{
// return false if we want to keep the surface texture
return surfaceTexture == null
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
}
val surfaceTexture = surfaceTexture
if(surfaceTexture != null)
textureView.surfaceTexture = surfaceTexture
}
}

View file

@ -1,3 +1,20 @@
/*
* 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.stream
import android.graphics.SurfaceTexture
@ -42,30 +59,9 @@ class StreamActivity : AppCompatActivity()
viewModel.init(connectInfo)
}
textureView.surfaceTextureListener = object: TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int)
{
if(viewModel.surfaceTexture != null)
return
viewModel.surfaceTexture = surface
viewModel.session?.setSurface(Surface(surface))
}
viewModel.session.attachToTextureView(textureView)
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean
{
// return false if we want to keep the surface texture
return viewModel.surfaceTexture == null
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
}
val surfaceTexture = viewModel.surfaceTexture
if(surfaceTexture != null)
textureView.surfaceTexture = surfaceTexture
viewModel.state.observe(this, Observer {
viewModel.session.state.observe(this, Observer {
stateTextView.text = "$it"
})
}

View file

@ -1,62 +1,45 @@
/*
* 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.stream
import android.graphics.SurfaceTexture
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.metallic.chiaki.StreamSession
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}
var session: Session? = null
private set(value) { field = value }
private val _state = MutableLiveData<StreamState>(StreamStateIdle)
val state: LiveData<StreamState> get() = _state
var surfaceTexture: SurfaceTexture? = null
private var _session: StreamSession? = null
val session: StreamSession get() = _session ?: throw UninitializedPropertyAccessException("StreamViewModel not initialized")
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))
}
_session = StreamSession(connectInfo)
}
override fun onCleared()
{
super.onCleared()
session?.stop()
session?.dispose()
surfaceTexture?.release()
_session?.shutdown()
}
}