Merge "Log.wtf when float properties in ViewState are set to NaN." into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d67f94f..f961984 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -189,22 +189,22 @@
             viewState.copyFrom(lastViewState);
 
             viewState.height = getIntrinsicHeight();
-            viewState.zTranslation = ambientState.getBaseZHeight();
+            viewState.setZTranslation(ambientState.getBaseZHeight());
             viewState.clipTopAmount = 0;
 
             if (ambientState.isExpansionChanging() && !ambientState.isOnKeyguard()) {
                 float expansion = ambientState.getExpansionFraction();
                 if (ambientState.isBouncerInTransit()) {
-                    viewState.alpha = aboutToShowBouncerProgress(expansion);
+                    viewState.setAlpha(aboutToShowBouncerProgress(expansion));
                 } else {
-                    viewState.alpha = ShadeInterpolation.getContentAlpha(expansion);
+                    viewState.setAlpha(ShadeInterpolation.getContentAlpha(expansion));
                 }
             } else {
-                viewState.alpha = 1f - ambientState.getHideAmount();
+                viewState.setAlpha(1f - ambientState.getHideAmount());
             }
             viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0;
             viewState.hideSensitive = false;
-            viewState.xTranslation = getTranslationX();
+            viewState.setXTranslation(getTranslationX());
             viewState.hasItemsInStableShelf = lastViewState.inShelf;
             viewState.firstViewInShelf = algorithmState.firstViewInShelf;
             if (mNotGoneIndex != -1) {
@@ -230,7 +230,7 @@
             }
 
             final float stackEnd = ambientState.getStackY() + ambientState.getStackHeight();
-            viewState.yTranslation = stackEnd - viewState.height;
+            viewState.setYTranslation(stackEnd - viewState.height);
         } else {
             viewState.hidden = true;
             viewState.location = ExpandableViewState.LOCATION_GONE;
@@ -794,7 +794,7 @@
         if (iconState == null) {
             return;
         }
-        iconState.alpha = ICON_ALPHA_INTERPOLATOR.getInterpolation(transitionAmount);
+        iconState.setAlpha(ICON_ALPHA_INTERPOLATOR.getInterpolation(transitionAmount));
         boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
         iconState.hidden = isAppearing
                 || (view instanceof ExpandableNotificationRow
@@ -809,12 +809,12 @@
 
         // Fade in icons at shelf start
         // This is important for conversation icons, which are badged and need x reset
-        iconState.xTranslation = mShelfIcons.getActualPaddingStart();
+        iconState.setXTranslation(mShelfIcons.getActualPaddingStart());
 
         final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
         if (stayingInShelf) {
             iconState.iconAppearAmount = 1.0f;
-            iconState.alpha = 1.0f;
+            iconState.setAlpha(1.0f);
             iconState.hidden = false;
         }
         int backgroundColor = getBackgroundColorWithoutTint();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 07ed013..087dc71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -3376,7 +3376,7 @@
 
         private void handleFixedTranslationZ(ExpandableNotificationRow row) {
             if (row.hasExpandingChild()) {
-                zTranslation = row.getTranslationZ();
+                setZTranslation(row.getTranslationZ());
                 clipTopAmount = row.getClipTopAmount();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 1e09b8a..38f0c55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -621,12 +621,12 @@
         // initialize with the default values of the view
         mViewState.height = getIntrinsicHeight();
         mViewState.gone = getVisibility() == View.GONE;
-        mViewState.alpha = 1f;
+        mViewState.setAlpha(1f);
         mViewState.notGoneIndex = -1;
-        mViewState.xTranslation = getTranslationX();
+        mViewState.setXTranslation(getTranslationX());
         mViewState.hidden = false;
-        mViewState.scaleX = getScaleX();
-        mViewState.scaleY = getScaleY();
+        mViewState.setScaleX(getScaleX());
+        mViewState.setScaleY(getScaleY());
         mViewState.inShelf = false;
         mViewState.headsUpIsVisible = false;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index d77e03f..7b23a56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -583,24 +583,26 @@
             ExpandableViewState childState = child.getViewState();
             int intrinsicHeight = child.getIntrinsicHeight();
             childState.height = intrinsicHeight;
-            childState.yTranslation = yPosition + launchTransitionCompensation;
+            childState.setYTranslation(yPosition + launchTransitionCompensation);
             childState.hidden = false;
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
-            childState.zTranslation =
-                    (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications)
-                    ? parentState.zTranslation
-                    : 0;
+            if (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications) {
+                childState.setZTranslation(parentState.getZTranslation());
+            } else {
+                childState.setZTranslation(0);
+            }
             childState.dimmed = parentState.dimmed;
             childState.hideSensitive = parentState.hideSensitive;
             childState.belowSpeedBump = parentState.belowSpeedBump;
             childState.clipTopAmount = 0;
-            childState.alpha = 0;
+            childState.setAlpha(0);
             if (i < firstOverflowIndex) {
-                childState.alpha = showingAsLowPriority() ? expandFactor : 1.0f;
+                childState.setAlpha(showingAsLowPriority() ? expandFactor : 1.0f);
             } else if (expandFactor == 1.0f && i <= lastVisibleIndex) {
-                childState.alpha = (mActualHeight - childState.yTranslation) / childState.height;
-                childState.alpha = Math.max(0.0f, Math.min(1.0f, childState.alpha));
+                childState.setAlpha(
+                        (mActualHeight - childState.getYTranslation()) / childState.height);
+                childState.setAlpha(Math.max(0.0f, Math.min(1.0f, childState.getAlpha())));
             }
             childState.location = parentState.location;
             childState.inShelf = parentState.inShelf;
@@ -621,13 +623,16 @@
                     if (mirrorView.getVisibility() == GONE) {
                         mirrorView = alignView;
                     }
-                    mGroupOverFlowState.alpha = mirrorView.getAlpha();
-                    mGroupOverFlowState.yTranslation += NotificationUtils.getRelativeYOffset(
+                    mGroupOverFlowState.setAlpha(mirrorView.getAlpha());
+                    float yTranslation = mGroupOverFlowState.getYTranslation()
+                            + NotificationUtils.getRelativeYOffset(
                             mirrorView, overflowView);
+                    mGroupOverFlowState.setYTranslation(yTranslation);
                 }
             } else {
-                mGroupOverFlowState.yTranslation += mNotificationHeaderMargin;
-                mGroupOverFlowState.alpha = 0.0f;
+                mGroupOverFlowState.setYTranslation(
+                        mGroupOverFlowState.getYTranslation() + mNotificationHeaderMargin);
+                mGroupOverFlowState.setAlpha(0.0f);
             }
         }
         if (mNotificationHeader != null) {
@@ -635,11 +640,11 @@
                 mHeaderViewState = new ViewState();
             }
             mHeaderViewState.initFrom(mNotificationHeader);
-            mHeaderViewState.zTranslation = childrenExpandedAndNotAnimating
-                    ? parentState.zTranslation
-                    : 0;
-            mHeaderViewState.yTranslation = mCurrentHeaderTranslation;
-            mHeaderViewState.alpha = mHeaderVisibleAmount;
+            mHeaderViewState.setZTranslation(childrenExpandedAndNotAnimating
+                    ? parentState.getZTranslation()
+                    : 0);
+            mHeaderViewState.setYTranslation(mCurrentHeaderTranslation);
+            mHeaderViewState.setAlpha(mHeaderVisibleAmount);
             // The hiding is done automatically by the alpha, otherwise we'll pick it up again
             // in the next frame with the initFrom call above and have an invisible header
             mHeaderViewState.hidden = false;
@@ -711,14 +716,14 @@
             // layout the divider
             View divider = mDividers.get(i);
             tmpState.initFrom(divider);
-            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
-            float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
-            if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
+            tmpState.setYTranslation(viewState.getYTranslation() - mDividerHeight);
+            float alpha = mChildrenExpanded && viewState.getAlpha() != 0 ? mDividerAlpha : 0;
+            if (mUserLocked && !showingAsLowPriority() && viewState.getAlpha() != 0) {
                 alpha = NotificationUtils.interpolate(0, mDividerAlpha,
-                        Math.min(viewState.alpha, expandFraction));
+                        Math.min(viewState.getAlpha(), expandFraction));
             }
             tmpState.hidden = !dividersVisible;
-            tmpState.alpha = alpha;
+            tmpState.setAlpha(alpha);
             tmpState.applyToView(divider);
             // There is no fake shadow to be drawn on the children
             child.setFakeShadowIntensity(0.0f, 0.0f, 0, 0);
@@ -790,24 +795,24 @@
             // layout the divider
             View divider = mDividers.get(i);
             tmpState.initFrom(divider);
-            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
-            float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
-            if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
+            tmpState.setYTranslation(viewState.getYTranslation() - mDividerHeight);
+            float alpha = mChildrenExpanded && viewState.getAlpha() != 0 ? mDividerAlpha : 0;
+            if (mUserLocked && !showingAsLowPriority() && viewState.getAlpha() != 0) {
                 alpha = NotificationUtils.interpolate(0, mDividerAlpha,
-                        Math.min(viewState.alpha, expandFraction));
+                        Math.min(viewState.getAlpha(), expandFraction));
             }
             tmpState.hidden = !dividersVisible;
