Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.2.x: fix lifecycle if pass lifecycleOwner (Activity, Fragment) to Scarlet.… #71

Open
wants to merge 9 commits into
base: 0.2.x
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package com.tinder.scarlet.lifecycle.android

import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
Expand All @@ -12,29 +13,32 @@ import android.net.ConnectivityManager
import com.tinder.scarlet.Lifecycle
import com.tinder.scarlet.LifecycleState
import com.tinder.scarlet.lifecycle.LifecycleRegistry
import java.lang.Exception

internal class ConnectivityOnLifecycle(
applicationContext: Context,
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry()
private val applicationContext: Context,
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry()
) : Lifecycle by lifecycleRegistry {

private val connectivityChangeBroadcastReceiver = ConnectivityChangeBroadcastReceiver()

init {
emitCurrentConnectivity(applicationContext)
subscribeToConnectivityChange(applicationContext)
}

private fun emitCurrentConnectivity(applicationContext: Context) {
val connectivityManager =
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
lifecycleRegistry.onNext(toLifecycleState(connectivityManager.isConnected()))
}

private fun subscribeToConnectivityChange(applicationContext: Context) {
val intentFilter = IntentFilter()
.apply { addAction(ConnectivityManager.CONNECTIVITY_ACTION) }
applicationContext.registerReceiver(ConnectivityChangeBroadcastReceiver(), intentFilter)
val intentFilter = IntentFilter().apply { addAction(ConnectivityManager.CONNECTIVITY_ACTION) }
applicationContext.registerReceiver(connectivityChangeBroadcastReceiver, intentFilter)
}

@SuppressLint("MissingPermission")
private fun ConnectivityManager.isConnected(): Boolean {
val activeNetworkInfo = activeNetworkInfo
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
Expand All @@ -46,6 +50,13 @@ internal class ConnectivityOnLifecycle(
LifecycleState.Stopped
}

fun unregisterReceiver() {
try {
applicationContext.unregisterReceiver(connectivityChangeBroadcastReceiver)
} catch (e: Exception) {
}
}

private inner class ConnectivityChangeBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val extras = intent.extras ?: return
Expand All @@ -54,3 +65,4 @@ internal class ConnectivityOnLifecycle(
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,27 @@ import com.tinder.scarlet.LifecycleState
import com.tinder.scarlet.lifecycle.LifecycleRegistry

internal class LifecycleOwnerResumedLifecycle(
private val lifecycleOwner: LifecycleOwner,
private val lifecycleRegistry: LifecycleRegistry
) : Lifecycle by lifecycleRegistry {
private val lifecycleOwner: LifecycleOwner,
private val lifecycleRegistry: LifecycleRegistry
) : LifecycleObserver, Lifecycle by lifecycleRegistry {

init {
lifecycleOwner.lifecycle.addObserver(ALifecycleObserver())
lifecycleOwner.lifecycle.addObserver(this)
}

private inner class ALifecycleObserver : LifecycleObserver {
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_PAUSE)
fun onPause() {
lifecycleRegistry.onNext(LifecycleState.Stopped)
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_PAUSE)
fun onPause() {
lifecycleRegistry.onNext(LifecycleState.Stopped)
}

@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_RESUME)
fun onResume() {
lifecycleRegistry.onNext(LifecycleState.Started)
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_RESUME)
fun onResume() {
lifecycleRegistry.onNext(LifecycleState.Started)
}

@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifecycleRegistry.onComplete()
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifecycleRegistry.onComplete()
lifecycleOwner.lifecycle.removeObserver(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,27 @@ import com.tinder.scarlet.LifecycleState
import com.tinder.scarlet.lifecycle.LifecycleRegistry

internal class LifecycleOwnerStartedLifecycle(
private val lifecycleOwner: LifecycleOwner,
private val lifecycleRegistry: LifecycleRegistry
) : Lifecycle by lifecycleRegistry {
private val lifecycleOwner: LifecycleOwner,
private val lifecycleRegistry: LifecycleRegistry
) : LifecycleObserver, Lifecycle by lifecycleRegistry {

init {
lifecycleOwner.lifecycle.addObserver(ALifecycleObserver())
lifecycleOwner.lifecycle.addObserver(this)
}

private inner class ALifecycleObserver : LifecycleObserver {
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_STOP)
fun onPause() {
lifecycleRegistry.onNext(LifecycleState.Stopped)
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_STOP)
fun onPause() {
lifecycleRegistry.onNext(LifecycleState.Stopped)
}

@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_START)
fun onResume() {
lifecycleRegistry.onNext(LifecycleState.Started)
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_START)
fun onResume() {
lifecycleRegistry.onNext(LifecycleState.Started)
}

@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifecycleRegistry.onComplete()
}
@OnLifecycleEvent(androidx.lifecycle.Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifecycleRegistry.onComplete()
lifecycleOwner.lifecycle.removeObserver(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ class StompIntegrationTest {
connection1.open()
connection1.client.sendText("message1")
connection1.client.sendText("message2")
connection1.client.sendText("message3")
connection1.clientClosure()

connection2.open()

LOGGER.info("${queueTextObserver.values}")
queueTextObserver.awaitCount(2)
queueTextObserver.awaitCount(3)
}

@Test
Expand All @@ -69,14 +70,15 @@ class StompIntegrationTest {
connection1.begin("tx1")
connection1.send(DESTINATION, "message1", "tx1", null)
connection1.send(DESTINATION, "message2", "tx1", null)
connection1.send(DESTINATION, "message3", "tx1", null)
connection1.commit("tx1")
connection1.disconnect()

connection2.open()

val queueTextObserver = connection2.client.observeText().test()

queueTextObserver.awaitCount(2)
queueTextObserver.awaitCount(3)
LOGGER.info("${queueTextObserver.values}")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ internal class FlowableTest {
fun send_givenConnectionIsEstablished_shouldBeReceivedByTheServer() {
// Given
connection.open()
val textMessage1 = "Hello"
val textMessage2 = "Hi"
val textMessage1 = "Hello!"
val textMessage2 = "Hi!"
val bytesMessage1 = "Yo".toByteArray()
val bytesMessage2 = "Sup".toByteArray()
val testTextSubscriber = connection.server.observeText().test()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,45 @@ import com.tinder.scarlet.Lifecycle
import com.tinder.scarlet.LifecycleState
import io.reactivex.Flowable
import org.reactivestreams.Publisher
import java.lang.reflect.Method

internal class FlowableLifecycle(
private val flowable: Flowable<LifecycleState>
private val flowable: Flowable<LifecycleState>
) : Lifecycle, Publisher<LifecycleState> by flowable {

companion object {
const val CONNECTIVITY_ON_LIFECYCLE_CLASS_NAME = "com.tinder.scarlet.lifecycle.android.ConnectivityOnLifecycle"
const val UNREGISTER_CONNECTIVITY_BROADCAST_RECEIVER_METHOD_NAME = "unregisterReceiver"
}

override fun combineWith(others: List<Lifecycle>): Lifecycle {
val lifecycles = others + this
val flowable = Flowable.combineLatest(lifecycles) { it.map { it as LifecycleState }.combine() }

val flowable =
Flowable.combineLatest(lifecycles) { lifecycle ->
val state = lifecycle.map { it as LifecycleState }.combine()
try {
lifecycles.unregisterConnectivityBroadcastReceiver(state)
} catch (e: Exception) {
}
state
}
return FlowableLifecycle(flowable)
}

private fun List<Lifecycle>.unregisterConnectivityBroadcastReceiver(state: LifecycleState) {
if (state == LifecycleState.Completed) {
val connectivityClazz: Class<*>? = Class.forName(CONNECTIVITY_ON_LIFECYCLE_CLASS_NAME)
connectivityClazz?.let {
val connectivityOnLifecycle: Lifecycle? = this.find { connectivityClazz.isInstance(it) }
connectivityOnLifecycle?.let {
val obj: Any? = connectivityClazz.cast(connectivityOnLifecycle)
val method: Method? = connectivityClazz.getMethod(UNREGISTER_CONNECTIVITY_BROADCAST_RECEIVER_METHOD_NAME)
if (obj != null && method != null) {
method.invoke(obj)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import com.tinder.scarlet.LifecycleState

internal fun List<LifecycleState>.combine(): LifecycleState {
val shouldStop = any { it == LifecycleState.Stopped }
if (shouldStop) {
return LifecycleState.Stopped
val completed = any { it == LifecycleState.Completed }

return when {
shouldStop -> LifecycleState.Stopped
completed -> LifecycleState.Completed
else -> LifecycleState.Started
}
return LifecycleState.Started
}