Fixed a racecondition which could lead to invisible backgrounds

Notification backgrounds could become invisible when doubletapping
a permanent notification.

Bug: 15545215
Change-Id: I799439a368701042b39ca47bcac6fcce281349a7
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b91e129..8d19f50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -158,7 +158,7 @@
     private final Runnable mTapTimeoutRunnable = new Runnable() {
         @Override
         public void run() {
-            makeInactive();
+            makeInactive(true /* animate */);
         }
     };
 
@@ -183,7 +183,7 @@
                 break;
             case MotionEvent.ACTION_MOVE:
                 if (!isWithinTouchSlop(event)) {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                     return false;
                 }
                 break;
@@ -193,14 +193,17 @@
                         makeActive();
                         postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
                     } else {
-                        performClick();
+                        boolean performed = performClick();
+                        if (performed) {
+                            removeCallbacks(mTapTimeoutRunnable);
+                        }
                     }
                 } else {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                 }
                 break;
             case MotionEvent.ACTION_CANCEL:
-                makeInactive();
+                makeInactive(true /* animate */);
                 break;
             default:
                 break;
@@ -257,10 +260,14 @@
     /**
      * Cancels the hotspot and makes the notification inactive.
      */
-    private void makeInactive() {
+    public void makeInactive(boolean animate) {
         if (mActivated) {
             if (mDimmed) {
-                startActivateAnimation(true /* reverse */);
+                if (animate) {
+                    startActivateAnimation(true /* reverse */);
+                } else {
+                    mBackgroundNormal.setVisibility(View.INVISIBLE);
+                }
             }
             mActivated = false;
         }
@@ -351,6 +358,7 @@
             mBackgroundDimmed.setVisibility(View.INVISIBLE);
             mBackgroundNormal.setVisibility(View.VISIBLE);
             mBackgroundNormal.setAlpha(1f);
+            removeCallbacks(mTapTimeoutRunnable);
         }
     }
 
@@ -581,7 +589,7 @@
     }
 
     public interface OnActivatedListener {
-        void onActivated(View view);
-        void onActivationReset(View view);
+        void onActivated(ActivatableNotificationView view);
+        void onActivationReset(ActivatableNotificationView view);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 5223217..66770b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -103,6 +103,7 @@
 import com.android.systemui.qs.CircularClipper;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -2917,7 +2918,6 @@
             mNotificationPanel.setKeyguardShowing(false);
             mScrimController.setKeyguardShowing(false);
         }
-
         updateStackScrollerState();
         updatePublicMode();
         updateNotifications();
@@ -2933,6 +2933,11 @@
                 ? View.INVISIBLE : View.VISIBLE);
         mStackScroller.setScrollingEnabled(!onKeyguard);
         mStackScroller.setExpandingEnabled(!onKeyguard);
+        ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
+        mStackScroller.setActivatedChild(null);
+        if (activatedChild != null) {
+            activatedChild.makeInactive(false /* animate */);
+        }
     }
 
     public void userActivity() {
@@ -2989,9 +2994,13 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
         userActivity();
         mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
+        ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
+        if (previousView != null) {
+            previousView.makeInactive(true /* animate */);
+        }
         mStackScroller.setActivatedChild(view);
     }
 
@@ -3004,7 +3013,7 @@
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
         if (view == mStackScroller.getActivatedChild()) {
             mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b21e12c..6d92b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.stack;
 
 import android.view.View;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 
 import java.util.ArrayList;
 
@@ -27,7 +28,7 @@
     private ArrayList<View> mDraggedViews = new ArrayList<View>();
     private int mScrollY;
     private boolean mDimmed;
-    private View mActivatedChild;
+    private ActivatableNotificationView mActivatedChild;
     private float mOverScrollTopAmount;
     private float mOverScrollBottomAmount;
     private int mSpeedBumpIndex = -1;
@@ -64,7 +65,7 @@
      * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
      * interaction. This child is then scaled normally and its background is fully opaque.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mActivatedChild = activatedChild;
     }
 
@@ -72,7 +73,7 @@
         return mDimmed;
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mActivatedChild;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 5ace89f..e47f475 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -33,6 +33,7 @@
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.SpeedBumpView;
@@ -1760,7 +1761,7 @@
     /**
      * See {@link AmbientState#setActivatedChild}.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mAmbientState.setActivatedChild(activatedChild);
         if (mAnimationsEnabled) {
             mActivateNeedsAnimation = true;
@@ -1769,7 +1770,7 @@
         requestChildrenUpdate();
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mAmbientState.getActivatedChild();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index faea8de..fa8ad4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.tv;
 
 import android.os.IBinder;
-import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
@@ -25,6 +24,7 @@
 import android.view.WindowManager;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 
 /*
@@ -164,10 +164,10 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
     }
 }