Skip to content

Commit

Permalink
Merge pull request #630 from mamykin-andrey/issues-499-fix-flipper-pl…
Browse files Browse the repository at this point in the history
…ugin-memory-leak

Fix Flipper Ribtree Plugin memory leak
  • Loading branch information
tyvsmith authored Mar 20, 2024
2 parents 9b5cff6 + 11096f6 commit 4cec42f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ import com.uber.rib.core.ViewRouter
internal class RibEventPayload(
private val sessionId: String,
private val eventType: RibEventType,
private val routerId: String,
private val router: Router<*>,
private val parentRouterId: String,
private val parentRouter: Router<*>?,
private val routerInfo: RouterInfo,
private val parentRouterInfo: RouterInfo,
) {

companion object {
const val ROUTER_NAME_PREFIX: String = "Router"
const val EVENT_PARAMETER_ID: String = "id"
const val EVENT_PARAMETER_HOST_CLASSNAME: String = "hostClassName"
const val EVENT_PARAMETER_ROUTER_CLASSNAME: String = "routerClassName"
Expand All @@ -49,52 +46,54 @@ internal class RibEventPayload(
val eventName: String
get() = eventType.toString()

val flipperPayload: FlipperObject
get() =
FlipperObject.Builder()
.put(EVENT_PARAMETER_SESSION_ID, sessionId)
.put(EVENT_PARAMETER_ROUTER, RibEventRouterPayload(routerId, router).flipperPayload)
.put(
EVENT_PARAMETER_PARENT,
RibEventRouterPayload(parentRouterId, parentRouter).flipperPayload,
)
.build()
fun toFlipperPayload(): FlipperObject {
return FlipperObject.Builder()
.put(EVENT_PARAMETER_SESSION_ID, sessionId)
.put(EVENT_PARAMETER_ROUTER, routerInfo.toFlipperPayload())
.put(EVENT_PARAMETER_PARENT, parentRouterInfo.toFlipperPayload())
.build()
}

internal class RibEventRouterPayload
constructor(private val id: String, private val router: Router<*>?) {
internal class RouterInfo(
val id: String,
val name: String,
val className: String,
val hasView: Boolean,
val activityClassName: String,
) {
companion object {
private const val ROUTER_NAME_PREFIX: String = "Router"

val flipperPayload: FlipperObject
get() {
val name =
if (router is Router<*>) {
router.javaClass.simpleName.replace(ROUTER_NAME_PREFIX, "")
} else {
""
}
val routerClassName = if (router is Router<*>) router.javaClass.simpleName else ""
val hasView = router is ViewRouter<*, *>
val activityClassName = if (router is ViewRouter<*, *>) getActivityClassName(router) else ""
return FlipperObject.Builder()
.put(EVENT_PARAMETER_ID, id)
.put(EVENT_PARAMETER_NAME, name)
.put(EVENT_PARAMETER_ROUTER_CLASSNAME, routerClassName)
.put(EVENT_PARAMETER_HAS_VIEW, hasView)
.put(EVENT_PARAMETER_HOST_CLASSNAME, activityClassName)
.build()
}
fun fromRouter(router: Router<*>?, routerId: String) =
RouterInfo(
id = routerId,
name = router?.javaClass?.simpleName?.replace(ROUTER_NAME_PREFIX, "") ?: "",
className = router?.javaClass?.simpleName ?: "",
hasView = router is ViewRouter<*, *>,
activityClassName = if (router is ViewRouter<*, *>) getActivityClassName(router) else "",
)

private fun getActivityClassName(router: ViewRouter<*, *>): String {
val view: android.view.View? = router.view
if (view != null) {
var context: android.content.Context? = view.getContext()
private fun getActivityClassName(router: ViewRouter<*, *>): String {
val view: View = router.view
var context: Context? = view.context
while (context is ContextWrapper) {
if (context is Activity) {
return context.javaClass.getName()
return context.javaClass.name
}
context = context.getBaseContext()
context = context.baseContext
}
return ""
}
return ""
}

fun toFlipperPayload(): FlipperObject {
return FlipperObject.Builder()
.put(EVENT_PARAMETER_ID, id)
.put(EVENT_PARAMETER_NAME, name)
.put(EVENT_PARAMETER_ROUTER_CLASSNAME, className)
.put(EVENT_PARAMETER_HAS_VIEW, hasView)
.put(EVENT_PARAMETER_HOST_CLASSNAME, activityClassName)
.build()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ import com.uber.rib.flipper.RibTreeMessageType.SHOW_HIGHLIGHT
import io.reactivex.disposables.Disposable
import io.reactivex.subjects.ReplaySubject
import java.lang.ref.WeakReference
import java.util.HashMap
import java.util.UUID
import java.util.WeakHashMap
import kotlin.jvm.Synchronized

/** Flipper debug tool plugin to help with RIBs developement. */
class RibTreePlugin : FlipperPlugin {
Expand All @@ -59,7 +57,12 @@ class RibTreePlugin : FlipperPlugin {
val routerId = createRouterIdIfNeeded(router)
val parentRouter: Router<*>? = e.parentRouter
val parentRouterId = createRouterIdIfNeeded(parentRouter)
RibEventPayload(sessionId, e.eventType, routerId, router, parentRouterId, parentRouter)
RibEventPayload(
sessionId = sessionId,
eventType = e.eventType,
routerInfo = RibEventPayload.RouterInfo.fromRouter(router, routerId),
parentRouterInfo = RibEventPayload.RouterInfo.fromRouter(parentRouter, parentRouterId),
)
}
.subscribe(events)
}
Expand All @@ -73,7 +76,7 @@ class RibTreePlugin : FlipperPlugin {
this.connection = connection
disposable =
events.subscribe { e: RibEventPayload ->
this.connection?.send(e.eventName, e.flipperPayload)
this.connection?.send(e.eventName, e.toFlipperPayload())
}
connection.receive(SHOW_HIGHLIGHT.toString()) { params: FlipperObject, _: FlipperResponder? ->
val id: String = params.getString(EVENT_PARAMETER_ID)
Expand Down

0 comments on commit 4cec42f

Please sign in to comment.