diff options
| author | 2019-09-25 06:12:08 +0000 | |
|---|---|---|
| committer | 2019-09-25 06:12:08 +0000 | |
| commit | ad456e85a27d870fb03ae80947ec17eaa9e05345 (patch) | |
| tree | f9590836f55da0ca7b078c0efe7af3fcfc50301f | |
| parent | f82d3672b1960924c71bc23ebf1ca06ecae066ca (diff) | |
| parent | 87af538d38a8815ef495a33d7b3c29cc45ad2d33 (diff) | |
Merge "Move assist handles from ScreenDecorations to navigation bar"
12 files changed, 388 insertions, 398 deletions
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml index 8ba4c9c05ba6..ba6b6956f187 100644 --- a/packages/SystemUI/res/layout/navigation_bar.xml +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -24,6 +24,21 @@ android:layout_width="match_parent" android:background="@drawable/system_bar_background"> + <com.android.systemui.CornerHandleView + android:id="@+id/assist_hint_left" + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_gravity="left|bottom" + android:rotation="270" + android:visibility="gone"/> + <com.android.systemui.CornerHandleView + android:id="@+id/assist_hint_right" + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_gravity="right|bottom" + android:rotation="180" + android:visibility="gone"/> + <com.android.systemui.statusbar.phone.NavigationBarInflaterView android:id="@+id/navigation_inflater" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml index b409c8f2ba5a..1849068d91b8 100644 --- a/packages/SystemUI/res/layout/rounded_corners.xml +++ b/packages/SystemUI/res/layout/rounded_corners.xml @@ -18,18 +18,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> - <com.android.systemui.CornerHandleView - android:id="@+id/assist_hint_left" - android:layout_width="36dp" - android:layout_height="36dp" - android:layout_gravity="left|top" - android:visibility="gone"/> - <com.android.systemui.CornerHandleView - android:id="@+id/assist_hint_right" - android:layout_width="36dp" - android:layout_height="36dp" - android:layout_gravity="right|bottom" - android:visibility="gone"/> <ImageView android:id="@+id/left" android:layout_width="12dp" diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index f38b4f259c88..3e068b0a0964 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -25,9 +25,6 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static com.android.systemui.tuner.TunablePadding.FLAG_END; import static com.android.systemui.tuner.TunablePadding.FLAG_START; -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.annotation.Dimension; import android.app.ActivityManager; import android.app.Fragment; @@ -52,7 +49,6 @@ import android.os.SystemProperties; import android.provider.Settings.Secure; import android.util.DisplayMetrics; import android.util.Log; -import android.util.MathUtils; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; @@ -64,9 +60,6 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewTreeObserver; import android.view.WindowManager; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.Interpolator; -import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; @@ -78,10 +71,7 @@ import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.SecureSetting; -import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; -import com.android.systemui.statusbar.phone.NavigationBarTransitions; -import com.android.systemui.statusbar.phone.NavigationModeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.tuner.TunablePadding; import com.android.systemui.tuner.TunerService; @@ -95,8 +85,7 @@ import java.util.List; * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout) * for antialiasing and emulation purposes. */ -public class ScreenDecorations extends SystemUI implements Tunable, - NavigationBarTransitions.DarkIntensityListener { +public class ScreenDecorations extends SystemUI implements Tunable { private static final boolean DEBUG = false; private static final String TAG = "ScreenDecorations"; @@ -120,15 +109,11 @@ public class ScreenDecorations extends SystemUI implements Tunable, private float mDensity; private WindowManager mWindowManager; private int mRotation; - private boolean mAssistHintVisible; private DisplayCutoutView mCutoutTop; private DisplayCutoutView mCutoutBottom; private SecureSetting mColorInversionSetting; private boolean mPendingRotationChange; private Handler mHandler; - private boolean mAssistHintBlocked = false; - private boolean mIsReceivingNavBarColor = false; - private boolean mInGesturalMode; /** * Converts a set of {@link Rect}s into a {@link Region} @@ -153,160 +138,6 @@ public class ScreenDecorations extends SystemUI implements Tunable, mHandler.post(this::startOnScreenDecorationsThread); setupStatusBarPaddingIfNeeded(); putComponent(ScreenDecorations.class, this); - mInGesturalMode = QuickStepContract.isGesturalMode( - Dependency.get(NavigationModeController.class) - .addListener(this::handleNavigationModeChange)); - } - - @VisibleForTesting - void handleNavigationModeChange(int navigationMode) { - if (!mHandler.getLooper().isCurrentThread()) { - mHandler.post(() -> handleNavigationModeChange(navigationMode)); - return; - } - boolean inGesturalMode = QuickStepContract.isGesturalMode(navigationMode); - if (mInGesturalMode != inGesturalMode) { - mInGesturalMode = inGesturalMode; - - if (mInGesturalMode && mOverlay == null) { - setupDecorations(); - if (mOverlay != null) { - updateLayoutParams(); - } - } - } - } - - /** - * Returns an animator that animates the given view from start to end over durationMs. Start and - * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an - * overshoot. - */ - Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs, - Interpolator interpolator) { - // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1]. - float scaleStart = MathUtils.lerp(2f, 1f, start); - float scaleEnd = MathUtils.lerp(2f, 1f, end); - Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd); - Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd); - float translationStart = MathUtils.lerp(0.2f, 0f, start); - float translationEnd = MathUtils.lerp(0.2f, 0f, end); - int xDirection = isLeft ? -1 : 1; - Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, - xDirection * translationStart * view.getWidth(), - xDirection * translationEnd * view.getWidth()); - Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, - translationStart * view.getHeight(), translationEnd * view.getHeight()); - - AnimatorSet set = new AnimatorSet(); - set.play(scaleX).with(scaleY); - set.play(scaleX).with(translateX); - set.play(scaleX).with(translateY); - set.setDuration(durationMs); - set.setInterpolator(interpolator); - return set; - } - - private void fade(View view, boolean fadeIn, boolean isLeft) { - if (fadeIn) { - view.animate().cancel(); - view.setAlpha(1f); - view.setVisibility(View.VISIBLE); - - // A piecewise spring-like interpolation. - // End value in one animator call must match the start value in the next, otherwise - // there will be a discontinuity. - AnimatorSet anim = new AnimatorSet(); - Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750, - new PathInterpolator(0, 0.45f, .67f, 1f)); - Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f); - Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400, - secondInterpolator); - Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400, - secondInterpolator); - Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400, - secondInterpolator); - anim.play(first).before(second); - anim.play(second).before(third); - anim.play(third).before(fourth); - anim.start(); - } else { - view.animate().cancel(); - view.animate() - .setInterpolator(new AccelerateInterpolator(1.5f)) - .setDuration(250) - .alpha(0f); - } - - } - - /** - * Controls the visibility of the assist gesture handles. - * - * @param visible whether the handles should be shown - */ - public void setAssistHintVisible(boolean visible) { - if (!mHandler.getLooper().isCurrentThread()) { - mHandler.post(() -> setAssistHintVisible(visible)); - return; - } - - if (mAssistHintBlocked && visible) { - if (VERBOSE) { - Log.v(TAG, "Assist hint blocked, cannot make it visible"); - } - return; - } - - if (mOverlay == null || mBottomOverlay == null) { - return; - } - - if (mAssistHintVisible != visible) { - mAssistHintVisible = visible; - - CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left); - CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right); - CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById( - R.id.assist_hint_left); - CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById( - R.id.assist_hint_right); - - switch (mRotation) { - case RotationUtils.ROTATION_NONE: - fade(assistHintBottomLeft, mAssistHintVisible, /* isLeft = */ true); - fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false); - break; - case RotationUtils.ROTATION_LANDSCAPE: - fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true); - fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false); - break; - case RotationUtils.ROTATION_SEASCAPE: - fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false); - fade(assistHintBottomLeft, mAssistHintVisible, /* isLeft = */ true); - break; - case RotationUtils.ROTATION_UPSIDE_DOWN: - fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false); - fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true); - break; - } - } - updateWindowVisibilities(); - } - - /** - * Prevents the assist hint from becoming visible even if `mAssistHintVisible` is true. - */ - public void setAssistHintBlocked(boolean blocked) { - if (!mHandler.getLooper().isCurrentThread()) { - mHandler.post(() -> setAssistHintBlocked(blocked)); - return; - } - - mAssistHintBlocked = blocked; - if (mAssistHintVisible && mAssistHintBlocked) { - hideAssistHandles(); - } } @VisibleForTesting @@ -316,15 +147,11 @@ public class ScreenDecorations extends SystemUI implements Tunable, return thread.getThreadHandler(); } - private boolean shouldHostHandles() { - return mInGesturalMode; - } - private void startOnScreenDecorationsThread() { mRotation = RotationUtils.getExactRotation(mContext); mWindowManager = mContext.getSystemService(WindowManager.class); updateRoundedCornerRadii(); - if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) { + if (hasRoundedCorners() || shouldDrawCutout()) { setupDecorations(); } @@ -501,26 +328,10 @@ public class ScreenDecorations extends SystemUI implements Tunable, if (mOverlay != null) { updateLayoutParams(); updateViews(); - if (mAssistHintVisible) { - // If assist handles are visible, hide them without animation and then make them - // show once again (with corrected rotation). - hideAssistHandles(); - setAssistHintVisible(true); - } } } } - private void hideAssistHandles() { - if (mOverlay != null && mBottomOverlay != null) { - mOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE); - mOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE); - mBottomOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE); - mBottomOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE); - mAssistHintVisible = false; - } - } - private void updateRoundedCornerRadii() { final int newRoundedDefault = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.rounded_corner_radius); @@ -569,52 +380,12 @@ public class ScreenDecorations extends SystemUI implements Tunable, updateView(bottomRight, Gravity.TOP | Gravity.LEFT, 0); } - updateAssistantHandleViews(); mCutoutTop.setRotation(mRotation); mCutoutBottom.setRotation(mRotation); updateWindowVisibilities(); } - private void updateAssistantHandleViews() { - View assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left); - View assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right); - View assistHintBottomLeft = mBottomOverlay.findViewById(R.id.assist_hint_left); - View assistHintBottomRight = mBottomOverlay.findViewById(R.id.assist_hint_right); - - final int assistHintVisibility = mAssistHintVisible ? View.VISIBLE : View.INVISIBLE; - - if (mRotation == RotationUtils.ROTATION_NONE) { - assistHintTopLeft.setVisibility(View.GONE); - assistHintTopRight.setVisibility(View.GONE); - assistHintBottomLeft.setVisibility(assistHintVisibility); - assistHintBottomRight.setVisibility(assistHintVisibility); - updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270); - updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180); - } else if (mRotation == RotationUtils.ROTATION_LANDSCAPE) { - assistHintTopLeft.setVisibility(View.GONE); - assistHintTopRight.setVisibility(assistHintVisibility); - assistHintBottomLeft.setVisibility(View.GONE); - assistHintBottomRight.setVisibility(assistHintVisibility); - updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.LEFT, 270); - updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180); - } else if (mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) { - assistHintTopLeft.setVisibility(assistHintVisibility); - assistHintTopRight.setVisibility(assistHintVisibility); - assistHintBottomLeft.setVisibility(View.GONE); - assistHintBottomRight.setVisibility(View.GONE); - updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.LEFT, 270); - updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.RIGHT, 180); - } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) { - assistHintTopLeft.setVisibility(assistHintVisibility); - assistHintTopRight.setVisibility(View.GONE); - assistHintBottomLeft.setVisibility(assistHintVisibility); - assistHintBottomRight.setVisibility(View.GONE); - updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.RIGHT, 180); - updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270); - } - } - private void updateView(View v, int gravity, int rotation) { ((FrameLayout.LayoutParams) v.getLayoutParams()).gravity = gravity; v.setRotation(rotation); @@ -629,10 +400,7 @@ public class ScreenDecorations extends SystemUI implements Tunable, boolean visibleForCutout = shouldDrawCutout() && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE; boolean visibleForRoundedCorners = hasRoundedCorners(); - boolean visibleForHandles = overlay.findViewById(R.id.assist_hint_left).getVisibility() - == View.VISIBLE || overlay.findViewById(R.id.assist_hint_right).getVisibility() - == View.VISIBLE; - overlay.setVisibility(visibleForCutout || visibleForRoundedCorners || visibleForHandles + overlay.setVisibility(visibleForCutout || visibleForRoundedCorners ? View.VISIBLE : View.GONE); } @@ -766,31 +534,6 @@ public class ScreenDecorations extends SystemUI implements Tunable, view.setLayoutParams(params); } - @Override - public void onDarkIntensity(float darkIntensity) { - if (!mHandler.getLooper().isCurrentThread()) { - mHandler.post(() -> onDarkIntensity(darkIntensity)); - return; - } - if (mOverlay != null) { - CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left); - CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right); - - assistHintTopLeft.updateDarkness(darkIntensity); - assistHintTopRight.updateDarkness(darkIntensity); - } - - if (mBottomOverlay != null) { - CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById( - R.id.assist_hint_left); - CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById( - R.id.assist_hint_right); - - assistHintBottomLeft.updateDarkness(darkIntensity); - assistHintBottomRight.updateDarkness(darkIntensity); - } - } - @VisibleForTesting static class TunablePaddingTagListener implements FragmentListener { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java index 9bdfa03408aa..a3b94fb1c8b0 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java @@ -32,7 +32,6 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.DumpController; import com.android.systemui.Dumpable; -import com.android.systemui.ScreenDecorations; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.NavigationModeController; @@ -71,7 +70,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac private final Handler mHandler; private final Runnable mHideHandles = this::hideHandles; private final Runnable mShowAndGo = this::showAndGoInternal; - private final Provider<ScreenDecorations> mScreenDecorations; + private final Provider<AssistHandleViewController> mAssistHandleViewController; private final PhenotypeHelper mPhenotypeHelper; private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap; @@ -90,7 +89,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac Context context, AssistUtils assistUtils, @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler, - Provider<ScreenDecorations> screenDecorations, + Provider<AssistHandleViewController> assistHandleViewController, PhenotypeHelper phenotypeHelper, Map<AssistHandleBehavior, BehaviorController> behaviorMap, NavigationModeController navigationModeController, @@ -98,7 +97,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac mContext = context; mAssistUtils = assistUtils; mHandler = handler; - mScreenDecorations = screenDecorations; + mAssistHandleViewController = assistHandleViewController; mPhenotypeHelper = phenotypeHelper; mBehaviorMap = behaviorMap; @@ -229,12 +228,13 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac } if (handlesUnblocked(ignoreThreshold)) { - ScreenDecorations screenDecorations = mScreenDecorations.get(); - if (screenDecorations == null) { - Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable"); + mHandlesShowing = true; + AssistHandleViewController assistHandleViewController = + mAssistHandleViewController.get(); + if (assistHandleViewController == null) { + Log.w(TAG, "Couldn't show handles, AssistHandleViewController unavailable"); } else { - mHandlesShowing = true; - screenDecorations.setAssistHintVisible(true); + assistHandleViewController.setAssistHintVisible(true); } } } @@ -244,13 +244,14 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac return; } - ScreenDecorations screenDecorations = mScreenDecorations.get(); - if (screenDecorations == null) { - Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable"); + mHandlesShowing = false; + mHandlesLastHiddenAt = SystemClock.elapsedRealtime(); + AssistHandleViewController assistHandleViewController = + mAssistHandleViewController.get(); + if (assistHandleViewController == null) { + Log.w(TAG, "Couldn't show handles, AssistHandleViewController unavailable"); } else { - mHandlesShowing = false; - mHandlesLastHiddenAt = SystemClock.elapsedRealtime(); - screenDecorations.setAssistHintVisible(false); + assistHandleViewController.setAssistHintVisible(false); } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java new file mode 100644 index 000000000000..f9ffb804f9f3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2019 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.assist; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.os.Handler; +import android.util.Log; +import android.util.MathUtils; +import android.view.View; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.PathInterpolator; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.CornerHandleView; +import com.android.systemui.R; +import com.android.systemui.statusbar.phone.NavigationBarTransitions; + +/** + * A class for managing Assistant handle show, hide and animation. + */ +public class AssistHandleViewController implements NavigationBarTransitions.DarkIntensityListener { + + private static final boolean DEBUG = false; + private static final String TAG = "AssistHandleViewController"; + + private Handler mHandler; + private CornerHandleView mAssistHintLeft; + private CornerHandleView mAssistHintRight; + + @VisibleForTesting + boolean mAssistHintVisible; + @VisibleForTesting + boolean mAssistHintBlocked = false; + + public AssistHandleViewController(Handler handler, View navBar) { + mHandler = handler; + mAssistHintLeft = navBar.findViewById(R.id.assist_hint_left); + mAssistHintRight = navBar.findViewById(R.id.assist_hint_right); + } + + @Override + public void onDarkIntensity(float darkIntensity) { + mAssistHintLeft.updateDarkness(darkIntensity); + mAssistHintRight.updateDarkness(darkIntensity); + } + + /** + * Controls the visibility of the assist gesture handles. + * + * @param visible whether the handles should be shown + */ + public void setAssistHintVisible(boolean visible) { + if (!mHandler.getLooper().isCurrentThread()) { + mHandler.post(() -> setAssistHintVisible(visible)); + return; + } + + if (mAssistHintBlocked && visible) { + if (DEBUG) { + Log.v(TAG, "Assist hint blocked, cannot make it visible"); + } + return; + } + + if (mAssistHintVisible != visible) { + mAssistHintVisible = visible; + fade(mAssistHintLeft, mAssistHintVisible, /* isLeft = */ true); + fade(mAssistHintRight, mAssistHintVisible, /* isLeft = */ false); + } + } + + /** + * Prevents the assist hint from becoming visible even if `mAssistHintVisible` is true. + */ + public void setAssistHintBlocked(boolean blocked) { + if (!mHandler.getLooper().isCurrentThread()) { + mHandler.post(() -> setAssistHintBlocked(blocked)); + return; + } + + mAssistHintBlocked = blocked; + if (mAssistHintVisible && mAssistHintBlocked) { + hideAssistHandles(); + } + } + + private void hideAssistHandles() { + mAssistHintLeft.setVisibility(View.GONE); + mAssistHintRight.setVisibility(View.GONE); + mAssistHintVisible = false; + } + + /** + * Returns an animator that animates the given view from start to end over durationMs. Start and + * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an + * overshoot. + */ + Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs, + Interpolator interpolator) { + // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1]. + float scaleStart = MathUtils.lerp(2f, 1f, start); + float scaleEnd = MathUtils.lerp(2f, 1f, end); + Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd); + Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd); + float translationStart = MathUtils.lerp(0.2f, 0f, start); + float translationEnd = MathUtils.lerp(0.2f, 0f, end); + int xDirection = isLeft ? -1 : 1; + Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, + xDirection * translationStart * view.getWidth(), + xDirection * translationEnd * view.getWidth()); + Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, + translationStart * view.getHeight(), translationEnd * view.getHeight()); + + AnimatorSet set = new AnimatorSet(); + set.play(scaleX).with(scaleY); + set.play(scaleX).with(translateX); + set.play(scaleX).with(translateY); + set.setDuration(durationMs); + set.setInterpolator(interpolator); + return set; + } + + private void fade(View view, boolean fadeIn, boolean isLeft) { + if (fadeIn) { + view.animate().cancel(); + view.setAlpha(1f); + view.setVisibility(View.VISIBLE); + + // A piecewise spring-like interpolation. + // End value in one animator call must match the start value in the next, otherwise + // there will be a discontinuity. + AnimatorSet anim = new AnimatorSet(); + Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750, + new PathInterpolator(0, 0.45f, .67f, 1f)); + Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f); + Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400, + secondInterpolator); + Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400, + secondInterpolator); + Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400, + secondInterpolator); + anim.play(first).before(second); + anim.play(second).before(third); + anim.play(third).before(fourth); + anim.start(); + } else { + view.animate().cancel(); + view.animate() + .setInterpolator(new AccelerateInterpolator(1.5f)) + .setDuration(250) + .alpha(0f); + } + + } +} diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java index 2a82d215e44a..739eade35ca6 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java @@ -24,8 +24,7 @@ import android.os.SystemClock; import androidx.slice.Clock; import com.android.internal.app.AssistUtils; -import com.android.systemui.ScreenDecorations; -import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.statusbar.NavigationBarController; import java.util.EnumMap; import java.util.Map; @@ -69,8 +68,9 @@ public abstract class AssistModule { } @Provides - static ScreenDecorations provideScreenDecorations(Context context) { - return SysUiServiceProvider.getComponent(context, ScreenDecorations.class); + static AssistHandleViewController provideAssistHandleViewController( + NavigationBarController navigationBarController) { + return navigationBarController.getAssistHandlerViewController(); } @Provides diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java index b346a6eb2b3c..bf81e1d3b7f1 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java @@ -38,9 +38,9 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.ScreenDecorations; -import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.assist.AssistHandleViewController; import com.android.systemui.assist.AssistManager; +import com.android.systemui.statusbar.NavigationBarController; import java.util.Locale; @@ -163,9 +163,11 @@ public class DefaultUiController implements AssistManager.UiController { } private void updateAssistHandleVisibility() { - ScreenDecorations decorations = SysUiServiceProvider.getComponent(mRoot.getContext(), - ScreenDecorations.class); - decorations.setAssistHintBlocked(mInvocationInProgress); + AssistHandleViewController controller = Dependency.get(NavigationBarController.class) + .getAssistHandlerViewController(); + if (controller != null) { + controller.setAssistHintBlocked(mInvocationInProgress); + } } private void attach() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java index 7bcbd3683130..09f80455a1b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java @@ -37,6 +37,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.systemui.Dependency; +import com.android.systemui.assist.AssistHandleViewController; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.phone.AutoHideController; @@ -233,4 +234,9 @@ public class NavigationBarController implements Callbacks { public NavigationBarFragment getDefaultNavigationBarFragment() { return mNavigationBars.get(DEFAULT_DISPLAY); } + + /** @return {@link AssistHandleViewController} (only on the default display). */ + public AssistHandleViewController getAssistHandlerViewController() { + return getDefaultNavigationBarFragment().getAssistHandlerViewController(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 2b8c86b8c549..b87140dddec3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -86,8 +86,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.ScreenDecorations; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.assist.AssistHandleViewController; import com.android.systemui.assist.AssistManager; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; @@ -174,7 +174,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback public int mDisplayId; private boolean mIsOnDefaultDisplay; public boolean mHomeBlockedThisTouch; - private ScreenDecorations mScreenDecorations; + + /** Only for default display */ + @Nullable + private AssistHandleViewController mAssistHandlerViewController; private Handler mHandler = Dependency.get(Dependency.MAIN_HANDLER); @@ -357,17 +360,22 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mDisabledFlags2 |= StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS; } setDisabled2Flags(mDisabledFlags2); - - mScreenDecorations = SysUiServiceProvider.getComponent(getContext(), - ScreenDecorations.class); - getBarTransitions().addDarkIntensityListener(mScreenDecorations); + if (mIsOnDefaultDisplay) { + mAssistHandlerViewController = + new AssistHandleViewController(mHandler, mNavigationBarView); + getBarTransitions().addDarkIntensityListener(mAssistHandlerViewController); + } } @Override public void onDestroyView() { super.onDestroyView(); if (mNavigationBarView != null) { - mNavigationBarView.getBarTransitions().removeDarkIntensityListener(mScreenDecorations); + if (mIsOnDefaultDisplay) { + mNavigationBarView.getBarTransitions() + .removeDarkIntensityListener(mAssistHandlerViewController); + mAssistHandlerViewController = null; + } mNavigationBarView.getBarTransitions().destroy(); mNavigationBarView.getLightTransitionsController().destroy(getContext()); } @@ -1019,6 +1027,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE); } + @Nullable + public AssistHandleViewController getAssistHandlerViewController() { + return mAssistHandlerViewController; + } + /** * Performs transitions on navigation bar. * diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index 3b5e12c4ef96..64ab060e14a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -45,7 +45,6 @@ import android.testing.TestableLooper.RunWithLooper; import android.view.Display; import android.view.View; import android.view.WindowManager; -import android.view.WindowManagerPolicyConstants; import androidx.test.filters.SmallTest; @@ -53,7 +52,6 @@ import com.android.systemui.R.dimen; import com.android.systemui.ScreenDecorations.TunablePaddingTagListener; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentService; -import com.android.systemui.statusbar.phone.NavigationModeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarWindowView; import com.android.systemui.tuner.TunablePadding; @@ -80,7 +78,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { private TunerService mTunerService; private StatusBarWindowView mView; private TunablePaddingService mTunablePaddingService; - private NavigationModeController mNavigationModeController; @Before public void setup() { @@ -90,8 +87,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class); mTunerService = mDependency.injectMockDependency(TunerService.class); mFragmentService = mDependency.injectMockDependency(FragmentService.class); - mNavigationModeController = mDependency.injectMockDependency( - NavigationModeController.class); mStatusBar = mock(StatusBar.class); mWindowManager = mock(WindowManager.class); @@ -213,54 +208,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { } @Test - public void testAssistHandles() { - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius, 0); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius_top, 0); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius_bottom, 0); - mContext.getOrCreateTestableResources() - .addOverride(dimen.rounded_corner_content_padding, 0); - when(mNavigationModeController.addListener(any())).thenReturn( - WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL); - - mScreenDecorations.start(); - - // Add 2 windows for rounded corners (top and bottom). - verify(mWindowManager, times(2)).addView(any(), any()); - } - - @Test - public void testDelayedAssistHandles() { - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius, 0); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius_top, 0); - mContext.getOrCreateTestableResources().addOverride( - com.android.internal.R.dimen.rounded_corner_radius_bottom, 0); - mContext.getOrCreateTestableResources() - .addOverride(dimen.rounded_corner_content_padding, 0); - when(mNavigationModeController.addListener(any())).thenReturn( - WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON); - - mScreenDecorations.start(); - - // No handles and no corners - verify(mWindowManager, never()).addView(any(), any()); - - mScreenDecorations.handleNavigationModeChange( - WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL); - - // Add 2 windows for rounded corners (top and bottom). - verify(mWindowManager, times(2)).addView(any(), any()); - } - - @Test public void hasRoundedCornerOverlayFlagSet() { assertThat(mScreenDecorations.getWindowLayoutParams().privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY, diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java index 9c920f52d56a..fbb8e0c171cd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java @@ -38,7 +38,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.app.AssistUtils; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.systemui.DumpController; -import com.android.systemui.ScreenDecorations; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; @@ -64,7 +63,6 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { private AssistHandleBehaviorController mAssistHandleBehaviorController; - @Mock private ScreenDecorations mMockScreenDecorations; @Mock private AssistUtils mMockAssistUtils; @Mock private Handler mMockHandler; @Mock private PhenotypeHelper mMockPhenotypeHelper; @@ -74,6 +72,7 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { @Mock private AssistHandleBehaviorController.BehaviorController mMockTestBehavior; @Mock private NavigationModeController mMockNavigationModeController; @Mock private DumpController mMockDumpController; + @Mock private AssistHandleViewController mMockAssistHandleViewController; @Before public void setup() { @@ -97,7 +96,7 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { mContext, mMockAssistUtils, mMockHandler, - () -> mMockScreenDecorations, + () -> mMockAssistHandleViewController, mMockPhenotypeHelper, behaviorMap, mMockNavigationModeController, @@ -114,14 +113,14 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.showAndStay(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.hide(); // Assert - verify(mMockScreenDecorations).setAssistHintVisible(false); - verifyNoMoreInteractions(mMockScreenDecorations); + verify(mMockAssistHandleViewController).setAssistHintVisible(false); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -129,13 +128,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.hide(); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -143,14 +142,14 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndStay(); // Assert - verify(mMockScreenDecorations).setAssistHintVisible(true); - verifyNoMoreInteractions(mMockScreenDecorations); + verify(mMockAssistHandleViewController).setAssistHintVisible(true); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -158,13 +157,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.showAndStay(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndStay(); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -172,13 +171,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndStay(); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -186,15 +185,15 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGo(); // Assert - InOrder inOrder = inOrder(mMockScreenDecorations); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false); + InOrder inOrder = inOrder(mMockAssistHandleViewController); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(true); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(false); inOrder.verifyNoMoreInteractions(); } @@ -203,14 +202,14 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.showAndStay(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGo(); // Assert - verify(mMockScreenDecorations).setAssistHintVisible(false); - verifyNoMoreInteractions(mMockScreenDecorations); + verify(mMockAssistHandleViewController).setAssistHintVisible(false); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -221,13 +220,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS), anyLong())).thenReturn(10000L); mAssistHandleBehaviorController.showAndGo(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGo(); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -235,13 +234,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGo(); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -249,15 +248,15 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGoDelayed(1000, false); // Assert - InOrder inOrder = inOrder(mMockScreenDecorations); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false); + InOrder inOrder = inOrder(mMockAssistHandleViewController); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(true); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(false); inOrder.verifyNoMoreInteractions(); } @@ -266,14 +265,14 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.showAndStay(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGoDelayed(1000, false); // Assert - verify(mMockScreenDecorations).setAssistHintVisible(false); - verifyNoMoreInteractions(mMockScreenDecorations); + verify(mMockAssistHandleViewController).setAssistHintVisible(false); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -281,16 +280,16 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME); mAssistHandleBehaviorController.showAndStay(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGoDelayed(1000, true); // Assert - InOrder inOrder = inOrder(mMockScreenDecorations); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true); - inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false); + InOrder inOrder = inOrder(mMockAssistHandleViewController); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(false); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(true); + inOrder.verify(mMockAssistHandleViewController).setAssistHintVisible(false); inOrder.verifyNoMoreInteractions(); } @@ -302,13 +301,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS), anyLong())).thenReturn(10000L); mAssistHandleBehaviorController.showAndGo(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGoDelayed(1000, false); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test @@ -316,13 +315,13 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase { // Arrange when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null); mAssistHandleBehaviorController.hide(); - reset(mMockScreenDecorations); + reset(mMockAssistHandleViewController); // Act mAssistHandleBehaviorController.showAndGoDelayed(1000, false); // Assert - verifyNoMoreInteractions(mMockScreenDecorations); + verifyNoMoreInteractions(mMockAssistHandleViewController); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleViewControllerTest.java new file mode 100644 index 000000000000..6e21ae218621 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleViewControllerTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 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.assist; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import android.os.Handler; +import android.os.Looper; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; +import android.view.View; +import android.view.ViewPropertyAnimator; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.CornerHandleView; +import com.android.systemui.SysuiTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class AssistHandleViewControllerTest extends SysuiTestCase { + + private AssistHandleViewController mAssistHandleViewController; + + @Mock private Handler mMockHandler; + @Mock private Looper mMockLooper; + @Mock private View mMockBarView; + @Mock private CornerHandleView mMockAssistHint; + @Mock private ViewPropertyAnimator mMockAnimator; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + when(mMockBarView.findViewById(anyInt())).thenReturn(mMockAssistHint); + when(mMockAssistHint.animate()).thenReturn(mMockAnimator); + when(mMockAnimator.setInterpolator(any())).thenReturn(mMockAnimator); + when(mMockAnimator.setDuration(anyLong())).thenReturn(mMockAnimator); + doNothing().when(mMockAnimator).cancel(); + when(mMockHandler.getLooper()).thenReturn(mMockLooper); + when(mMockLooper.isCurrentThread()).thenReturn(true); + + mAssistHandleViewController = new AssistHandleViewController(mMockHandler, mMockBarView); + } + + @Test + public void testSetVisibleWithoutBlocked() { + // Act + mAssistHandleViewController.setAssistHintVisible(true); + + // Assert + assertTrue(mAssistHandleViewController.mAssistHintVisible); + } + + @Test + public void testSetInvisibleWithoutBlocked() { + // Arrange + mAssistHandleViewController.setAssistHintVisible(true); + + // Act + mAssistHandleViewController.setAssistHintVisible(false); + + // Assert + assertFalse(mAssistHandleViewController.mAssistHintVisible); + } + + @Test + public void testSetVisibleWithBlocked() { + // Act + mAssistHandleViewController.setAssistHintBlocked(true); + mAssistHandleViewController.setAssistHintVisible(true); + + // Assert + assertFalse(mAssistHandleViewController.mAssistHintVisible); + assertTrue(mAssistHandleViewController.mAssistHintBlocked); + } +} |