1
0
Fork 0
mirror of https://gitlab.com/futo-org/fcast.git synced 2025-08-07 09:42:50 +00:00

Android: Addressed most warnings

This commit is contained in:
Michael Hollister 2025-07-09 22:58:45 -05:00
parent 2080a5ccfc
commit 7a507b0204
10 changed files with 38 additions and 59 deletions

View file

@ -19,7 +19,7 @@ class BootReceiver : BroadcastReceiver() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Show a notification with an action to start the service // Show a notification with an action to start the service
showStartServiceNotification(context); showStartServiceNotification(context)
} else { } else {
// Directly start the service for older versions // Directly start the service for older versions
val serviceIntent = Intent(context, NetworkService::class.java) val serviceIntent = Intent(context, NetworkService::class.java)

View file

@ -4,4 +4,4 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
class CustomPlayerView(context: Context, attrs: AttributeSet? = null) : PlayerView(context, attrs) { } class CustomPlayerView(context: Context, attrs: AttributeSet? = null) : PlayerView(context, attrs)

View file

@ -1,6 +1,5 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import WebSocketListenerService
import android.content.Context import android.content.Context
import android.net.nsd.NsdManager import android.net.nsd.NsdManager
import android.net.nsd.NsdServiceInfo import android.net.nsd.NsdServiceInfo
@ -40,14 +39,14 @@ class DiscoveryService(private val _context: Context) {
try { try {
_nsdManager?.unregisterService(_registrationListenerTcp) _nsdManager?.unregisterService(_registrationListenerTcp)
} catch (e: Throwable) { } catch (_: Throwable) {
Log.e(TAG, "Failed to unregister TCP Listener."); Log.e(TAG, "Failed to unregister TCP Listener.")
} }
try { try {
_nsdManager?.unregisterService(_registrationListenerWs) _nsdManager?.unregisterService(_registrationListenerWs)
} catch (e: Throwable) { } catch (_: Throwable) {
Log.e(TAG, "Failed to unregister TCP Listener."); Log.e(TAG, "Failed to unregister TCP Listener.")
} }
_nsdManager = null _nsdManager = null

View file

@ -1,27 +1,13 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import android.util.Base64
import android.util.Log import android.util.Log
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.io.DataOutputStream import java.io.DataOutputStream
import java.io.OutputStream import java.io.OutputStream
import java.math.BigInteger
import java.net.SocketAddress import java.net.SocketAddress
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.security.KeyFactory
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.MessageDigest
import java.security.PrivateKey
import java.security.spec.X509EncodedKeySpec
import java.util.UUID import java.util.UUID
import javax.crypto.Cipher
import javax.crypto.KeyAgreement
import javax.crypto.spec.DHParameterSpec
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
enum class SessionState { enum class SessionState {
@ -48,8 +34,8 @@ enum class Opcode(val value: Byte) {
Pong(13); Pong(13);
companion object { companion object {
private val _map = values().associateBy { it.value } private val _map = entries.associateBy { it.value }
fun find(value: Byte): Opcode = _map[value] ?: Opcode.None fun find(value: Byte): Opcode = _map[value] ?: None
} }
} }
@ -111,7 +97,7 @@ class FCastSession(outputStream: OutputStream, private val _remoteSocketAddress:
} }
fun processBytes(data: ByteBuffer) { fun processBytes(data: ByteBuffer) {
Log.i(TAG, "${data.remaining()} bytes received from ${_remoteSocketAddress}") Log.i(TAG, "${data.remaining()} bytes received from $_remoteSocketAddress")
if (!data.hasArray()) { if (!data.hasArray()) {
throw IllegalArgumentException("ByteBuffer does not have a backing array") throw IllegalArgumentException("ByteBuffer does not have a backing array")
} }
@ -132,7 +118,7 @@ class FCastSession(outputStream: OutputStream, private val _remoteSocketAddress:
return return
} }
Log.i(TAG, "$count bytes received from ${_remoteSocketAddress}") Log.i(TAG, "$count bytes received from $_remoteSocketAddress")
when (_state) { when (_state) {
SessionState.WaitingForLength -> handleLengthBytes(data, 0, count) SessionState.WaitingForLength -> handleLengthBytes(data, 0, count)
@ -166,7 +152,7 @@ class FCastSession(outputStream: OutputStream, private val _remoteSocketAddress:
} }
if (bytesRemaining > 0) { if (bytesRemaining > 0) {
Log.i(TAG, "$bytesRemaining remaining bytes ${_remoteSocketAddress} pushed to handlePacketBytes") Log.i(TAG, "$bytesRemaining remaining bytes $_remoteSocketAddress pushed to handlePacketBytes")
handlePacketBytes(data, offset + bytesToRead, bytesRemaining) handlePacketBytes(data, offset + bytesToRead, bytesRemaining)
} }
} }
@ -181,7 +167,7 @@ class FCastSession(outputStream: OutputStream, private val _remoteSocketAddress:
Log.i(TAG, "Read $bytesToRead bytes from packet") Log.i(TAG, "Read $bytesToRead bytes from packet")
if (_bytesRead >= _packetLength) { if (_bytesRead >= _packetLength) {
Log.i(TAG, "Packet finished receiving from ${_remoteSocketAddress} of $_packetLength bytes.") Log.i(TAG, "Packet finished receiving from $_remoteSocketAddress of $_packetLength bytes.")
handleNextPacket() handleNextPacket()
_state = SessionState.WaitingForLength _state = SessionState.WaitingForLength
@ -189,14 +175,14 @@ class FCastSession(outputStream: OutputStream, private val _remoteSocketAddress:
_bytesRead = 0 _bytesRead = 0
if (bytesRemaining > 0) { if (bytesRemaining > 0) {
Log.i(TAG, "$bytesRemaining remaining bytes ${_remoteSocketAddress} pushed to handleLengthBytes") Log.i(TAG, "$bytesRemaining remaining bytes $_remoteSocketAddress pushed to handleLengthBytes")
handleLengthBytes(data, offset + bytesToRead, bytesRemaining) handleLengthBytes(data, offset + bytesToRead, bytesRemaining)
} }
} }
} }
private fun handleNextPacket() { private fun handleNextPacket() {
Log.i(TAG, "Processing packet of $_bytesRead bytes from ${_remoteSocketAddress}") Log.i(TAG, "Processing packet of $_bytesRead bytes from $_remoteSocketAddress")
val opcode = Opcode.find(_buffer[0]) val opcode = Opcode.find(_buffer[0])
val body = if (_packetLength > 1) _buffer.copyOfRange(1, _packetLength) val body = if (_packetLength > 1) _buffer.copyOfRange(1, _packetLength)

View file

@ -1,16 +1,12 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import WebSocketListenerService
import android.Manifest import android.Manifest
import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageInstaller import android.content.pm.PackageInstaller
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.drawable.Animatable import android.graphics.drawable.Animatable
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
@ -34,12 +30,12 @@ import androidx.media3.ui.PlayerView
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
import com.journeyapps.barcodescanner.BarcodeEncoder import com.journeyapps.barcodescanner.BarcodeEncoder
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.net.NetworkInterface import java.net.NetworkInterface
import androidx.core.net.toUri
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -153,7 +149,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "connection url: $url") Log.i(TAG, "connection url: $url")
val bitmap = barcodeEncoder.encodeBitmap(url, BarcodeFormat.QR_CODE, px, px) val bitmap = barcodeEncoder.encodeBitmap(url, BarcodeFormat.QR_CODE, px, px)
_imageQr.setImageBitmap(bitmap) _imageQr.setImageBitmap(bitmap)
} catch (e: java.lang.Exception) { } catch (_: java.lang.Exception) {
_textScanToConnect.visibility = View.GONE _textScanToConnect.visibility = View.GONE
_imageQr.visibility = View.GONE _imageQr.visibility = View.GONE
} }
@ -201,7 +197,7 @@ class MainActivity : AppCompatActivity() {
_player = ExoPlayer.Builder(this).build() _player = ExoPlayer.Builder(this).build()
_videoBackground.player = _player _videoBackground.player = _player
val mediaItem = MediaItem.fromUri(Uri.parse("android.resource://" + packageName + "/" + R.raw.c)) val mediaItem = MediaItem.fromUri(("android.resource://" + packageName + "/" + R.raw.c).toUri())
_player.setMediaItem(mediaItem) _player.setMediaItem(mediaItem)
_player.prepare() _player.prepare()
_player.repeatMode = Player.REPEAT_MODE_ALL _player.repeatMode = Player.REPEAT_MODE_ALL
@ -224,7 +220,7 @@ class MainActivity : AppCompatActivity() {
if (listPermissionsNeeded.isNotEmpty()) { if (listPermissionsNeeded.isNotEmpty()) {
val permissionRequestedKey = "NOTIFICATIONS_PERMISSION_REQUESTED" val permissionRequestedKey = "NOTIFICATIONS_PERMISSION_REQUESTED"
val sharedPref = this.getSharedPreferences(_preferenceFileKey, Context.MODE_PRIVATE) val sharedPref = this.getSharedPreferences(_preferenceFileKey, MODE_PRIVATE)
val hasRequestedPermission = sharedPref.getBoolean(permissionRequestedKey, false) val hasRequestedPermission = sharedPref.getBoolean(permissionRequestedKey, false)
if (!hasRequestedPermission) { if (!hasRequestedPermission) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS) ActivityCompat.requestPermissions(this, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS)
@ -244,7 +240,7 @@ class MainActivity : AppCompatActivity() {
private fun requestSystemAlertWindowPermission() { private fun requestSystemAlertWindowPermission() {
try { try {
val permissionRequestedKey = "SYSTEM_ALERT_WINDOW_PERMISSION_REQUESTED" val permissionRequestedKey = "SYSTEM_ALERT_WINDOW_PERMISSION_REQUESTED"
val sharedPref = this.getSharedPreferences(_preferenceFileKey, Context.MODE_PRIVATE) val sharedPref = this.getSharedPreferences(_preferenceFileKey, MODE_PRIVATE)
val hasRequestedPermission = sharedPref.getBoolean(permissionRequestedKey, false) val hasRequestedPermission = sharedPref.getBoolean(permissionRequestedKey, false)
if (!Settings.canDrawOverlays(this)) { if (!Settings.canDrawOverlays(this)) {
@ -254,7 +250,8 @@ class MainActivity : AppCompatActivity() {
.setMessage(R.string.permission_dialog_message) .setMessage(R.string.permission_dialog_message)
.setPositiveButton(R.string.permission_dialog_positive_button) { _, _ -> .setPositiveButton(R.string.permission_dialog_positive_button) { _, _ ->
try { try {
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName")) val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
"package:$packageName".toUri())
_systemAlertWindowPermissionLauncher.launch(intent) _systemAlertWindowPermissionLauncher.launch(intent)
} catch (e: Throwable) { } catch (e: Throwable) {
Log.e("OverlayPermission", "Error requesting overlay permission", e) Log.e("OverlayPermission", "Error requesting overlay permission", e)
@ -276,7 +273,7 @@ class MainActivity : AppCompatActivity() {
Toast.makeText(this, "Optional system alert window permission missing", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Optional system alert window permission missing", Toast.LENGTH_SHORT).show()
} }
} }
} catch (e: Throwable) { } catch (_: Throwable) {
Log.e(TAG, "Failed to request system alert window permissions") Log.e(TAG, "Failed to request system alert window permissions")
} }
} }
@ -367,7 +364,7 @@ class MainActivity : AppCompatActivity() {
_updateSpinner.visibility = View.INVISIBLE _updateSpinner.visibility = View.INVISIBLE
setText(resources.getText(R.string.there_is_an_update_available_do_you_wish_to_update)) setText(resources.getText(R.string.there_is_an_update_available_do_you_wish_to_update))
_buttonUpdate.visibility = View.VISIBLE _buttonUpdate.visibility = View.VISIBLE
} catch (e: Throwable) { } catch (_: Throwable) {
Toast.makeText(this@MainActivity, "Failed to show update dialog", Toast.LENGTH_LONG).show() Toast.makeText(this@MainActivity, "Failed to show update dialog", Toast.LENGTH_LONG).show()
Log.w(TAG, "Error occurred in update dialog.") Log.w(TAG, "Error occurred in update dialog.")
} }
@ -388,11 +385,11 @@ class MainActivity : AppCompatActivity() {
.build() .build()
val response = client.newCall(request).execute() val response = client.newCall(request).execute()
if (!response.isSuccessful || response.body == null) { if (!response.isSuccessful) {
return null return null
} }
return response.body?.string()?.trim()?.toInt() return response.body.string().trim().toInt()
} }
private fun update() { private fun update() {
@ -414,7 +411,7 @@ class MainActivity : AppCompatActivity() {
val response = client.newCall(request).execute() val response = client.newCall(request).execute()
val body = response.body val body = response.body
if (response.isSuccessful && body != null) { if (response.isSuccessful) {
inputStream = body.byteStream() inputStream = body.byteStream()
val dataLength = body.contentLength() val dataLength = body.contentLength()
install(inputStream, dataLength) install(inputStream, dataLength)

View file

@ -1,8 +1,6 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import WebSocketListenerService
import android.app.* import android.app.*
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ServiceInfo import android.content.pm.ServiceInfo
import android.os.Build import android.os.Build
@ -10,10 +8,8 @@ import android.os.IBinder
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
class NetworkService : Service() { class NetworkService : Service() {
@ -48,7 +44,7 @@ class NetworkService : Service() {
description = descriptionText description = descriptionText
} }
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notificationManager: NotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel) notificationManager.createNotificationChannel(channel)
} }
@ -72,7 +68,7 @@ class NetworkService : Service() {
try { try {
Log.i(TAG, "Sending version ${session.id}") Log.i(TAG, "Sending version ${session.id}")
session.send(Opcode.Version, VersionMessage(2)) session.send(Opcode.Version, VersionMessage(2))
} catch (e: Throwable) { } catch (_: Throwable) {
Log.e(TAG, "Failed to send version ${session.id}") Log.e(TAG, "Failed to send version ${session.id}")
} }
} }
@ -122,7 +118,7 @@ class NetworkService : Service() {
try { try {
_webSocketListenerService?.stop() _webSocketListenerService?.stop()
} catch (e: Throwable) { } catch (_: Throwable) {
//Ignored //Ignored
} finally { } finally {
_webSocketListenerService = null _webSocketListenerService = null
@ -193,7 +189,7 @@ class NetworkService : Service() {
.setAutoCancel(true) .setAutoCancel(true)
.build() .build()
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(PLAY_NOTIFICATION_ID, playNotification) notificationManager.notify(PLAY_NOTIFICATION_ID, playNotification)
} }
} else { } else {

View file

@ -1,6 +1,5 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import android.content.Context
import android.graphics.drawable.Animatable import android.graphics.drawable.Animatable
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
@ -44,6 +43,7 @@ import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.max import kotlin.math.max
import androidx.core.net.toUri
class PlayerActivity : AppCompatActivity() { class PlayerActivity : AppCompatActivity() {
@ -245,7 +245,7 @@ class PlayerActivity : AppCompatActivity() {
_playerControlView.controllerAutoShow = false _playerControlView.controllerAutoShow = false
Log.i(TAG, "Attached onConnectionAvailable listener.") Log.i(TAG, "Attached onConnectionAvailable listener.")
_connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager _connectivityManager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val netReq = NetworkRequest.Builder() val netReq = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
@ -398,7 +398,7 @@ class PlayerActivity : AppCompatActivity() {
} }
if (!playMessage.url.isNullOrEmpty()) { if (!playMessage.url.isNullOrEmpty()) {
mediaItemBuilder.setUri(Uri.parse(playMessage.url)) mediaItemBuilder.setUri(playMessage.url.toUri())
} else if (!playMessage.content.isNullOrEmpty()) { } else if (!playMessage.content.isNullOrEmpty()) {
val tempFile = File.createTempFile("content_", ".tmp", cacheDir) val tempFile = File.createTempFile("content_", ".tmp", cacheDir)
tempFile.deleteOnExit() tempFile.deleteOnExit()

View file

@ -1,7 +1,6 @@
package com.futo.fcast.receiver package com.futo.fcast.receiver
import android.util.Log import android.util.Log
import java.io.BufferedInputStream
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.ServerSocket import java.net.ServerSocket
import java.net.Socket import java.net.Socket

View file

@ -1,6 +1,6 @@
package com.futo.fcast.receiver
import android.util.Log import android.util.Log
import com.futo.fcast.receiver.FCastSession
import com.futo.fcast.receiver.NetworkService
import org.java_websocket.WebSocket import org.java_websocket.WebSocket
import org.java_websocket.handshake.ClientHandshake import org.java_websocket.handshake.ClientHandshake
import org.java_websocket.server.WebSocketServer import org.java_websocket.server.WebSocketServer

View file

@ -1,3 +1,5 @@
package com.futo.fcast.receiver
import org.java_websocket.WebSocket import org.java_websocket.WebSocket
import java.io.IOException import java.io.IOException
import java.io.OutputStream import java.io.OutputStream