import android.view.SurfaceView;
import android.view.ViewGroup;
+import com.google.common.annotations.VisibleForTesting;
+
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.content.browser.ContentViewCore;
*/
@JNINamespace("android_webview")
public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
- private static final int INVALID_PLAYER_ID = -1;
+ protected static final int INVALID_PLAYER_ID = -1;
// Because WebView does hole-punching by itself, instead, the hole-punching logic
// in SurfaceView can clear out some web elements like media control or subtitle.
private static WeakReference<ExternalVideoSurfaceContainer> sActiveContainer =
new WeakReference<ExternalVideoSurfaceContainer>(null);
- private final int mNativeExternalVideoSurfaceContainer;
+ private final long mNativeExternalVideoSurfaceContainer;
private final ContentViewCore mContentViewCore;
private int mPlayerId = INVALID_PLAYER_ID;
private SurfaceView mSurfaceView;
private int mWidth;
private int mHeight;
+ /**
+ * Factory class to facilitate dependency injection.
+ */
+ public static class Factory {
+ public ExternalVideoSurfaceContainer create(
+ long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+ return new ExternalVideoSurfaceContainer(
+ nativeExternalVideoSurfaceContainer, contentViewCore);
+ }
+ }
+ private static Factory sFactory = new Factory();
+
+ @VisibleForTesting
+ public static void setFactory(Factory factory) {
+ sFactory = factory;
+ }
+
@CalledByNative
private static ExternalVideoSurfaceContainer create(
- int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
- return new ExternalVideoSurfaceContainer(
- nativeExternalVideoSurfaceContainer, contentViewCore);
+ long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+ return sFactory.create(nativeExternalVideoSurfaceContainer, contentViewCore);
}
- private ExternalVideoSurfaceContainer(
- int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+ protected ExternalVideoSurfaceContainer(
+ long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
assert contentViewCore != null;
mNativeExternalVideoSurfaceContainer = nativeExternalVideoSurfaceContainer;
mContentViewCore = contentViewCore;
* @param playerId The ID of the media player.
*/
@CalledByNative
- private void requestExternalVideoSurface(int playerId) {
+ protected void requestExternalVideoSurface(int playerId) {
if (mPlayerId == playerId) return;
if (mPlayerId == INVALID_PLAYER_ID) {
* @param playerId The ID of the media player.
*/
@CalledByNative
- private void releaseExternalVideoSurface(int playerId) {
+ protected void releaseExternalVideoSurface(int playerId) {
if (mPlayerId != playerId) return;
releaseIfActiveContainer(this);
}
@CalledByNative
- private void destroy() {
+ protected void destroy() {
releaseExternalVideoSurface(mPlayerId);
}
* @param bottom The absolute CSS Y coordinate of the bottom side of the video element.
*/
@CalledByNative
- private void onExternalVideoSurfacePositionChanged(
+ protected void onExternalVideoSurfacePositionChanged(
int playerId, float left, float top, float right, float bottom) {
if (mPlayerId != playerId) return;
* Called when the page that contains the video element is scrolled or zoomed.
*/
@CalledByNative
- private void onFrameInfoUpdated() {
+ protected void onFrameInfoUpdated() {
if (mPlayerId == INVALID_PLAYER_ID) return;
layOutSurfaceView();