Add PiP Resize drag handle.

We will only display the handle on the first entry.

Bug: 156917828
Test: Enter PiP, see drag handle - after fullscreen expand
and re-enter PIP, no longer see the handle

Change-Id: I5b5ec8bf532366525e8696dc3059a75967398323
This commit is contained in:
Ben Lin
2020-05-20 13:22:16 -07:00
parent 2f988b5a82
commit 906a02b87c
6 changed files with 96 additions and 22 deletions

View File

@@ -0,0 +1,29 @@
<?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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12.0dp"
android:height="12.0dp"
android:viewportWidth="12"
android:viewportHeight="12">
<group
android:translateX="12"
android:rotation="90">
<path
android:fillColor="#FFFFFF"
android:pathData="M3.41421 0L2 1.41422L10.4853 9.8995L11.8995 8.48528L3.41421 0ZM2.41421 4.24268L1 5.65689L6.65685 11.3137L8.07107 9.89953L2.41421 4.24268Z" />
</group>
</vector>

View File

@@ -81,4 +81,13 @@
android:src="@drawable/ic_close_white"
android:background="?android:selectableItemBackgroundBorderless" />
<!--TODO (b/156917828): Add content description for a11y purposes?-->
<ImageButton
android:id="@+id/resize_handle"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
android:layout_gravity="top|start"
android:padding="@dimen/pip_action_padding"
android:src="@drawable/pip_resize_handle"
android:background="?android:selectableItemBackgroundBorderless" />
</FrameLayout>

View File

@@ -194,6 +194,14 @@ public class PipBoundsHandler {
mLastPipComponentName = null;
}
/**
* Returns ture if there's a valid snap fraction. This is used with {@link EXTRA_IS_FIRST_ENTRY}
* to see if this is the first time user has entered PIP for the component.
*/
public boolean hasSaveReentryBounds() {
return mReentrySnapFraction != INVALID_SNAP_FRACTION;
}
public Rect getDisplayBounds() {
return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}

View File

@@ -29,6 +29,7 @@ import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CON
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MENU_STATE;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU_WITH_DELAY;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_RESIZE_HANDLE;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_WILL_RESIZE_MENU;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
@@ -119,6 +120,7 @@ public class PipMenuActivity extends Activity {
private LinearLayout mActionsGroup;
private View mSettingsButton;
private View mDismissButton;
private View mResizeHandle;
private int mBetweenActionPaddingLand;
private AnimatorSet mMenuContainerAnimator;
@@ -142,7 +144,8 @@ public class PipMenuActivity extends Activity {
data.getParcelable(EXTRA_STACK_BOUNDS),
data.getBoolean(EXTRA_ALLOW_TIMEOUT),
data.getBoolean(EXTRA_WILL_RESIZE_MENU),
data.getBoolean(EXTRA_SHOW_MENU_WITH_DELAY));
data.getBoolean(EXTRA_SHOW_MENU_WITH_DELAY),
data.getBoolean(EXTRA_SHOW_RESIZE_HANDLE));
break;
}
case MESSAGE_POKE_MENU:
@@ -212,6 +215,8 @@ public class PipMenuActivity extends Activity {
expandPip();
}
});
mResizeHandle = findViewById(R.id.resize_handle);
mResizeHandle.setAlpha(0);
mActionsGroup = findViewById(R.id.actions_group);
mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
R.dimen.pip_between_action_padding_land);
@@ -342,7 +347,7 @@ public class PipMenuActivity extends Activity {
}
private void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean resizeMenuOnShow, boolean withDelay) {
boolean resizeMenuOnShow, boolean withDelay, boolean showResizeHandle) {
mAllowMenuTimeout = allowMenuTimeout;
if (mMenuState != menuState) {
// Disallow touches if the menu needs to resize while showing, and we are transitioning
@@ -363,10 +368,14 @@ public class PipMenuActivity extends Activity {
mSettingsButton.getAlpha(), 1f);
ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
mDismissButton.getAlpha(), 1f);
ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA,
mResizeHandle.getAlpha(), menuState == MENU_STATE_CLOSE && showResizeHandle
? 1f : 0f);
if (menuState == MENU_STATE_FULL) {
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim);
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim,
resizeAnim);
} else {
mMenuContainerAnimator.playTogether(dismissAnim);
mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
}
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
@@ -417,7 +426,9 @@ public class PipMenuActivity extends Activity {
mSettingsButton.getAlpha(), 0f);
ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
mDismissButton.getAlpha(), 0f);
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim);
ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA,
mResizeHandle.getAlpha(), 0f);
mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
@@ -462,7 +473,9 @@ public class PipMenuActivity extends Activity {
boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true);
boolean willResizeMenu = intent.getBooleanExtra(EXTRA_WILL_RESIZE_MENU, false);
boolean withDelay = intent.getBooleanExtra(EXTRA_SHOW_MENU_WITH_DELAY, false);
showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay);
boolean showResizeHandle = intent.getBooleanExtra(EXTRA_SHOW_RESIZE_HANDLE, false);
showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay,
showResizeHandle);
}
}

View File

