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

Fix Flipper Ribtree Plugin memory leak #630

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading