Skip to content

Commit

Permalink
refactor: ♻️ not much change in android app
Browse files Browse the repository at this point in the history
  • Loading branch information
tobycm committed Jun 23, 2024
1 parent 84e51d0 commit d42292c
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 123 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.vscode
.vscode
.idea
16 changes: 8 additions & 8 deletions android-app/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ android {

signingConfigs {
create("release") {
val keystoreProperties = Properties().apply {
load(rootProject.file("keystore.properties").inputStream())
}
storeFile = file(keystoreProperties.getProperty("storeFile"))
keyAlias = keystoreProperties.getProperty("keyAlias")
storePassword = keystoreProperties.getProperty("storePassword")
keyPassword = keystoreProperties.getProperty("keyPassword")
enableV3Signing = true
// val keystoreProperties = Properties().apply {
// load(rootProject.file("keystore.properties").inputStream())
// }
// storeFile = file(keystoreProperties.getProperty("storeFile"))
// keyAlias = keystoreProperties.getProperty("keyAlias")
// storePassword = keystoreProperties.getProperty("storePassword")
// keyPassword = keystoreProperties.getProperty("keyPassword")
// enableV3Signing = true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,20 @@ class MainActivity : AppCompatActivity() {
binding.bottomNavigation.setupWithNavController(navController)

// request permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) requestPermissions(
arrayOf(
Manifest.permission.POST_NOTIFICATIONS
), 0
)


sharedPreferences = PreferenceManager.getDefaultSharedPreferences(application)
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent == null) {
return
}
if (intent == null) return


// tap update notification to start downloading
if (intent.getStringExtra("action") == "update") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ class NetClient(private val handler: Handler, private val application: Applicati
}

enum class CMD {
CMD_NONE,
CMD_GET_FORMAT,
CMD_START_PLAY,
CMD_HEARTBEAT,
CMD_NONE, CMD_GET_FORMAT, CMD_START_PLAY, CMD_HEARTBEAT,
}

private var tcpChannel: Channel? = null
Expand All @@ -101,14 +98,12 @@ class NetClient(private val handler: Handler, private val application: Applicati
application.getString(R.string.audio_tcp_connect_timeout)
)!!.toInt()
val remoteAddress = InetSocketAddress(host, port)
val f = Bootstrap().group(workerGroup)
.channel(NioSocketChannel::class.java)
val f = Bootstrap().group(workerGroup).channel(NioSocketChannel::class.java)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout)
.handler(object : ChannelInitializer<SocketChannel>() {
override fun initChannel(ch: SocketChannel) {
ch.pipeline()
.addLast(TcpChannelAdapter.TcpMessageEncoder())
ch.pipeline().addLast(TcpChannelAdapter.TcpMessageEncoder())
.addLast(TcpChannelAdapter.TcpMessageDecoder())
.addLast(TcpChannelAdapter(this@NetClient))
}
Expand All @@ -124,8 +119,7 @@ class NetClient(private val handler: Handler, private val application: Applicati
tcpChannel = f.channel()
Log.d(tag, "tcpChannel.localAddress: ${tcpChannel!!.localAddress()}")

udpChannel = Bootstrap().group(workerGroup)
.channel(NioDatagramChannel::class.java)
udpChannel = Bootstrap().group(workerGroup).channel(NioDatagramChannel::class.java)
.handler(object : ChannelInitializer<DatagramChannel>() {
override fun initChannel(ch: DatagramChannel) {
ch.pipeline()
Expand Down Expand Up @@ -183,35 +177,34 @@ class NetClient(private val handler: Handler, private val application: Applicati
override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
Log.d(tag, "channelRead tcp")
try {
if (msg is TcpMessage) {
if (msg.cmd == CMD.CMD_GET_FORMAT) {
val audioFormat = msg.audioFormat
if (audioFormat != null) {
parent.onGetFormat(ctx, audioFormat)
}
} else if (msg.cmd == CMD.CMD_START_PLAY) {
val id = msg.id
if (id > 0) {
parent.udpChannel?.writeAndFlush(id)
parent.heartbeatLastTick = TimeSource.Monotonic.markNow()
parent.heartbeatTimer = timer(null, false, 0, 3000) {
if (TimeSource.Monotonic.markNow() - parent.heartbeatLastTick > 5.seconds) {
parent.onFailed(IOException("Heartbeat Timeout"))
}
Log.d(tag, "heartbeatTimer")
}
Log.d(tag, "start heartbeat")
} else {
Log.e(tag, "id <= 0")
}
} else if (msg.cmd == CMD.CMD_HEARTBEAT) {
if (msg !is TcpMessage) {
Log.e(tag, "msg is not TcpMessage")
return
}
if (msg.cmd == CMD.CMD_GET_FORMAT) {
val audioFormat = msg.audioFormat
if (audioFormat != null) parent.onGetFormat(ctx, audioFormat)
} else if (msg.cmd == CMD.CMD_START_PLAY) {
val id = msg.id
if (id > 0) {
parent.udpChannel?.writeAndFlush(id)
parent.heartbeatLastTick = TimeSource.Monotonic.markNow()
parent.sendCMD(ctx, CMD.CMD_HEARTBEAT)
parent.heartbeatTimer = timer(null, false, 0, 3000) {
if (TimeSource.Monotonic.markNow() - parent.heartbeatLastTick > 5.seconds) parent.onFailed(
IOException("Heartbeat Timeout")
)

Log.d(tag, "heartbeatTimer")
}
Log.d(tag, "start heartbeat")
} else {
Log.e(tag, "error cmd")
Log.e(tag, "id <= 0")
}
} else if (msg.cmd == CMD.CMD_HEARTBEAT) {
parent.heartbeatLastTick = TimeSource.Monotonic.markNow()
parent.sendCMD(ctx, CMD.CMD_HEARTBEAT)
} else {
Log.e(tag, "msg is not valid type")
Log.e(tag, "error cmd")
}
} catch (e: Exception) {
Log.d("channelRead tcp", e.stackTraceToString())
Expand All @@ -220,19 +213,15 @@ class NetClient(private val handler: Handler, private val application: Applicati

class TcpMessageDecoder : ByteToMessageDecoder() {
override fun decode(
ctx: ChannelHandlerContext?,
`in`: ByteBuf?,
out: MutableList<Any>?
ctx: ChannelHandlerContext?, `in`: ByteBuf?, out: MutableList<Any>?
) {
if (`in` == null || out == null) {
return
}
if (`in` == null || out == null) return


Log.d(tag, "decode")

if (`in`.readableBytes() < Int.SIZE_BYTES) {
return
}
if (`in`.readableBytes() < Int.SIZE_BYTES) return


`in`.markReaderIndex()

Expand All @@ -241,7 +230,7 @@ class NetClient(private val handler: Handler, private val application: Applicati

Log.d(tag, "decode cmd id=${id}")

val cmd = CMD.values()[id]
val cmd = CMD.entries[id]

tcpMessage.cmd = cmd

Expand Down Expand Up @@ -278,9 +267,8 @@ class NetClient(private val handler: Handler, private val application: Applicati

open class TcpMessageEncoder : MessageToByteEncoder<Int>() {
override fun encode(ctx: ChannelHandlerContext?, msg: Int?, out: ByteBuf?) {
if (msg != null && out != null) {
out.writeIntLE(msg)
}
if (msg == null || out == null) return
out.writeIntLE(msg)
}
}
}
Expand All @@ -298,9 +286,8 @@ class NetClient(private val handler: Handler, private val application: Applicati
class UdpMessageEncoder(private val remoteAddress: InetSocketAddress) :
MessageToMessageEncoder<Int>() {
override fun encode(ctx: ChannelHandlerContext?, msg: Int?, out: MutableList<Any>?) {
if (ctx == null || msg == null || out == null) {
return
}
if (ctx == null || msg == null || out == null) return

val buf = ctx.alloc().buffer(Int.SIZE_BYTES)
buf.writeIntLE(msg)
val data = DatagramPacket(buf, remoteAddress)
Expand All @@ -310,13 +297,10 @@ class NetClient(private val handler: Handler, private val application: Applicati

class UdpMessageDecoder : MessageToMessageDecoder<DatagramPacket>() {
override fun decode(
ctx: ChannelHandlerContext?,
msg: DatagramPacket?,
out: MutableList<Any>?
ctx: ChannelHandlerContext?, msg: DatagramPacket?, out: MutableList<Any>?
) {
if (ctx == null || msg == null || out == null) {
return
}
if (ctx == null || msg == null || out == null) return


// Log.d("NetClient", "Udp decode")

Expand All @@ -334,13 +318,13 @@ class NetClient(private val handler: Handler, private val application: Applicati
override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
// Log.d(tag, "channelRead udp")
try {
if (msg is FloatArray) {
parent.audioTrack.write(
msg, 0, msg.size, AudioTrack.WRITE_NON_BLOCKING
)
} else {
Log.e("NetClient", "msg is not valid type")
if (msg !is FloatArray) {
Log.e(tag, "msg is not FloatArray")
return
}
parent.audioTrack.write(
msg, 0, msg.size, AudioTrack.WRITE_NON_BLOCKING
)
} catch (e: Exception) {
Log.d("channelRead", e.stackTraceToString())
}
Expand Down Expand Up @@ -437,38 +421,28 @@ class NetClient(private val handler: Handler, private val application: Applicati
}

Log.i(
tag,
"encoding: $encoding, channelMask: $channelMask, sampleRate: ${format.sampleRate}"
tag, "encoding: $encoding, channelMask: $channelMask, sampleRate: ${format.sampleRate}"
)

Log.i(tag, "native order: ${ByteOrder.nativeOrder()}")

val minBufferSize = AudioTrack.getMinBufferSize(format.sampleRate, channelMask, encoding)
val bufferSizeScale = sharedPreferences.getString(
"audio_buffer_size_scale",
application.getString(R.string.audio_buffer_size_scale)
"audio_buffer_size_scale", application.getString(R.string.audio_buffer_size_scale)
)!!.toInt()
val bufferSize = minBufferSize * bufferSizeScale
Log.i(
tag,
"minBufferSize: $minBufferSize, bufferSizeScale: $bufferSizeScale, bufferSize: $bufferSize Bytes"
)

val builder = AudioTrack.Builder()
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
.setAudioFormat(
AudioFormat.Builder()
.setEncoding(encoding)
.setChannelMask(channelMask)
.setSampleRate(format.sampleRate)
.build()
).setBufferSizeInBytes(bufferSize)
.setTransferMode(AudioTrack.MODE_STREAM)
val builder = AudioTrack.Builder().setAudioAttributes(
AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
).setAudioFormat(
AudioFormat.Builder().setEncoding(encoding).setChannelMask(channelMask)
.setSampleRate(format.sampleRate).build()
).setBufferSizeInBytes(bufferSize).setTransferMode(AudioTrack.MODE_STREAM)

// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// builder.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY)
Expand All @@ -478,26 +452,24 @@ class NetClient(private val handler: Handler, private val application: Applicati

_loudnessEnhancer = LoudnessEnhancer(audioTrack.audioSessionId)
val targetGain = sharedPreferences.getString(
"audio_loudness_enhancer",
application.getString(R.string.audio_loudness_enhancer)
"audio_loudness_enhancer", application.getString(R.string.audio_loudness_enhancer)
)!!.toInt()
loudnessEnhancer.setTargetGain(targetGain)
loudnessEnhancer.enabled = true
Log.d(tag, "LoudnessEnhancer targetGain: ${loudnessEnhancer.targetGain}mB")

val audioVolume = sharedPreferences.getFloat(
"audio_volume",
AudioTrack.getMaxVolume()
"audio_volume", AudioTrack.getMaxVolume()
)
audioTrack.setVolume(audioVolume)

return audioTrack
}

private fun onFailed(exc: Throwable?) {
if (exc == null) {
if (exc == null)
return
}


MainScope().launch(Dispatchers.Main) {
if (exc is ConnectTimeoutException || exc is IOException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ import io.github.mkckr0.audio_share_app.R

class HomeViewModel(private val application: Application) : AndroidViewModel(application) {

private val sharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(application) }
private val sharedPreferences by lazy {
PreferenceManager.getDefaultSharedPreferences(
application
)
}
private val netClient by lazy { NetClient(NetClientHandler(), application) }

val audioVolume = MutableLiveData<Float>().apply {
value = sharedPreferences.getFloat(
"audio_volume",
AudioTrack.getMaxVolume()
"audio_volume", AudioTrack.getMaxVolume()
)
}

Expand All @@ -60,35 +63,29 @@ class HomeViewModel(private val application: Application) : AndroidViewModel(app

fun onAudioVolumeChange(value: Float) {
audioVolume.value = value
if (isPlaying.value!! && netClient.isPlaying()) {
netClient.setVolume(value)
}
if (isPlaying.value!! && netClient.isPlaying()) netClient.setVolume(value)

}

fun switchPlay() {
if (netClient.isPlaying()) {
stopPlay()
} else {
startPlay()
}
if (netClient.isPlaying()) stopPlay()
else startPlay()

}

private fun startPlay() {
if (host.value.isNullOrBlank() || port.value.isNullOrBlank()) {
if (host.value.isNullOrBlank()) {
if (host.value.isNullOrBlank() || port.value.isNullOrBlank()) {
if (host.value.isNullOrBlank())
hostError.value = "Host is Empty"
}
if (port.value.isNullOrBlank()) {

if (port.value.isNullOrBlank())
portError.value = "Port is Empty"
}

return
}

// save host and port
sharedPreferences.edit()
.putString("host", host.value)
.putString("port", port.value)
.apply()
sharedPreferences.edit().putString("host", host.value).putString("port", port.value).apply()

isPlaying.value = true
info.value = application.getString(R.string.audio_starting)
Expand Down
Loading

0 comments on commit d42292c

Please sign in to comment.