Merge "Add additional fake task views on overview gesture completion."

This commit is contained in:
TreeHugger Robot
2020-12-23 01:34:00 +00:00
committed by Android (Google) Code Review
7 changed files with 106 additions and 13 deletions

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/gesture_tutorial_fake_previous_task_view_color" />
</shape>

View File

@@ -30,6 +30,14 @@
android:layout_height="20dp"
android:visibility="invisible" />
<View
android:id="@+id/gesture_tutorial_fake_previous_task_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleX="0.98"
android:scaleY="0.98"
android:visibility="invisible" />
<View
android:id="@+id/gesture_tutorial_fake_task_view"
android:layout_width="match_parent"

View File

@@ -56,7 +56,7 @@ import com.android.systemui.shared.system.QuickStepContract;
/** Utility class to handle Home and Assistant gestures. */
public class NavBarGestureHandler implements OnTouchListener,
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
TriggerSwipeUpTouchTracker.OnSwipeUpListener, MotionPauseDetector.OnMotionPauseListener {
private static final String LOG_TAG = "NavBarGestureHandler";
private static final long RETRACT_GESTURE_ANIMATION_DURATION_MS = 300;
@@ -181,7 +181,7 @@ public class NavBarGestureHandler implements OnTouchListener,
mLaunchedAssistant = false;
mSwipeUpTouchTracker.init();
mMotionPauseDetector.clear();
mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
mMotionPauseDetector.setOnMotionPauseListener(this);
break;
case MotionEvent.ACTION_MOVE:
mLastPos.set(event.getX(), event.getY());
@@ -256,7 +256,13 @@ public class NavBarGestureHandler implements OnTouchListener,
|| event.getY() >= mDisplaySize.y - mBottomGestureHeight;
}
protected void onMotionPauseDetected() {
@Override
public void onMotionPauseChanged(boolean isPaused) {
mGestureCallback.onMotionPaused(isPaused);
}
@Override
public void onMotionPauseDetected() {
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
}
@@ -311,6 +317,9 @@ public class NavBarGestureHandler implements OnTouchListener,
/** Called whenever any touch is completed. */
void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity);
/** Called when a motion stops or resumes */
default void onMotionPaused(boolean isPaused) {}
/** Indicates how far a touch originating in the nav bar has moved from the nav bar. */
default void setNavBarGestureProgress(@Nullable Float displacement) {}

View File

