Merge "Show x for short period of time when activity is PIP'd" into oc-dev

This commit is contained in:
Mady Mellor
2017-04-12 15:32:26 +00:00
committed by Android (Google) Code Review
4 changed files with 171 additions and 103 deletions

View File

@@ -26,16 +26,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:forceHasOverlappingRendering="false"> android:forceHasOverlappingRendering="false">
<ImageView
android:id="@+id/dismiss"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
android:layout_gravity="top|end"
android:padding="@dimen/pip_action_padding"
android:contentDescription="@string/pip_phone_close"
android:src="@drawable/ic_close_white"
android:background="?android:selectableItemBackgroundBorderless" />
<!-- The margins for this container is calculated in the code depending on whether the <!-- The margins for this container is calculated in the code depending on whether the
actions_container is visible. --> actions_container is visible. -->
<FrameLayout <FrameLayout
@@ -67,4 +57,15 @@
android:showDividers="middle" /> android:showDividers="middle" />
</FrameLayout> </FrameLayout>
</FrameLayout> </FrameLayout>
<ImageView
android:id="@+id/dismiss"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
android:layout_gravity="top|end"
android:padding="@dimen/pip_action_padding"
android:contentDescription="@string/pip_phone_close"
android:src="@drawable/ic_close_white"
android:background="?android:selectableItemBackgroundBorderless" />
</FrameLayout> </FrameLayout>

View File

@@ -21,11 +21,16 @@ import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ALL
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MENU_STATE;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.Nullable; import android.annotation.Nullable;
@@ -85,7 +90,7 @@ public class PipMenuActivity extends Activity {
private static final float DISABLED_ACTION_ALPHA = 0.54f; private static final float DISABLED_ACTION_ALPHA = 0.54f;
private boolean mMenuVisible; private int mMenuState;
private boolean mAllowMenuTimeout = true; private boolean mAllowMenuTimeout = true;
private final List<RemoteAction> mActions = new ArrayList<>(); private final List<RemoteAction> mActions = new ArrayList<>();
@@ -98,7 +103,8 @@ public class PipMenuActivity extends Activity {
private ImageView mExpandButton; private ImageView mExpandButton;
private int mBetweenActionPaddingLand; private int mBetweenActionPaddingLand;
private ObjectAnimator mMenuContainerAnimator; private AnimatorSet mMenuContainerAnimator;
private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener = private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
new ValueAnimator.AnimatorUpdateListener() { new ValueAnimator.AnimatorUpdateListener() {
@Override @Override
@@ -119,7 +125,8 @@ public class PipMenuActivity extends Activity {
switch (msg.what) { switch (msg.what) {
case MESSAGE_SHOW_MENU: { case MESSAGE_SHOW_MENU: {
final Bundle data = (Bundle) msg.obj; final Bundle data = (Bundle) msg.obj;
showMenu(data.getParcelable(EXTRA_STACK_BOUNDS), showMenu(data.getInt(EXTRA_MENU_STATE),
data.getParcelable(EXTRA_STACK_BOUNDS),
data.getParcelable(EXTRA_MOVEMENT_BOUNDS), data.getParcelable(EXTRA_MOVEMENT_BOUNDS),
data.getBoolean(EXTRA_ALLOW_TIMEOUT)); data.getBoolean(EXTRA_ALLOW_TIMEOUT));
break; break;
@@ -170,9 +177,14 @@ public class PipMenuActivity extends Activity {
mMenuContainer = findViewById(R.id.menu_container); mMenuContainer = findViewById(R.id.menu_container);
mMenuContainer.setAlpha(0); mMenuContainer.setAlpha(0);
mMenuContainer.setOnClickListener((v) -> { mMenuContainer.setOnClickListener((v) -> {
expandPip(); if (mMenuState == MENU_STATE_CLOSE) {
showPipMenu();
} else {
expandPip();
}
}); });
mDismissButton = findViewById(R.id.dismiss); mDismissButton = findViewById(R.id.dismiss);
mDismissButton.setAlpha(0);
mDismissButton.setOnClickListener((v) -> { mDismissButton.setOnClickListener((v) -> {
dismissPip(); dismissPip();
}); });
@@ -236,7 +248,8 @@ public class PipMenuActivity extends Activity {
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
mDownDelta.set(ev.getX() - mDownPosition.x, ev.getY() - mDownPosition.y); mDownDelta.set(ev.getX() - mDownPosition.x, ev.getY() - mDownPosition.y);
if (mDownDelta.length() > mViewConfig.getScaledTouchSlop() && mMenuVisible) { if (mDownDelta.length() > mViewConfig.getScaledTouchSlop()
&& mMenuState != MENU_STATE_NONE) {
// Restore the input consumer and let that drive the movement of this menu // Restore the input consumer and let that drive the movement of this menu
notifyRegisterInputConsumer(); notifyRegisterInputConsumer();
cancelDelayedFinish(); cancelDelayedFinish();
@@ -259,17 +272,28 @@ public class PipMenuActivity extends Activity {
// Do nothing // Do nothing
} }
private void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) { private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
boolean allowMenuTimeout) {
mAllowMenuTimeout = allowMenuTimeout; mAllowMenuTimeout = allowMenuTimeout;
if (!mMenuVisible) { if (mMenuState != menuState) {
cancelDelayedFinish();
updateActionViews(stackBounds); updateActionViews(stackBounds);
if (mMenuContainerAnimator != null) { if (mMenuContainerAnimator != null) {
mMenuContainerAnimator.cancel(); mMenuContainerAnimator.cancel();
} }
notifyMenuVisibility(true); notifyMenuStateChange(menuState);
updateExpandButtonFromBounds(stackBounds, movementBounds); updateExpandButtonFromBounds(stackBounds, movementBounds);
mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA, mMenuContainerAnimator = new AnimatorSet();
ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
mMenuContainer.getAlpha(), 1f); mMenuContainer.getAlpha(), 1f);
menuAnim.addUpdateListener(mMenuBgUpdateListener);
ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
mDismissButton.getAlpha(), 1f);
if (menuState == MENU_STATE_FULL) {
mMenuContainerAnimator.playTogether(menuAnim, dismissAnim);
} else {
mMenuContainerAnimator.play(dismissAnim);
}
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN); mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION); mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
if (allowMenuTimeout) { if (allowMenuTimeout) {
@@ -280,7 +304,6 @@ public class PipMenuActivity extends Activity {
} }
}); });
} }
mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
mMenuContainerAnimator.start(); mMenuContainerAnimator.start();
} else { } else {
// If we are already visible, then just start the delayed dismiss and unregister any // If we are already visible, then just start the delayed dismiss and unregister any
@@ -297,13 +320,18 @@ public class PipMenuActivity extends Activity {
} }
private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility) { private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility) {
if (mMenuVisible) { if (mMenuState != MENU_STATE_NONE) {
cancelDelayedFinish(); cancelDelayedFinish();
if (notifyMenuVisibility) { if (notifyMenuVisibility) {
notifyMenuVisibility(false); notifyMenuStateChange(MENU_STATE_NONE);
} }
mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA, mMenuContainerAnimator = new AnimatorSet();
ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
mMenuContainer.getAlpha(), 0f); mMenuContainer.getAlpha(), 0f);
menuAnim.addUpdateListener(mMenuBgUpdateListener);
ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
mDismissButton.getAlpha(), 0f);
mMenuContainerAnimator.playTogether(menuAnim, dismissAnim);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT); mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION); mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() { mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
@@ -312,11 +340,9 @@ public class PipMenuActivity extends Activity {
if (animationFinishedRunnable != null) { if (animationFinishedRunnable != null) {
animationFinishedRunnable.run(); animationFinishedRunnable.run();
} }
finish(); finish();
} }
}); });
mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
mMenuContainerAnimator.start(); mMenuContainerAnimator.start();
} else { } else {
// If the menu is not visible, just finish now // If the menu is not visible, just finish now
@@ -332,11 +358,12 @@ public class PipMenuActivity extends Activity {
mActions.clear(); mActions.clear();
mActions.addAll(actions.getList()); mActions.addAll(actions.getList());
} }
if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) { final int menuState = intent.getIntExtra(EXTRA_MENU_STATE, MENU_STATE_NONE);
if (menuState != MENU_STATE_NONE) {
Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS); Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
Rect movementBounds = intent.getParcelableExtra(EXTRA_MOVEMENT_BOUNDS); Rect movementBounds = intent.getParcelableExtra(EXTRA_MOVEMENT_BOUNDS);
boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true); boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true);
showMenu(stackBounds, movementBounds, allowMenuTimeout); showMenu(menuState, stackBounds, movementBounds, allowMenuTimeout);
} }
} }
@@ -372,7 +399,7 @@ public class PipMenuActivity extends Activity {
return true; return true;
}); });
if (mActions.isEmpty()) { if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE) {
actionsContainer.setVisibility(View.INVISIBLE); actionsContainer.setVisibility(View.INVISIBLE);
} else { } else {
actionsContainer.setVisibility(View.VISIBLE); actionsContainer.setVisibility(View.VISIBLE);
@@ -427,12 +454,17 @@ public class PipMenuActivity extends Activity {
private void updateDismissFraction(float fraction) { private void updateDismissFraction(float fraction) {
int alpha; int alpha;
if (mMenuVisible) { final float menuAlpha = 1 - fraction;
mMenuContainer.setAlpha(1 - fraction); if (mMenuState == MENU_STATE_FULL) {
mMenuContainer.setAlpha(menuAlpha);
mDismissButton.setAlpha(menuAlpha);
final float interpolatedAlpha = final float interpolatedAlpha =
MENU_BACKGROUND_ALPHA * (1.0f - fraction) + DISMISS_BACKGROUND_ALPHA * fraction; MENU_BACKGROUND_ALPHA * menuAlpha + DISMISS_BACKGROUND_ALPHA * fraction;
alpha = (int) (interpolatedAlpha * 255); alpha = (int) (interpolatedAlpha * 255);
} else { } else {
if (mMenuState == MENU_STATE_CLOSE) {
mDismissButton.setAlpha(menuAlpha);
}
alpha = (int) (fraction * DISMISS_BACKGROUND_ALPHA * 255); alpha = (int) (fraction * DISMISS_BACKGROUND_ALPHA * 255);
} }
mBackgroundDrawable.setAlpha(alpha); mBackgroundDrawable.setAlpha(alpha);
@@ -450,11 +482,11 @@ public class PipMenuActivity extends Activity {
sendMessage(m, "Could not notify controller to unregister input consumer"); sendMessage(m, "Could not notify controller to unregister input consumer");
} }
private void notifyMenuVisibility(boolean visible) { private void notifyMenuStateChange(int menuState) {
mMenuVisible = visible; mMenuState = menuState;
Message m = Message.obtain(); Message m = Message.obtain();
m.what = PipMenuActivityController.MESSAGE_MENU_VISIBILITY_CHANGED; m.what = PipMenuActivityController.MESSAGE_MENU_STATE_CHANGED;
m.arg1 = visible ? 1 : 0; m.arg1 = menuState;
sendMessage(m, "Could not notify controller of PIP menu visibility"); sendMessage(m, "Could not notify controller of PIP menu visibility");
} }
@@ -481,6 +513,12 @@ public class PipMenuActivity extends Activity {
}, false /* notifyMenuVisibility */); }, false /* notifyMenuVisibility */);
} }
private void showPipMenu() {
Message m = Message.obtain();
m.what = PipMenuActivityController.MESSAGE_SHOW_MENU;
sendMessage(m, "Could not notify controller to show PIP menu");
}
private void notifyActivityCallback(Messenger callback) { private void notifyActivityCallback(Messenger callback) {
Message m = Message.obtain(); Message m = Message.obtain();
m.what = PipMenuActivityController.MESSAGE_UPDATE_ACTIVITY_CALLBACK; m.what = PipMenuActivityController.MESSAGE_UPDATE_ACTIVITY_CALLBACK;

View File

@@ -57,16 +57,21 @@ public class PipMenuActivityController {
public static final String EXTRA_STACK_BOUNDS = "stack_bounds"; public static final String EXTRA_STACK_BOUNDS = "stack_bounds";
public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds"; public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds";
public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout"; public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout";
public static final String EXTRA_SHOW_MENU = "show_menu";
public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction"; public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction";
public static final String EXTRA_MENU_STATE = "menu_state";
public static final int MESSAGE_MENU_VISIBILITY_CHANGED = 100; public static final int MESSAGE_MENU_STATE_CHANGED = 100;
public static final int MESSAGE_EXPAND_PIP = 101; public static final int MESSAGE_EXPAND_PIP = 101;
public static final int MESSAGE_MINIMIZE_PIP = 102; public static final int MESSAGE_MINIMIZE_PIP = 102;
public static final int MESSAGE_DISMISS_PIP = 103; public static final int MESSAGE_DISMISS_PIP = 103;
public static final int MESSAGE_UPDATE_ACTIVITY_CALLBACK = 104; public static final int MESSAGE_UPDATE_ACTIVITY_CALLBACK = 104;
public static final int MESSAGE_REGISTER_INPUT_CONSUMER = 105; public static final int MESSAGE_REGISTER_INPUT_CONSUMER = 105;
public static final int MESSAGE_UNREGISTER_INPUT_CONSUMER = 106; public static final int MESSAGE_UNREGISTER_INPUT_CONSUMER = 106;
public static final int MESSAGE_SHOW_MENU = 107;
public static final int MENU_STATE_NONE = 0;
public static final int MENU_STATE_CLOSE = 1;
public static final int MENU_STATE_FULL = 2;
/** /**
* A listener interface to receive notification on changes in PIP. * A listener interface to receive notification on changes in PIP.
@@ -75,10 +80,10 @@ public class PipMenuActivityController {
/** /**
* Called when the PIP menu visibility changes. * Called when the PIP menu visibility changes.
* *
* @param menuVisible whether or not the menu is visible * @param menuState the current state of the menu
* @param resize whether or not to resize the PiP with the visibility change * @param resize whether or not to resize the PiP with the state change
*/ */
void onPipMenuVisibilityChanged(boolean menuVisible, boolean resize); void onPipMenuStateChanged(int menuState, boolean resize);
/** /**
* Called when the PIP requested to be expanded. * Called when the PIP requested to be expanded.
@@ -94,6 +99,11 @@ public class PipMenuActivityController {
* Called when the PIP requested to be dismissed. * Called when the PIP requested to be dismissed.
*/ */
void onPipDismiss(); void onPipDismiss();
/**
* Called when the PIP requested to show the menu.
*/
void onPipShowMenu();
} }
private Context mContext; private Context mContext;
@@ -104,7 +114,7 @@ public class PipMenuActivityController {
private ArrayList<Listener> mListeners = new ArrayList<>(); private ArrayList<Listener> mListeners = new ArrayList<>();
private ParceledListSlice mAppActions; private ParceledListSlice mAppActions;
private ParceledListSlice mMediaActions; private ParceledListSlice mMediaActions;
private boolean mMenuVisible; private int mMenuState;
// The dismiss fraction update is sent frequently, so use a temporary bundle for the message // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
private Bundle mTmpDismissFractionData = new Bundle(); private Bundle mTmpDismissFractionData = new Bundle();
@@ -115,16 +125,16 @@ public class PipMenuActivityController {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case MESSAGE_MENU_VISIBILITY_CHANGED: { case MESSAGE_MENU_STATE_CHANGED: {
boolean visible = msg.arg1 > 0; int menuState = msg.arg1;
onMenuVisibilityChanged(visible, true /* resize */); onMenuStateChanged(menuState, true /* resize */);
break; break;
} }
case MESSAGE_EXPAND_PIP: { case MESSAGE_EXPAND_PIP: {
mListeners.forEach(l -> l.onPipExpand()); mListeners.forEach(l -> l.onPipExpand());
// Preemptively mark the menu as invisible once we expand the PiP, but don't // Preemptively mark the menu as invisible once we expand the PiP, but don't
// resize as we will be animating the stack // resize as we will be animating the stack
onMenuVisibilityChanged(false, false /* resize */); onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
break; break;
} }
case MESSAGE_MINIMIZE_PIP: { case MESSAGE_MINIMIZE_PIP: {
@@ -135,7 +145,11 @@ public class PipMenuActivityController {
mListeners.forEach(l -> l.onPipDismiss()); mListeners.forEach(l -> l.onPipDismiss());
// Preemptively mark the menu as invisible once we dismiss the PiP, but don't // Preemptively mark the menu as invisible once we dismiss the PiP, but don't
// resize as we'll be removing the stack in place // resize as we'll be removing the stack in place
onMenuVisibilityChanged(false, false /* resize */); onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
break;
}
case MESSAGE_SHOW_MENU: {
mListeners.forEach(l -> l.onPipShowMenu());
break; break;
} }
case MESSAGE_REGISTER_INPUT_CONSUMER: { case MESSAGE_REGISTER_INPUT_CONSUMER: {
@@ -151,7 +165,7 @@ public class PipMenuActivityController {
mStartActivityRequested = false; mStartActivityRequested = false;
// Mark the menu as invisible once the activity finishes as well // Mark the menu as invisible once the activity finishes as well
if (mToActivityMessenger == null) { if (mToActivityMessenger == null) {
onMenuVisibilityChanged(false, true /* resize */); onMenuStateChanged(MENU_STATE_NONE, true /* resize */);
} }
break; break;
} }
@@ -176,7 +190,7 @@ public class PipMenuActivityController {
} }
public void onActivityPinned() { public void onActivityPinned() {
if (!mMenuVisible) { if (mMenuState == MENU_STATE_NONE) {
// If the menu is not visible, then re-register the input consumer if it is not already // If the menu is not visible, then re-register the input consumer if it is not already
// registered // registered
mInputConsumerController.registerInputConsumer(); mInputConsumerController.registerInputConsumer();
@@ -209,23 +223,25 @@ public class PipMenuActivityController {
try { try {
mToActivityMessenger.send(m); mToActivityMessenger.send(m);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Could not notify menu to show", e); Log.e(TAG, "Could not notify menu to update dismiss fraction", e);
} }
} else if (!mStartActivityRequested) { } else if (!mStartActivityRequested) {
startMenuActivity(null /* stackBounds */, null /* movementBounds */, startMenuActivity(MENU_STATE_NONE, null /* stackBounds */,
false /* showMenu */, false /* allowMenuTimeout */); null /* movementBounds */, false /* allowMenuTimeout */);
} }
} }
/** /**
* Shows the menu activity. * Shows the menu activity.
*/ */
public void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) { public void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
boolean allowMenuTimeout) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "showMenu() hasActivity=" + (mToActivityMessenger != null)); Log.d(TAG, "showMenu() hasActivity=" + (mToActivityMessenger != null));
} }
if (mToActivityMessenger != null) { if (mToActivityMessenger != null) {
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putInt(EXTRA_MENU_STATE, menuState);
data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds); data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds); data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
@@ -238,7 +254,7 @@ public class PipMenuActivityController {
Log.e(TAG, "Could not notify menu to show", e); Log.e(TAG, "Could not notify menu to show", e);
} }
} else if (!mStartActivityRequested) { } else if (!mStartActivityRequested) {
startMenuActivity(stackBounds, movementBounds, true /* showMenu */, allowMenuTimeout); startMenuActivity(menuState, stackBounds, movementBounds, allowMenuTimeout);
} }
} }
@@ -279,10 +295,10 @@ public class PipMenuActivityController {
} }
/** /**
* @return whether the menu is currently visible. * @return the current menu state.
*/ */
public boolean isMenuVisible() { public int getMenuState() {
return mMenuVisible; return mMenuState;
} }
/** /**
@@ -306,7 +322,7 @@ public class PipMenuActivityController {
/** /**
* Starts the menu activity on the top task of the pinned stack. * Starts the menu activity on the top task of the pinned stack.
*/ */
private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu, private void startMenuActivity(int menuState, Rect stackBounds, Rect movementBounds,
boolean allowMenuTimeout) { boolean allowMenuTimeout) {
try { try {
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -321,7 +337,7 @@ public class PipMenuActivityController {
if (movementBounds != null) { if (movementBounds != null) {
intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds); intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds);
} }
intent.putExtra(EXTRA_SHOW_MENU, showMenu); intent.putExtra(EXTRA_MENU_STATE, menuState);
intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
options.setLaunchTaskId( options.setLaunchTaskId(
@@ -378,19 +394,19 @@ public class PipMenuActivityController {
/** /**
* Handles changes in menu visibility. * Handles changes in menu visibility.
*/ */
private void onMenuVisibilityChanged(boolean visible, boolean resize) { private void onMenuStateChanged(int menuState, boolean resize) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onMenuVisibilityChanged() mMenuVisible=" + mMenuVisible Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
+ " menuVisible=" + visible + " resize=" + resize); + " menuState=" + menuState + " resize=" + resize);
} }
if (visible) { if (menuState == MENU_STATE_NONE) {
mInputConsumerController.unregisterInputConsumer();
} else {
mInputConsumerController.registerInputConsumer(); mInputConsumerController.registerInputConsumer();
} else {
mInputConsumerController.unregisterInputConsumer();
} }
if (visible != mMenuVisible) { if (menuState != mMenuState) {
mListeners.forEach(l -> l.onPipMenuVisibilityChanged(visible, resize)); mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize));
if (visible) { if (menuState == MENU_STATE_FULL) {
// Once visible, start listening for media action changes. This call will trigger // Once visible, start listening for media action changes. This call will trigger
// the menu actions to be updated again. // the menu actions to be updated again.
mMediaController.addListener(mMediaActionListener); mMediaController.addListener(mMediaActionListener);
@@ -400,13 +416,13 @@ public class PipMenuActivityController {
mMediaController.removeListener(mMediaActionListener); mMediaController.removeListener(mMediaActionListener);
} }
} }
mMenuVisible = visible; mMenuState = menuState;
} }
public void dump(PrintWriter pw, String prefix) { public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " "; final String innerPrefix = prefix + " ";
pw.println(prefix + TAG); pw.println(prefix + TAG);
pw.println(innerPrefix + "mMenuVisible=" + mMenuVisible); pw.println(innerPrefix + "mMenuState=" + mMenuState);
pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger); pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger);
pw.println(innerPrefix + "mListeners=" + mListeners.size()); pw.println(innerPrefix + "mListeners=" + mListeners.size());
} }

