Merge "Updating PIP to match UX"
This commit is contained in:
committed by
Android (Google) Code Review
commit
e7e4998784
@@ -21,7 +21,6 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.view.Gravity;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.Scroller;
|
||||
@@ -44,9 +43,6 @@ public class PipSnapAlgorithm {
|
||||
// The friction multiplier to control how slippery the PIP is when flung
|
||||
private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
|
||||
|
||||
// The fraction of the stack width to show when minimized
|
||||
private static final float MINIMIZED_VISIBLE_FRACTION = 0.25f;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private final ArrayList<Integer> mSnapGravities = new ArrayList<>();
|
||||
@@ -56,8 +52,12 @@ public class PipSnapAlgorithm {
|
||||
private Scroller mScroller;
|
||||
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
|
||||
private final int mMinimizedVisibleSize;
|
||||
|
||||
public PipSnapAlgorithm(Context context) {
|
||||
mContext = context;
|
||||
mMinimizedVisibleSize = context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.pip_minimized_visible_size);
|
||||
onConfigurationChanged();
|
||||
}
|
||||
|
||||
@@ -129,11 +129,10 @@ public class PipSnapAlgorithm {
|
||||
* Applies the offset to the {@param stackBounds} to adjust it to a minimized state.
|
||||
*/
|
||||
public void applyMinimizedOffset(Rect stackBounds, Rect movementBounds, Point displaySize) {
|
||||
int visibleWidth = (int) (MINIMIZED_VISIBLE_FRACTION * stackBounds.width());
|
||||
if (stackBounds.left <= movementBounds.centerX()) {
|
||||
stackBounds.offsetTo(-stackBounds.width() + visibleWidth, stackBounds.top);
|
||||
stackBounds.offsetTo(-stackBounds.width() + mMinimizedVisibleSize, stackBounds.top);
|
||||
} else {
|
||||
stackBounds.offsetTo(displaySize.x - visibleWidth, stackBounds.top);
|
||||
stackBounds.offsetTo(displaySize.x - mMinimizedVisibleSize, stackBounds.top);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,15 +219,23 @@ public class PipSnapAlgorithm {
|
||||
* the new bounds out to {@param boundsOut}.
|
||||
*/
|
||||
private void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut) {
|
||||
final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
|
||||
final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
|
||||
final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
|
||||
final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
|
||||
// If the stackBounds are minimized, then it should only be snapped back horizontally
|
||||
final int boundedLeft = Math.max(movementBounds.left, Math.min(movementBounds.right,
|
||||
stackBounds.left));
|
||||
final int boundedTop = Math.max(movementBounds.top, Math.min(movementBounds.bottom,
|
||||
stackBounds.top));
|
||||
boundsOut.set(stackBounds);
|
||||
if (stackBounds.left < movementBounds.left ||
|
||||
stackBounds.left > movementBounds.right) {
|
||||
boundsOut.offsetTo(boundedLeft, boundsOut.top);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, just find the closest edge
|
||||
final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
|
||||
final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
|
||||
final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
|
||||
final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
|
||||
if (fromLeft <= fromTop && fromLeft <= fromRight && fromLeft <= fromBottom) {
|
||||
boundsOut.offsetTo(movementBounds.left, boundedTop);
|
||||
} else if (fromTop <= fromLeft && fromTop <= fromRight && fromTop <= fromBottom) {
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
when the user opens homescreen. -->
|
||||
<dimen name="docked_stack_minimize_thickness">8dp</dimen>
|
||||
|
||||
<!-- The amount to leave on-screen when the PIP is minimized. -->
|
||||
<dimen name="pip_minimized_visible_size">48dp</dimen>
|
||||
|
||||
<!-- Min width for a tablet device -->
|
||||
<dimen name="min_xlarge_screen_width">800dp</dimen>
|
||||
|
||||
|
||||
@@ -1542,6 +1542,7 @@
|
||||
<java-symbol type="dimen" name="docked_stack_divider_thickness" />
|
||||
<java-symbol type="dimen" name="docked_stack_divider_insets" />
|
||||
<java-symbol type="dimen" name="docked_stack_minimize_thickness" />
|
||||
<java-symbol type="dimen" name="pip_minimized_visible_size" />
|
||||
<java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
|
||||
<java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
|
||||
<java-symbol type="fraction" name="thumbnail_fullscreen_scale" />
|
||||
|
||||
@@ -13,32 +13,9 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout
|
||||
<ImageView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/pip_menu_action_icon_size"
|
||||
android:layout_height="@dimen/pip_menu_action_icon_size"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="4dp" />
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:includeFontPadding="false"
|
||||
android:gravity="center"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:textAllCaps="true"
|
||||
android:fontFamily="sans-serif" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="10dp"
|
||||
android:background="?android:selectableItemBackgroundBorderless" />
|
||||
@@ -13,47 +13,38 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#66000000">
|
||||
android:background="#00000000">
|
||||
<!-- The above background is only for the dismiss button ripple to show. -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="48dp">
|
||||
</LinearLayout>
|
||||
<ImageView
|
||||
android:id="@+id/dismiss"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="top|end"
|
||||
android:padding="10dp"
|
||||
android:contentDescription="@string/pip_phone_dismiss"
|
||||
android:src="@drawable/ic_close_white"
|
||||
android:background="?android:selectableItemBackgroundBorderless" />
|
||||
|
||||
<LinearLayout
|
||||
<FrameLayout
|
||||
android:id="@+id/actions_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/dismiss"
|
||||
android:layout_width="0dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:background="#66000000"
|
||||
android:visibility="invisible">
|
||||
<LinearLayout
|
||||
android:id="@+id/actions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/pip_phone_dismiss"
|
||||
android:background="?android:selectableItemBackground" />
|
||||
<TextView
|
||||
android:id="@+id/expand"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/pip_phone_expand"
|
||||
android:background="?android:selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="horizontal" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -724,10 +724,7 @@
|
||||
<!-- The alpha to apply to the recents row when it doesn't have focus -->
|
||||
<item name="recents_recents_row_dim_alpha" format="float" type="dimen">0.5</item>
|
||||
|
||||
<!-- The size of the PIP dismiss target. -->
|
||||
<!-- The size of the PIP drag-to-dismiss target. -->
|
||||
<dimen name="pip_dismiss_target_size">48dp</dimen>
|
||||
|
||||
<!-- The size of a PIP menu action icon. -->
|
||||
<dimen name="pip_menu_action_icon_size">32dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1704,14 +1704,6 @@
|
||||
not appear on production builds ever. -->
|
||||
<string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
|
||||
|
||||
<!-- PIP swipe to dismiss title. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_swipe_to_dismiss_title" translatable="false">Swipe to dismiss</string>
|
||||
|
||||
<!-- PIP swipe to dismiss description. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_swipe_to_dismiss_summary" translatable="false">Swipe left or right off screen to close the PIP</string>
|
||||
|
||||
<!-- PIP drag to dismiss title. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_drag_to_dismiss_title" translatable="false">Drag to dismiss</string>
|
||||
@@ -1720,22 +1712,6 @@
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_drag_to_dismiss_summary" translatable="false">Drag to the dismiss target at the bottom of the screen to close the PIP</string>
|
||||
|
||||
<!-- PIP tap once to break through to the activity title. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_tap_through_title" translatable="false">Tap to interact</string>
|
||||
|
||||
<!-- PIP tap once to break through to the activity description. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_tap_through_summary" translatable="false">Tap once to interact with the activity</string>
|
||||
|
||||
<!-- PIP snap to closest edge title. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_snap_mode_edge_title" translatable="false">Snap to closest edge</string>
|
||||
|
||||
<!-- PIP snap to closest edge description. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_snap_mode_edge_summary" translatable="false">Snap to the closest edge</string>
|
||||
|
||||
<!-- PIP allow minimize title. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_allow_minimize_title" translatable="false">Allow PIP to minimize</string>
|
||||
|
||||
@@ -125,35 +125,17 @@
|
||||
android:key="picture_in_picture"
|
||||
android:title="@string/picture_in_picture">
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_swipe_to_dismiss"
|
||||
android:title="@string/pip_swipe_to_dismiss_title"
|
||||
android:summary="@string/pip_swipe_to_dismiss_summary"
|
||||
sysui:defValue="true" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_drag_to_dismiss"
|
||||
android:title="@string/pip_drag_to_dismiss_title"
|
||||
android:summary="@string/pip_drag_to_dismiss_summary"
|
||||
sysui:defValue="true" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_tap_through"
|
||||
android:title="@string/pip_tap_through_title"
|
||||
android:summary="@string/pip_tap_through_summary"
|
||||
sysui:defValue="false" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_snap_mode_edge"
|
||||
android:title="@string/pip_snap_mode_edge_title"
|
||||
android:summary="@string/pip_snap_mode_edge_summary"
|
||||
sysui:defValue="false" />
|
||||
sysui:defValue="false" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_allow_minimize"
|
||||
android:title="@string/pip_allow_minimize_title"
|
||||
android:summary="@string/pip_allow_minimize_summary"
|
||||
sysui:defValue="false" />
|
||||
sysui:defValue="true" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@ public class PipMenuActivity extends Activity {
|
||||
private final List<RemoteAction> mActions = new ArrayList<>();
|
||||
private View mMenuContainer;
|
||||
private View mDismissButton;
|
||||
private View mExpandButton;
|
||||
|
||||
private ObjectAnimator mMenuContainerAnimator;
|
||||
|
||||
@@ -126,10 +125,6 @@ public class PipMenuActivity extends Activity {
|
||||
mDismissButton.setOnClickListener((v) -> {
|
||||
dismissPip();
|
||||
});
|
||||
mExpandButton = findViewById(R.id.expand);
|
||||
mExpandButton.setOnClickListener((v) -> {
|
||||
expandPip();
|
||||
});
|
||||
|
||||
notifyActivityCallback(mMessenger);
|
||||
showMenu();
|
||||
@@ -245,29 +240,35 @@ public class PipMenuActivity extends Activity {
|
||||
}
|
||||
|
||||
private void updateActionViews() {
|
||||
ViewGroup actionsContainer = (ViewGroup) findViewById(R.id.actions);
|
||||
if (actionsContainer != null) {
|
||||
actionsContainer.removeAllViews();
|
||||
ViewGroup actionsContainer = (ViewGroup) findViewById(R.id.actions_container);
|
||||
actionsContainer.setOnTouchListener((v, ev) -> {
|
||||
// Do nothing, prevent click through to parent
|
||||
return true;
|
||||
});
|
||||
|
||||
// Recreate the layout
|
||||
final LayoutInflater inflater = LayoutInflater.from(this);
|
||||
for (int i = 0; i < mActions.size(); i++) {
|
||||
final RemoteAction action = mActions.get(i);
|
||||
final ViewGroup actionContainer = (ViewGroup) inflater.inflate(
|
||||
R.layout.pip_menu_action, actionsContainer, false);
|
||||
actionContainer.setOnClickListener((v) -> {
|
||||
action.sendActionInvoked();
|
||||
});
|
||||
if (mActions.isEmpty()) {
|
||||
actionsContainer.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
actionsContainer.setVisibility(View.VISIBLE);
|
||||
ViewGroup actionsGroup = (ViewGroup) findViewById(R.id.actions);
|
||||
if (actionsGroup != null) {
|
||||
actionsGroup.removeAllViews();
|
||||
|
||||
final TextView title = (TextView) actionContainer.findViewById(R.id.title);
|
||||
title.setText(action.getTitle());
|
||||
title.setContentDescription(action.getContentDescription());
|
||||
|
||||
final ImageView icon = (ImageView) actionContainer.findViewById(R.id.icon);
|
||||
action.getIcon().loadDrawableAsync(this, (d) -> {
|
||||
icon.setImageDrawable(d);
|
||||
}, mHandler);
|
||||
actionsContainer.addView(actionContainer);
|
||||
// Recreate the layout
|
||||
final LayoutInflater inflater = LayoutInflater.from(this);
|
||||
for (int i = 0; i < mActions.size(); i++) {
|
||||
final RemoteAction action = mActions.get(i);
|
||||
final ImageView actionView = (ImageView) inflater.inflate(
|
||||
R.layout.pip_menu_action, actionsGroup, false);
|
||||
action.getIcon().loadDrawableAsync(this, d -> {
|
||||
actionView.setImageDrawable(d);
|
||||
}, mHandler);
|
||||
actionView.setContentDescription(action.getContentDescription());
|
||||
actionView.setOnClickListener(v -> {
|
||||
action.sendActionInvoked();
|
||||
});
|
||||
actionsGroup.addView(actionView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +58,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
private static final String TAG = "PipTouchHandler";
|
||||
private static final boolean DEBUG_ALLOW_OUT_OF_BOUNDS_STACK = false;
|
||||
|
||||
private static final String TUNER_KEY_SWIPE_TO_DISMISS = "pip_swipe_to_dismiss";
|
||||
private static final String TUNER_KEY_DRAG_TO_DISMISS = "pip_drag_to_dismiss";
|
||||
private static final String TUNER_KEY_TAP_THROUGH = "pip_tap_through";
|
||||
private static final String TUNER_KEY_SNAP_MODE_EDGE = "pip_snap_mode_edge";
|
||||
private static final String TUNER_KEY_ALLOW_MINIMIZE = "pip_allow_minimize";
|
||||
|
||||
private static final int SNAP_STACK_DURATION = 225;
|
||||
@@ -71,8 +68,6 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
|
||||
// The fraction of the stack width that the user has to drag offscreen to minimize the PIP
|
||||
private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.15f;
|
||||
// The fraction of the stack width that the user has to move when flinging to dismiss the PIP
|
||||
private static final float DISMISS_FLING_DISTANCE_FRACTION = 0.3f;
|
||||
|
||||
private final Context mContext;
|
||||
private final IActivityManager mActivityManager;
|
||||
@@ -87,16 +82,10 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
private final PipSnapAlgorithm mSnapAlgorithm;
|
||||
private PipMotionHelper mMotionHelper;
|
||||
|
||||
// Allow swiping offscreen to dismiss the PIP
|
||||
private boolean mEnableSwipeToDismiss = true;
|
||||
// Allow dragging the PIP to a location to close it
|
||||
private boolean mEnableDragToDismiss = true;
|
||||
// Allow tapping on the PIP to show additional controls
|
||||
private boolean mEnableTapThrough = false;
|
||||
// Allow snapping the PIP to the closest edge and not the corners of the screen
|
||||
private boolean mEnableSnapToEdge = false;
|
||||
private boolean mEnableDragToDismiss = false;
|
||||
// Allow the PIP to be "docked" slightly offscreen
|
||||
private boolean mEnableMinimizing = false;
|
||||
private boolean mEnableMinimizing = true;
|
||||
|
||||
private final Rect mPinnedStackBounds = new Rect();
|
||||
private final Rect mBoundedPinnedStackBounds = new Rect();
|
||||
@@ -192,16 +181,15 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
mSnapAlgorithm = new PipSnapAlgorithm(mContext);
|
||||
mTouchState = new PipTouchState(mViewConfig);
|
||||
mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
|
||||
mGestures = new PipTouchGesture[]{
|
||||
mDragToDismissGesture, mSwipeToDismissGesture, mTapThroughGesture, mMinimizeGesture,
|
||||
mDefaultMovementGesture
|
||||
mGestures = new PipTouchGesture[] {
|
||||
mDragToDismissGesture, mTapThroughGesture, mMinimizeGesture, mDefaultMovementGesture
|
||||
};
|
||||
mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
|
||||
registerInputConsumer();
|
||||
setSnapToEdge(true);
|
||||
|
||||
// Register any tuner settings changes
|
||||
TunerService.get(context).addTunable(this, TUNER_KEY_SWIPE_TO_DISMISS,
|
||||
TUNER_KEY_DRAG_TO_DISMISS, TUNER_KEY_TAP_THROUGH, TUNER_KEY_SNAP_MODE_EDGE,
|
||||
TunerService.get(context).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
|
||||
TUNER_KEY_ALLOW_MINIMIZE);
|
||||
}
|
||||
|
||||
@@ -209,34 +197,18 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (newValue == null) {
|
||||
// Reset back to default
|
||||
mEnableSwipeToDismiss = true;
|
||||
mEnableDragToDismiss = true;
|
||||
mEnableMinimizing = false;
|
||||
mEnableDragToDismiss = false;
|
||||
mEnableMinimizing = true;
|
||||
setMinimizedState(false);
|
||||
mEnableTapThrough = false;
|
||||
mIsTappingThrough = false;
|
||||
mEnableSnapToEdge = false;
|
||||
setSnapToEdge(false);
|
||||
return;
|
||||
}
|
||||
switch (key) {
|
||||
case TUNER_KEY_SWIPE_TO_DISMISS:
|
||||
mEnableSwipeToDismiss = Integer.parseInt(newValue) != 0;
|
||||
break;
|
||||
case TUNER_KEY_DRAG_TO_DISMISS:
|
||||
mEnableDragToDismiss = Integer.parseInt(newValue) != 0;
|
||||
break;
|
||||
case TUNER_KEY_ALLOW_MINIMIZE:
|
||||
mEnableMinimizing = Integer.parseInt(newValue) != 0;
|
||||
break;
|
||||
case TUNER_KEY_TAP_THROUGH:
|
||||
mEnableTapThrough = Integer.parseInt(newValue) != 0;
|
||||
mIsTappingThrough = false;
|
||||
break;
|
||||
case TUNER_KEY_SNAP_MODE_EDGE:
|
||||
mEnableSnapToEdge = Integer.parseInt(newValue) != 0;
|
||||
setSnapToEdge(mEnableSnapToEdge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,45 +452,6 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the velocity is coincident with the current pinned stack bounds to be
|
||||
* considered a fling to dismiss.
|
||||
*/
|
||||
private boolean isFlingToDismiss(float velocityX) {
|
||||
Point displaySize = new Point();
|
||||
mContext.getDisplay().getRealSize(displaySize);
|
||||
return (mPinnedStackBounds.right > displaySize.x && velocityX > 0) ||
|
||||
(mPinnedStackBounds.left < 0 && velocityX < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flings the PIP to dismiss it offscreen.
|
||||
*/
|
||||
private void flingToDismiss(float velocityX) {
|
||||
Point displaySize = new Point();
|
||||
mContext.getDisplay().getRealSize(displaySize);
|
||||
float offsetX = velocityX > 0
|
||||
? displaySize.x + mPinnedStackBounds.width()
|
||||
: -mPinnedStackBounds.width();
|
||||
|
||||
Rect toBounds = new Rect(mPinnedStackBounds);
|
||||
toBounds.offsetTo((int) offsetX, toBounds.top);
|
||||
if (!mPinnedStackBounds.equals(toBounds)) {
|
||||
mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
|
||||
toBounds, 0, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
|
||||
mFlingAnimationUtils.apply(mPinnedStackBoundsAnimator, 0,
|
||||
distanceBetweenRectOffsets(mPinnedStackBounds, toBounds),
|
||||
velocityX);
|
||||
mPinnedStackBoundsAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
BackgroundThread.getHandler().post(PipTouchHandler.this::dismissPinnedStack);
|
||||
}
|
||||
});
|
||||
mPinnedStackBoundsAnimator.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the dismissal of the PIP over the dismiss target bounds.
|
||||
*/
|
||||
@@ -642,57 +575,6 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
|
||||
/**** Gestures ****/
|
||||
|
||||
/**
|
||||
* Gesture controlling swiping offscreen to dismiss the PIP.
|
||||
*/
|
||||
private PipTouchGesture mSwipeToDismissGesture = new PipTouchGesture() {
|
||||
@Override
|
||||
boolean onMove(PipTouchState touchState) {
|
||||
if (mEnableSwipeToDismiss) {
|
||||
boolean isDraggingOffscreen = isDraggingOffscreen(touchState);
|
||||
|
||||
if (touchState.startedDragging() && isDraggingOffscreen) {
|
||||
// Reset the minimized state once we drag horizontally
|
||||
setMinimizedState(false);
|
||||
}
|
||||
|
||||
if (touchState.allowDraggingOffscreen() && isDraggingOffscreen) {
|
||||
// Move the pinned stack, but ignore the vertical movement
|
||||
float left = mPinnedStackBounds.left + touchState.getLastTouchDelta().x;
|
||||
mTmpBounds.set(mPinnedStackBounds);
|
||||
mTmpBounds.offsetTo((int) left, mPinnedStackBounds.top);
|
||||
if (!mTmpBounds.equals(mPinnedStackBounds)) {
|
||||
mPinnedStackBounds.set(mTmpBounds);
|
||||
mMotionHelper.resizeToBounds(mPinnedStackBounds);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUp(PipTouchState touchState) {
|
||||
if (mEnableSwipeToDismiss && touchState.isDragging()) {
|
||||
PointF vel = touchState.getVelocity();
|
||||
PointF downDelta = touchState.getDownTouchDelta();
|
||||
float minFlingVel = mFlingAnimationUtils.getMinVelocityPxPerSecond();
|
||||
float flingVelScale = mEnableMinimizing ? 3f : 2f;
|
||||
if (Math.abs(vel.x) > (flingVelScale * minFlingVel)) {
|
||||
// Determine if this gesture is actually a fling to dismiss
|
||||
if (isFlingToDismiss(vel.x) && Math.abs(downDelta.x) >=
|
||||
(DISMISS_FLING_DISTANCE_FRACTION * mPinnedStackBounds.width())) {
|
||||
flingToDismiss(vel.x);
|
||||
} else {
|
||||
flingToSnapTarget(vel.length(), vel.x, vel.y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gesture controlling dragging the PIP slightly offscreen to minimize it.
|
||||
*/
|
||||
@@ -771,8 +653,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
|
||||
@Override
|
||||
public boolean onUp(PipTouchState touchState) {
|
||||
if (mEnableTapThrough && !touchState.isDragging() && !mIsMinimized &&
|
||||
!mIsTappingThrough) {
|
||||
if (!touchState.isDragging() && !mIsMinimized && !mIsTappingThrough) {
|
||||
mMenuController.showMenu();
|
||||
mIsTappingThrough = true;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user