Start Session on Android

This commit is contained in:
Florian Märkl 2019-09-15 11:53:04 +02:00
commit 093cd6e443
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
10 changed files with 190 additions and 23 deletions

View file

@ -39,6 +39,11 @@ android {
} }
} }
androidExtensions {
// for @Parcelize
experimental = true
}
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View file

@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.metallic.chiaki"> package="com.metallic.chiaki">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -9,13 +12,15 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".MainActivity"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".StreamActivity" />
</application> </application>
</manifest> </manifest>

View file

@ -55,7 +55,7 @@ JNIEXPORT jstring JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_errorCodeToS
return E->NewStringUTF(env, chiaki_error_string((ChiakiErrorCode)value)); return E->NewStringUTF(env, chiaki_error_string((ChiakiErrorCode)value));
} }
JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_createSession(JNIEnv *env, jobject obj, jobject result, jobject connect_info_obj) JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionCreate(JNIEnv *env, jobject obj, jobject result, jobject connect_info_obj)
{ {
ChiakiSession *session = NULL; ChiakiSession *session = NULL;
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS; ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
@ -120,3 +120,9 @@ beach:
E->SetIntField(env, result, E->GetFieldID(env, result_class, "errorCode", "I"), (jint)err); E->SetIntField(env, result, E->GetFieldID(env, result_class, "errorCode", "I"), (jint)err);
E->SetLongField(env, result, E->GetFieldID(env, result_class, "sessionPtr", "J"), (jlong)session); E->SetLongField(env, result, E->GetFieldID(env, result_class, "sessionPtr", "J"), (jlong)session);
} }
JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionStart(JNIEnv *env, jobject obj, jlong ptr)
{
ChiakiSession *session = (ChiakiSession *)ptr;
return chiaki_session_start(session);
}

View file

@ -1,11 +1,13 @@
package com.metallic.chiaki package com.metallic.chiaki
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import com.metallic.chiaki.lib.ChiakiNative import android.util.Base64
import com.metallic.chiaki.lib.ConnectInfo import androidx.core.content.edit
import com.metallic.chiaki.lib.ConnectVideoProfile import androidx.core.widget.addTextChangedListener
import com.metallic.chiaki.lib.ErrorCode import com.metallic.chiaki.lib.*
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() class MainActivity : AppCompatActivity()
@ -15,12 +17,43 @@ class MainActivity : AppCompatActivity()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
val result = ChiakiNative.CreateSessionResult(0, 0) val prefs = getPreferences(Context.MODE_PRIVATE)
ChiakiNative.createSession(result, ConnectInfo("host",
ByteArray(0x10) { 0 },
ByteArray(0x10) { 0 },
ConnectVideoProfile(0, 0, 0, 0)))
testTextView.text = "${ErrorCode(0).toString()}\n${result}\n${ErrorCode(result.errorCode)}" hostEditText.setText(prefs.getString("debug_host", ""))
registKeyEditText.setText(prefs.getString("debug_regist_key", ""))
morningEditText.setText(prefs.getString("debug_morning", ""))
hostEditText.addTextChangedListener {
prefs.edit {
putString("debug_host", it?.toString())
}
}
registKeyEditText.addTextChangedListener {
prefs.edit {
putString("debug_regist_key", it?.toString())
}
}
morningEditText.addTextChangedListener {
prefs.edit {
putString("debug_morning", it?.toString())
}
}
startButton.setOnClickListener {
val registKeyBase = registKeyEditText.text.toString().toByteArray(Charsets.US_ASCII)
val registKey = registKeyBase + ByteArray(0x10 - registKeyBase.size) { 0 }
val morning = Base64.decode(morningEditText.text.toString(), Base64.DEFAULT)
val connectInfo = ConnectInfo(hostEditText.text.toString(),
registKey,
morning,
ConnectVideoProfile(1280, 720, 60, 10000))
Intent(this, StreamActivity::class.java).let {
it.putExtra(StreamActivity.EXTRA_CONNECT_INFO, connectInfo)
startActivity(it)
}
}
} }
} }

View file

@ -0,0 +1,34 @@
package com.metallic.chiaki
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.metallic.chiaki.lib.ConnectInfo
import com.metallic.chiaki.lib.Session
import kotlinx.android.synthetic.main.activity_stream.*
class StreamActivity : AppCompatActivity()
{
companion object
{
const val EXTRA_CONNECT_INFO = "connect_info"
}
private lateinit var session: Session
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_stream)
val connectInfo = intent.getParcelableExtra<ConnectInfo>(EXTRA_CONNECT_INFO)
if(connectInfo == null)
{
finish()
return
}
session = Session(connectInfo)
session.start()
testTextView.text = ""
}
}

View file