-            tmpState.alpha = alpha;
+            tmpState.setAlpha(alpha);
             tmpState.animateTo(divider, properties);
             // There is no fake shadow to be drawn on the children
             child.setFakeShadowIntensity(0.0f, 0.0f, 0, 0);
         }
         if (mOverflowNumber != null) {
             if (mNeverAppliedGroupState) {
-                float alpha = mGroupOverFlowState.alpha;
-                mGroupOverFlowState.alpha = 0;
+                float alpha = mGroupOverFlowState.getAlpha();
+                mGroupOverFlowState.setAlpha(0);
                 mGroupOverFlowState.applyToView(mOverflowNumber);
-                mGroupOverFlowState.alpha = alpha;
+                mGroupOverFlowState.setAlpha(alpha);
                 mNeverAppliedGroupState = false;
             }
             mGroupOverFlowState.animateTo(mOverflowNumber, properties);
@@ -949,7 +954,7 @@
             child.setAlpha(start);
             ViewState viewState = new ViewState();
             viewState.initFrom(child);
-            viewState.alpha = target;
+            viewState.setAlpha(target);
             ALPHA_FADE_IN.setDelay(i * 50);
             viewState.animateTo(child, ALPHA_FADE_IN);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 6821b14..836cacc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -3188,7 +3188,7 @@
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     private boolean shouldHunAppearFromBottom(ExpandableViewState viewState) {
-        return viewState.yTranslation + viewState.height
+        return viewState.getYTranslation() + viewState.height
                 >= mAmbientState.getMaxHeadsUpTranslation();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 32591ce..8d28f75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -134,23 +134,23 @@
 
             if (isHunGoingToShade) {
                 // Keep 100% opacity for heads up notification going to shade.
-                viewState.alpha = 1f;
+                viewState.setAlpha(1f);
             } else if (ambientState.isOnKeyguard()) {
                 // Adjust alpha for wakeup to lockscreen.
-                viewState.alpha = 1f - ambientState.getHideAmount();
+                viewState.setAlpha(1f - ambientState.getHideAmount());
             } else if (ambientState.isExpansionChanging()) {
                 // Adjust alpha for shade open & close.
                 float expansion = ambientState.getExpansionFraction();
-                viewState.alpha = ambientState.isBouncerInTransit()
+                viewState.setAlpha(ambientState.isBouncerInTransit()
                         ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
-                        : ShadeInterpolation.getContentAlpha(expansion);
+                        : ShadeInterpolation.getContentAlpha(expansion));
             }
 
             // For EmptyShadeView if on keyguard, we need to control the alpha to create
             // a nice transition when the user is dragging down the notification panel.
             if (view instanceof EmptyShadeView && ambientState.isOnKeyguard()) {
                 final float fractionToShade = ambientState.getFractionToShade();
-                viewState.alpha = ShadeInterpolation.getContentAlpha(fractionToShade);
+                viewState.setAlpha(ShadeInterpolation.getContentAlpha(fractionToShade));
             }
 
             NotificationShelf shelf = ambientState.getShelf();
@@ -166,10 +166,10 @@
                     continue;
                 }
 
-                final float shelfTop = shelfState.yTranslation;
-                final float viewTop = viewState.yTranslation;
+                final float shelfTop = shelfState.getYTranslation();
+                final float viewTop = viewState.getYTranslation();
                 if (viewTop >= shelfTop) {
-                    viewState.alpha = 0;
+                    viewState.setAlpha(0);
                 }
             }
         }