@@ -61,16 +61,21 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
@TargetApi(Build.VERSION_CODES.R)
abstract class SwipeUpGestureTutorialController extends TutorialController {
private final ViewSwipeUpAnimation mViewSwipeUpAnimation;
private static final int FAKE_PREVIOUS_TASK_MARGIN = Utilities.dpToPx(12);
private final ViewSwipeUpAnimation mTaskViewSwipeUpAnimation;
private float mFakeTaskViewRadius;
private Rect mFakeTaskViewRect = new Rect();
private RunningWindowAnim mRunningWindowAnim;
private boolean mShowTasks = false;
private boolean mShowPreviousTasks = false;
SwipeUpGestureTutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
super(tutorialFragment, tutorialType);
RecentsAnimationDeviceState deviceState = new RecentsAnimationDeviceState(mContext);
OverviewComponentObserver observer = new OverviewComponentObserver(mContext, deviceState);
mViewSwipeUpAnimation = new ViewSwipeUpAnimation(mContext, deviceState,
mTaskViewSwipeUpAnimation = new ViewSwipeUpAnimation(mContext, deviceState,
new GestureState(observer, -1));
observer.onDestroy();
deviceState.destroy();
@@ -83,16 +88,22 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
.getWindowInsets()
.getInsets(WindowInsets.Type.systemBars());
dp.updateInsets(new Rect(insets.left, insets.top, insets.right, insets.bottom));
mViewSwipeUpAnimation.initDp(dp);
mTaskViewSwipeUpAnimation.initDp(dp);
mFakeTaskViewRadius = QuickStepContract.getWindowCornerRadius(mContext.getResources());
mFakeTaskView.setClipToOutline(true);
mFakeTaskView.setOutlineProvider(new ViewOutlineProvider() {
ViewOutlineProvider outlineProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(mFakeTaskViewRect, mFakeTaskViewRadius);
}
});
};
mFakeTaskView.setClipToOutline(true);
mFakeTaskView.setOutlineProvider(outlineProvider);
mFakePreviousTaskView.setClipToOutline(true);
mFakePreviousTaskView.setOutlineProvider(outlineProvider);
}
private void cancelRunningAnimation() {
@@ -114,16 +125,22 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
mFakeIconView.setVisibility(View.INVISIBLE);
mFakeTaskView.setVisibility(View.INVISIBLE);
mFakeTaskView.setAlpha(1);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakePreviousTaskView.setAlpha(1);
mShowTasks = false;
mShowPreviousTasks = false;
mRunningWindowAnim = null;
}
};
if (toOverviewFirst) {
anim.setFloat(mViewSwipeUpAnimation.getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
anim.setFloat(mTaskViewSwipeUpAnimation
.getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
PendingAnimation fadeAnim = new PendingAnimation(300);
fadeAnim.setViewAlpha(mFakeTaskView, 0, ACCEL);
fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
fadeAnim.addListener(resetTaskView);
AnimatorSet animset = fadeAnim.buildAnim();
animset.setStartDelay(100);
@@ -133,6 +150,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
});
} else {
anim.setViewAlpha(mFakeTaskView, 0, ACCEL);
anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
anim.setViewAlpha(mFakeIconView, 0, ACCEL);
anim.addListener(resetTaskView);
}
@@ -148,8 +166,10 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
hideFeedback();
hideHandCoachingAnimation();
cancelRunningAnimation();
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mShowPreviousTasks = false;
RectFSpringAnim rectAnim =
mViewSwipeUpAnimation.handleSwipeUpToHome(finalVelocity);
mTaskViewSwipeUpAnimation.handleSwipeUpToHome(finalVelocity);
// After home animation finishes, fade out and run onEndRunnable.
rectAnim.addAnimatorListener(AnimationSuccessListener.forRunnable(
() -> fadeOutFakeTaskView(false, onEndRunnable)));
@@ -161,11 +181,31 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
if (displacement == null || mTutorialType == HOME_NAVIGATION_COMPLETE
|| mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
mFakeTaskView.setVisibility(View.INVISIBLE);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
} else {
mShowTasks = true;
mFakeTaskView.setVisibility(View.VISIBLE);
if (mRunningWindowAnim == null) {
mViewSwipeUpAnimation.updateDisplacement(displacement);
if (mShowPreviousTasks) {
mFakePreviousTaskView.setVisibility(View.VISIBLE);
}
if (mRunningWindowAnim == null) {
mTaskViewSwipeUpAnimation.updateDisplacement(displacement);
}
}
}
@Override
public void onMotionPaused(boolean unused) {
if (mShowTasks) {
if (!mShowPreviousTasks) {
mFakePreviousTaskView.setTranslationX(
-(2 * mFakePreviousTaskView.getWidth() + FAKE_PREVIOUS_TASK_MARGIN));
mFakePreviousTaskView.animate()
.setDuration(300)
.translationX(-(mFakePreviousTaskView.getWidth() + FAKE_PREVIOUS_TASK_MARGIN))
.start();
}
mShowPreviousTasks = true;
}
}
@@ -232,6 +272,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
false /* isVerticalBarLayout */);
mFakeIconView.setAlpha(1);
mFakeTaskView.setAlpha(getWindowAlpha(progress));
mFakePreviousTaskView.setAlpha(getWindowAlpha(progress));
}
@Override
@@ -258,9 +299,11 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
public void applySurfaceParams(SurfaceParams[] params) {
SurfaceParams p = params[0];
mFakeTaskView.setAnimationMatrix(p.matrix);
mFakePreviousTaskView.setAnimationMatrix(p.matrix);
mFakeTaskViewRect.set(p.windowCrop);
mFakeTaskViewRadius = p.cornerRadius;
mFakeTaskView.invalidateOutline();
mFakePreviousTaskView.invalidateOutline();
}
}
}

View File

@@ -52,6 +52,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
final View mLauncherView;
final ClipIconView mFakeIconView;
final View mFakeTaskView;
final View mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
@Nullable final TutorialHandAnimation mHandCoachingAnimation;
@@ -74,6 +75,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mLauncherView = getMockLauncherView();
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
mFakePreviousTaskView =
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
mHandCoachingAnimation = tutorialFragment.getHandAnimation();
@@ -93,6 +96,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
if (mContext != null) {
rootView.setBackground(mContext.getDrawable(getMockWallpaperResId()));
mFakeTaskView.setBackground(mContext.getDrawable(getMockAppTaskThumbnailResId()));
mFakePreviousTaskView.setBackground(
mContext.getDrawable(getMockPreviousAppTaskThumbnailResId()));
mFakeIconView.setBackground(mContext.getDrawable(getMockAppIconResId()));
}
}
@@ -126,6 +131,11 @@ abstract class TutorialController implements BackGestureAttemptCallback,
return R.drawable.default_sandbox_app_task_thumbnail;
}
@DrawableRes
protected int getMockPreviousAppTaskThumbnailResId() {
return R.drawable.default_sandbox_app_previous_task_thumbnail;
}
@Nullable
public View getMockLauncherView() {
InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext);

View File

@@ -37,6 +37,7 @@
<color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
<color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
<color name="gesture_tutorial_fake_previous_task_view_color">#9CCC65</color> <!-- Light Green -->
<color name="gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
<color name="gesture_tutorial_primary_color">#1A73E8</color> <!-- Blue -->
</resources>

View File

@@ -404,6 +404,11 @@ public final class Utilities {
return (size / densityRatio);
}
/** Converts a dp value to pixels for the current device. */
public static int dpToPx(float dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxFromSp(float size, DisplayMetrics metrics) {
return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
size, metrics));