@ -1,22 +1,28 @@
package com.metallic.chiaki.lib package com.metallic.chiaki.lib
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import java.lang.Exception
@Parcelize
data class ConnectVideoProfile( data class ConnectVideoProfile(
val width: Int, val width: Int,
val height: Int, val height: Int,
val maxFPS: Int, val maxFPS: Int,
val bitrate: Int val bitrate: Int
) ): Parcelable
@Parcelize
data class ConnectInfo( data class ConnectInfo(
val host: String, val host: String,
val registKey: ByteArray, val registKey: ByteArray,
val morning: ByteArray, val morning: ByteArray,
val videoProfile: ConnectVideoProfile val videoProfile: ConnectVideoProfile
) ): Parcelable
class ChiakiNative class ChiakiNative
{ {
data class CreateSessionResult(var errorCode: Int, var sessionPtr: Long) data class SessionCreateResult(var errorCode: Int, var sessionPtr: Long)
companion object companion object
{ {
init init
@ -24,16 +30,35 @@ class ChiakiNative
System.loadLibrary("chiaki-jni") System.loadLibrary("chiaki-jni")
} }
@JvmStatic external fun errorCodeToString(value: Int): String @JvmStatic external fun errorCodeToString(value: Int): String
@JvmStatic external fun createSession(result: CreateSessionResult, connectInfo: ConnectInfo) @JvmStatic external fun sessionCreate(result: SessionCreateResult, connectInfo: ConnectInfo)
@JvmStatic external fun sessionStart(ptr: Long): Int
} }
} }
class ErrorCode(val value: Int) class ErrorCode(val value: Int)
{ {
override fun toString() = ChiakiNative.errorCodeToString(value) override fun toString() = ChiakiNative.errorCodeToString(value)
var isSuccess = value == 0
} }
class Session class SessionCreateError(val errorCode: ErrorCode): Exception("Failed to create Session: $errorCode")
class Session(connectInfo: ConnectInfo)
{ {
private val nativePtr: Long = 0 private val nativePtr: Long
init
{
val result = ChiakiNative.SessionCreateResult(0, 0)
ChiakiNative.sessionCreate(result, connectInfo)
val errorCode = ErrorCode(result.errorCode)
if(!errorCode.isSuccess)
throw SessionCreateError(errorCode)
nativePtr = result.sessionPtr
}
fun start()
{
ChiakiNative.sessionStart(nativePtr)
}
} }

View file

@ -6,14 +6,49 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView <EditText
android:id="@+id/testTextView" android:id="@+id/hostEditText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="Host"
app:layout_constraintBottom_toTopOf="@+id/registKeyEditText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"/>
<EditText
android:id="@+id/registKeyEditText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="Regist Key"
app:layout_constraintBottom_toTopOf="@+id/morningEditText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/hostEditText" />
<EditText
android:id="@+id/morningEditText"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="Morning (base64)"
app:layout_constraintBottom_toTopOf="@+id/startButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/registKeyEditText" />
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" android:text="Start"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@+id/morningEditText" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/testTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -38,7 +38,7 @@ ExternalProject_Add(OpenSSL-ExternalProject
INSTALL_DIR "${OPENSSL_INSTALL_DIR}" INSTALL_DIR "${OPENSSL_INSTALL_DIR}"
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV} CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV}
"<SOURCE_DIR>/Configure" "--prefix=<INSTALL_DIR>" no-shared ${OPENSSL_CONFIG_EXTRA_ARGS} "${OPENSSL_OS_COMPILER}" "<SOURCE_DIR>/Configure" "--prefix=<INSTALL_DIR>" no-shared ${OPENSSL_CONFIG_EXTRA_ARGS} "${OPENSSL_OS_COMPILER}"
BUILD_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV} "${MAKE_EXE}" build_libs BUILD_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV} "${MAKE_EXE}" -j4 build_libs
INSTALL_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV} "${MAKE_EXE}" install_dev) INSTALL_COMMAND ${CMAKE_COMMAND} -E env ${OPENSSL_BUILD_ENV} "${MAKE_EXE}" install_dev)
add_library(OpenSSL_Crypto INTERFACE) add_library(OpenSSL_Crypto INTERFACE)

View file

@ -584,6 +584,11 @@ static bool session_thread_request_session(ChiakiSession *session)
session_sock = socket(ai->ai_family, SOCK_STREAM, 0); session_sock = socket(ai->ai_family, SOCK_STREAM, 0);
if(CHIAKI_SOCKET_IS_INVALID(session_sock)) if(CHIAKI_SOCKET_IS_INVALID(session_sock))
{ {
#ifdef _WIN32
CHIAKI_LOGE(session->log, "Failed to create socket to request session");
#else
CHIAKI_LOGE(session->log, "Failed to create socket to request session: %s", strerror(errno));
#endif
free(sa); free(sa);
continue; continue;
} }