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

Commit 2a82fe58 authored by Winson Chung's avatar Winson Chung
Browse files

Refactor PiP logic in preparation for expanded state.



- #1: Move logic for handling IME size changes into SysUI, and only rely
      on PinnedStackController to provide bounds when first entering
      PiP and on rotation
- #2: Doing #1 allows us to move PipMotionHelper to SysUI completely, which
      lets us aggregate the animation calls out of PipTouchHandler
- #3: Add proper callbacks to the listeners when the movement bounds
      changed from config change, ime change, or aspect ratio change. This
      allows SysUI to calculate the associated movement bounds for the
      expanded state, and we can then remove the corresponding WM call.
      It also means that SysUI is the only thing that needs to know about
      the expanded state.
- #4: Fix issue where TV was getting the default bounds, not taking the
      aspect ratio when the PiP was entered into account.  Doing #3
      allows us to report the right bounds.
- #5: Remove dead code related to edge snapping/minimizing now that they
      are on by default and associated tuner setting, and controller
      callbacks

Test: android.server.cts.ActivityManagerPinnedStackTests (all existing tests pass)

Change-Id: I3ef361bdf8d44094b4c0a11c70ba4db7d697fdec
Signed-off-by: default avatarWinson Chung <winsonc@google.com>
parent 9c2a6867
Loading
Loading
Loading
Loading
+1 −13
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package android.view;

import android.graphics.Rect;

/**
 * An interface to the PinnedStackController to update it of state changes, and to query
 * information based on the current state.
@@ -27,17 +25,7 @@ import android.graphics.Rect;
interface IPinnedStackController {

    /**
     * Notifies the controller that the user is currently interacting with the PIP.
     */
    oneway void setInInteractiveMode(boolean inInteractiveMode);

    /**
     * Notifies the controller that the PIP is currently minimized.
     * Notifies the controller that the PiP is currently minimized.
     */
    oneway void setIsMinimized(boolean isMinimized);

    /**
     * Notifies the controller that the desired snap mode is to the closest edge.
     */
    oneway void setSnapToEdge(boolean snapToEdge);
}
+16 −11
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.content.pm.ParceledListSlice;
import android.graphics.Rect;
import android.view.IPinnedStackController;

/**
@@ -33,24 +34,28 @@ oneway interface IPinnedStackListener {
    void onListenerRegistered(IPinnedStackController controller);

    /**
     * Called when window manager decides to adjust the pinned stack bounds, or when the listener
     * is first registered to allow the listener to synchronized its state with the controller.
     * Called when the window manager has detected a change that would cause the movement bounds
     * to be changed (ie. after configuration change, aspect ratio change, etc). It then provides
     * the components that allow the listener to calculate the movement bounds itself. The
     * {@param normalBounds} are also the default bounds that the PiP would be entered in its
     * current state with the aspect ratio applied.
     */
    void onBoundsChanged(boolean adjustedForIme);
    void onMovementBoundsChanged(in Rect insetBounds, in Rect normalBounds,
            boolean fromImeAdjustement);

    /**
     * Called when window manager decides to adjust the minimized state, or when the listener
     * is first registered to allow the listener to synchronized its state with the controller.
     * Called when window manager decides to adjust the pinned stack bounds because of the IME, or
     * when the listener is first registered to allow the listener to synchronized its state with
     * the controller.  This call will always be followed by a onMovementBoundsChanged() call
     * with fromImeAdjustement set to true.
     */
    void onMinimizedStateChanged(boolean isMinimized);
    void onImeVisibilityChanged(boolean imeVisible, int imeHeight);

    /**
     * Called when window manager decides to adjust the snap-to-edge state, which determines whether
     * to snap only to the corners of the screen or to the closest edge.  It is called when the
     * listener is first registered to allow the listener to synchronized its state with the
     * controller.
     * Called when window manager decides to adjust the minimized state, or when the listener
     * is first registered to allow the listener to synchronized its state with the controller.
     */
    void onSnapToEdgeStateChanged(boolean isSnapToEdge);
    void onMinimizedStateChanged(boolean isMinimized);

    /**
     * Called when the set of actions for the current PiP activity changes, or when the listener
+0 −10
Original line number Diff line number Diff line
@@ -336,16 +336,6 @@ interface IWindowManager
     */
    void registerPinnedStackListener(int displayId, IPinnedStackListener listener);

    /**
     * Returns the initial bounds that PIP will be shown when it is first started.
     */
    Rect getPictureInPictureDefaultBounds(int displayId);

    /**
     * Returns the bounds that the PIP can move on the screen in the current PIP state.
     */
    Rect getPictureInPictureMovementBounds(int displayId);

    /**
     * Updates the dim layer used while resizing.
     *
+0 −91
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.internal.policy;

import android.animation.RectEvaluator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

/**
 * A helper to animate the PIP.
 */
