Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56fbd2cb authored by Josh Tsuji's avatar Josh Tsuji Committed by Automerger Merge Worker
Browse files

Merge "ActivityView animations!" into rvc-dev am: ab0ffd1d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11793537

Change-Id: I09bf418b06f30beb06ae6469543e9a643d613629
parents 4512999c ab0ffd1d
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -1222,10 +1222,6 @@
    <dimen name="bubble_dismiss_slop">16dp</dimen>
    <!-- Height of button allowing users to adjust settings for bubbles. -->
    <dimen name="bubble_manage_button_height">48dp</dimen>
    <!-- How far, horizontally, to animate the expanded view over when animating in/out. -->
    <dimen name="bubble_expanded_animate_x_distance">100dp</dimen>
    <!-- How far, vertically, to animate the expanded view over when animating in/out. -->
    <dimen name="bubble_expanded_animate_y_distance">500dp</dimen>
    <!-- Max width of the message bubble-->
    <dimen name="bubble_message_max_width">144dp</dimen>
    <!-- Min width of the message bubble -->
+102 −10
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.graphics.PixelFormat.TRANSPARENT;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.sNewInsetsMode;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -33,7 +34,6 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPAND
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;

import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
@@ -46,6 +46,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
@@ -55,12 +56,19 @@ import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceControl;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -88,6 +96,7 @@ public class BubbleExpandedView extends LinearLayout {
    // The triangle pointing to the expanded view
    private View mPointerView;
    private int mPointerMargin;
    @Nullable private int[] mExpandedViewContainerLocation;

    private AlphaOptimizedButton mSettingsIcon;

@@ -121,6 +130,16 @@ public class BubbleExpandedView extends LinearLayout {
    private View mVirtualImeView;
    private WindowManager mVirtualDisplayWindowManager;
    private boolean mImeShowing = false;
    private float mCornerRadius = 0f;

    /**
     * Container for the ActivityView that has a solid, round-rect background that shows if the
     * ActivityView hasn't loaded.
     */
    private FrameLayout mActivityViewContainer = new FrameLayout(getContext());

    /** The SurfaceView that the ActivityView draws to. */
    @Nullable private SurfaceView mActivitySurface;

    private ActivityView.StateCallback mStateCallback = new ActivityView.StateCallback() {
        @Override
@@ -269,7 +288,28 @@ public class BubbleExpandedView extends LinearLayout {

        // Set ActivityView's alpha value as zero, since there is no view content to be shown.
        setContentVisibility(false);
        addView(mActivityView);

        mActivityViewContainer.setBackgroundColor(Color.WHITE);
        mActivityViewContainer.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius);
            }
        });
        mActivityViewContainer.setClipToOutline(true);
        mActivityViewContainer.addView(mActivityView);
        mActivityViewContainer.setLayoutParams(
                new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
        addView(mActivityViewContainer);

        if (mActivityView != null
                && mActivityView.getChildCount() > 0
                && mActivityView.getChildAt(0) instanceof SurfaceView) {
            // Retrieve the surface from the ActivityView so we can screenshot it and change its
            // z-ordering. This should always be possible, since ActivityView's constructor adds the
            // SurfaceView as its first child.
            mActivitySurface = (SurfaceView) mActivityView.getChildAt(0);
        }

        // Expanded stack layout, top to bottom:
        // Expanded view container
@@ -327,6 +367,39 @@ public class BubbleExpandedView extends LinearLayout {
        return mBubble != null ? mBubble.getKey() : "null";
    }

    /**
     * Asks the ActivityView's surface to draw on top of all other views in the window. This is
     * useful for ordering surfaces during animations, but should otherwise be set to false so that
     * bubbles and menus can draw over the ActivityView.
     */
    void setSurfaceZOrderedOnTop(boolean onTop) {
        if (mActivitySurface == null) {
            return;
        }

        mActivitySurface.setZOrderedOnTop(onTop, true);
    }

    /** Return a GraphicBuffer with the contents of the ActivityView's underlying surface. */
    @Nullable SurfaceControl.ScreenshotGraphicBuffer snapshotActivitySurface() {
        if (mActivitySurface == null) {
            return null;
        }

        return SurfaceControl.captureLayers(
                mActivitySurface.getSurfaceControl(),
                new Rect(0, 0, mActivityView.getWidth(), mActivityView.getHeight()),
                1 /* scale */);
    }

    int[] getActivityViewLocationOnScreen() {
        if (mActivityView != null) {
            return mActivityView.getLocationOnScreen();
        } else {
            return new int[]{0, 0};
        }
    }

    void setManageClickListener(OnClickListener manageClickListener) {
        findViewById(R.id.settings_button).setOnClickListener(manageClickListener);
    }
@@ -345,12 +418,12 @@ public class BubbleExpandedView extends LinearLayout {
    void applyThemeAttrs() {
        final TypedArray ta = mContext.obtainStyledAttributes(
                new int[] {android.R.attr.dialogCornerRadius});
        float cornerRadius = ta.getDimensionPixelSize(0, 0);
        mCornerRadius = ta.getDimensionPixelSize(0, 0);
        ta.recycle();

        if (mActivityView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
                mContext.getResources())) {
            mActivityView.setCornerRadius(cornerRadius);
            mActivityView.setCornerRadius(mCornerRadius);
        }
    }

@@ -398,6 +471,7 @@ public class BubbleExpandedView extends LinearLayout {
        mPointerView.setAlpha(alpha);
        if (mActivityView != null) {
            mActivityView.setAlpha(alpha);
            mActivityView.bringToFront();
        }
    }

@@ -557,6 +631,11 @@ public class BubbleExpandedView extends LinearLayout {
        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
            Log.d(TAG, "updateHeight: bubble=" + getBubbleKey());
        }

        if (mExpandedViewContainerLocation == null) {
            return;
        }

        if (usingActivityView()) {
            float desiredHeight = mOverflowHeight;
            if (!mIsOverflow) {
@@ -564,7 +643,7 @@ public class BubbleExpandedView extends LinearLayout {
            }
            float height = Math.min(desiredHeight, getMaxExpandedHeight());
            height = Math.max(height, mIsOverflow? mOverflowHeight : mMinHeight);
            LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
            ViewGroup.LayoutParams lp = mActivityView.getLayoutParams();
            mNeedsNewHeight = lp.height != height;
            if (!mKeyboardVisible) {
                // If the keyboard is visible... don't adjust the height because that will cause
@@ -574,7 +653,8 @@ public class BubbleExpandedView extends LinearLayout {
                mNeedsNewHeight = false;
            }
            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
                Log.d(TAG, "updateHeight: bubble=" + getBubbleKey() + " height=" + height
                Log.d(TAG, "updateHeight: bubble=" + getBubbleKey()
                        + " height=" + height
                        + " mNeedsNewHeight=" + mNeedsNewHeight);
            }
        }
@@ -582,29 +662,41 @@ public class BubbleExpandedView extends LinearLayout {

    private int getMaxExpandedHeight() {
        mWindowManager.getDefaultDisplay().getRealSize(mDisplaySize);
        int[] windowLocation = mActivityView.getLocationOnScreen();
        int bottomInset = getRootWindowInsets() != null
                ? getRootWindowInsets().getStableInsetBottom()
                : 0;
        return mDisplaySize.y - windowLocation[1] - mSettingsIconHeight - mPointerHeight

        return mDisplaySize.y
                - mExpandedViewContainerLocation[1]
                - getPaddingTop()
                - getPaddingBottom()
                - mSettingsIconHeight
                - mPointerHeight
                - mPointerMargin - bottomInset;
    }

    /**
     * Update appearance of the expanded view being displayed.
     *
     * @param containerLocationOnScreen The location on-screen of the container the expanded view is
     *                                  added to. This allows us to calculate max height without
     *                                  waiting for layout.
     */
    public void updateView() {
    public void updateView(int[] containerLocationOnScreen) {
        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
            Log.d(TAG, "updateView: bubble="
                    + getBubbleKey());
        }

        mExpandedViewContainerLocation = containerLocationOnScreen;

        if (usingActivityView()
                && mActivityView.getVisibility() == VISIBLE
                && mActivityView.isAttachedToWindow()) {
            mActivityView.onLocationChanged();
        }
            updateHeight();
        }
    }

    /**
     * Set the x position that the tip of the triangle should point to.
+370 −97

File changed.

Preview size limit exceeded, changes collapsed.

+137 −0
Original line number Diff line number Diff line
/*
 * 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.
 */
package com.android.systemui.bubbles.animation;

import android.graphics.Matrix;

import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.FloatPropertyCompat;

/**
 * Matrix whose scale properties can be animated using physics animations, via the {@link #SCALE_X}
 * and {@link #SCALE_Y} FloatProperties.
 *
 * This is useful when you need to perform a scale animation with a pivot point, since pivot points
 * are not supported by standard View scale operations but are supported by matrices.
 *
 * NOTE: DynamicAnimation assumes that all custom properties are denominated in pixels, and thus
 * considers 1 to be the smallest user-visible change for custom properties. This means that if you
 * animate {@link #SCALE_X} and {@link #SCALE_Y} to 3f, for example, the animation would have only
 * three frames.
 *
 * To work around this, whenever animating to a desired scale value, animate to the value returned
 * by {@link #getAnimatableValueForScaleFactor} instead. The SCALE_X and SCALE_Y properties will
 * convert that (larger) value into the appropriate scale factor when scaling the matrix.
 */
public class AnimatableScaleMatrix extends Matrix {

    /**
     * The X value of the scale.
     *
     * NOTE: This must be set or animated to the value returned by
     * {@link #getAnimatableValueForScaleFactor}, not the desired scale factor itself.
     */
    public static final FloatPropertyCompat<AnimatableScaleMatrix> SCALE_X =
            new FloatPropertyCompat<AnimatableScaleMatrix>("matrixScaleX") {
        @Override
        public float getValue(AnimatableScaleMatrix object) {
            return getAnimatableValueForScaleFactor(object.mScaleX);
        }

        @Override
        public void setValue(AnimatableScaleMatrix object, float value) {
            object.setScaleX(value * DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
        }
    };

    /**
     * The Y value of the scale.
     *
     * NOTE: This must be set or animated to the value returned by
     * {@link #getAnimatableValueForScaleFactor}, not the desired scale factor itself.
     */
    public static final FloatPropertyCompat<AnimatableScaleMatrix> SCALE_Y =
            new FloatPropertyCompat<AnimatableScaleMatrix>("matrixScaleY") {
                @Override
                public float getValue(AnimatableScaleMatrix object) {
                    return getAnimatableValueForScaleFactor(object.mScaleY);
                }

                @Override
                public void setValue(AnimatableScaleMatrix object, float value) {
                    object.setScaleY(value * DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
                }
            };

    private float mScaleX = 1f;
    private float mScaleY = 1f;

    private float mPivotX = 0f;
    private float mPivotY = 0f;

    /**
     * Return the value to animate SCALE_X or SCALE_Y to in order to achieve the desired scale
     * factor.
     */
    public static float getAnimatableValueForScaleFactor(float scale) {
        return scale * (1f / DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
    }

    @Override
    public void setScale(float sx, float sy, float px, float py) {
        mScaleX = sx;
        mScaleY = sy;
        mPivotX = px;
        mPivotY = py;
        super.setScale(mScaleX, mScaleY, mPivotX, mPivotY);
    }

    public void setScaleX(float scaleX) {
        mScaleX = scaleX;
        super.setScale(mScaleX, mScaleY, mPivotX, mPivotY);
    }

    public void setScaleY(float scaleY) {
        mScaleY = scaleY;
        super.setScale(mScaleX, mScaleY, mPivotX, mPivotY);
    }

    public void setPivotX(float pivotX) {
        mPivotX = pivotX;
        super.setScale(mScaleX, mScaleY, mPivotX, mPivotY);
    }

    public void setPivotY(float pivotY) {
        mPivotY = pivotY;
        super.setScale(mScaleX, mScaleY, mPivotX, mPivotY);
    }

    public float getScaleX() {
        return mScaleX;
    }

    public float getScaleY() {
        return mScaleY;
    }

    public float getPivotX() {
        return mPivotX;
    }

    public float getPivotY() {
        return mPivotY;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ public class ExpandedAnimationController
    private static final int ANIMATE_TRANSLATION_FACTOR = 4;

    /** Duration of the expand/collapse target path animation. */
    private static final int EXPAND_COLLAPSE_TARGET_ANIM_DURATION = 175;
    public static final int EXPAND_COLLAPSE_TARGET_ANIM_DURATION = 175;

    /** Stiffness for the expand/collapse path-following animation. */
    private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 1000;
Loading