View File

@@ -16,6 +16,10 @@
package com.android.systemui.pip.phone; package com.android.systemui.pip.phone;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
@@ -106,7 +110,7 @@ public class PipTouchHandler implements TunerService.Tunable {
private boolean mEnableMinimize = false; private boolean mEnableMinimize = false;
// Behaviour states // Behaviour states
private boolean mIsMenuVisible; private int mMenuState;
private boolean mIsMinimized; private boolean mIsMinimized;
private boolean mIsImeShowing; private boolean mIsImeShowing;
private int mImeHeight; private int mImeHeight;
@@ -129,8 +133,8 @@ public class PipTouchHandler implements TunerService.Tunable {
*/ */
private class PipMenuListener implements PipMenuActivityController.Listener { private class PipMenuListener implements PipMenuActivityController.Listener {
@Override @Override
public void onPipMenuVisibilityChanged(boolean menuVisible, boolean resize) { public void onPipMenuStateChanged(int menuState, boolean resize) {
setMenuVisibilityState(menuVisible, resize); setMenuState(menuState, resize);
} }
@Override @Override
@@ -152,6 +156,12 @@ public class PipTouchHandler implements TunerService.Tunable {
MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED, MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
METRIC_VALUE_DISMISSED_BY_TAP); METRIC_VALUE_DISMISSED_BY_TAP);
} }
@Override
public void onPipShowMenu() {
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
mMovementBounds, true /* allowMenuTimeout */);
}
} }
public PipTouchHandler(Context context, IActivityManager activityManager, public PipTouchHandler(Context context, IActivityManager activityManager,
@@ -193,20 +203,21 @@ public class PipTouchHandler implements TunerService.Tunable {
public void showPictureInPictureMenu() { public void showPictureInPictureMenu() {
// Only show the menu if the user isn't currently interacting with the PiP // Only show the menu if the user isn't currently interacting with the PiP
if (!mTouchState.isUserInteracting()) { if (!mTouchState.isUserInteracting()) {
mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds, mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
false /* allowMenuTimeout */); mMovementBounds, false /* allowMenuTimeout */);
} }
} }
public void onActivityPinned() { public void onActivityPinned() {
// Reset some states once we are pinned // Reset some states once we are pinned
if (mIsMenuVisible) { mMenuState = MENU_STATE_NONE;
mIsMenuVisible = false;
}
if (mIsMinimized) { if (mIsMinimized) {
setMinimizedStateInternal(false); setMinimizedStateInternal(false);
} }
mDismissViewController.destroyDismissTarget(); mDismissViewController.destroyDismissTarget();
mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
mMovementBounds, true /* allowMenuTimeout */);
} }
public void onPinnedStackAnimationEnded() { public void onPinnedStackAnimationEnded() {
@@ -266,7 +277,7 @@ public class PipTouchHandler implements TunerService.Tunable {
// touching the screen // touching the screen
} else { } else {
final Rect bounds = new Rect(animatingBounds); final Rect bounds = new Rect(animatingBounds);
final Rect toMovementBounds = mIsMenuVisible final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
? expandedMovementBounds ? expandedMovementBounds
: normalMovementBounds; : normalMovementBounds;
if (mIsImeShowing) { if (mIsImeShowing) {
@@ -293,7 +304,7 @@ public class PipTouchHandler implements TunerService.Tunable {
// above // above
mNormalMovementBounds = normalMovementBounds; mNormalMovementBounds = normalMovementBounds;
mExpandedMovementBounds = expandedMovementBounds; mExpandedMovementBounds = expandedMovementBounds;
updateMovementBounds(mIsMenuVisible); updateMovementBounds(mMenuState);
} }
private void onRegistrationChanged(boolean isRegistered) { private void onRegistrationChanged(boolean isRegistered) {
@@ -303,8 +314,8 @@ public class PipTouchHandler implements TunerService.Tunable {
} }
private void onAccessibilityShowMenu() { private void onAccessibilityShowMenu() {
mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds, mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
false /* allowMenuTimeout */); mMovementBounds, false /* allowMenuTimeout */);
} }
private boolean handleTouchEvent(MotionEvent ev) { private boolean handleTouchEvent(MotionEvent ev) {
@@ -336,7 +347,7 @@ public class PipTouchHandler implements TunerService.Tunable {
case MotionEvent.ACTION_UP: { case MotionEvent.ACTION_UP: {
// Update the movement bounds again if the state has changed since the user started // Update the movement bounds again if the state has changed since the user started
// dragging (ie. when the IME shows) // dragging (ie. when the IME shows)
updateMovementBounds(mIsMenuVisible); updateMovementBounds(mMenuState);
for (PipTouchGesture gesture : mGestures) { for (PipTouchGesture gesture : mGestures) {
if (gesture.onUp(mTouchState)) { if (gesture.onUp(mTouchState)) {
@@ -378,7 +389,7 @@ public class PipTouchHandler implements TunerService.Tunable {
break; break;
} }
} }
return !mIsMenuVisible; return mMenuState == MENU_STATE_NONE;
} }
/** /**
@@ -393,7 +404,7 @@ public class PipTouchHandler implements TunerService.Tunable {
final float distance = bounds.bottom - target; final float distance = bounds.bottom - target;
fraction = Math.min(distance / bounds.height(), 1f); fraction = Math.min(distance / bounds.height(), 1f);
} }
if (Float.compare(fraction, 0f) != 0 || mMenuController.isMenuVisible()) { if (Float.compare(fraction, 0f) != 0 || mMenuState != MENU_STATE_NONE) {
// Update if the fraction > 0, or if fraction == 0 and the menu was already visible // Update if the fraction > 0, or if fraction == 0 and the menu was already visible
mMenuController.setDismissFraction(fraction); mMenuController.setDismissFraction(fraction);
} }
@@ -449,8 +460,8 @@ public class PipTouchHandler implements TunerService.Tunable {
/** /**
* Sets the menu visibility. * Sets the menu visibility.
*/ */
void setMenuVisibilityState(boolean menuVisible, boolean resize) { void setMenuState(int menuState, boolean resize) {
if (menuVisible) { if (menuState == MENU_STATE_FULL) {
// Save the current snap fraction and if we do not drag or move the PiP, then // Save the current snap fraction and if we do not drag or move the PiP, then
// we store back to this snap fraction. Otherwise, we'll reset the snap // we store back to this snap fraction. Otherwise, we'll reset the snap
// fraction and snap to the closest edge // fraction and snap to the closest edge
@@ -459,7 +470,7 @@ public class PipTouchHandler implements TunerService.Tunable {
mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds, mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
mMovementBounds, mExpandedMovementBounds); mMovementBounds, mExpandedMovementBounds);
} }
} else { } else if (menuState == MENU_STATE_NONE) {
// Try and restore the PiP to the closest edge, using the saved snap fraction // Try and restore the PiP to the closest edge, using the saved snap fraction
// if possible // if possible
if (resize) { if (resize) {
@@ -469,10 +480,12 @@ public class PipTouchHandler implements TunerService.Tunable {
} }
mSavedSnapFraction = -1f; mSavedSnapFraction = -1f;
} }
mIsMenuVisible = menuVisible; mMenuState = menuState;
updateMovementBounds(menuVisible); updateMovementBounds(menuState);
MetricsLogger.visibility(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU, if (menuState != MENU_STATE_CLOSE) {
menuVisible); MetricsLogger.visibility(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU,
menuState == MENU_STATE_FULL);
}
} }
/** /**
@@ -501,7 +514,7 @@ public class PipTouchHandler implements TunerService.Tunable {
// If the menu is still visible, and we aren't minimized, then just poke the menu // 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 // so that it will timeout after the user stops touching it
if (mMenuController.isMenuVisible() && !mIsMinimized) { if (mMenuState != MENU_STATE_NONE && !mIsMinimized) {
mMenuController.pokeMenu(); mMenuController.pokeMenu();
} }
@@ -599,7 +612,7 @@ public class PipTouchHandler implements TunerService.Tunable {
!mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) { !mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) {
// Pip should be minimized // Pip should be minimized
setMinimizedStateInternal(true); setMinimizedStateInternal(true);
if (mMenuController.isMenuVisible()) { if (mMenuState == MENU_STATE_FULL) {
// If the user dragged the expanded PiP to the edge, then hiding the menu // If the user dragged the expanded PiP to the edge, then hiding the menu
// will trigger the PiP to be scaled back to the normal size with the // will trigger the PiP to be scaled back to the normal size with the
// minimize offset adjusted // minimize offset adjusted
@@ -617,11 +630,11 @@ public class PipTouchHandler implements TunerService.Tunable {
} }
AnimatorListenerAdapter postAnimationCallback = null; AnimatorListenerAdapter postAnimationCallback = null;
if (mMenuController.isMenuVisible()) { if (mMenuState != MENU_STATE_NONE) {
// If the menu is still visible, and we aren't minimized, then just poke the // 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 // menu so that it will timeout after the user stops touching it
mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds, mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(),
true /* allowMenuTimeout */); mMovementBounds, true /* allowMenuTimeout */);
} else { } else {
// If the menu is not visible, then we can still be showing the activity for the // If the menu is not visible, then we can still be showing the activity for the
// dismiss overlay, so just finish it after the animation completes // dismiss overlay, so just finish it after the animation completes
@@ -645,9 +658,9 @@ public class PipTouchHandler implements TunerService.Tunable {
mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */, mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */,
null /* animatorListener */); null /* animatorListener */);
setMinimizedStateInternal(false); setMinimizedStateInternal(false);
} else if (!mIsMenuVisible) { } else if (mMenuState != MENU_STATE_FULL) {
mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds, mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */); mMovementBounds, true /* allowMenuTimeout */);
} else { } else {
mMotionHelper.expandPip(); mMotionHelper.expandPip();
} }
@@ -658,8 +671,8 @@ public class PipTouchHandler implements TunerService.Tunable {
/** /**
* Updates the current movement bounds based on whether the menu is currently visible. * Updates the current movement bounds based on whether the menu is currently visible.
*/ */
private void updateMovementBounds(boolean isExpanded) { private void updateMovementBounds(int menuState) {
mMovementBounds = isExpanded mMovementBounds = menuState == MENU_STATE_FULL
? mExpandedMovementBounds ? mExpandedMovementBounds
: mNormalMovementBounds; : mNormalMovementBounds;
} }
@@ -672,7 +685,7 @@ public class PipTouchHandler implements TunerService.Tunable {
pw.println(innerPrefix + "mNormalMovementBounds=" + mNormalMovementBounds); pw.println(innerPrefix + "mNormalMovementBounds=" + mNormalMovementBounds);
pw.println(innerPrefix + "mExpandedBounds=" + mExpandedBounds); pw.println(innerPrefix + "mExpandedBounds=" + mExpandedBounds);
pw.println(innerPrefix + "mExpandedMovementBounds=" + mExpandedMovementBounds); pw.println(innerPrefix + "mExpandedMovementBounds=" + mExpandedMovementBounds);
pw.println(innerPrefix + "mIsMenuVisible=" + mIsMenuVisible); pw.println(innerPrefix + "mMenuState=" + mMenuState);
pw.println(innerPrefix + "mIsMinimized=" + mIsMinimized); pw.println(innerPrefix + "mIsMinimized=" + mIsMinimized);
pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing); pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
pw.println(innerPrefix + "mImeHeight=" + mImeHeight); pw.println(innerPrefix + "mImeHeight=" + mImeHeight);