@@ -277,7 +277,7 @@
             if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
                 clipStart = Math.max(drawStart, clipStart);
             }
-            float newYTranslation = state.yTranslation;
+            float newYTranslation = state.getYTranslation();
             float newHeight = state.height;
             float newNotificationEnd = newYTranslation + newHeight;
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
@@ -322,7 +322,8 @@
             childViewState.hideSensitive = hideSensitive;
             boolean isActivatedChild = activatedChild == child;
             if (dimmed && isActivatedChild) {
-                childViewState.zTranslation += 2.0f * ambientState.getZDistanceBetweenElements();
+                childViewState.setZTranslation(childViewState.getZTranslation()
+                        + 2.0f * ambientState.getZDistanceBetweenElements());
             }
         }
     }
@@ -527,12 +528,12 @@
 
         // Must set viewState.yTranslation _before_ use.
         // Incoming views have yTranslation=0 by default.
-        viewState.yTranslation = algorithmState.mCurrentYPosition;
+        viewState.setYTranslation(algorithmState.mCurrentYPosition);
 
+        float viewEnd = viewState.getYTranslation() + viewState.height + ambientState.getStackY();
         maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(),
-                view.mustStayOnScreen(), /* topVisible */ viewState.yTranslation >= 0,
-                /* viewEnd */ viewState.yTranslation + viewState.height + ambientState.getStackY(),
-                /* hunMax */ ambientState.getMaxHeadsUpTranslation()
+                view.mustStayOnScreen(), /* topVisible */ viewState.getYTranslation() >= 0,
+                viewEnd, /* hunMax */ ambientState.getMaxHeadsUpTranslation()
         );
         if (view instanceof FooterView) {
             final boolean shadeClosed = !ambientState.isShadeExpanded();
@@ -552,7 +553,7 @@
             if (view instanceof EmptyShadeView) {
                 float fullHeight = ambientState.getLayoutMaxHeight() + mMarginBottom
                         - ambientState.getStackY();
-                viewState.yTranslation = (fullHeight - getMaxAllowedChildHeight(view)) / 2f;
+                viewState.setYTranslation((fullHeight - getMaxAllowedChildHeight(view)) / 2f);
             } else if (view != ambientState.getTrackedHeadsUpRow()) {
                 if (ambientState.isExpansionChanging()) {
                     // We later update shelf state, then hide views below the shelf.
@@ -591,13 +592,13 @@
                 + mPaddingBetweenElements;
 
         setLocation(view.getViewState(), algorithmState.mCurrentYPosition, i);
-        viewState.yTranslation += ambientState.getStackY();
+        viewState.setYTranslation(viewState.getYTranslation() + ambientState.getStackY());
     }
 
     @VisibleForTesting
     void updateViewWithShelf(ExpandableView view, ExpandableViewState viewState, float shelfStart) {
-        viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
-        if (viewState.yTranslation >= shelfStart) {
+        viewState.setYTranslation(Math.min(viewState.getYTranslation(), shelfStart));
+        if (viewState.getYTranslation() >= shelfStart) {
             viewState.hidden = !view.isExpandAnimationRunning()
                     && !view.hasExpandingChild();
             viewState.inShelf = true;
@@ -690,9 +691,9 @@
         if (trackedHeadsUpRow != null) {
             ExpandableViewState childState = trackedHeadsUpRow.getViewState();
             if (childState != null) {
-                float endPosition = childState.yTranslation - ambientState.getStackTranslation();
-                childState.yTranslation = MathUtils.lerp(
-                        headsUpTranslation, endPosition, ambientState.getAppearFraction());
+                float endPos = childState.getYTranslation() - ambientState.getStackTranslation();
+                childState.setYTranslation(MathUtils.lerp(
+                        headsUpTranslation, endPos, ambientState.getAppearFraction()));
             }
         }
 
@@ -712,7 +713,7 @@
                 childState.location = ExpandableViewState.LOCATION_FIRST_HUN;
             }
             boolean isTopEntry = topHeadsUpEntry == row;
-            float unmodifiedEndLocation = childState.yTranslation + childState.height;
+            float unmodifiedEndLocation = childState.getYTranslation() + childState.height;
             if (mIsExpanded) {
                 if (row.mustStayOnScreen() && !childState.headsUpIsVisible
                         && !row.showingPulsing()) {
@@ -727,13 +728,14 @@
                 }
             }
             if (row.isPinned()) {
-                childState.yTranslation = Math.max(childState.yTranslation, headsUpTranslation);
+                childState.setYTranslation(
+                        Math.max(childState.getYTranslation(), headsUpTranslation));
                 childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
                 childState.hidden = false;
                 ExpandableViewState topState =
                         topHeadsUpEntry == null ? null : topHeadsUpEntry.getViewState();
                 if (topState != null && !isTopEntry && (!mIsExpanded
-                        || unmodifiedEndLocation > topState.yTranslation + topState.height)) {
+                        || unmodifiedEndLocation > topState.getYTranslation() + topState.height)) {
                     // Ensure that a headsUp doesn't vertically extend further than the heads-up at
                     // the top most z-position
                     childState.height = row.getIntrinsicHeight();
@@ -745,11 +747,12 @@
                 // heads up show full of row's content and any scroll y indicate that the
                 // translationY need to move up the HUN.
                 if (!mIsExpanded && isTopEntry && ambientState.getScrollY() > 0) {
-                    childState.yTranslation -= ambientState.getScrollY();
+                    childState.setYTranslation(
+                            childState.getYTranslation() - ambientState.getScrollY());
                 }
             }
             if (row.isHeadsUpAnimatingAway()) {
-                childState.yTranslation = Math.max(childState.yTranslation, mHeadsUpInset);
+                childState.setYTranslation(Math.max(childState.getYTranslation(), mHeadsUpInset));
                 childState.hidden = false;
             }
         }
@@ -765,13 +768,13 @@
             ExpandableViewState viewState) {
 
         final float newTranslation = Math.max(quickQsOffsetHeight + stackTranslation,
-                viewState.yTranslation);
+                viewState.getYTranslation());
 
         // Transition from collapsed pinned state to fully expanded state
         // when the pinned HUN approaches its actual location (when scrolling back to top).
-        final float distToRealY = newTranslation - viewState.yTranslation;
+        final float distToRealY = newTranslation - viewState.getYTranslation();
         viewState.height = (int) Math.max(viewState.height - distToRealY, collapsedHeight);
-        viewState.yTranslation = newTranslation;
+        viewState.setYTranslation(newTranslation);
     }
 
     // Pin HUN to bottom of expanded QS
@@ -784,10 +787,10 @@
         maxHeadsUpTranslation = Math.min(maxHeadsUpTranslation, maxShelfPosition);
 
         final float bottomPosition = maxHeadsUpTranslation - row.getCollapsedHeight();
-        final float newTranslation = Math.min(childState.yTranslation, bottomPosition);
+        final float newTranslation = Math.min(childState.getYTranslation(), bottomPosition);
         childState.height = (int) Math.min(childState.height, maxHeadsUpTranslation
                 - newTranslation);
-        childState.yTranslation = newTranslation;
+        childState.setYTranslation(newTranslation);
 
         // Animate pinned HUN bottom corners to and from original roundness.
         final float originalCornerRadius =
@@ -859,17 +862,17 @@
         float baseZ = ambientState.getBaseZHeight();
         if (child.mustStayOnScreen() && !childViewState.headsUpIsVisible
                 && !ambientState.isDozingAndNotPulsing(child)
-                && childViewState.yTranslation < ambientState.getTopPadding()
+                && childViewState.getYTranslation() < ambientState.getTopPadding()
                 + ambientState.getStackTranslation()) {
             if (childrenOnTop != 0.0f) {
                 childrenOnTop++;
             } else {
                 float overlap = ambientState.getTopPadding()
-                        + ambientState.getStackTranslation() - childViewState.yTranslation;
+                        + ambientState.getStackTranslation() - childViewState.getYTranslation();
                 childrenOnTop += Math.min(1.0f, overlap / childViewState.height);
             }
-            childViewState.zTranslation = baseZ
-                    + childrenOnTop * zDistanceBetweenElements;
+            childViewState.setZTranslation(baseZ
+                    + childrenOnTop * zDistanceBetweenElements);
         } else if (shouldElevateHun) {
             // In case this is a new view that has never been measured before, we don't want to
             // elevate if we are currently expanded more then the notification
@@ -878,28 +881,28 @@
             float shelfStart = ambientState.getInnerHeight()
                     - shelfHeight + ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
-            float notificationEnd = childViewState.yTranslation + child.getIntrinsicHeight()
+            float notificationEnd = childViewState.getYTranslation() + child.getIntrinsicHeight()
                     + mPaddingBetweenElements;
             if (shelfStart > notificationEnd) {
-                childViewState.zTranslation = baseZ;
+                childViewState.setZTranslation(baseZ);
             } else {
                 float factor = (notificationEnd - shelfStart) / shelfHeight;
                 if (Float.isNaN(factor)) { // Avoid problems when the above is 0/0.
                     factor = 1.0f;
                 }
                 factor = Math.min(factor, 1.0f);
-                childViewState.zTranslation = baseZ + factor * zDistanceBetweenElements;
+                childViewState.setZTranslation(baseZ + factor * zDistanceBetweenElements);
             }
         } else {
-            childViewState.zTranslation = baseZ;
+            childViewState.setZTranslation(baseZ);
         }
 
         // We need to scrim the notification more from its surrounding content when we are pinned,
         // and we therefore elevate it higher.
         // We can use the headerVisibleAmount for this, since the value nicely goes from 0 to 1 when
         // expanding after which we have a normal elevation again.
-        childViewState.zTranslation += (1.0f - child.getHeaderVisibleAmount())
-                * mPinnedZTranslationExtra;
+        childViewState.setZTranslation(childViewState.getZTranslation()
+                + (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra);
         return childrenOnTop;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 174bf4c..ee72943 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -169,9 +169,9 @@
         adaptDurationWhenGoingToFullShade(child, viewState, wasAdded, animationStaggerCount);
         mAnimationProperties.delay = 0;
         if (wasAdded || mAnimationFilter.hasDelays
-                        && (viewState.yTranslation != child.getTranslationY()
-                        || viewState.zTranslation != child.getTranslationZ()
-                        || viewState.alpha != child.getAlpha()
+                        && (viewState.getYTranslation() != child.getTranslationY()
+                        || viewState.getZTranslation() != child.getTranslationZ()
+                        || viewState.getAlpha() != child.getAlpha()
                         || viewState.height != child.getActualHeight()
                         || viewState.clipTopAmount != child.getClipTopAmount())) {
             mAnimationProperties.delay = mCurrentAdditionalDelay
@@ -191,7 +191,7 @@
                 mAnimationProperties.duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50
                         + (long) (100 * longerDurationFactor);
             }
-            child.setTranslationY(viewState.yTranslation + startOffset);
+            child.setTranslationY(viewState.getYTranslation() + startOffset);
         }
     }
 
@@ -400,7 +400,7 @@
                     // travelled
                     ExpandableViewState viewState =
                             ((ExpandableView) event.viewAfterChangingView).getViewState();
-                    translationDirection = ((viewState.yTranslation
+                    translationDirection = ((viewState.getYTranslation()
                             - (ownPosition + actualHeight / 2.0f)) * 2 /
                             actualHeight);
                     translationDirection = Math.max(Math.min(translationDirection, 1.0f),-1.0f);
@@ -433,7 +433,7 @@
                 ExpandableViewState viewState = changingView.getViewState();
                 mTmpState.copyFrom(viewState);
                 if (event.headsUpFromBottom) {
-                    mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
+                    mTmpState.setYTranslation(mHeadsUpAppearHeightBottom);
                 } else {
                     Runnable onAnimationEnd = null;
                     if (loggable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index 786de29..d07da38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -21,6 +21,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.util.Log;
 import android.util.Property;
 import android.view.View;
 import android.view.animation.Interpolator;
@@ -42,7 +43,7 @@
  * A state of a view. This can be used to apply a set of view properties to a view with
  * {@link com.android.systemui.statusbar.notification.stack.StackScrollState} or start
  * animations with {@link com.android.systemui.statusbar.notification.stack.StackStateAnimator}.
-*/
+ */
 public class ViewState implements Dumpable {
 
     /**
@@ -51,6 +52,7 @@
      */
     protected static final AnimationProperties NO_NEW_ANIMATIONS = new AnimationProperties() {
         AnimationFilter mAnimationFilter = new AnimationFilter();
+
         @Override
         public AnimationFilter getAnimationFilter() {
             return mAnimationFilter;
@@ -68,6 +70,7 @@
     private static final int TAG_START_TRANSLATION_Y = R.id.translation_y_animator_start_value_tag;
     private static final int TAG_START_TRANSLATION_Z = R.id.translation_z_animator_start_value_tag;
     private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag;
+    private static final String LOG_TAG = "StackViewState";
 
     private static final AnimatableProperty SCALE_X_PROPERTY
             = new AnimatableProperty() {
@@ -117,35 +120,127 @@
         }
     };
 
-    public float alpha;
-    public float xTranslation;
-    public float yTranslation;
-    public float zTranslation;
     public boolean gone;
     public boolean hidden;
-    public float scaleX = 1.0f;
-    public float scaleY = 1.0f;
+
+    private float mAlpha;
+    private float mXTranslation;
+    private float mYTranslation;
+    private float mZTranslation;
+    private float mScaleX = 1.0f;
+    private float mScaleY = 1.0f;
+
+    public float getAlpha() {
+        return mAlpha;
+    }
+
+    /**
+     * @param alpha View transparency.
+     */
+    public void setAlpha(float alpha) {
+        if (isValidFloat(alpha, "alpha")) {
+            this.mAlpha = alpha;
+        }
+    }
+
+    public float getXTranslation() {
+        return mXTranslation;
+    }
+
+    /**
+     * @param xTranslation x-axis translation value for the animation.
+     */
+    public void setXTranslation(float xTranslation) {
+        if (isValidFloat(xTranslation, "xTranslation")) {
+            this.mXTranslation = xTranslation;
+        }
+    }
+
+    public float getYTranslation() {
+        return mYTranslation;
+    }
+
+    /**
+     * @param yTranslation y-axis translation value for the animation.
+     */
+    public void setYTranslation(float yTranslation) {
+        if (isValidFloat(yTranslation, "yTranslation")) {
+            this.mYTranslation = yTranslation;
+        }
+    }
+
+    public float getZTranslation() {
+        return mZTranslation;
+    }
+
+
+    /**
+     * @param zTranslation z-axis translation value for the animation.
+     */
+    public void setZTranslation(float zTranslation) {
+        if (isValidFloat(zTranslation, "zTranslation")) {
+            this.mZTranslation = zTranslation;
+        }
+    }
+
+    public float getScaleX() {
+        return mScaleX;
+    }
+
+    /**
+     * @param scaleX x-axis scale property for the animation.
+     */
+    public void setScaleX(float scaleX) {
+        if (isValidFloat(scaleX, "scaleX")) {
+            this.mScaleX = scaleX;
+        }
+    }
+
+    public float getScaleY() {
+        return mScaleY;
+    }
+
+    /**
+     * @param scaleY y-axis scale property for the animation.
+     */
+    public void setScaleY(float scaleY) {
+        if (isValidFloat(scaleY, "scaleY")) {
+            this.mScaleY = scaleY;
+        }
+    }
+
+    /**
+     * Checks if {@code value} is a valid float value. If it is not, logs it (using {@code name})
+     * and returns false.
+     */
+    private boolean isValidFloat(float value, String name) {
+        if (Float.isNaN(value)) {
+            Log.wtf(LOG_TAG, "Cannot set property " + name + " to NaN");
+            return false;
+        }
+        return true;
+    }
 
     public void copyFrom(ViewState viewState) {
-        alpha = viewState.alpha;
-        xTranslation = viewState.xTranslation;
-        yTranslation = viewState.yTranslation;
-        zTranslation = viewState.zTranslation;
+        mAlpha = viewState.mAlpha;
+        mXTranslation = viewState.mXTranslation;
+        mYTranslation = viewState.mYTranslation;
+        mZTranslation = viewState.mZTranslation;
         gone = viewState.gone;
         hidden = viewState.hidden;
-        scaleX = viewState.scaleX;
-        scaleY = viewState.scaleY;
+        mScaleX = viewState.mScaleX;
+        mScaleY = viewState.mScaleY;
     }
 
     public void initFrom(View view) {
-        alpha = view.getAlpha();
-        xTranslation = view.getTranslationX();
-        yTranslation = view.getTranslationY();
-        zTranslation = view.getTranslationZ();
+        mAlpha = view.getAlpha();
+        mXTranslation = view.getTranslationX();
+        mYTranslation = view.getTranslationY();
+        mZTranslation = view.getTranslationZ();
         gone = view.getVisibility() == View.GONE;
         hidden = view.getVisibility() == View.INVISIBLE;
-        scaleX = view.getScaleX();
-        scaleY = view.getScaleY();
+        mScaleX = view.getScaleX();
+        mScaleY = view.getScaleY();
     }
 
     /**
@@ -161,51 +256,51 @@
         boolean animatingX = isAnimating(view, TAG_ANIMATOR_TRANSLATION_X);
         if (animatingX) {
             updateAnimationX(view);
-        } else if (view.getTranslationX() != this.xTranslation){
-            view.setTranslationX(this.xTranslation);
+        } else if (view.getTranslationX() != this.mXTranslation) {
+            view.setTranslationX(this.mXTranslation);
         }
 
         // apply yTranslation
         boolean animatingY = isAnimating(view, TAG_ANIMATOR_TRANSLATION_Y);
         if (animatingY) {
             updateAnimationY(view);
-        } else if (view.getTranslationY() != this.yTranslation) {
-            view.setTranslationY(this.yTranslation);
+        } else if (view.getTranslationY() != this.mYTranslation) {
+            view.setTranslationY(this.mYTranslation);
         }
 
         // apply zTranslation
         boolean animatingZ = isAnimating(view, TAG_ANIMATOR_TRANSLATION_Z);
         if (animatingZ) {
             updateAnimationZ(view);
-        } else if (view.getTranslationZ() != this.zTranslation) {
-            view.setTranslationZ(this.zTranslation);
+        } else if (view.getTranslationZ() != this.mZTranslation) {
+            view.setTranslationZ(this.mZTranslation);
         }
 
         // apply scaleX
         boolean animatingScaleX = isAnimating(view, SCALE_X_PROPERTY);
         if (animatingScaleX) {
-            updateAnimation(view, SCALE_X_PROPERTY, scaleX);
-        } else if (view.getScaleX() != scaleX) {
-            view.setScaleX(scaleX);
+            updateAnimation(view, SCALE_X_PROPERTY, mScaleX);
+        } else if (view.getScaleX() != mScaleX) {
+            view.setScaleX(mScaleX);
         }
 
         // apply scaleY
         boolean animatingScaleY = isAnimating(view, SCALE_Y_PROPERTY);
         if (animatingScaleY) {
-            updateAnimation(view, SCALE_Y_PROPERTY, scaleY);
-        } else if (view.getScaleY() != scaleY) {
-            view.setScaleY(scaleY);
+            updateAnimation(view, SCALE_Y_PROPERTY, mScaleY);
+        } else if (view.getScaleY() != mScaleY) {
+            view.setScaleY(mScaleY);
         }
 
         int oldVisibility = view.getVisibility();
-        boolean becomesInvisible = this.alpha == 0.0f
+        boolean becomesInvisible = this.mAlpha == 0.0f
                 || (this.hidden && (!isAnimating(view) || oldVisibility != View.VISIBLE));
         boolean animatingAlpha = isAnimating(view, TAG_ANIMATOR_ALPHA);
         if (animatingAlpha) {
             updateAlphaAnimation(view);
-        } else if (view.getAlpha() != this.alpha) {
+        } else if (view.getAlpha() != this.mAlpha) {
             // apply layer type
-            boolean becomesFullyVisible = this.alpha == 1.0f;
+            boolean becomesFullyVisible = this.mAlpha == 1.0f;
             boolean becomesFaded = !becomesInvisible && !becomesFullyVisible;
             if (FadeOptimizedNotification.FADE_LAYER_OPTIMIZATION_ENABLED
                     && view instanceof FadeOptimizedNotification) {
@@ -229,7 +324,7 @@
             }
 
             // apply alpha
-            view.setAlpha(this.alpha);
+            view.setAlpha(this.mAlpha);
         }
 
         // apply visibility
@@ -274,54 +369,55 @@
 
     /**
      * Start an animation to this viewstate
-     * @param child the view to animate
+     *
+     * @param child               the view to animate
      * @param animationProperties the properties of the animation
      */
     public void animateTo(View child, AnimationProperties animationProperties) {
         boolean wasVisible = child.getVisibility() == View.VISIBLE;
-        final float alpha = this.alpha;
+        final float alpha = this.mAlpha;
         if (!wasVisible && (alpha != 0 || child.getAlpha() != 0)
                 && !this.gone && !this.hidden) {
             child.setVisibility(View.VISIBLE);
         }
         float childAlpha = child.getAlpha();
-        boolean alphaChanging = this.alpha != childAlpha;
+        boolean alphaChanging = this.mAlpha != childAlpha;
         if (child instanceof ExpandableView) {
             // We don't want views to change visibility when they are animating to GONE
             alphaChanging &= !((ExpandableView) child).willBeGone();
         }
 
         // start translationX animation
-        if (child.getTranslationX() != this.xTranslation) {
+        if (child.getTranslationX() != this.mXTranslation) {
             startXTranslationAnimation(child, animationProperties);
         } else {
             abortAnimation(child, TAG_ANIMATOR_TRANSLATION_X);
         }
 
         // start translationY animation
-        if (child.getTranslationY() != this.yTranslation) {
+        if (child.getTranslationY() != this.mYTranslation) {
             startYTranslationAnimation(child, animationProperties);
         } else {
             abortAnimation(child, TAG_ANIMATOR_TRANSLATION_Y);
         }
 
         // start translationZ animation
-        if (child.getTranslationZ() != this.zTranslation) {
+        if (child.getTranslationZ() != this.mZTranslation) {
             startZTranslationAnimation(child, animationProperties);
         } else {
             abortAnimation(child, TAG_ANIMATOR_TRANSLATION_Z);
         }
 
         // start scaleX animation
-        if (child.getScaleX() != scaleX) {
-            PropertyAnimator.startAnimation(child, SCALE_X_PROPERTY, scaleX, animationProperties);
+        if (child.getScaleX() != mScaleX) {
+            PropertyAnimator.startAnimation(child, SCALE_X_PROPERTY, mScaleX, animationProperties);
         } else {
             abortAnimation(child, SCALE_X_PROPERTY.getAnimatorTag());
         }
 
         // start scaleX animation
-        if (child.getScaleY() != scaleY) {
-            PropertyAnimator.startAnimation(child, SCALE_Y_PROPERTY, scaleY, animationProperties);
+        if (child.getScaleY() != mScaleY) {
+            PropertyAnimator.startAnimation(child, SCALE_Y_PROPERTY, mScaleY, animationProperties);
         } else {
             abortAnimation(child, SCALE_Y_PROPERTY.getAnimatorTag());
         }
@@ -329,7 +425,7 @@
         // start alpha animation
         if (alphaChanging) {
             startAlphaAnimation(child, animationProperties);
-        }  else {
+        } else {
             abortAnimation(child, TAG_ANIMATOR_ALPHA);
         }
     }
@@ -339,9 +435,9 @@
     }
 
     private void startAlphaAnimation(final View child, AnimationProperties properties) {
-        Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
-        Float previousEndValue = getChildTag(child,TAG_END_ALPHA);
-        final float newEndValue = this.alpha;
+        Float previousStartValue = getChildTag(child, TAG_START_ALPHA);
+        Float previousEndValue = getChildTag(child, TAG_END_ALPHA);
+        final float newEndValue = this.mAlpha;
         if (previousEndValue != null && previousEndValue == newEndValue) {
             return;
         }
@@ -426,9 +522,9 @@
     }
 
     private void startZTranslationAnimation(final View child, AnimationProperties properties) {
-        Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z);
-        Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z);
-        float newEndValue = this.zTranslation;
+        Float previousStartValue = getChildTag(child, TAG_START_TRANSLATION_Z);
+        Float previousEndValue = getChildTag(child, TAG_END_TRANSLATION_Z);
+        float newEndValue = this.mZTranslation;
         if (previousEndValue != null && previousEndValue == newEndValue) {
             return;
         }
@@ -487,9 +583,9 @@
     }
 
     private void startXTranslationAnimation(final View child, AnimationProperties properties) {
-        Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_X);
-        Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_X);
-        float newEndValue = this.xTranslation;
+        Float previousStartValue = getChildTag(child, TAG_START_TRANSLATION_X);
+        Float previousEndValue = getChildTag(child, TAG_END_TRANSLATION_X);
+        float newEndValue = this.mXTranslation;
         if (previousEndValue != null && previousEndValue == newEndValue) {
             return;
         }
@@ -519,7 +615,7 @@
                 child.getTranslationX(), newEndValue);
         Interpolator customInterpolator = properties.getCustomInterpolator(child,
                 View.TRANSLATION_X);
-        Interpolator interpolator =  customInterpolator != null ? customInterpolator
+        Interpolator interpolator = customInterpolator != null ? customInterpolator
                 : Interpolators.FAST_OUT_SLOW_IN;
         animator.setInterpolator(interpolator);
         long newDuration = cancelAnimatorAndGetNewDuration(properties.duration, previousAnimator);
@@ -553,9 +649,9 @@
     }
 
     private void startYTranslationAnimation(final View child, AnimationProperties properties) {
-        Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Y);
-        Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Y);
-        float newEndValue = this.yTranslation;
+        Float previousStartValue = getChildTag(child, TAG_START_TRANSLATION_Y);
+        Float previousEndValue = getChildTag(child, TAG_END_TRANSLATION_Y);
+        float newEndValue = this.mYTranslation;
         if (previousEndValue != null && previousEndValue == newEndValue) {
             return;
         }
@@ -585,7 +681,7 @@
                 child.getTranslationY(), newEndValue);
         Interpolator customInterpolator = properties.getCustomInterpolator(child,
                 View.TRANSLATION_Y);
-        Interpolator interpolator =  customInterpolator != null ? customInterpolator
+        Interpolator interpolator = customInterpolator != null ? customInterpolator
                 : Interpolators.FAST_OUT_SLOW_IN;
         animator.setInterpolator(interpolator);
         long newDuration = cancelAnimatorAndGetNewDuration(properties.duration, previousAnimator);
@@ -644,7 +740,7 @@
     /**
      * Cancel the previous animator and get the duration of the new animation.
      *
-     * @param duration the new duration
+     * @param duration         the new duration
      * @param previousAnimator the animator which was running before
      * @return the new duration
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 5a70d89..9767103 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -211,11 +211,11 @@
             canvas.drawLine(end, 0, end, height, paint);
 
             paint.setColor(Color.GREEN);
-            int lastIcon = (int) mLastVisibleIconState.xTranslation;
+            int lastIcon = (int) mLastVisibleIconState.getXTranslation();
             canvas.drawLine(lastIcon, 0, lastIcon, height, paint);
 
             if (mFirstVisibleIconState != null) {
-                int firstIcon = (int) mFirstVisibleIconState.xTranslation;
+                int firstIcon = (int) mFirstVisibleIconState.getXTranslation();
                 canvas.drawLine(firstIcon, 0, firstIcon, height, paint);
             }
 
@@ -413,7 +413,7 @@
             View view = getChildAt(i);
             ViewState iconState = mIconStates.get(view);
             iconState.initFrom(view);
-            iconState.alpha = mIsolatedIcon == null || view == mIsolatedIcon ? 1.0f : 0.0f;
+            iconState.setAlpha(mIsolatedIcon == null || view == mIsolatedIcon ? 1.0f : 0.0f);
             iconState.hidden = false;
         }
     }
@@ -467,7 +467,7 @@
                 // We only modify the xTranslation if it's fully inside of the container
                 // since during the transition to the shelf, the translations are controlled
                 // from the outside
-                iconState.xTranslation = translationX;
+                iconState.setXTranslation(translationX);
             }
             if (mFirstVisibleIconState == null) {
                 mFirstVisibleIconState = iconState;
@@ -501,7 +501,7 @@
                 View view = getChildAt(i);
                 IconState iconState = mIconStates.get(view);
                 int dotWidth = mStaticDotDiameter + mDotPadding;
-                iconState.xTranslation = translationX;
+                iconState.setXTranslation(translationX);
                 if (mNumDots < MAX_DOTS) {
                     if (mNumDots == 0 && iconState.iconAppearAmount < 0.8f) {
                         iconState.visibleState = StatusBarIconView.STATE_ICON;
@@ -525,7 +525,8 @@
             for (int i = 0; i < childCount; i++) {
                 View view = getChildAt(i);
                 IconState iconState = mIconStates.get(view);
-                iconState.xTranslation = getWidth() - iconState.xTranslation - view.getWidth();
+                iconState.setXTranslation(
+                        getWidth() - iconState.getXTranslation() - view.getWidth());
             }
         }
         if (mIsolatedIcon != null) {
@@ -533,8 +534,8 @@
             if (iconState != null) {
                 // Most of the time the icon isn't yet added when this is called but only happening
                 // later
-                iconState.xTranslation = mIsolatedIconLocation.left - mAbsolutePosition[0]
-                        - (1 - mIsolatedIcon.getIconScale()) * mIsolatedIcon.getWidth() / 2.0f;
+                iconState.setXTranslation(mIsolatedIconLocation.left - mAbsolutePosition[0]
+                        - (1 - mIsolatedIcon.getIconScale()) * mIsolatedIcon.getWidth() / 2.0f);
                 iconState.visibleState = StatusBarIconView.STATE_ICON;
             }
         }
@@ -609,8 +610,10 @@
             return 0;
         }
 
-        int translation = (int) (isLayoutRtl() ? getWidth() - mLastVisibleIconState.xTranslation
-                : mLastVisibleIconState.xTranslation + mIconSize);
+        int translation = (int) (isLayoutRtl()
+                ? getWidth() - mLastVisibleIconState.getXTranslation()
+                : mLastVisibleIconState.getXTranslation() + mIconSize);
+
         // There's a chance that last translation goes beyond the edge maybe
         return Math.min(getWidth(), translation);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index d464acb..26c1767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -337,7 +337,7 @@
             // without cutting off the child view.
             translationX -= getViewTotalWidth(child);
             childState.visibleState = STATE_ICON;
-            childState.xTranslation = translationX;
+            childState.setXTranslation(translationX);
             mLayoutStates.add(0, childState);
 
             // Shift translationX over by mIconSpacing for the next view.
@@ -354,13 +354,13 @@
         for (int i = totalVisible - 1; i >= 0; i--) {
             StatusIconState state = mLayoutStates.get(i);
             // Allow room for underflow if we found we need it in onMeasure
-            if (mNeedsUnderflow && (state.xTranslation < (contentStart + mUnderflowWidth))||
-                    (mShouldRestrictIcons && visible >= maxVisible)) {
+            if (mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth))
+                    || (mShouldRestrictIcons && (visible >= maxVisible))) {
                 firstUnderflowIndex = i;
                 break;
             }
             mUnderflowStart = (int) Math.max(
-                    contentStart, state.xTranslation - mUnderflowWidth - mIconSpacing);
+                    contentStart, state.getXTranslation() - mUnderflowWidth - mIconSpacing);
             visible++;
         }
 
@@ -371,7 +371,7 @@
             for (int i = firstUnderflowIndex; i >= 0; i--) {
                 StatusIconState state = mLayoutStates.get(i);
                 if (totalDots < MAX_DOTS) {
-                    state.xTranslation = dotOffset;
+                    state.setXTranslation(dotOffset);
                     state.visibleState = STATE_DOT;
                     dotOffset -= dotWidth;
                     totalDots++;
@@ -386,7 +386,7 @@
             for (int i = 0; i < childCount; i++) {
                 View child = getChildAt(i);
                 StatusIconState state = getViewStateFromChild(child);
-                state.xTranslation = width - state.xTranslation - child.getWidth();
+                state.setXTranslation(width - state.getXTranslation() - child.getWidth());
             }
         }
     }
@@ -410,7 +410,7 @@
             }
 
             vs.initFrom(child);
-            vs.alpha = 1.0f;
+            vs.setAlpha(1.0f);
             vs.hidden = false;
         }
     }
@@ -442,7 +442,7 @@
                 parentWidth = ((View) view.getParent()).getWidth();
             }
 
-            float currentDistanceToEnd = parentWidth - xTranslation;
+            float currentDistanceToEnd = parentWidth - getXTranslation();
 
             if (!(view instanceof StatusIconDisplayable)) {
                 return;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
new file mode 100644
index 0000000..da543d4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification.stack
+
+import android.testing.AndroidTestingRunner
+import android.util.Log
+import android.util.Log.TerribleFailureHandler
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import kotlin.math.log2
+import kotlin.math.sqrt
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ViewStateTest : SysuiTestCase() {
+    private val viewState = ViewState()
+
+    private var wtfHandler: TerribleFailureHandler? = null
+    private var wtfCount = 0
+
+    @Suppress("DIVISION_BY_ZERO")
+    @Test
+    fun testWtfs() {
+        interceptWtfs()
+
+        // Setting valid values doesn't cause any wtfs.
+        viewState.alpha = 0.1f
+        viewState.xTranslation = 0f
+        viewState.yTranslation = 10f
+        viewState.zTranslation = 20f
+        viewState.scaleX = 0.5f
+        viewState.scaleY = 0.25f
+
+        expectWtfs(0)
+
+        // Setting NaN values leads to wtfs being logged, and the value not being changed.
+        viewState.alpha = 0.0f / 0.0f
+        expectWtfs(1)
+        Assert.assertEquals(viewState.alpha, 0.1f)
+
+        viewState.xTranslation = Float.NaN
+        expectWtfs(2)
+        Assert.assertEquals(viewState.xTranslation, 0f)
+
+        viewState.yTranslation = log2(-10.0).toFloat()
+        expectWtfs(3)
+        Assert.assertEquals(viewState.yTranslation, 10f)
+
+        viewState.zTranslation = sqrt(-1.0).toFloat()
+        expectWtfs(4)
+        Assert.assertEquals(viewState.zTranslation, 20f)
+
+        viewState.scaleX = Float.POSITIVE_INFINITY + Float.NEGATIVE_INFINITY
+        expectWtfs(5)
+        Assert.assertEquals(viewState.scaleX, 0.5f)
+
+        viewState.scaleY = Float.POSITIVE_INFINITY * 0
+        expectWtfs(6)
+        Assert.assertEquals(viewState.scaleY, 0.25f)
+    }
+
+    private fun interceptWtfs() {
+        wtfCount = 0
+        wtfHandler =
+            Log.setWtfHandler { _: String?, e: Log.TerribleFailure, _: Boolean ->
+                Log.e("ViewStateTest", "Observed WTF: $e")
+                wtfCount++
+            }
+    }
+
+    private fun expectWtfs(expectedWtfCount: Int) {
+        Assert.assertNotNull(wtfHandler)
+        Assert.assertEquals(expectedWtfCount, wtfCount)
+    }
+}