From faac3dddfba9f4a06b88bcdfb7664e1f3961fc88 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Mon, 5 Dec 2022 07:07:44 -0800 Subject: [PATCH] Android activity tracking uses root view resolver as sole source of truth Summary: The previous approach was to append any 'extra/floating' root view to the end of the childrens for the application descriptor. But the active child was always the last view so if there was a 'floating' decor view with no activity it would always be the active child, even if you opened a real activity from it. This was possible to do in FB4a and you could get into a situation where you couldn't see the top most activity. New approach is to only iterate the root views from the resolver since it contains everything and map to activity if possible. Reviewed By: lblasa Differential Revision: D41731951 fbshipit-source-id: 9ef3fcfdaa41e9b07606ca6781cf22482b54e072 --- .../descriptors/ApplicationRefDescriptor.kt | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt index 7bf0f27af..4a3beadc7 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt @@ -9,6 +9,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors import android.app.Activity import android.view.View +import android.view.ViewGroup import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.util.DisplayMetrics @@ -34,17 +35,21 @@ object ApplicationRefDescriptor : ChainedDescriptor() { val activeRoots = node.rootsResolver.rootViews() - val added = mutableSetOf() - for (activity: Activity in node.activitiesStack) { - children.add(activity) - added.add(activity.window.decorView) - } + val decorViewToActivity: Map = + node.activitiesStack.toList().map { it.window.decorView to it }.toMap() - // Picks up root views not tied to an activity (dialogs) for (root in activeRoots) { - if (!added.contains(root)) { - children.add(root) - added.add(root) + // if there is an activity for this root view use that, + // if not just return the mystery floating decor view + val activity = decorViewToActivity[root] + if (activity != null) { + children.add(activity) + } else { + if (root is ViewGroup && root.childCount > 0) { + // sometimes there is a root view on top that has no children and we dont want to add + // these as they will become active + children.add(root) + } } }