diff options
7 files changed, 127 insertions, 14 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 10fd8b579b16..30392d2c9d85 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -34,6 +34,9 @@ <dimen name="navigation_handle_bottom">10dp</dimen> <dimen name="navigation_handle_sample_horizontal_margin">10dp</dimen> <dimen name="navigation_home_handle_width">108dp</dimen> + <!-- Used while animating the navbar during a long press. --> + <dimen name="navigation_home_handle_additional_width_for_animation">20dp</dimen> + <dimen name="navigation_home_handle_additional_height_for_animation">4dp</dimen> <!-- Size of the nav bar edge panels, should be greater to the edge sensitivity + the drag threshold --> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl index dc34ef754825..26e785d9a704 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl @@ -144,5 +144,15 @@ interface ISystemUiProxy { */ oneway void onStatusBarTrackpadEvent(in MotionEvent event) = 52; - // Next id = 54 + /** + * Animate the nav bar being long-pressed. + * + * @param isTouchDown {@code true} if the button is starting to be pressed ({@code false} if + * released or canceled) + * @param durationMs how long the animation should take (for the {@code isTouchDown} case, this + * should be the same as the amount of time to trigger a long-press) + */ + oneway void animateNavBarLongPress(boolean isTouchDown, long durationMs) = 54; + + // Next id = 55 } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index ad1c77d05534..a985236cb38e 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -112,7 +112,6 @@ import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.LatencyTracker; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Gefingerpoken; -import com.android.systemui.res.R; import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.DisplayId; @@ -130,6 +129,7 @@ import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.res.R; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; @@ -399,6 +399,11 @@ public class NavigationBar extends ViewController<NavigationBarView> implements } @Override + public void animateNavBarLongPress(boolean isTouchDown, long durationMs) { + mView.getHomeHandle().animateLongPress(isTouchDown, durationMs); + } + + @Override public void onHomeRotationEnabled(boolean enabled) { mView.getRotationButtonController().setHomeRotationEnabled(enabled); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java index 10084bd4ccad..5fe830e6e442 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java @@ -247,6 +247,14 @@ public class ButtonDispatcher { } } + public void animateLongPress(boolean isTouchDown, long durationMs) { + for (int i = 0; i < mViews.size(); i++) { + if (mViews.get(i) instanceof ButtonInterface) { + ((ButtonInterface) mViews.get(i)).animateLongPress(isTouchDown, durationMs); + } + } + } + public void setLongClickable(boolean isLongClickable) { mLongClickable = isLongClickable; final int N = mViews.size(); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java index 8d291ddf5f19..356b2f7c7cb8 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java @@ -30,4 +30,14 @@ public interface ButtonInterface { void setDarkIntensity(float intensity); void setDelayTouchFeedback(boolean shouldDelay); + + /** + * Animate the button being long-pressed. + * + * @param isTouchDown {@code true} if the button is starting to be pressed ({@code false} if + * released or canceled) + * @param durationMs how long the animation should take (for the {@code isTouchDown} case, this + * should be the same as the amount of time to trigger a long-press) + */ + default void animateLongPress(boolean isTouchDown, long durationMs) {} } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java index 5a22c385cb51..5bfc7dc5f7ae 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java @@ -17,6 +17,7 @@ package com.android.systemui.navigationbar.gestural; import android.animation.ArgbEvaluator; +import android.animation.ObjectAnimator; import android.annotation.ColorInt; import android.content.Context; import android.content.res.Resources; @@ -24,12 +25,15 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.FloatProperty; import android.view.ContextThemeWrapper; import android.view.View; +import android.view.animation.Interpolator; +import com.android.app.animation.Interpolators; import com.android.settingslib.Utils; -import com.android.systemui.res.R; import com.android.systemui.navigationbar.buttons.ButtonInterface; +import com.android.systemui.res.R; public class NavigationHandle extends View implements ButtonInterface { @@ -38,8 +42,26 @@ public class NavigationHandle extends View implements ButtonInterface { private @ColorInt final int mDarkColor; protected final float mRadius; protected final float mBottom; + private final float mAdditionalWidthForAnimation; + private final float mAdditionalHeightForAnimation; private boolean mRequiresInvalidate; + private ObjectAnimator mPulseAnimator = null; + private float mPulseAnimationProgress; + + private static final FloatProperty<NavigationHandle> PULSE_ANIMATION_PROGRESS = + new FloatProperty<>("pulseAnimationProgress") { + @Override + public Float get(NavigationHandle controller) { + return controller.getPulseAnimationProgress(); + } + + @Override + public void setValue(NavigationHandle controller, float progress) { + controller.setPulseAnimationProgress(progress); + } + }; + public NavigationHandle(Context context) { this(context, null); } @@ -49,6 +71,10 @@ public class NavigationHandle extends View implements ButtonInterface { final Resources res = context.getResources(); mRadius = res.getDimension(R.dimen.navigation_handle_radius); mBottom = res.getDimension(R.dimen.navigation_handle_bottom); + mAdditionalWidthForAnimation = + res.getDimension(R.dimen.navigation_home_handle_additional_width_for_animation); + mAdditionalHeightForAnimation = + res.getDimension(R.dimen.navigation_home_handle_additional_height_for_animation); final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme); final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme); @@ -75,23 +101,24 @@ public class NavigationHandle extends View implements ButtonInterface { // Draw that bar int navHeight = getHeight(); - float height = mRadius * 2; - int width = getWidth(); - float y = (navHeight - mBottom - height); - canvas.drawRoundRect(0, y, width, y + height, mRadius, mRadius, mPaint); + float additionalHeight = mAdditionalHeightForAnimation * mPulseAnimationProgress; + float height = mRadius * 2 + additionalHeight; + float additionalWidth = mAdditionalWidthForAnimation * mPulseAnimationProgress; + float width = getWidth() + additionalWidth; + float x = -(additionalWidth / 2); + float y = navHeight - mBottom - height - (additionalHeight / 2); + float adjustedRadius = height / 2; + canvas.drawRoundRect(x, y, width, y + height, adjustedRadius, adjustedRadius, mPaint); } @Override - public void setImageDrawable(Drawable drawable) { - } + public void setImageDrawable(Drawable drawable) {} @Override - public void abortCurrentGesture() { - } + public void abortCurrentGesture() {} @Override - public void setVertical(boolean vertical) { - } + public void setVertical(boolean vertical) {} @Override public void setDarkIntensity(float intensity) { @@ -108,6 +135,43 @@ public class NavigationHandle extends View implements ButtonInterface { } @Override - public void setDelayTouchFeedback(boolean shouldDelay) { + public void setDelayTouchFeedback(boolean shouldDelay) {} + + @Override + public void animateLongPress(boolean isTouchDown, long durationMs) { + if (mPulseAnimator != null) { + mPulseAnimator.cancel(); + } + + Interpolator interpolator; + if (isTouchDown) { + // For now we animate the navbar expanding and contracting so that the navbar is the + // original size by the end of {@code duration}. This is because a screenshot is taken + // at that point and we don't want to capture the larger navbar. + // TODO(b/306400785): Determine a way to exclude navbar from the screenshot. + + // Fraction of the touch down animation to expand; remaining is used to contract again. + float expandFraction = 0.9f; + interpolator = t -> t <= expandFraction + ? Interpolators.clampToProgress(Interpolators.LEGACY, t, 0, expandFraction) + : 1 - Interpolators.clampToProgress( + Interpolators.LINEAR, t, expandFraction, 1); + } else { + interpolator = Interpolators.LEGACY_DECELERATE; + } + + mPulseAnimator = + ObjectAnimator.ofFloat(this, PULSE_ANIMATION_PROGRESS, isTouchDown ? 1 : 0); + mPulseAnimator.setDuration(durationMs).setInterpolator(interpolator); + mPulseAnimator.start(); + } + + private void setPulseAnimationProgress(float pulseAnimationProgress) { + mPulseAnimationProgress = pulseAnimationProgress; + invalidate(); + } + + private float getPulseAnimationProgress() { + return mPulseAnimationProgress; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 4465504d12f5..1334660ea4d5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -245,6 +245,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis } @Override + public void animateNavBarLongPress(boolean isTouchDown, long durationMs) { + verifyCallerAndClearCallingIdentityPostMain("animateNavBarLongPress", () -> + notifyAnimateNavBarLongPress(isTouchDown, durationMs)); + } + + @Override public void onBackPressed() { verifyCallerAndClearCallingIdentityPostMain("onBackPressed", () -> { sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); @@ -914,6 +920,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis } } + private void notifyAnimateNavBarLongPress(boolean isTouchDown, long durationMs) { + for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) { + mConnectionCallbacks.get(i).animateNavBarLongPress(isTouchDown, durationMs); + } + } + public void notifyAssistantVisibilityChanged(float visibility) { try { if (mOverviewProxy != null) { @@ -1058,6 +1070,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis default void onAssistantGestureCompletion(float velocity) {} default void startAssistant(Bundle bundle) {} default void setAssistantOverridesRequested(int[] invocationTypes) {} + default void animateNavBarLongPress(boolean isTouchDown, long durationMs) {} } /** |