Skip to content

Commit

Permalink
Dependency update
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
dkrivoruchko committed Jul 16, 2022
1 parent 3e94826 commit 73b1cbe
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 92 deletions.
24 changes: 12 additions & 12 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId = "info.dvkr.screenstream"
minSdkVersion(21)
targetSdkVersion(32)
versionCode = 30902
versionName = "3.9.2"
versionCode = 30903
versionName = "3.9.3"
resConfigs 'en', 'ru', 'pt-rBR', 'zh-rTW', 'fr-rFR', 'fa', 'it', 'pl', 'hi', 'de', 'sk', 'es', 'ar', 'ja', 'gl', 'ca', 'uk', 'nl'

vectorDrawables.useSupportLibrary = true
Expand Down Expand Up @@ -91,22 +91,22 @@ dependencies {

implementation(project(":data"))

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")

implementation("androidx.core:core-ktx:1.8.0")
implementation("androidx.activity:activity-ktx:1.4.0")
implementation("androidx.fragment:fragment-ktx:1.4.1")
implementation("androidx.activity:activity-ktx:1.5.0")
implementation("androidx.fragment:fragment-ktx:1.5.0")
implementation("androidx.appcompat:appcompat:1.4.2")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("com.google.android.material:material:1.6.1")
implementation("androidx.window:window:1.0.0")

implementation("androidx.navigation:navigation-fragment-ktx:2.4.2")
implementation("androidx.navigation:navigation-ui-ktx:2.4.2")
implementation("androidx.lifecycle:lifecycle-livedata:2.4.1")
implementation("androidx.lifecycle:lifecycle-common:2.4.1")
implementation("androidx.navigation:navigation-fragment-ktx:2.5.0")
implementation("androidx.navigation:navigation-ui-ktx:2.5.0")
implementation("androidx.lifecycle:lifecycle-livedata:2.5.0")
implementation("androidx.lifecycle:lifecycle-common:2.5.0")

implementation("com.afollestad.material-dialogs:core:3.3.0")
implementation("com.afollestad.material-dialogs:color:3.3.0")
Expand All @@ -124,9 +124,9 @@ dependencies {
implementation("com.google.android.play:app-update-ktx:2.0.0") {
exclude group: "com.android.support"
}
firebaseImplementation("com.google.firebase:firebase-analytics:21.0.0")
firebaseImplementation("com.google.firebase:firebase-analytics:21.1.0")
firebaseImplementation("com.google.firebase:firebase-crashlytics:18.2.11")
firebaseImplementation("com.google.android.gms:play-services-ads:21.0.0")
firebaseImplementation("com.google.android.gms:play-services-ads:21.1.0")

// debugImplementation("com.squareup.leakcanary:leakcanary-android:2.9.1")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package info.dvkr.screenstream.ui.activity

import android.content.Intent
import android.os.Bundle
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -13,12 +12,6 @@ abstract class BaseActivity(@LayoutRes contentLayoutId: Int) : AppCompatActivity
XLog.d(getLog("onCreate", "Invoked"))
}

@Suppress("DEPRECATION")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
XLog.e(getLog("onActivityResult"), IllegalStateException("Unknown requestCode: $requestCode"))
super.onActivityResult(requestCode, resultCode, data)
}

