Commit 07cb7d14 authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

VR: Wait until orientation changes to remove black overlay.

This changes removes the black overlay with an animation after the
orientation change is completed and the GvrLayout is the correct size.

Bug: 860764
Change-Id: I8e0f1a0bc3779905d6259ecfcae0e487341f8ff6
Reviewed-on: https://chromium-review.googlesource.com/1132315
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574193}
parent 9d3ec8dc
......@@ -4,6 +4,9 @@
package org.chromium.chrome.browser.vr_shell;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
......@@ -58,7 +61,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.webapps.WebappActivity;
import org.chromium.content_public.browser.ScreenOrientationDelegate;
import org.chromium.content_public.browser.ScreenOrientationProvider;
import org.chromium.ui.UiUtils;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.display.DisplayAndroidManager;
import org.chromium.ui.widget.UiWidgetFactory;
......@@ -959,13 +961,37 @@ public class VrShellDelegate
View v = new View(activity);
v.setId(R.id.vr_overlay_view);
v.setBackgroundColor(Color.BLACK);
activity.getWindow().addContentView(v, params);
FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView();
decor.addView(v, params);
}
private static void removeBlackOverlayView(ChromeActivity activity) {
/* package */ static void removeBlackOverlayView(ChromeActivity activity, boolean animate) {
View overlay = activity.getWindow().findViewById(R.id.vr_overlay_view);
if (overlay == null) return;
UiUtils.removeViewFromParent(overlay);
FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView();
if (!animate) {
decor.removeView(overlay);
} else {
overlay.animate()
.alpha(0)
.setDuration(activity.getResources().getInteger(
android.R.integer.config_mediumAnimTime))
.setListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {}
@Override
public void onAnimationRepeat(Animator arg0) {}
@Override
public void onAnimationEnd(Animator arg0) {
decor.removeView(overlay);
}
@Override
public void onAnimationCancel(Animator arg0) {}
});
}
}
private static boolean isVrCoreCompatible(final Tab tabToShowInfobarIn) {
......@@ -1261,7 +1287,7 @@ public class VrShellDelegate
if (mVisible) mVrShell.resume();
mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
removeBlackOverlayView(mActivity);
if (!donSuceeded && isDaydreamCurrentViewerInternal()) {
// TODO(mthiesse): This is a VERY dirty hack. We need to know whether or not entering VR
// will trigger the DON flow, so that we can wait for it to complete before we let the
......@@ -1427,6 +1453,7 @@ public class VrShellDelegate
activity.getWindow().getDecorView().setSystemUiVisibility(flags | VR_SYSTEM_UI_FLAGS);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void setWindowModeForVr() {
// Decouple the compositor size from the view size, or we'll get an unnecessary resize due
// to the orientation change when entering VR, then another resize once VR has settled on
......@@ -1436,17 +1463,22 @@ public class VrShellDelegate
}
ScreenOrientationProvider.setOrientationDelegate(this);
// Hide system UI.
setSystemUiVisibilityForVr(mActivity);
// Set correct orientation.
if (mRestoreOrientation == null) {
mRestoreOrientation = mActivity.getRequestedOrientation();
}
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// Hide system UI.
setSystemUiVisibilityForVr(mActivity);
mRestoreSystemUiVisibility = true;
mActivity.getWindow().getAttributes().rotationAnimation =
WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void restoreWindowMode() {
ScreenOrientationProvider.setOrientationDelegate(null);
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
......@@ -1464,6 +1496,9 @@ public class VrShellDelegate
if (mActivity.getCompositorViewHolder() != null) {
mActivity.getCompositorViewHolder().onExitVr();
}
mActivity.getWindow().getAttributes().rotationAnimation =
WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
}
/* package */ boolean canEnterVr() {
......@@ -1871,7 +1906,7 @@ public class VrShellDelegate
private void cancelPendingVrEntry() {
if (DEBUG_LOGS) Log.i(TAG, "cancelPendingVrEntry");
removeBlackOverlayView(mActivity);
removeBlackOverlayView(mActivity, false /* animate */);
mDonSucceeded = false;
mActivateFromHeadsetInsertion = false;
maybeSetPresentResult(false, false);
......@@ -2030,9 +2065,17 @@ public class VrShellDelegate
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
decor.addView(mVrShell.getContainer(), params);
// If the overlay exists, make sure to hide the GvrLayout behind it.
View overlay = mActivity.getWindow().findViewById(R.id.vr_overlay_view);
if (overlay != null) overlay.bringToFront();
mActivity.onEnterVr();
}
protected boolean isBlackOverlayVisible() {
View overlay = mActivity.getWindow().findViewById(R.id.vr_overlay_view);
return overlay != null;
}
private void removeVrViews() {
mActivity.onExitVr();
FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
......
......@@ -365,7 +365,7 @@ public class VrShellImpl
DisplayMetrics dm = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
// We're supposed to be in landscape at this point, but it's possible for us to get here
// before the change has fully propogated. In this case, the width and height are swapped,
// before the change has fully propagated. In this case, the width and height are swapped,
// which causes an incorrect display size to be used, and the page to appear zoomed in.
if (dm.widthPixels < dm.heightPixels) {
int tempWidth = dm.heightPixels;
......@@ -374,6 +374,10 @@ public class VrShellImpl
float tempXDpi = dm.ydpi;
dm.xdpi = dm.ydpi;
dm.ydpi = tempXDpi;
// In the case where we're still in portrait, keep the black overlay visible until the
// GvrLayout is in the correct orientation.
} else {
VrShellDelegate.removeBlackOverlayView(mActivity, false /* animate */);
}
float displayWidthMeters = (dm.widthPixels / dm.xdpi) * INCHES_TO_METERS;
float displayHeightMeters = (dm.heightPixels / dm.ydpi) * INCHES_TO_METERS;
......@@ -1145,6 +1149,12 @@ public class VrShellImpl
if (mNativeVrShell != 0) nativeOnOverlayTextureEmptyChanged(mNativeVrShell, false);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
if (width > height) VrShellDelegate.removeBlackOverlayView(mActivity, true /* animate */);
}
/**
* Sets the callback that will be run when VrShellImpl's dispatchTouchEvent
* is run and the parent consumed the event.
......
......@@ -65,6 +65,11 @@ public class TestVrShellDelegate extends VrShellDelegate {
super.setFeedbackFrequency(frequency);
}
@Override
public boolean isBlackOverlayVisible() {
return super.isBlackOverlayVisible();
}
@Override
public boolean isListeningForWebVrActivate() {
return super.isListeningForWebVrActivate();
......
......@@ -130,6 +130,7 @@ public class WebVrInputTest {
TestFramework.executeStepAndWait(
"stepVerifyNoInitialTaps()", framework.getFirstTabWebContents());
TransitionUtils.enterPresentationOrFail(framework);
TransitionUtils.waitForOverlayGone();
// Wait on VrShellImpl to say that its parent consumed the touch event
// Set to 2 because there's an ACTION_DOWN followed by ACTION_UP
final CountDownLatch touchRegisteredLatch = new CountDownLatch(2);
......@@ -143,7 +144,7 @@ public class WebVrInputTest {
});
TouchCommon.singleClickView(mTestRule.getActivity().getWindow().getDecorView());
Assert.assertTrue("VrShellImpl dispatched touches",
touchRegisteredLatch.await(POLL_TIMEOUT_SHORT_MS, TimeUnit.MILLISECONDS));
touchRegisteredLatch.await(POLL_TIMEOUT_LONG_MS * 10, TimeUnit.MILLISECONDS));
TestFramework.executeStepAndWait(
"stepVerifyNoAdditionalTaps()", framework.getFirstTabWebContents());
TestFramework.endTest(framework.getFirstTabWebContents());
......
......@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.vr_shell.util;
import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_TIMEOUT_SHORT_MS;
import android.content.Intent;
import android.net.Uri;
......@@ -140,6 +141,18 @@ public class TransitionUtils {
}
}
/**
* Waits for the black overlay that shows during VR entry to be gone.
*/
public static void waitForOverlayGone() {
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
return !TestVrShellDelegate.getInstance().isBlackOverlayVisible();
}
}, POLL_TIMEOUT_SHORT_MS, POLL_CHECK_INTERVAL_SHORT_MS);
}
/**
* @return Whether the VR back button is enabled.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment