Fix Android Build

This commit is contained in:
Florian Märkl 2020-12-28 19:33:38 +01:00
commit bcda423db7
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
14 changed files with 101 additions and 50 deletions

View file

@ -574,11 +574,11 @@ JNIEXPORT void JNICALL JNI_FCN(discoveryServiceFree)(JNIEnv *env, jobject obj, j
free(service);
}
JNIEXPORT jint JNICALL JNI_FCN(discoveryServiceWakeup)(JNIEnv *env, jobject obj, jlong ptr, jstring host_string, jlong user_credential)
JNIEXPORT jint JNICALL JNI_FCN(discoveryServiceWakeup)(JNIEnv *env, jobject obj, jlong ptr, jstring host_string, jlong user_credential, jboolean ps5)
{
AndroidDiscoveryService *service = (AndroidDiscoveryService *)ptr;
const char *host = E->GetStringUTFChars(env, host_string, NULL);
ChiakiErrorCode r = chiaki_discovery_wakeup(&global_log, service ? &service->service.discovery : NULL, host, (uint64_t)user_credential);
ChiakiErrorCode r = chiaki_discovery_wakeup(&global_log, service ? &service->service.discovery : NULL, host, (uint64_t)user_credential, ps5);
E->ReleaseStringUTFChars(env, host_string, host);
return r;
}
@ -601,6 +601,13 @@ typedef struct android_chiaki_regist_t
jmethodID java_regist_host_ctor;
} AndroidChiakiRegist;
static jobject create_jni_target(JNIEnv *env, ChiakiTarget target)
{
jclass cls = E->FindClass(env, BASE_PACKAGE"/Target");
jmethodID meth = E->GetStaticMethodID(env, cls, "fromValue", "(I)L"BASE_PACKAGE"/Target;");
return E->CallStaticObjectMethod(env, cls, meth, (jint)target);
}
static void android_chiaki_regist_cb(ChiakiRegistEvent *event, void *user)
{
AndroidChiakiRegist *regist = user;
@ -622,12 +629,13 @@ static void android_chiaki_regist_cb(ChiakiRegistEvent *event, void *user)
{
ChiakiRegisteredHost *host = event->registered_host;
jobject java_host = E->NewObject(env, regist->java_regist_host_class, regist->java_regist_host_ctor,
create_jni_target(env, host->target),
jnistr_from_ascii(env, host->ap_ssid),
jnistr_from_ascii(env, host->ap_bssid),
jnistr_from_ascii(env, host->ap_key),
jnistr_from_ascii(env, host->ap_name),
jnibytearray_create(env, host->ps4_mac, sizeof(host->ps4_mac)),
jnistr_from_ascii(env, host->ps4_nickname),
jnibytearray_create(env, host->server_mac, sizeof(host->server_mac)),
jnistr_from_ascii(env, host->server_nickname),
jnibytearray_create(env, (const uint8_t *)host->rp_regist_key, sizeof(host->rp_regist_key)),
(jint)host->rp_key_type,
jnibytearray_create(env, host->rp_key, sizeof(host->rp_key)));
@ -675,6 +683,7 @@ JNIEXPORT void JNICALL JNI_FCN(registStart)(JNIEnv *env, jobject obj, jobject re
regist->java_regist_host_class = E->NewGlobalRef(env, E->FindClass(env, BASE_PACKAGE"/RegistHost"));
regist->java_regist_host_ctor = E->GetMethodID(env, regist->java_regist_host_class, "<init>", "("
"L"BASE_PACKAGE"/Target;" // target: Target
"Ljava/lang/String;" // apSsid: String
"Ljava/lang/String;" // apBssid: String
"Ljava/lang/String;" // apKey: String

View file

@ -4,9 +4,12 @@ package com.metallic.chiaki.common
import android.content.Context
import androidx.room.*
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.metallic.chiaki.lib.Target
@Database(
version = 1,
version = 2,
entities = [RegisteredHost::class, ManualHost::class])
@TypeConverters(Converters::class)
abstract class AppDatabase: RoomDatabase()
@ -16,6 +19,16 @@ abstract class AppDatabase: RoomDatabase()
abstract fun importDao(): ImportDao
}
val MIGRATION_1_2 = object : Migration(1, 2)
{
override fun migrate(database: SupportSQLiteDatabase)
{
database.execSQL("ALTER TABLE registered_host RENAME ps4_mac TO server_mac")
database.execSQL("ALTER TABLE registered_host RENAME ps4_nickname TO server_nickname")
database.execSQL("ALTER TABLE registered_host ADD target INTEGER NOT NULL DEFAULT 1000")
}
}
private var database: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase
{
@ -25,7 +38,9 @@ fun getDatabase(context: Context): AppDatabase
val db = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"chiaki").build()
"chiaki")
.addMigrations(MIGRATION_1_2)
.build()
database = db
return db
}
@ -37,4 +52,10 @@ private class Converters
@TypeConverter
fun macToValue(addr: MacAddress) = addr.value
@TypeConverter
fun targetFromValue(v: Int) = Target.fromValue(v)
@TypeConverter
fun targetToValue(target: Target) = target.value
}

