Fix floating toolbar touchable region bug.

The floating toolbar is rendered inside a transparent popup window
so that we can have smooth animations inside of the window (NOTE that
animating a view and a window at the same time do not work well as
both are not in sync.) Having a transparent window implies that we
can't get touch events through to the content below the window for
areas covered by the transparent window. To handle this issue we
"burn a hole" through the window by specifying it's "touchable area".
This is done using the mInsetsComputer which is set on the popup
window's root view's tree observer. When the popup is dismissed and
re-shown, we need to reset the mInsetsComputer as we most likely
won't have that root view any longer.

Change-Id: I13ea50bc19950180d339d05d82cbee03230e2f05
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index a14e98d..579cad4 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -346,6 +346,17 @@
         };
 
         private final Region mTouchableRegion = new Region();
+        private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
+                new ViewTreeObserver.OnComputeInternalInsetsListener() {
+                    public void onComputeInternalInsets(
+                            ViewTreeObserver.InternalInsetsInfo info) {
+                        info.contentInsets.setEmpty();
+                        info.visibleInsets.setEmpty();
+                        info.touchableRegion.set(mTouchableRegion);
+                        info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo
+                                .TOUCHABLE_INSETS_REGION);
+                    }
+                };
 
         private boolean mDismissed = true; // tracks whether this popup is dismissed or dismissing.
         private boolean mHidden; // tracks whether this popup is hidden or hiding.
@@ -382,21 +393,6 @@
                             mPopupWindow.dismiss();
                         }
                     });
-            // Make the touchable area of this popup be the area specified by mTouchableRegion.
-            mPopupWindow.getContentView()
-                    .getRootView()
-                    .getViewTreeObserver()
-                    .addOnComputeInternalInsetsListener(
-                            new ViewTreeObserver.OnComputeInternalInsetsListener() {
-                                public void onComputeInternalInsets(
-                                        ViewTreeObserver.InternalInsetsInfo info) {
-                                    info.contentInsets.setEmpty();
-                                    info.visibleInsets.setEmpty();
-                                    info.touchableRegion.set(mTouchableRegion);
-                                    info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo
-                                            .TOUCHABLE_INSETS_REGION);
-                                }
-                            });
             mMarginHorizontal = parent.getResources()
                     .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
             mMarginVertical = parent.getResources()
@@ -447,6 +443,7 @@
             // The "show" animation will make this visible.
             mContentContainer.setAlpha(0);
             mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, x, y);
+            setTouchableSurfaceInsetsComputer();
             runShowAnimation();
         }
 
@@ -804,6 +801,19 @@
                     (int) mContentContainer.getX() + width,
                     (int) mContentContainer.getY() + height);
         }
+
+        /**
+         * Make the touchable area of this popup be the area specified by mTouchableRegion.
+         * This should be called after the popup window has been dismissed (dismiss/hide)
+         * and is probably being re-shown with a new content root view.
+         */
+        private void setTouchableSurfaceInsetsComputer() {
+            ViewTreeObserver viewTreeObserver = mPopupWindow.getContentView()
+                    .getRootView()
+                    .getViewTreeObserver();
+            viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer);
+            viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer);
+        }
     }
 
     /**