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

Commit 5098159a authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Dim stack while dismissing

When dismissing the docked or fullscreen stack, a dim layer is
introduced for a nicer visual effect.

Change-Id: I9f12e331e978208aa9fd9e9883b3c8a36d4da3a0
parent 81fe2d1f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -361,4 +361,13 @@ interface IWindowManager
     * the docked stack gets added/removed.
     */
    void registerDockedStackListener(IDockedStackListener listener);

    /**
     * Updates the dim layer used while resizing.
     *
     * @param visible Whether the dim layer should be visible.
     * @param targetStackId The id of the task stack the dim layer should be placed on.
     * @param alpha The translucency of the dim layer, between 0 and 1.
     */
    void setResizeDimLayer(boolean visible, int targetStackId, float alpha);
}
+18 −0
Original line number Diff line number Diff line
@@ -100,6 +100,24 @@ public class DividerSnapAlgorithm {
        }
    }

    public float calculateDismissingFraction(int position) {
        if (position < mFirstSplitTarget.position) {
            return 1f - (float) position / mFirstSplitTarget.position;
        } else if (position > mLastSplitTarget.position) {
            return (float) (position - mLastSplitTarget.position)
                    / (mDismissEndTarget.position - mLastSplitTarget.position);
        }
        return 0f;
    }

    public SnapTarget getClosestDismissTarget(int position) {
        if (position - mDismissStartTarget.position < mDismissEndTarget.position - position) {
            return mDismissStartTarget;
        } else {
            return mDismissEndTarget;
        }
    }

    private SnapTarget snap(int position) {
        int minIndex = -1;
        int minDistance = Integer.MAX_VALUE;
+19 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.app.ActivityManager.StackId;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -60,6 +61,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
    private static final String TAG = "DividerView";

    private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
    private static final float DIM_START_FRACTION = 0.5f;
    private static final float DIM_DAMP_FACTOR = 1.7f;

    private ImageButton mHandle;
    private View mBackground;
@@ -264,6 +267,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        } else {
            mWindowManagerProxy.maximizeDockedStack();
        }
        mWindowManagerProxy.setResizeDimLayer(false, -1, 0f);
    }

    private void liftBackground() {
@@ -420,6 +424,21 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        } else {
            mWindowManagerProxy.resizeDockedStack(mDockedRect, null, null, null, null);
        }
        float fraction = mSnapAlgorithm.calculateDismissingFraction(position);
        fraction = Math.max(0,
                Math.min((fraction / DIM_START_FRACTION - 1f) / DIM_DAMP_FACTOR, 1f));
        mWindowManagerProxy.setResizeDimLayer(fraction != 0f,
                getStackIdForDismissTarget(mSnapAlgorithm.getClosestDismissTarget(position)),
                fraction);
    }

    private int getStackIdForDismissTarget(SnapTarget dismissTarget) {
        if (dismissTarget.flag == SnapTarget.FLAG_DISMISS_START &&
                (mDockSide == WindowManager.DOCKED_LEFT || mDockSide == WindowManager.DOCKED_TOP)) {
            return StackId.DOCKED_STACK_ID;
        } else {
            return StackId.FULLSCREEN_WORKSPACE_STACK_ID;
        }
    }

    @Override
+24 −0
Original line number Diff line number Diff line
@@ -51,6 +51,11 @@ public class WindowManagerProxy {
    private final Rect mTmpRect3 = new Rect();
    private final Rect mTmpRect4 = new Rect();
    private final Rect mTmpRect5 = new Rect();

    private boolean mDimLayerVisible;
    private int mDimLayerTargetStack;
    private float mDimLayerAlpha;

    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    private final Runnable mResizeRunnable = new Runnable() {
@@ -98,6 +103,18 @@ public class WindowManagerProxy {
        }
    };

    private final Runnable mDimLayerRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                WindowManagerGlobal.getWindowManagerService().setResizeDimLayer(mDimLayerVisible,
                        mDimLayerTargetStack, mDimLayerAlpha);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed to resize stack: " + e);
            }
        }
    };

    private WindowManagerProxy() {
    }

@@ -162,4 +179,11 @@ public class WindowManagerProxy {
        }
        return DOCKED_INVALID;
    }

    public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
        mDimLayerVisible = visible;
        mDimLayerTargetStack = targetStackId;
        mDimLayerAlpha = alpha;
        mExecutor.execute(mDimLayerRunnable);
    }
}
+45 −1
Original line number Diff line number Diff line
@@ -21,9 +21,14 @@ import android.graphics.Rect;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.IDockedStackListener;
import android.view.SurfaceControl;

import com.android.server.wm.DimLayer.DimLayerUser;

import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_RIGHT;
@@ -34,7 +39,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
/**
 * Keeps information about the docked stack divider.
 */
public class DockedStackDividerController {
public class DockedStackDividerController implements DimLayerUser {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "DockedStackDividerController" : TAG_WM;

@@ -48,6 +53,7 @@ public class DockedStackDividerController {
    private boolean mLastVisibility = false;
    private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
            = new RemoteCallbackList<>();
    private final DimLayer mDimLayer;

    DockedStackDividerController(Context context, DisplayContent displayContent) {
        mDisplayContent = displayContent;
@@ -55,6 +61,7 @@ public class DockedStackDividerController {
                com.android.internal.R.dimen.docked_stack_divider_thickness);
        mDividerInsets = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.docked_stack_divider_insets);
        mDimLayer = new DimLayer(displayContent.mService, this, displayContent.getDisplayId());
    }

    boolean isResizing() {
@@ -85,6 +92,9 @@ public class DockedStackDividerController {
        }
        mLastVisibility = visible;
        notifyDockedDividerVisibilityChanged(visible);
        if (!visible) {
            setResizeDimLayer(false, INVALID_STACK_ID, 0f);
        }
    }

    boolean wasVisible() {
@@ -158,4 +168,38 @@ public class DockedStackDividerController {
        notifyDockedStackExistsChanged(
                mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID) != null);
    }

    void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
        SurfaceControl.openTransaction();
        TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(targetStackId);
        if (visible && stack != null) {
            stack.getDimBounds(mTmpRect);
            mDimLayer.setBounds(mTmpRect);
            mDimLayer.show(mDisplayContent.mService.mLayersController.getResizeDimLayer(), alpha,
                    0 /* duration */);
        } else {
            mDimLayer.hide();
        }
        SurfaceControl.closeTransaction();
    }

    @Override
    public boolean isFullscreen() {
        return false;
    }

    @Override
    public DisplayInfo getDisplayInfo() {
        return mDisplayContent.getDisplayInfo();
    }

    @Override
    public void getDimBounds(Rect outBounds) {
        // This dim layer user doesn't need this.
    }

    @Override
    public String toShortString() {
        return TAG;
    }
}
Loading