View file

@ -20,8 +20,8 @@ class DiscoveredDisplayHost(
): DisplayHost()
{
override val host get() = discoveredHost.hostAddr ?: ""
override val name get() = discoveredHost.hostName ?: registeredHost?.ps4Nickname
override val id get() = discoveredHost.hostId ?: registeredHost?.ps4Mac?.toString()
override val name get() = discoveredHost.hostName ?: registeredHost?.serverNickname
override val id get() = discoveredHost.hostId ?: registeredHost?.serverMac?.toString()
override fun equals(other: Any?): Boolean =
if(other !is DiscoveredDisplayHost)
@ -40,8 +40,8 @@ class ManualDisplayHost(
): DisplayHost()
{
override val host get() = manualHost.host
override val name get() = registeredHost?.ps4Nickname
override val id get() = registeredHost?.ps4Mac?.toString()
override val name get() = registeredHost?.serverNickname
override val id get() = registeredHost?.serverMac?.toString()
override fun equals(other: Any?): Boolean =
if(other !is ManualDisplayHost)

View file

@ -5,6 +5,7 @@ package com.metallic.chiaki.common
import androidx.room.*
import androidx.room.ColumnInfo.BLOB
import com.metallic.chiaki.lib.RegistHost
import com.metallic.chiaki.lib.Target
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Maybe
@ -13,24 +14,26 @@ import io.reactivex.Single
@Entity(tableName = "registered_host")
data class RegisteredHost(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
@ColumnInfo(name = "target") val target: Target,
@ColumnInfo(name = "ap_ssid") val apSsid: String?,
@ColumnInfo(name = "ap_bssid") val apBssid: String?,
@ColumnInfo(name = "ap_key") val apKey: String?,
@ColumnInfo(name = "ap_name") val apName: String?,
@ColumnInfo(name = "ps4_mac") val ps4Mac: MacAddress,
@ColumnInfo(name = "ps4_nickname") val ps4Nickname: String?,
@ColumnInfo(name = "server_mac") val serverMac: MacAddress,
@ColumnInfo(name = "server_nickname") val serverNickname: String?,
@ColumnInfo(name = "rp_regist_key", typeAffinity = BLOB) val rpRegistKey: ByteArray, // CHIAKI_SESSION_AUTH_SIZE
@ColumnInfo(name = "rp_key_type") val rpKeyType: Int,
@ColumnInfo(name = "rp_key", typeAffinity = BLOB) val rpKey: ByteArray // 0x10
)
{
constructor(registHost: RegistHost) : this(
target = registHost.target,
apSsid = registHost.apSsid,
apBssid = registHost.apBssid,
apKey = registHost.apKey,
apName = registHost.apName,
ps4Mac = MacAddress(registHost.ps4Mac),
ps4Nickname = registHost.ps4Nickname,
serverMac = MacAddress(registHost.serverMac),
serverNickname = registHost.serverNickname,
rpRegistKey = registHost.rpRegistKey,
rpKeyType = registHost.rpKeyType.toInt(),
rpKey = registHost.rpKey
@ -44,12 +47,13 @@ data class RegisteredHost(
other as RegisteredHost
if(id != other.id) return false
if(target != other.target) return false
if(apSsid != other.apSsid) return false
if(apBssid != other.apBssid) return false
if(apKey != other.apKey) return false
if(apName != other.apName) return false
if(ps4Mac != other.ps4Mac) return false
if(ps4Nickname != other.ps4Nickname) return false
if(serverMac != other.serverMac) return false
if(serverNickname != other.serverNickname) return false
if(!rpRegistKey.contentEquals(other.rpRegistKey)) return false
if(rpKeyType != other.rpKeyType) return false
if(!rpKey.contentEquals(other.rpKey)) return false
@ -60,12 +64,13 @@ data class RegisteredHost(
override fun hashCode(): Int
{
var result = id.hashCode()
result = 31 * result + target.hashCode()
result = 31 * result + (apSsid?.hashCode() ?: 0)
result = 31 * result + (apBssid?.hashCode() ?: 0)
result = 31 * result + (apKey?.hashCode() ?: 0)
result = 31 * result + (apName?.hashCode() ?: 0)
result = 31 * result + ps4Mac.hashCode()
result = 31 * result + (ps4Nickname?.hashCode() ?: 0)
result = 31 * result + serverMac.hashCode()
result = 31 * result + (serverNickname?.hashCode() ?: 0)
result = 31 * result + rpRegistKey.contentHashCode()
result = 31 * result + rpKeyType
result = 31 * result + rpKey.contentHashCode()
@ -79,10 +84,10 @@ interface RegisteredHostDao
@Query("SELECT * FROM registered_host")
fun getAll(): Flowable<List<RegisteredHost>>
@Query("SELECT * FROM registered_host WHERE ps4_mac == :mac LIMIT 1")
@Query("SELECT * FROM registered_host WHERE server_mac == :mac LIMIT 1")
fun getByMac(mac: MacAddress): Maybe<RegisteredHost>
@Query("DELETE FROM registered_host WHERE ps4_mac == :mac")
@Query("DELETE FROM registered_host WHERE server_mac == :mac")
fun deleteByMac(mac: MacAddress): Completable
@Delete

View file

@ -12,6 +12,7 @@ import androidx.core.content.FileProvider
import androidx.room.*
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.metallic.chiaki.R
import com.metallic.chiaki.lib.Target
import com.squareup.moshi.*
import io.reactivex.Completable
import io.reactivex.Flowable
@ -29,23 +30,25 @@ import java.io.IOException
@JsonClass(generateAdapter = true)
class SerializedRegisteredHost(
@Json(name = "target") val target: Target,
@Json(name = "ap_ssid") val apSsid: String?,
@Json(name = "ap_bssid") val apBssid: String?,
@Json(name = "ap_key") val apKey: String?,
@Json(name = "ap_name") val apName: String?,
@Json(name = "ps4_mac") val ps4Mac: MacAddress,
@Json(name = "ps4_nickname") val ps4Nickname: String?,
@Json(name = "server_mac") val serverMac: MacAddress,
@Json(name = "server_nickname") val serverNickname: String?,
@Json(name = "rp_regist_key") val rpRegistKey: ByteArray,
@Json(name = "rp_key_type") val rpKeyType: Int,
@Json(name = "rp_key") val rpKey: ByteArray
){
constructor(registeredHost: RegisteredHost) : this(
registeredHost.target,
registeredHost.apSsid,
registeredHost.apBssid,
registeredHost.apKey,
registeredHost.apName,
registeredHost.ps4Mac,
registeredHost.ps4Nickname,
registeredHost.serverMac,
registeredHost.serverNickname,
registeredHost.rpRegistKey,
registeredHost.rpKeyType,
registeredHost.rpKey
@ -55,7 +58,7 @@ class SerializedRegisteredHost(
@JsonClass(generateAdapter = true)
class SerializedManualHost(
@Json(name = "host") val host: String,
@Json(name = "ps4_mac") val ps4Mac: MacAddress?
@Json(name = "server_mac") val serverMac: MacAddress?
)
@JsonClass(generateAdapter = true)
@ -77,7 +80,7 @@ data class SerializedSettings(
manualHost.host,
manualHost.registeredHost?.let { registeredHostId ->
registeredHosts.firstOrNull { it.id == registeredHostId }
}?.ps4Mac
}?.serverMac
)
})
}
@ -197,13 +200,13 @@ fun importSettingsFromUri(activity: Activity, uri: Uri, disposable: CompositeDis
if(it.isEmpty())
"-"
else
it.joinToString(separator = "") { host -> "\n - ${host.ps4Nickname ?: "?"} / ${host.ps4Mac}" }
it.joinToString(separator = "") { host -> "\n - ${host.serverNickname ?: "?"} / ${host.serverMac}" }
},
settings.manualHosts.let {
if(it.isEmpty())
"-"
else
it.joinToString(separator = "") { host -> "\n - ${host.host} / ${host.ps4Mac ?: "unregistered"}" }
it.joinToString(separator = "") { host -> "\n - ${host.host} / ${host.serverMac ?: "unregistered"}" }
}
))
.setTitle(R.string.alert_title_import)
@ -242,7 +245,7 @@ abstract class ImportDao
class IdWithMac(val id: Long, val mac: MacAddress)
@Query("SELECT id, ps4_mac AS mac FROM registered_host WHERE ps4_mac IN (:macs)")
@Query("SELECT id, server_mac AS mac FROM registered_host WHERE server_mac IN (:macs)")
abstract fun registeredHostsByMac(macs: List<MacAddress>): List<IdWithMac>
@Transaction
@ -251,19 +254,20 @@ abstract class ImportDao
insertRegisteredHosts(
settings.registeredHosts.map {
RegisteredHost(
target = it.target,
apSsid = it.apSsid,
apBssid = it.apBssid,
apKey = it.apKey,
apName = it.apName,
ps4Mac = it.ps4Mac,
ps4Nickname = it.ps4Nickname,
serverMac = it.serverMac,
serverNickname = it.serverNickname,
rpRegistKey = it.rpRegistKey,
rpKeyType = it.rpKeyType,
rpKey = it.rpKey
)
})
val macs = settings.manualHosts.mapNotNull { it.ps4Mac }
val macs = settings.manualHosts.mapNotNull { it.serverMac }
val idMacs =
if(macs.isNotEmpty())
registeredHostsByMac(macs)
@ -274,7 +278,7 @@ abstract class ImportDao
settings.manualHosts.map {
ManualHost(
host = it.host,
registeredHost = idMacs.firstOrNull { regHost -> regHost.mac == it.ps4Mac }?.id
registeredHost = idMacs.firstOrNull { regHost -> regHost.mac == it.serverMac }?.id
)
})
}

View file

@ -92,14 +92,14 @@ class DiscoveryManager
disposable.dispose()
}
fun sendWakeup(host: String, registKey: ByteArray)
fun sendWakeup(host: String, registKey: ByteArray, ps5: Boolean)
{
val registKeyString = registKey.indexOfFirst { it == 0.toByte() }.let { end -> registKey.copyOfRange(0, if(end >= 0) end else registKey.size) }.toString(StandardCharsets.UTF_8)
val credential = try { registKeyString.toULong(16) } catch(e: NumberFormatException) {
Log.e("DiscoveryManager", "Failed to convert registKey to int", e)
return
}
DiscoveryService.wakeup(discoveryService, host, credential)
DiscoveryService.wakeup(discoveryService, host, credential, ps5)
}
private fun updateService()

View file

@ -11,9 +11,20 @@ import kotlin.math.abs
enum class Target(val value: Int)
{
PS4_UNKNOWN(0),
PS4_8(800),
PS4_9(900),
PS4_10(1000)
PS4_10(1000),
PS5_UNKNOWN(1000000),
PS5_1(1000100);
companion object
{
@JvmStatic
fun fromValue(value: Int) = values().firstOrNull { it.value == value } ?: PS4_10
}
val isPS5 get() = value >= PS5_UNKNOWN.value
}
enum class VideoResolutionPreset(val value: Int)
@ -76,7 +87,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 discoveryServiceWakeup(ptr: Long, host: String, userCredential: Long)
@JvmStatic external fun discoveryServiceWakeup(ptr: Long, host: String, userCredential: Long, ps5: Boolean)
@JvmStatic external fun registStart(result: CreateResult, registInfo: RegistInfo, javaLog: ChiakiLog, javaRegist: Regist)
@JvmStatic external fun registStop(ptr: Long)
@JvmStatic external fun registFree(ptr: Long)
@ -289,8 +300,8 @@ class DiscoveryService(
{
companion object
{
fun wakeup(service: DiscoveryService?, host: String, userCredential: ULong) =
ChiakiNative.discoveryServiceWakeup(service?.nativePtr ?: 0, host, userCredential.toLong())
fun wakeup(service: DiscoveryService?, host: String, userCredential: ULong, ps5: Boolean) =
ChiakiNative.discoveryServiceWakeup(service?.nativePtr ?: 0, host, userCredential.toLong(), ps5)
}
private var nativePtr: Long
@ -339,12 +350,13 @@ data class RegistInfo(
}
data class RegistHost(
val target: Target,
val apSsid: String,
val apBssid: String,
val apKey: String,
val apName: String,
val ps4Mac: ByteArray,
val ps4Nickname: String,
val serverMac: ByteArray,
val serverNickname: String,
val rpRegistKey: ByteArray,
val rpKeyType: UInt,
val rpKey: ByteArray

View file

@ -209,7 +209,7 @@ class MainActivity : AppCompatActivity()
private fun wakeupHost(host: DisplayHost)
{
val registeredHost = host.registeredHost ?: return
viewModel.discoveryManager.sendWakeup(host.host, registeredHost.rpRegistKey)
viewModel.discoveryManager.sendWakeup(host.host, registeredHost.rpRegistKey, registeredHost.target.isPS5)
}
private fun editHost(host: DisplayHost)

View file

@ -31,7 +31,7 @@ class MainViewModel(val database: AppDatabase, val preferences: Preferences): Vi
database.registeredHostDao().getAll().toObservable(),
discoveryManager.discoveredHosts)
{ manualHosts, registeredHosts, discoveredHosts ->
val macRegisteredHosts = registeredHosts.associateBy { it.ps4Mac }
val macRegisteredHosts = registeredHosts.associateBy { it.serverMac }
val idRegisteredHosts = registeredHosts.associateBy { it.id }
discoveredHosts.map {
DiscoveredDisplayHost(it.ps4Mac?.let { mac -> macRegisteredHosts[mac] }, it)

View file

@ -81,7 +81,7 @@ class EditManualConsoleActivity: AppCompatActivity(), RevealActivity
if(registeredHost == null)
getString(R.string.add_manual_regist_on_connect)
else
"${registeredHost.ps4Nickname ?: ""} (${registeredHost.ps4Mac})"
"${registeredHost.serverNickname ?: ""} (${registeredHost.serverMac})"
private fun saveHost()
{

View file

@ -114,7 +114,7 @@ class RegistExecuteActivity: AppCompatActivity()
if(dialog != null)
return
val macStr = viewModel.host?.ps4Mac?.let { MacAddress(it).toString() } ?: ""
val macStr = viewModel.host?.serverMac?.let { MacAddress(it).toString() } ?: ""
dialog = MaterialAlertDialogBuilder(this)
.setMessage(getString(R.string.alert_regist_duplicate, macStr))

View file

@ -78,7 +78,7 @@ class RegistExecuteViewModel(val database: AppDatabase): ViewModel()
private fun registSuccess(host: RegistHost)
{
this.host = host
database.registeredHostDao().getByMac(MacAddress(host.ps4Mac))
database.registeredHostDao().getByMac(MacAddress(host.serverMac))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess {
@ -98,7 +98,7 @@ class RegistExecuteViewModel(val database: AppDatabase): ViewModel()
val dao = database.registeredHostDao()
val manualHostDao = database.manualHostDao()
val registeredHost = RegisteredHost(host)
dao.deleteByMac(registeredHost.ps4Mac)
dao.deleteByMac(registeredHost.serverMac)
.andThen(dao.insert(registeredHost))
.let {
if(assignManualHostId != null)

View file

@ -29,7 +29,7 @@ class SettingsRegisteredHostsAdapter: RecyclerView.Adapter<SettingsRegisteredHos
{
val view = holder.itemView
val host = hosts[position]
view.nameTextView.text = host.ps4Nickname
view.summaryTextView.text = host.ps4Mac.toString()
view.nameTextView.text = host.serverNickname
view.summaryTextView.text = host.serverMac.toString()
}
}

View file

@ -45,7 +45,7 @@ class SettingsRegisteredHostsFragment: AppCompatDialogFragment(), TitleFragment
val pos = viewHolder.adapterPosition
val host = viewModel.registeredHosts.value?.getOrNull(pos) ?: return
MaterialAlertDialogBuilder(viewHolder.itemView.context)
.setMessage(getString(R.string.alert_message_delete_registered_host, host.ps4Nickname, host.ps4Mac.toString()))
.setMessage(getString(R.string.alert_message_delete_registered_host, host.serverNickname, host.serverMac.toString()))
.setPositiveButton(R.string.action_delete) { _, _ ->
viewModel.deleteHost(host)
}