Commit 3f70454c by eguven Committed by Oliver Woodman

Fix controller ui toggling when using SphericalSurfaceView

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=209909845
parent 74e2384f
...@@ -59,6 +59,7 @@ import com.google.android.exoplayer2.text.TextOutput; ...@@ -59,6 +59,7 @@ import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
import com.google.android.exoplayer2.ui.spherical.SingleTapListener;
import com.google.android.exoplayer2.ui.spherical.SphericalSurfaceView; import com.google.android.exoplayer2.ui.spherical.SphericalSurfaceView;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ErrorMessageProvider; import com.google.android.exoplayer2.util.ErrorMessageProvider;
...@@ -390,6 +391,7 @@ public class PlayerView extends FrameLayout { ...@@ -390,6 +391,7 @@ public class PlayerView extends FrameLayout {
Assertions.checkState(Util.SDK_INT >= 15); Assertions.checkState(Util.SDK_INT >= 15);
SphericalSurfaceView sphericalSurfaceView = new SphericalSurfaceView(context); SphericalSurfaceView sphericalSurfaceView = new SphericalSurfaceView(context);
sphericalSurfaceView.setSurfaceListener(componentListener); sphericalSurfaceView.setSurfaceListener(componentListener);
sphericalSurfaceView.setSingleTapListener(componentListener);
surfaceView = sphericalSurfaceView; surfaceView = sphericalSurfaceView;
break; break;
default: default:
...@@ -1021,15 +1023,10 @@ public class PlayerView extends FrameLayout { ...@@ -1021,15 +1023,10 @@ public class PlayerView extends FrameLayout {
@Override @Override
public boolean onTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) {
if (!useController || player == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) { if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
return false; return false;
} }
if (!controller.isVisible()) { return toggleControllerVisibility();
maybeShowController(true);
} else if (controllerHideOnTouch) {
controller.hide();
}
return true;
} }
@Override @Override
...@@ -1067,6 +1064,18 @@ public class PlayerView extends FrameLayout { ...@@ -1067,6 +1064,18 @@ public class PlayerView extends FrameLayout {
} }
} }
private boolean toggleControllerVisibility() {
if (!useController || player == null) {
return false;
}
if (!controller.isVisible()) {
maybeShowController(true);
} else if (controllerHideOnTouch) {
controller.hide();
}
return true;
}
/** Shows the playback controls, but only if forced or shown indefinitely. */ /** Shows the playback controls, but only if forced or shown indefinitely. */
private void maybeShowController(boolean isForced) { private void maybeShowController(boolean isForced) {
if (isPlayingAd() && controllerHideDuringAds) { if (isPlayingAd() && controllerHideDuringAds) {
...@@ -1286,7 +1295,8 @@ public class PlayerView extends FrameLayout { ...@@ -1286,7 +1295,8 @@ public class PlayerView extends FrameLayout {
TextOutput, TextOutput,
VideoListener, VideoListener,
OnLayoutChangeListener, OnLayoutChangeListener,
SphericalSurfaceView.SurfaceListener { SphericalSurfaceView.SurfaceListener,
SingleTapListener {
// TextOutput implementation // TextOutput implementation
...@@ -1391,5 +1401,12 @@ public class PlayerView extends FrameLayout { ...@@ -1391,5 +1401,12 @@ public class PlayerView extends FrameLayout {
} }
} }
} }
// SingleTapListener implementation
@Override
public boolean onSingleTapUp(MotionEvent e) {
return toggleControllerVisibility();
}
} }
} }
/*
* Copyright (C) 2018 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.
*/
package com.google.android.exoplayer2.ui.spherical;
import android.view.MotionEvent;
/** Listens tap events on a {@link android.view.View}. */
public interface SingleTapListener {
/**
* Notified when a tap occurs with the up {@link MotionEvent} that triggered it.
*
* @param e The up motion event that completed the first tap.
* @return Whether the event is consumed.
*/
boolean onSingleTapUp(MotionEvent e);
}
...@@ -91,6 +91,7 @@ public final class SphericalSurfaceView extends GLSurfaceView ...@@ -91,6 +91,7 @@ public final class SphericalSurfaceView extends GLSurfaceView
private final PhoneOrientationListener phoneOrientationListener; private final PhoneOrientationListener phoneOrientationListener;
private final Renderer renderer; private final Renderer renderer;
private final Handler mainHandler; private final Handler mainHandler;
private final TouchTracker touchTracker;
private @Nullable SurfaceListener surfaceListener; private @Nullable SurfaceListener surfaceListener;
private @Nullable SurfaceTexture surfaceTexture; private @Nullable SurfaceTexture surfaceTexture;
private @Nullable Surface surface; private @Nullable Surface surface;
...@@ -121,7 +122,7 @@ public final class SphericalSurfaceView extends GLSurfaceView ...@@ -121,7 +122,7 @@ public final class SphericalSurfaceView extends GLSurfaceView
renderer = new Renderer(); renderer = new Renderer();
TouchTracker touchTracker = new TouchTracker(renderer, PX_PER_DEGREES); touchTracker = new TouchTracker(context, renderer, PX_PER_DEGREES);
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = Assertions.checkNotNull(windowManager).getDefaultDisplay(); Display display = Assertions.checkNotNull(windowManager).getDefaultDisplay();
phoneOrientationListener = new PhoneOrientationListener(display, touchTracker, renderer); phoneOrientationListener = new PhoneOrientationListener(display, touchTracker, renderer);
...@@ -155,6 +156,11 @@ public final class SphericalSurfaceView extends GLSurfaceView ...@@ -155,6 +156,11 @@ public final class SphericalSurfaceView extends GLSurfaceView
surfaceListener = listener; surfaceListener = listener;
} }
/** Sets the {@link SingleTapListener} used to listen to single tap events on this view. */
public void setSingleTapListener(@Nullable SingleTapListener listener) {
touchTracker.setSingleTapListener(listener);
}
@Override @Override
public void onVideoFrameAboutToBeRendered( public void onVideoFrameAboutToBeRendered(
long presentationTimeUs, long releaseTimeNs, Format format) { long presentationTimeUs, long releaseTimeNs, Format format) {
......
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
*/ */
package com.google.android.exoplayer2.ui.spherical; package com.google.android.exoplayer2.ui.spherical;
import android.content.Context;
import android.graphics.PointF; import android.graphics.PointF;
import android.support.annotation.BinderThread; import android.support.annotation.BinderThread;
import android.support.annotation.Nullable;
import android.view.GestureDetector;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
...@@ -42,7 +45,8 @@ import android.view.View; ...@@ -42,7 +45,8 @@ import android.view.View;
* Mesh as the user moves their finger. However, that requires quaternion interpolation. * Mesh as the user moves their finger. However, that requires quaternion interpolation.
*/ */
// @VisibleForTesting // @VisibleForTesting
/*package*/ class TouchTracker implements View.OnTouchListener { /*package*/ class TouchTracker extends GestureDetector.SimpleOnGestureListener
implements View.OnTouchListener {
/*package*/ interface Listener { /*package*/ interface Listener {
void onScrollChange(PointF scrollOffsetDegrees); void onScrollChange(PointF scrollOffsetDegrees);
...@@ -58,16 +62,27 @@ import android.view.View; ...@@ -58,16 +62,27 @@ import android.view.View;
private final Listener listener; private final Listener listener;
private final float pxPerDegrees; private final float pxPerDegrees;
private final GestureDetector gestureDetector;
// The conversion from touch to yaw & pitch requires compensating for device roll. This is set // The conversion from touch to yaw & pitch requires compensating for device roll. This is set
// on the sensor thread and read on the UI thread. // on the sensor thread and read on the UI thread.
private volatile float roll; private volatile float roll;
private @Nullable SingleTapListener singleTapListener;
public TouchTracker(Listener listener, float pxPerDegrees) { @SuppressWarnings({
"nullness:assignment.type.incompatible",
"nullness:argument.type.incompatible"
})
public TouchTracker(Context context, Listener listener, float pxPerDegrees) {
this.listener = listener; this.listener = listener;
this.pxPerDegrees = pxPerDegrees; this.pxPerDegrees = pxPerDegrees;
gestureDetector = new GestureDetector(context, this);
roll = SphericalSurfaceView.UPRIGHT_ROLL; roll = SphericalSurfaceView.UPRIGHT_ROLL;
} }
public void setSingleTapListener(@Nullable SingleTapListener listener) {
singleTapListener = listener;
}
/** /**
* Converts ACTION_MOVE events to pitch & yaw events while compensating for device roll. * Converts ACTION_MOVE events to pitch & yaw events while compensating for device roll.
* *
...@@ -75,36 +90,46 @@ import android.view.View; ...@@ -75,36 +90,46 @@ import android.view.View;
*/ */
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) { return gestureDetector.onTouchEvent(event);
case MotionEvent.ACTION_DOWN: }
// Initialize drag gesture.
previousTouchPointPx.set(event.getX(), event.getY());
return true;
case MotionEvent.ACTION_MOVE:
// Calculate the touch delta in screen space.
float touchX = (event.getX() - previousTouchPointPx.x) / pxPerDegrees;
float touchY = (event.getY() - previousTouchPointPx.y) / pxPerDegrees;
previousTouchPointPx.set(event.getX(), event.getY());
float r = roll; // Copy volatile state. @Override
float cr = (float) Math.cos(r); public boolean onDown(MotionEvent e) {
float sr = (float) Math.sin(r); // Initialize drag gesture.
// To convert from screen space to the 3D space, we need to adjust the drag vector based previousTouchPointPx.set(e.getX(), e.getY());
// on the roll of the phone. This is standard rotationMatrix(roll) * vector math but has return true;
// an inverted y-axis due to the screen-space coordinates vs GL coordinates. }
// Handle yaw.
accumulatedTouchOffsetDegrees.x -= cr * touchX - sr * touchY;
// Handle pitch and limit it to 45 degrees.
accumulatedTouchOffsetDegrees.y += sr * touchX + cr * touchY;
accumulatedTouchOffsetDegrees.y =
Math.max(
-MAX_PITCH_DEGREES, Math.min(MAX_PITCH_DEGREES, accumulatedTouchOffsetDegrees.y));
listener.onScrollChange(accumulatedTouchOffsetDegrees); @Override
return true; public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
default: // Calculate the touch delta in screen space.
return false; float touchX = (e2.getX() - previousTouchPointPx.x) / pxPerDegrees;
float touchY = (e2.getY() - previousTouchPointPx.y) / pxPerDegrees;
previousTouchPointPx.set(e2.getX(), e2.getY());
float r = roll; // Copy volatile state.
float cr = (float) Math.cos(r);
float sr = (float) Math.sin(r);
// To convert from screen space to the 3D space, we need to adjust the drag vector based
// on the roll of the phone. This is standard rotationMatrix(roll) * vector math but has
// an inverted y-axis due to the screen-space coordinates vs GL coordinates.
// Handle yaw.
accumulatedTouchOffsetDegrees.x -= cr * touchX - sr * touchY;
// Handle pitch and limit it to 45 degrees.
accumulatedTouchOffsetDegrees.y += sr * touchX + cr * touchY;
accumulatedTouchOffsetDegrees.y =
Math.max(-MAX_PITCH_DEGREES, Math.min(MAX_PITCH_DEGREES, accumulatedTouchOffsetDegrees.y));
listener.onScrollChange(accumulatedTouchOffsetDegrees);
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (singleTapListener != null) {
return singleTapListener.onSingleTapUp(e);
} }
return false;
} }
@BinderThread @BinderThread
......
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 sign in to comment