public class PipMotionHelper {

    private static final String TAG = "PipMotionHelper";

    private static final RectEvaluator RECT_EVALUATOR = new RectEvaluator(new Rect());
    private static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    private static final int DEFAULT_DURATION = 225;

    private IActivityManager mActivityManager;
    private Handler mHandler;

    public PipMotionHelper(Handler handler) {
        mHandler = handler;
    }

    /**
     * Moves the PIP to give given {@param bounds}.
     */
    public void resizeToBounds(Rect toBounds) {
        mHandler.post(() -> {
            if (mActivityManager == null) {
                mActivityManager = ActivityManager.getService();
            }
            try {
                mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */);
            } catch (RemoteException e) {
                Log.e(TAG, "Could not move pinned stack to bounds: " + toBounds, e);
            }
        });
    }

    /**
     * Creates an animation to move the PIP to give given {@param toBounds} with the default
     * animation properties.
     */
    public ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds) {
        return createAnimationToBounds(fromBounds, toBounds, DEFAULT_DURATION, FAST_OUT_SLOW_IN,
                null);
    }

    /**
     * Creates an animation to move the PIP to give given {@param toBounds}.
     */
    public ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration,
            Interpolator interpolator, ValueAnimator.AnimatorUpdateListener updateListener) {
        ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR, fromBounds, toBounds);
        anim.setDuration(duration);
        anim.setInterpolator(interpolator);
        anim.addUpdateListener((ValueAnimator animation) -> {
            resizeToBounds((Rect) animation.getAnimatedValue());
        });
        if (updateListener != null) {
            anim.addUpdateListener(updateListener);
        }
        return anim;
    }


}
+15 −7
Original line number Diff line number Diff line
@@ -83,13 +83,6 @@ public class PipSnapAlgorithm {
        mIsMinimized = isMinimized;
    }

    /**
     * Enables snapping to the closest edge.
     */
    public void setSnapToEdge(boolean snapToEdge) {
        mSnapMode = snapToEdge ? SNAP_MODE_EDGE : mDefaultSnapMode;
    }

    /**
     * @return the closest absolute snap stack bounds for the given {@param stackBounds} moving at
     * the given {@param velocityX} and {@param velocityY}.  The {@param movementBounds} should be
@@ -232,6 +225,21 @@ public class PipSnapAlgorithm {
        }
    }

    /**
     * Adjusts {@param movementBoundsOut} so that it is the movement bounds for the given
     * {@param stackBounds}.
     */
    public void getMovementBounds(Rect stackBounds, Rect insetBounds, Rect movementBoundsOut,
            int imeHeight) {
        // Adjust the right/bottom to ensure the stack bounds never goes offscreen
        movementBoundsOut.set(insetBounds);
        movementBoundsOut.right = Math.max(insetBounds.left, insetBounds.right -
                stackBounds.width());
        movementBoundsOut.bottom = Math.max(insetBounds.top, insetBounds.bottom -
                stackBounds.height());
        movementBoundsOut.bottom -= imeHeight;
    }

    /**
     * @return the closest point in {@param points} to the given {@param x} and {@param y}.
     */
Loading