Update how PIP size is determined
- minSize = 108dp - defaultSmallestEdge = max(23% of screen width, minSize) - the shortest edge of the PIP should be minSize and the rest scales according to the aspect ratio - rather than a default PIP size, use default aspect ratio - adding expand button - fitting actions to spec Fixes: 35358504 Test: manually used test app to try different aspect ratios Change-Id: Ib6890fb7824889b9edeea7efb5b9771e64fc1514 Signed-off-by: Winson Chung <winsonc@google.com>
This commit is contained in:
committed by
Winson Chung
parent
d2d909778c
commit
a7f69740b5
@@ -18,9 +18,11 @@ package com.android.internal.policy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Size;
|
||||
import android.view.Gravity;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.Scroller;
|
||||
@@ -56,6 +58,10 @@ public class PipSnapAlgorithm {
|
||||
private final int mDefaultSnapMode = SNAP_MODE_CORNERS_AND_EDGES;
|
||||
private int mSnapMode = mDefaultSnapMode;
|
||||
|
||||
private final float mDefaultSizePercent;
|
||||
private final float mMinAspectRatioForMinSize;
|
||||
private final float mMaxAspectRatioForMinSize;
|
||||
|
||||
private Scroller mScroller;
|
||||
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
|
||||
@@ -63,9 +69,15 @@ public class PipSnapAlgorithm {
|
||||
private boolean mIsMinimized;
|
||||
|
||||
public PipSnapAlgorithm(Context context) {
|
||||
Resources res = context.getResources();
|
||||
mContext = context;
|
||||
mMinimizedVisibleSize = context.getResources().getDimensionPixelSize(
|
||||
mMinimizedVisibleSize = res.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.pip_minimized_visible_size);
|
||||
mDefaultSizePercent = res.getFloat(
|
||||
com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent);
|
||||
mMaxAspectRatioForMinSize = res.getFloat(
|
||||
com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
|
||||
mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
|
||||
onConfigurationChanged();
|
||||
}
|
||||
|
||||
@@ -241,6 +253,40 @@ public class PipSnapAlgorithm {
|
||||
movementBoundsOut.bottom -= imeHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size of the PiP at the given {@param aspectRatio}, ensuring that the minimum edge
|
||||
* is at least {@param minEdgeSize}.
|
||||
*/
|
||||
public Size getSizeForAspectRatio(float aspectRatio, float minEdgeSize, int displayWidth,
|
||||
int displayHeight) {
|
||||
final int smallestDisplaySize = Math.min(displayWidth, displayHeight);
|
||||
final int minSize = (int) Math.max(minEdgeSize, smallestDisplaySize * mDefaultSizePercent);
|
||||
|
||||
final int width;
|
||||
final int height;
|
||||
if (aspectRatio <= mMinAspectRatioForMinSize || aspectRatio > mMaxAspectRatioForMinSize) {
|
||||
// Beyond these points, we can just use the min size as the shorter edge
|
||||
if (aspectRatio <= 1) {
|
||||
// Portrait, width is the minimum size
|
||||
width = minSize;
|
||||
height = Math.round(width / aspectRatio);
|
||||
} else {
|
||||
// Landscape, height is the minimum size
|
||||
height = minSize;
|
||||
width = Math.round(height * aspectRatio);
|
||||
}
|
||||
} else {
|
||||
// Within these points, we ensure that the bounds fit within the radius of the limits
|
||||
// at the points
|
||||
final float widthAtMaxAspectRatioForMinSize = mMaxAspectRatioForMinSize * minSize;
|
||||
final float radius = PointF.length(widthAtMaxAspectRatioForMinSize, minSize);
|
||||
height = (int) Math.round(Math.sqrt((radius * radius) /
|
||||
(aspectRatio * aspectRatio + 1)));
|
||||
width = Math.round(height * aspectRatio);
|
||||
}
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the closest point in {@param points} to the given {@param x} and {@param y}.
|
||||
*/
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
<!-- Flags enabling default window features. See Window.java -->
|
||||
<bool name="config_defaultWindowFeatureOptionsPanel">false</bool>
|
||||
|
||||
<!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
|
||||
These values are in DPs and will be converted to pixel sizes internally. -->
|
||||
<string translatable="false" name="config_defaultPictureInPictureSize">240x135</string>
|
||||
<!-- The percentage of the screen width to use for the default width or height of
|
||||
picture-in-picture windows. Regardless of the percent set here, calculated size will never
|
||||
be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
|
||||
<item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.14</item>
|
||||
|
||||
<!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
|
||||
These values are in DPs and will be converted to pixel sizes internally. -->
|
||||
|
||||
@@ -2545,9 +2545,17 @@
|
||||
These values are in DPs and will be converted to pixel sizes internally. -->
|
||||
<string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string>
|
||||
|
||||
<!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
|
||||
These values are in DPs and will be converted to pixel sizes internally. -->
|
||||
<string translatable="false" name="config_defaultPictureInPictureSize">192x120</string>
|
||||
<!-- The percentage of the screen width to use for the default width or height of
|
||||
picture-in-picture windows. Regardless of the percent set here, calculated size will never
|
||||
be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
|
||||
<item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.23</item>
|
||||
|
||||
<!-- The default aspect ratio for picture-in-picture windows. -->
|
||||
<item name="config_pictureInPictureDefaultAspectRatio" format="float" type="dimen">1.777778</item>
|
||||
|
||||
<!-- This is the limit for the max and min aspect ratio (1 / this value) at which the min size
|
||||
will be used instead of an adaptive size based loosely on area. -->
|
||||
<item name="config_pictureInPictureAspectRatioLimitForMinSize" format="float" type="dimen">1.777778</item>
|
||||
|
||||
<!-- The default gravity for the picture-in-picture window.
|
||||
Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
|
||||
|
||||
@@ -486,6 +486,9 @@
|
||||
<!-- The default minimal size of a resizable task, in both dimensions. -->
|
||||
<dimen name="default_minimal_size_resizable_task">220dp</dimen>
|
||||
|
||||
<!-- The default minimal size of a PiP task, in both dimensions. -->
|
||||
<dimen name="default_minimal_size_pip_resizable_task">108dp</dimen>
|
||||
|
||||
<!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
|
||||
<dimen name="task_height_of_minimized_mode">80dp</dimen>
|
||||
|
||||
|
||||
@@ -318,7 +318,9 @@
|
||||
<java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" />
|
||||
<java-symbol type="bool" name="config_enableAppWidgetService" />
|
||||
<java-symbol type="string" name="config_defaultPictureInPictureScreenEdgeInsets" />
|
||||
<java-symbol type="string" name="config_defaultPictureInPictureSize" />
|
||||
<java-symbol type="dimen" name="config_pictureInPictureDefaultSizePercent" />
|
||||
<java-symbol type="dimen" name="config_pictureInPictureDefaultAspectRatio" />
|
||||
<java-symbol type="dimen" name="config_pictureInPictureAspectRatioLimitForMinSize" />
|
||||
<java-symbol type="integer" name="config_defaultPictureInPictureGravity" />
|
||||
<java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
|
||||
<java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
|
||||
@@ -1777,6 +1779,7 @@
|
||||
<java-symbol type="id" name="replace_message" />
|
||||
<java-symbol type="fraction" name="config_dimBehindFadeDuration" />
|
||||
<java-symbol type="dimen" name="default_minimal_size_resizable_task" />
|
||||
<java-symbol type="dimen" name="default_minimal_size_pip_resizable_task" />
|
||||
<java-symbol type="dimen" name="task_height_of_minimized_mode" />
|
||||
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
|
||||
<java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
|
||||
|
||||
38
packages/SystemUI/res/drawable/pip_expand.xml
Normal file
38
packages/SystemUI/res/drawable/pip_expand.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2017 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="60dp"
|
||||
android:height="60dp"
|
||||
android:viewportWidth="60"
|
||||
android:viewportHeight="60">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M8,7.5v45c0,2.75,2.25,5,5,5h34.05c2.75,0,4.95-2.25,4.95-5v-45c0-2.75-2.2-5-4.95-5H13
|
||||
C10.25,2.5,8,4.75,8,7.5z
|
||||
M13,6.5h34c0.55,0,1,0.45,1,1v45c0,0.55-0.45,1-1,1H13c-0.55,0-1-0.45-1-1v-45C12,6.95,12.45,6.5,13,6.5z" />
|
||||
<path
|
||||
android:pathData="M60,0L0,0l0,60h60V0z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M20.86,35h-2c-0.55,0-1,0.45-1,1v10.5c0,0.55,0.45,1,1,1h10.5c0.55,0,1-0.45,1-1v-2c0-0.55-0.45-1-1-1h-7.5
|
||||
V36C21.86,35.45,21.41,35,20.86,35z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M29.64,13.5v2c0,0.55,0.45,1,1,1h7.5V24c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1V13.5c0-0.55-0.45-1-1-1
|
||||
h-10.5C30.09,12.5,29.64,12.95,29.64,13.5z" />
|
||||
</vector>
|
||||
@@ -31,20 +31,33 @@
|
||||
android:src="@drawable/ic_close_white"
|
||||
android:background="?android:selectableItemBackgroundBorderless" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/expand_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ImageView
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/pip_phone_expand"
|
||||
android:src="@drawable/pip_expand"
|
||||
android:background="?android:selectableItemBackgroundBorderless" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actions_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:background="#66000000"
|
||||
android:visibility="invisible">
|
||||
<LinearLayout
|
||||
android:id="@+id/actions"
|
||||
android:id="@+id/actions_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="horizontal" />
|
||||
android:orientation="horizontal"
|
||||
android:divider="@android:color/transparent"
|
||||
android:showDividers="middle" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -731,6 +731,13 @@
|
||||
<!-- The size of the PIP drag-to-dismiss target. -->
|
||||
<dimen name="pip_dismiss_target_size">48dp</dimen>
|
||||
|
||||
<!-- The shortest-edge size of the expanded PiP. -->
|
||||
<dimen name="pip_expanded_shortest_edge_size">160dp</dimen>
|
||||
|
||||
<!-- The padding between actions in the PiP in landscape Note that the PiP does not reflect
|
||||
the configuration of the device, so we can't use -land resources. -->
|
||||
<dimen name="pip_between_action_padding_land">8dp</dimen>
|
||||
|
||||
<dimen name="default_gear_space">18dp</dimen>
|
||||
<dimen name="cell_overlay_padding">18dp</dimen>
|
||||
|
||||
|
||||
@@ -40,8 +40,9 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
@@ -57,8 +58,9 @@ public class PipMenuActivity extends Activity {
|
||||
private static final String TAG = "PipMenuActivity";
|
||||
|
||||
public static final int MESSAGE_SHOW_MENU = 1;
|
||||
public static final int MESSAGE_HIDE_MENU = 2;
|
||||
public static final int MESSAGE_UPDATE_ACTIONS = 3;
|
||||
public static final int MESSAGE_POKE_MENU = 2;
|
||||
public static final int MESSAGE_HIDE_MENU = 3;
|
||||
public static final int MESSAGE_UPDATE_ACTIONS = 4;
|
||||
|
||||
private static final long INITIAL_DISMISS_DELAY = 2000;
|
||||
private static final long POST_INTERACTION_DISMISS_DELAY = 1500;
|
||||
@@ -67,7 +69,9 @@ public class PipMenuActivity extends Activity {
|
||||
private boolean mMenuVisible;
|
||||
private final List<RemoteAction> mActions = new ArrayList<>();
|
||||
private View mMenuContainer;
|
||||
private LinearLayout mActionsGroup;
|
||||
private View mDismissButton;
|
||||
private int mBetweenActionPaddingLand;
|
||||
|
||||
private ObjectAnimator mMenuContainerAnimator;
|
||||
|
||||
@@ -83,6 +87,9 @@ public class PipMenuActivity extends Activity {
|
||||
case MESSAGE_SHOW_MENU:
|
||||
showMenu();
|
||||
break;
|
||||
case MESSAGE_POKE_MENU:
|
||||
cancelDelayedFinish();
|
||||
break;
|
||||
case MESSAGE_HIDE_MENU:
|
||||
hideMenu();
|
||||
break;
|
||||
@@ -127,6 +134,9 @@ public class PipMenuActivity extends Activity {
|
||||
mDismissButton.setOnClickListener((v) -> {
|
||||
dismissPip();
|
||||
});
|
||||
mActionsGroup = (LinearLayout) findViewById(R.id.actions_group);
|
||||
mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
|
||||
R.dimen.pip_between_action_padding_land);
|
||||
|
||||
notifyActivityCallback(mMessenger);
|
||||
showMenu();
|
||||
@@ -260,26 +270,30 @@ public class PipMenuActivity extends Activity {
|
||||
}
|
||||
|
||||
private void updateActionViews() {
|
||||
ViewGroup expandContainer = (ViewGroup) findViewById(R.id.expand_container);
|
||||
ViewGroup actionsContainer = (ViewGroup) findViewById(R.id.actions_container);
|
||||
actionsContainer.setOnTouchListener((v, ev) -> {
|
||||
// Do nothing, prevent click through to parent
|
||||
return true;
|
||||
});
|
||||
|
||||
int actionsContainerHeight = 0;
|
||||
if (mActions.isEmpty()) {
|
||||
actionsContainer.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
actionsContainer.setVisibility(View.VISIBLE);
|
||||
ViewGroup actionsGroup = (ViewGroup) findViewById(R.id.actions);
|
||||
if (actionsGroup != null) {
|
||||
actionsGroup.removeAllViews();
|
||||
if (mActionsGroup != null) {
|
||||
mActionsGroup.removeAllViews();
|
||||
|
||||
// Recreate the layout
|
||||
final View decorView = getWindow().getDecorView();
|
||||
final boolean isLandscapePip = decorView.getMeasuredWidth()
|
||||
> decorView.getMeasuredHeight();
|
||||
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);
|
||||
R.layout.pip_menu_action, mActionsGroup, false);
|
||||
action.getIcon().loadDrawableAsync(this, d -> {
|
||||
d.setTint(Color.WHITE);
|
||||
actionView.setImageDrawable(d);
|
||||
@@ -292,10 +306,21 @@ public class PipMenuActivity extends Activity {
|
||||
Log.w(TAG, "Failed to send action", e);
|
||||
}
|
||||
});
|
||||
actionsGroup.addView(actionView);
|
||||
if (isLandscapePip && i > 0) {
|
||||
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
|
||||
actionView.getLayoutParams();
|
||||
lp.leftMargin = mBetweenActionPaddingLand;
|
||||
}
|
||||
mActionsGroup.addView(actionView);
|
||||
}
|
||||
}
|
||||
actionsContainerHeight = actionsContainer.getLayoutParams().height;
|
||||
}
|
||||
|
||||
// Update the expand container margin to account for the existence of the action container
|
||||
((FrameLayout.LayoutParams) expandContainer.getLayoutParams()).bottomMargin =
|
||||
actionsContainerHeight;
|
||||
expandContainer.requestLayout();
|
||||
}
|
||||
|
||||
private void notifyRegisterInputConsumer() {
|
||||
|
||||
@@ -209,6 +209,21 @@ public class PipMenuActivityController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pokes the menu, indicating that the user is interacting with it.
|
||||
*/
|
||||
public void pokeMenu() {
|
||||
if (mToActivityMessenger != null) {
|
||||
Message m = Message.obtain();
|
||||
m.what = PipMenuActivity.MESSAGE_POKE_MENU;
|
||||
try {
|
||||
mToActivityMessenger.send(m);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not notify poke menu", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the menu activity.
|
||||
*/
|
||||
|
||||
@@ -57,8 +57,8 @@ public class PipMotionHelper {
|
||||
private static final int DEFAULT_MOVE_STACK_DURATION = 225;
|
||||
private static final int SNAP_STACK_DURATION = 225;
|
||||
private static final int DISMISS_STACK_DURATION = 375;
|
||||
private static final int SHRINK_STACK_FROM_MENU_DURATION = 175;
|
||||
private static final int EXPAND_STACK_TO_MENU_DURATION = 175;
|
||||
private static final int SHRINK_STACK_FROM_MENU_DURATION = 150;
|
||||
private static final int EXPAND_STACK_TO_MENU_DURATION = 150;
|
||||
private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 225;
|
||||
private static final int MINIMIZE_STACK_MAX_DURATION = 200;
|
||||
|
||||
|
||||
@@ -18,11 +18,13 @@ package com.android.systemui.pip.phone;
|
||||
|
||||
import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.view.IPinnedStackController;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.MotionEvent;
|
||||
@@ -31,6 +33,7 @@ import android.view.ViewConfiguration;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.policy.PipSnapAlgorithm;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.FlingAnimationUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -69,6 +72,7 @@ public class PipTouchHandler {
|
||||
private Rect mNormalMovementBounds = new Rect();
|
||||
private Rect mExpandedBounds = new Rect();
|
||||
private Rect mExpandedMovementBounds = new Rect();
|
||||
private int mExpandedShortestEdgeSize;
|
||||
|
||||
private Handler mHandler = new Handler();
|
||||
private Runnable mShowDismissAffordance = new Runnable() {
|
||||
@@ -145,6 +149,8 @@ public class PipTouchHandler {
|
||||
};
|
||||
mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mSnapAlgorithm,
|
||||
mFlingAnimationUtils);
|
||||
mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.pip_expanded_shortest_edge_size);
|
||||
|
||||
// Register the listener for input consumer touch events
|
||||
inputConsumerController.setTouchListener(this::handleTouchEvent);
|
||||
@@ -181,8 +187,14 @@ public class PipTouchHandler {
|
||||
Rect normalMovementBounds = new Rect();
|
||||
mSnapAlgorithm.getMovementBounds(mNormalBounds, insetBounds, normalMovementBounds,
|
||||
mIsImeShowing ? mImeHeight : 0);
|
||||
// TODO: Figure out the expanded size policy
|
||||
mExpandedBounds = new Rect(normalBounds);
|
||||
|
||||
// Calculate the expanded size
|
||||
float aspectRatio = (float) normalBounds.width() / normalBounds.height();
|
||||
Point displaySize = new Point();
|
||||
mContext.getDisplay().getRealSize(displaySize);
|
||||
Size expandedSize = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio,
|
||||
mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
|
||||
mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
|
||||
Rect expandedMovementBounds = new Rect();
|
||||
mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
|
||||
mIsImeShowing ? mImeHeight : 0);
|
||||
@@ -360,6 +372,12 @@ public class PipTouchHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the menu is still visible, and we aren't minimized, then just poke the menu
|
||||
// so that it will timeout after the user stops touching it
|
||||
if (mMenuController.isMenuVisible() && !mIsMinimized) {
|
||||
mMenuController.pokeMenu();
|
||||
}
|
||||
|
||||
if (ENABLE_DRAG_TO_DISMISS) {
|
||||
mDismissViewController.createDismissTarget();
|
||||
mHandler.postDelayed(mShowDismissAffordance, SHOW_DISMISS_AFFORDANCE_DELAY);
|
||||
|
||||
@@ -94,13 +94,16 @@ class PinnedStackController {
|
||||
|
||||
// The size and position information that describes where the pinned stack will go by default.
|
||||
private int mDefaultStackGravity;
|
||||
private Size mDefaultStackSize;
|
||||
private float mDefaultAspectRatio;
|
||||
private Point mScreenEdgeInsets;
|
||||
|
||||
// The aspect ratio bounds of the PIP.
|
||||
private float mMinAspectRatio;
|
||||
private float mMaxAspectRatio;
|
||||
|
||||
// The minimum edge size of the normal PiP bounds.
|
||||
private int mMinSize;
|
||||
|
||||
// Temp vars for calculation
|
||||
private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
|
||||
private final Rect mTmpInsets = new Rect();
|
||||
@@ -151,15 +154,15 @@ class PinnedStackController {
|
||||
*/
|
||||
void reloadResources() {
|
||||
final Resources res = mService.mContext.getResources();
|
||||
final Size defaultSizeDp = Size.parseSize(res.getString(
|
||||
com.android.internal.R.string.config_defaultPictureInPictureSize));
|
||||
mMinSize = res.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
|
||||
mDefaultAspectRatio = res.getFloat(
|
||||
com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
|
||||
final Size screenEdgeInsetsDp = Size.parseSize(res.getString(
|
||||
com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets));
|
||||
mDefaultStackGravity = res.getInteger(
|
||||
com.android.internal.R.integer.config_defaultPictureInPictureGravity);
|
||||
mDisplayContent.getDisplay().getRealMetrics(mTmpMetrics);
|
||||
mDefaultStackSize = new Size(dpToPx(defaultSizeDp.getWidth(), mTmpMetrics),
|
||||
dpToPx(defaultSizeDp.getHeight(), mTmpMetrics));
|
||||
mScreenEdgeInsets = new Point(dpToPx(screenEdgeInsetsDp.getWidth(), mTmpMetrics),
|
||||
dpToPx(screenEdgeInsetsDp.getHeight(), mTmpMetrics));
|
||||
mMinAspectRatio = res.getFloat(
|
||||
@@ -199,16 +202,13 @@ class PinnedStackController {
|
||||
* specified aspect ratio.
|
||||
*/
|
||||
Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio) {
|
||||
// Save the snap fraction, calculate the aspect ratio based on the current bounds
|
||||
// Save the snap fraction, calculate the aspect ratio based on screen size
|
||||
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
|
||||
getMovementBounds(stackBounds));
|
||||
final float radius = PointF.length(stackBounds.width(), stackBounds.height());
|
||||
final int height = (int) Math.round(Math.sqrt((radius * radius) /
|
||||
(aspectRatio * aspectRatio + 1)));
|
||||
final int width = Math.round(height * aspectRatio);
|
||||
final int left = (int) (stackBounds.centerX() - width / 2f);
|
||||
final int top = (int) (stackBounds.centerY() - height / 2f);
|
||||
stackBounds.set(left, top, left + width, top + height);
|
||||
final Size size = getSize(aspectRatio);
|
||||
final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
|
||||
final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
|
||||
stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
|
||||
mSnapAlgorithm.applySnapFraction(stackBounds, getMovementBounds(stackBounds), snapFraction);
|
||||
if (mIsMinimized) {
|
||||
applyMinimizedOffset(stackBounds, getMovementBounds(stackBounds));
|
||||
@@ -216,6 +216,14 @@ class PinnedStackController {
|
||||
return stackBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size of the PIP based on the given {@param aspectRatio}.
|
||||
*/
|
||||
Size getSize(float aspectRatio) {
|
||||
return mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mMinSize,
|
||||
mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default bounds to show the PIP when there is no active PIP.
|
||||
*/
|
||||
@@ -224,8 +232,9 @@ class PinnedStackController {
|
||||
getInsetBounds(insetBounds);
|
||||
|
||||
final Rect defaultBounds = new Rect();
|
||||
Gravity.apply(mDefaultStackGravity, mDefaultStackSize.getWidth(),
|
||||
mDefaultStackSize.getHeight(), insetBounds, 0, 0, defaultBounds);
|
||||
final Size size = getSize(mDefaultAspectRatio);
|
||||
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds, 0, 0,
|
||||
defaultBounds);
|
||||
return defaultBounds;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user