summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Johannes Gallmann <gallmann@google.com> 2022-12-21 14:15:48 +0100
committer Johannes Gallmann <gallmann@google.com> 2022-12-21 14:15:48 +0100
commitcd562bb9bef40b2225d111d19108c5a06e52f24d (patch)
tree1841f4e72782692fa34701d0222fb5b77b6e637d
parent8118ea49efaa687a1734fdeb4f69c9a728ae2d6e (diff)
Reapply changes of inline reply CL
Just before merging ag/20462188, I had to change the flag ID because there was a conflict. Unfortunately, a very stupid mistake happened during this minor fix. I changed the flag ID in an old version of the CL and uploaded that old version (as can be seen in the changelog of the latest uploaded patch in that CL). Therefore, this CL reapplies all changes that were undone in the latest patchset of ag/20462188 and ag/20462188. Bug: 174148361 Test: atest RemoteInputViewTest, Manual, i.e. posting various types of Notifications from the Notify2-RVC application with a reply action added to them. Then observing the animations visually and analyzing frames from screen recordings. Change-Id: I0f9deb15e8fae361ef6ebb6ff0119d2ee6888372
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java110
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java3
3 files changed, 61 insertions, 55 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 351603700f98..80a891319f6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -464,9 +464,6 @@ public class NotificationRemoteInputManager implements Dumpable {
riv.getController().setRemoteInputs(inputs);
riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
- if (parent != null) {
- riv.setDefocusTargetHeight(parent.getHeight());
- }
riv.focusAnimated(parent);
if (userMessageContent != null) {
riv.setEditTextContent(userMessageContent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index d8a8c5de90d7..c9ed0cb4155d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -47,6 +47,7 @@ import android.view.OnReceiveContentListener;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
import android.view.ViewRootImpl;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
@@ -57,7 +58,6 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
-import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -133,6 +133,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
private RevealParams mRevealParams;
private Rect mContentBackgroundBounds;
private boolean mIsFocusAnimationFlagActive;
+ private boolean mIsAnimatingAppearance = false;
// TODO(b/193539698): move these to a Controller
private RemoteInputController mController;
@@ -142,10 +143,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
private boolean mSending;
private NotificationViewWrapper mWrapper;
- private Integer mDefocusTargetHeight = null;
- private boolean mIsAnimatingAppearance = false;
-
-
// TODO(b/193539698): remove this; views shouldn't have access to their controller, and places
// that need the controller shouldn't have access to the view
private RemoteInputViewController mViewController;
@@ -423,18 +420,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
return mIsAnimatingAppearance;
}
- /**
- * View will ensure to use at most the provided defocusTargetHeight, when defocusing animated.
- * This is to ensure that the parent can resize itself to the targetHeight while the defocus
- * animation of the RemoteInputView is running.
- *
- * @param defocusTargetHeight The target height the parent will resize itself to. If null, the
- * RemoteInputView will not resize itself.
- */
- public void setDefocusTargetHeight(Integer defocusTargetHeight) {
- mDefocusTargetHeight = defocusTargetHeight;
- }
-
@VisibleForTesting
void onDefocus(boolean animate, boolean logClose) {
mController.removeRemoteInput(mEntry, mToken);
@@ -443,35 +428,28 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
// During removal, we get reattached and lose focus. Not hiding in that
// case to prevent flicker.
if (!mRemoved) {
- if (animate && mIsFocusAnimationFlagActive) {
- Animator animator = getDefocusAnimator();
-
- // When defocusing, the notification needs to shrink. Therefore, we need to free
- // up the space that is needed for the RemoteInputView. This is done by setting
- // a negative top margin of the height difference of the RemoteInputView and its
- // sibling (the actions_container_layout containing the Reply button)
- if (mDefocusTargetHeight != null && mDefocusTargetHeight < getHeight()
- && mDefocusTargetHeight >= 0
- && getLayoutParams() instanceof FrameLayout.LayoutParams) {
- int heightToShrink = getHeight() - mDefocusTargetHeight;
- FrameLayout.LayoutParams layoutParams =
- (FrameLayout.LayoutParams) getLayoutParams();
- layoutParams.topMargin = -heightToShrink;
- setLayoutParams(layoutParams);
- ((ViewGroup) getParent().getParent()).setClipChildren(false);
- }
+ ViewGroup parent = (ViewGroup) getParent();
+ if (animate && parent != null && mIsFocusAnimationFlagActive) {
+
+
+ ViewGroup grandParent = (ViewGroup) parent.getParent();
+ ViewGroupOverlay overlay = parent.getOverlay();
+
+ // After adding this RemoteInputView to the overlay of the parent (and thus removing
+ // it from the parent itself), the parent will shrink in height. This causes the
+ // overlay to be moved. To correct the position of the overlay we need to offset it.
+ int overlayOffsetY = getMaxSiblingHeight() - getHeight();
+ overlay.add(this);
+ if (grandParent != null) grandParent.setClipChildren(false);
+ Animator animator = getDefocusAnimator(overlayOffsetY);
+ View self = this;
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- //reset top margin after the animation
- if (getLayoutParams() instanceof FrameLayout.LayoutParams) {
- FrameLayout.LayoutParams layoutParams =
- (FrameLayout.LayoutParams) getLayoutParams();
- layoutParams.topMargin = 0;
- setLayoutParams(layoutParams);
- ((ViewGroup) getParent().getParent()).setClipChildren(true);
- }
+ overlay.remove(self);
+ parent.addView(self);
+ if (grandParent != null) grandParent.setClipChildren(true);
setVisibility(GONE);
if (mWrapper != null) {
mWrapper.setRemoteInputVisible(false);
@@ -609,7 +587,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
}
/**
- * Sets whether the feature flag for the updated inline reply animation is active or not.
+ * Sets whether the feature flag for the revised inline reply animation is active or not.
* @param active
*/
public void setIsFocusAnimationFlagActive(boolean active) {
@@ -846,6 +824,23 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
}
}
+ /**
+ * @return max sibling height (0 in case of no siblings)
+ */
+ public int getMaxSiblingHeight() {
+ ViewGroup parentView = (ViewGroup) getParent();
+ int maxHeight = 0;
+ if (parentView == null) return 0;
+ for (int i = 0; i < parentView.getChildCount(); i++) {
+ View siblingView = parentView.getChildAt(i);
+ if (siblingView != this) maxHeight = Math.max(maxHeight, siblingView.getHeight());
+ }
+ return maxHeight;
+ }
+
+ /**
+ * Creates an animator for the focus animation.
+ */
private Animator getFocusAnimator(View crossFadeView) {
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
@@ -854,7 +849,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(FOCUS_ANIMATION_MIN_SCALE, 1f);
scaleAnimator.addUpdateListener(valueAnimator -> {
- setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
+ setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue(), 0);
});
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
@@ -875,21 +870,26 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
return animatorSet;
}
- private Animator getDefocusAnimator() {
+ /**
+ * Creates an animator for the defocus animation.
+ *
+ * @param offsetY The RemoteInputView will be offset by offsetY during the animation
+ */
+ private Animator getDefocusAnimator(int offsetY) {
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
scaleAnimator.addUpdateListener(valueAnimator -> {
- setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue());
+ setFocusAnimationScaleY((float) scaleAnimator.getAnimatedValue(), offsetY);
});
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
scaleAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
- setFocusAnimationScaleY(1f);
+ setFocusAnimationScaleY(1f /* scaleY */, 0 /* verticalOffset */);
}
});
@@ -901,15 +901,21 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
/**
* Sets affected view properties for a vertical scale animation
*
- * @param scaleY desired vertical view scale
+ * @param scaleY desired vertical view scale
+ * @param verticalOffset vertical offset to apply to the RemoteInputView during the animation
*/
- private void setFocusAnimationScaleY(float scaleY) {
+ private void setFocusAnimationScaleY(float scaleY, int verticalOffset) {
int verticalBoundOffset = (int) ((1f - scaleY) * 0.5f * mContentView.getHeight());
- mContentBackgroundBounds = new Rect(0, verticalBoundOffset, mContentView.getWidth(),
+ Rect contentBackgroundBounds = new Rect(0, verticalBoundOffset, mContentView.getWidth(),
mContentView.getHeight() - verticalBoundOffset);
- mContentBackground.setBounds(mContentBackgroundBounds);
+ mContentBackground.setBounds(contentBackgroundBounds);
mContentView.setBackground(mContentBackground);
- setTranslationY(verticalBoundOffset);
+ if (scaleY == 1f) {
+ mContentBackgroundBounds = null;
+ } else {
+ mContentBackgroundBounds = contentBackgroundBounds;
+ }
+ setTranslationY(verticalBoundOffset + verticalOffset);
}
/** Handler for button click on send action in IME. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 2c472049cdda..4b32ee262cdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -55,6 +55,7 @@ import android.view.ViewRootImpl;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
@@ -414,7 +415,9 @@ public class RemoteInputViewTest extends SysuiTestCase {
mDependency,
TestableLooper.get(this));
ExpandableNotificationRow row = helper.createRow();
+ FrameLayout remoteInputViewParent = new FrameLayout(mContext);
RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
+ remoteInputViewParent.addView(view);
bindController(view, row.getEntry());
// Start defocus animation