@@ -65,6 +65,7 @@ public class PipMenuActivityController {
public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction";
public static final String EXTRA_MENU_STATE = "menu_state";
public static final String EXTRA_SHOW_MENU_WITH_DELAY = "show_menu_with_delay";
public static final String EXTRA_SHOW_RESIZE_HANDLE = "show_resize_handle";
public static final int MESSAGE_MENU_STATE_CHANGED = 100;
public static final int MESSAGE_EXPAND_PIP = 101;
@@ -248,7 +249,7 @@ public class PipMenuActivityController {
// start, then start it
startMenuActivity(MENU_STATE_NONE, null /* stackBounds */,
false /* allowMenuTimeout */, false /* resizeMenuOnShow */,
false /* withDelay */);
false /* withDelay */, false /* showResizeHandle */);
}
}
@@ -257,28 +258,29 @@ public class PipMenuActivityController {
* PiP window transition is finished.
*/
public void showMenuWithDelay(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean willResizeMenu) {
boolean willResizeMenu, boolean showResizeHandle) {
showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu,
true /* withDelay */);
true /* withDelay */, showResizeHandle);
}
/**
* Shows the menu activity immediately.
*/
public void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean willResizeMenu) {
boolean willResizeMenu, boolean showResizeHandle) {
showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu,
false /* withDelay */);
false /* withDelay */, showResizeHandle);
}
private void showMenuInternal(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean willResizeMenu, boolean withDelay) {
boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) {
if (DEBUG) {
Log.d(TAG, "showMenu() state=" + menuState
+ " hasActivity=" + (mToActivityMessenger != null)
+ " allowMenuTimeout=" + allowMenuTimeout
+ " willResizeMenu=" + willResizeMenu
+ " withDelay=" + withDelay
+ " showResizeHandle=" + showResizeHandle
+ " callers=\n" + Debug.getCallers(5, " "));
}
@@ -291,6 +293,7 @@ public class PipMenuActivityController {
data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
data.putBoolean(EXTRA_WILL_RESIZE_MENU, willResizeMenu);
data.putBoolean(EXTRA_SHOW_MENU_WITH_DELAY, withDelay);
data.putBoolean(EXTRA_SHOW_RESIZE_HANDLE, showResizeHandle);
Message m = Message.obtain();
m.what = PipMenuActivity.MESSAGE_SHOW_MENU;
m.obj = data;
@@ -302,7 +305,8 @@ public class PipMenuActivityController {
} else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) {
// If we haven't requested the start activity, or if it previously took too long to
// start, then start it
startMenuActivity(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay);
startMenuActivity(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay,
showResizeHandle);
}
}
@@ -405,7 +409,7 @@ public class PipMenuActivityController {
* Starts the menu activity on the top task of the pinned stack.
*/
private void startMenuActivity(int menuState, Rect stackBounds, boolean allowMenuTimeout,
boolean willResizeMenu, boolean withDelay) {
boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) {
try {
StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
@@ -422,6 +426,7 @@ public class PipMenuActivityController {
intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
intent.putExtra(EXTRA_WILL_RESIZE_MENU, willResizeMenu);
intent.putExtra(EXTRA_SHOW_MENU_WITH_DELAY, withDelay);
intent.putExtra(EXTRA_SHOW_RESIZE_HANDLE, showResizeHandle);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
options.setLaunchTaskId(
pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);

View File

@@ -203,7 +203,7 @@ public class PipTouchHandler {
@Override
public void onPipShowMenu() {
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu());
true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle());
}
}
@@ -235,7 +235,7 @@ public class PipTouchHandler {
this::updateMovementBounds);
mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
() -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu()));
true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()));
Resources res = context.getResources();
mExpandedShortestEdgeSize = res.getDimensionPixelSize(
@@ -310,6 +310,10 @@ public class PipTouchHandler {
mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView);
}
private boolean shouldShowResizeHandle() {
return !mPipBoundsHandler.hasSaveReentryBounds();
}
public void setTouchGesture(PipTouchGesture gesture) {
mGesture = gesture;
}
@@ -322,7 +326,8 @@ public class PipTouchHandler {
// Only show the menu if the user isn't currently interacting with the PiP
if (!mTouchState.isUserInteracting()) {
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
false /* allowMenuTimeout */, willResizeMenu());
false /* allowMenuTimeout */, willResizeMenu(),
shouldShowResizeHandle());
}
}
@@ -358,7 +363,8 @@ public class PipTouchHandler {
if (mShowPipMenuOnAnimationEnd) {
mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, false /* willResizeMenu */);
true /* allowMenuTimeout */, false /* willResizeMenu */,
shouldShowResizeHandle());
mShowPipMenuOnAnimationEnd = false;
}
}
@@ -565,7 +571,8 @@ public class PipTouchHandler {
private void onAccessibilityShowMenu() {
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu());
true /* allowMenuTimeout */, willResizeMenu(),
shouldShowResizeHandle());
}
private boolean handleTouchEvent(InputEvent inputEvent) {
@@ -641,7 +648,8 @@ public class PipTouchHandler {
// Let's not enable menu show/hide for a11y services.
if (!mAccessibilityManager.isTouchExplorationEnabled()) {
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
false /* allowMenuTimeout */, false /* willResizeMenu */);
false /* allowMenuTimeout */, false /* willResizeMenu */,
shouldShowResizeHandle());
}
case MotionEvent.ACTION_HOVER_MOVE: {
if (!shouldDeliverToMenu && !mSendingHoverAccessibilityEvents) {
@@ -904,7 +912,8 @@ public class PipTouchHandler {
// If the menu is still visible, then just poke the menu so that
// it will timeout after the user stops touching it
mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu());
true /* allowMenuTimeout */, willResizeMenu(),
shouldShowResizeHandle());
}
mShouldHideMenuAfterFling = mMenuState == MENU_STATE_NONE;
@@ -921,7 +930,8 @@ public class PipTouchHandler {
// User has stalled long enough for this not to be a drag or a double tap, just
// expand the menu
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu());
true /* allowMenuTimeout */, willResizeMenu(),
shouldShowResizeHandle());
} else {
// Next touch event _may_ be the second tap for the double-tap, schedule a
// fallback runnable to trigger the menu if no touch event occurs before the