override fun onStart() {
super.onStart()
XLog.d(getLog("onStart", "Invoked"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package info.dvkr.screenstream.ui.activity

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.media.projection.MediaProjectionManager
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.callbacks.onDismiss
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.elvishew.xlog.XLog
import info.dvkr.screenstream.R
Expand All @@ -19,91 +18,71 @@ import info.dvkr.screenstream.service.helper.IntentAction

abstract class PermissionActivity(@LayoutRes contentLayoutId: Int) : ServiceActivity(contentLayoutId) {

companion object {
private const val CAST_PERMISSION_PENDING_KEY = "CAST_PERMISSION_PENDING_KEY"
private const val SCREEN_CAPTURE_REQUEST_CODE = 10
private companion object {
private const val KEY_CAST_PERMISSION_PENDING = "KEY_CAST_PERMISSION_PENDING"
}

private var permissionsErrorDialog: MaterialDialog? = null
private var isCastPermissionsPending: Boolean = false

private val startMediaProjection =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
XLog.d(getLog("registerForActivityResult", "Cast permission granted"))
IntentAction.CastIntent(result.data!!).sendToAppService(this@PermissionActivity)
} else {
XLog.w(getLog("registerForActivityResult", "Cast permission denied"))
IntentAction.CastPermissionsDenied.sendToAppService(this@PermissionActivity)
permissionsErrorDialog?.dismiss()
showErrorDialog(
R.string.permission_activity_cast_permission_required_title,
R.string.permission_activity_cast_permission_required
)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isCastPermissionsPending = savedInstanceState?.getBoolean(CAST_PERMISSION_PENDING_KEY) ?: false
isCastPermissionsPending = savedInstanceState?.getBoolean(KEY_CAST_PERMISSION_PENDING) ?: false
XLog.d(getLog("onCreate", "isCastPermissionsPending: $isCastPermissionsPending"))
}

override fun onSaveInstanceState(outState: Bundle) {
XLog.d(getLog("onSaveInstanceState", "isCastPermissionsPending: $isCastPermissionsPending"))
outState.putBoolean(CAST_PERMISSION_PENDING_KEY, isCastPermissionsPending)
outState.putBoolean(KEY_CAST_PERMISSION_PENDING, isCastPermissionsPending)
super.onSaveInstanceState(outState)
}

@Suppress("DEPRECATION")
override fun onServiceMessage(serviceMessage: ServiceMessage) {
super.onServiceMessage(serviceMessage)

if (serviceMessage is ServiceMessage.ServiceState) {
if (serviceMessage.isWaitingForPermission) {
if (isCastPermissionsPending) {
XLog.i(getLog("onServiceMessage", "Ignoring: isCastPermissionsPending == true"))
} else {
isCastPermissionsPending = true
permissionsErrorDialog?.dismiss()
permissionsErrorDialog = null
val projectionManager =
getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
try {
// val dm = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
// val options = ActivityOptions.makeBasic()
// options.launchDisplayId = dm.displays[1].displayId
val createScreenCaptureIntent = projectionManager.createScreenCaptureIntent()
startActivityForResult(
createScreenCaptureIntent, SCREEN_CAPTURE_REQUEST_CODE//,options.toBundle()
)
} catch (ex: ActivityNotFoundException) {
showErrorDialog(
R.string.permission_activity_error_title_activity_not_found,
R.string.permission_activity_error_activity_not_found
)
}
}
} else {
if (serviceMessage.isWaitingForPermission.not()) {
isCastPermissionsPending = false
return
}
}
}

@Deprecated("Deprecated in Java")
@Suppress("DEPRECATION")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == SCREEN_CAPTURE_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
XLog.d(getLog("onActivityResult", "Cast permission granted"))
require(data != null) { "onActivityResult: data = null" }
IntentAction.CastIntent(data).sendToAppService(this@PermissionActivity)
} else {
XLog.w(getLog("onActivityResult", "Cast permission denied"))
if (isCastPermissionsPending) {
XLog.i(getLog("onServiceMessage", "Ignoring: isCastPermissionsPending == true"))
return
}

permissionsErrorDialog?.dismiss()
isCastPermissionsPending = true
try {
val projectionManager = getSystemService(MediaProjectionManager::class.java)
startMediaProjection.launch(projectionManager.createScreenCaptureIntent())
} catch (ignore: ActivityNotFoundException) {
IntentAction.CastPermissionsDenied.sendToAppService(this@PermissionActivity)
isCastPermissionsPending = false

showErrorDialog(
R.string.permission_activity_cast_permission_required_title,
R.string.permission_activity_cast_permission_required
R.string.permission_activity_error_title_activity_not_found,
R.string.permission_activity_error_activity_not_found
)
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}

private fun showErrorDialog(
@StringRes titleRes: Int = R.string.permission_activity_error_title,
@StringRes messageRes: Int = R.string.permission_activity_error_unknown
) {
permissionsErrorDialog?.dismiss()

private fun showErrorDialog(@StringRes titleRes: Int, @StringRes messageRes: Int) {
permissionsErrorDialog = MaterialDialog(this).show {
lifecycleOwner(this@PermissionActivity)
icon(R.drawable.ic_permission_dialog_24dp)
Expand All @@ -112,6 +91,7 @@ abstract class PermissionActivity(@LayoutRes contentLayoutId: Int) : ServiceActi
positiveButton(android.R.string.ok)
cancelable(false)
cancelOnTouchOutside(false)
onDismiss { permissionsErrorDialog = null }
}
}
}
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ buildscript {

dependencies {
classpath("com.android.tools.build:gradle:7.2.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0")
classpath("com.google.gms:google-services:4.3.10")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
classpath("com.google.gms:google-services:4.3.13")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.1")
}
}

Expand Down
10 changes: 5 additions & 5 deletions data/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ android {
}

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.10")

implementation("androidx.core:core:1.8.0")
implementation("androidx.window:window:1.0.0")

implementation("io.ktor:ktor-server-cio:2.0.2")
implementation("io.ktor:ktor-server-default-headers:2.0.2")
implementation("io.ktor:ktor-server-status-pages:2.0.2")
implementation("io.ktor:ktor-server-cio:2.0.3")
implementation("io.ktor:ktor-server-default-headers:2.0.3")
implementation("io.ktor:ktor-server-status-pages:2.0.3")

implementation("com.github.iamironz:binaryprefs:1.0.1") //Migrating to datastore
implementation("androidx.datastore:datastore-preferences:1.0.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import info.dvkr.screenstream.data.other.getLog
import info.dvkr.screenstream.data.settings.SettingsReadOnly
import io.ktor.server.cio.*
import io.ktor.server.engine.*
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -84,9 +85,10 @@ internal class HttpServer(
XLog.d(getLog("startServer"))

val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
if (throwable is IOException) return@CoroutineExceptionHandler
if (throwable is CancellationException) return@CoroutineExceptionHandler
XLog.d(getLog("onCoroutineException", "ktorServer: ${ktorServer?.hashCode()}"))
XLog.e(getLog("onCoroutineException", throwable.toString()), throwable)
if (throwable is IOException) return@CoroutineExceptionHandler
ktorServer?.stop(0, 250)
ktorServer = null
when (throwable) {
Expand Down Expand Up @@ -132,11 +134,7 @@ internal class HttpServer(
val environment = applicationEngineEnvironment {
parentCoroutineContext = coroutineScope.coroutineContext
watchPaths = emptyList() // Fix for java.lang.ClassNotFoundException: java.nio.file.FileSystems for API < 26
module {
appModule(
httpServerFiles, clientData, mjpegSharedFlow, lastJPEG, blockedJPEG, stopDeferred
) { sendEvent(it) }
}
module { appModule(httpServerFiles, clientData, mjpegSharedFlow, lastJPEG, blockedJPEG, stopDeferred) { sendEvent(it) } }
serverAddresses.forEach { netInterface ->
connector {
host = netInterface.address.hostAddress!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import java.io.IOException
import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.atomic.AtomicReference
Expand Down Expand Up @@ -82,6 +83,7 @@ internal fun Application.appModule(
call.respondRedirect(HttpServerFiles.PIN_REQUEST_ADDRESS)
}
exception<Throwable> { call, cause ->
if (cause is IOException) return@exception
if (cause is CancellationException) return@exception
val headers = CIOHeadersResearch.getHeadersAsString(call.request.headers as CIOHeaders)
XLog.e(this@appModule.getLog("exception<Throwable>", headers))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fun Int.toByteArray(): ByteArray = ByteBuffer.allocate(Int.SIZE_BYTES).putInt(th

fun InetAddress.asString(): String = if (this is Inet6Address) "[${this.hostAddress}]" else this.hostAddress ?: ""

fun InetSocketAddress.asString(): String = "${this.hostName?.let { it + "\n" }}${this.address.asString()}:${this.port}"
fun InetSocketAddress?.asString(): String = "${this?.hostName?.let { it + "\n" }}${this?.address?.asString()}:${this?.port}"

fun Context.getFileFromAssets(fileName: String): ByteArray {
XLog.d(getLog("getFileFromAssets", fileName))
Expand Down

0 comments on commit 73b1cbe

Please sign in to comment.