Use SurfaceSyncGroup
to ensure resize transaction isn't dropped
This workaround is only applied on API 34, because the problem isn't present on API 33 and it is fixed in the platform for API 35 onwards. Issue: androidx/media#1237 #cherrypick PiperOrigin-RevId: 644729909
This commit is contained in:
parent
6cc6444dd9
commit
968f72fec6
@ -24,6 +24,9 @@
|
||||
connected, the session activity can be updated with
|
||||
`MediaSession.setSessionActivity(ControllerInfo, PendingIntent)`.
|
||||
* UI:
|
||||
* Work around a platform bug causing stretched/cropped video when using
|
||||
`SurfaceView` inside a Compose `AndroidView` on API 34
|
||||
([#1237](https://github.com/androidx/media/issues/1237)).
|
||||
* Downloads:
|
||||
* OkHttp Extension:
|
||||
* Cronet Extension:
|
||||
|
@ -31,6 +31,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
@ -39,9 +40,11 @@ import android.opengl.GLSurfaceView;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.AttachedSurfaceControl;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
@ -49,6 +52,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.window.SurfaceSyncGroup;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.IntDef;
|
||||
@ -293,6 +297,7 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
@Nullable private final View shutterView;
|
||||
@Nullable private final View surfaceView;
|
||||
private final boolean surfaceViewIgnoresVideoAspectRatio;
|
||||
@Nullable private final SurfaceSyncGroupCompatV34 surfaceSyncGroupV34;
|
||||
@Nullable private final ImageView imageView;
|
||||
@Nullable private final ImageView artworkView;
|
||||
@Nullable private final SubtitleView subtitleView;
|
||||
@ -353,6 +358,7 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
shutterView = null;
|
||||
surfaceView = null;
|
||||
surfaceViewIgnoresVideoAspectRatio = false;
|
||||
surfaceSyncGroupV34 = null;
|
||||
imageView = null;
|
||||
artworkView = null;
|
||||
subtitleView = null;
|
||||
@ -489,6 +495,7 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
surfaceView = null;
|
||||
}
|
||||
this.surfaceViewIgnoresVideoAspectRatio = surfaceViewIgnoresVideoAspectRatio;
|
||||
this.surfaceSyncGroupV34 = Util.SDK_INT == 34 ? new SurfaceSyncGroupCompatV34() : null;
|
||||
|
||||
// Ad overlay frame layout.
|
||||
adOverlayFrameLayout = findViewById(R.id.exo_ad_overlay);
|
||||
@ -1773,6 +1780,14 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
contentFrame, surfaceViewIgnoresVideoAspectRatio ? 0 : videoAspectRatio);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
if (Util.SDK_INT == 34) {
|
||||
checkNotNull(surfaceSyncGroupV34).maybeMarkSyncReadyAndClear();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
private static void configureEditModeLogoV23(
|
||||
Context context, Resources resources, ImageView logo) {
|
||||
@ -1862,6 +1877,17 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
updateAspectRatio();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceSizeChanged(int width, int height) {
|
||||
if (Util.SDK_INT == 34 && surfaceView instanceof SurfaceView) {
|
||||
// Register a SurfaceSyncGroup to work around https://github.com/androidx/media/issues/1237
|
||||
// (only present on API 34, fixed on API 35).
|
||||
checkNotNull(surfaceSyncGroupV34)
|
||||
.postRegister(
|
||||
mainLooperHandler, (SurfaceView) surfaceView, PlayerView.this::invalidate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderedFirstFrame() {
|
||||
if (shutterView != null) {
|
||||
@ -1981,4 +2007,36 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
||||
surfaceView.setSurfaceLifecycle(SurfaceView.SURFACE_LIFECYCLE_FOLLOWS_ATTACHMENT);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(34)
|
||||
private static final class SurfaceSyncGroupCompatV34 {
|
||||
|
||||
@Nullable SurfaceSyncGroup surfaceSyncGroup;
|
||||
|
||||
@DoNotInline
|
||||
public void postRegister(
|
||||
Handler mainLooperHandler, SurfaceView surfaceView, Runnable invalidate) {
|
||||
mainLooperHandler.post(
|
||||
() -> {
|
||||
@Nullable
|
||||
AttachedSurfaceControl rootSurfaceControl = surfaceView.getRootSurfaceControl();
|
||||
if (rootSurfaceControl == null) {
|
||||
// The SurfaceView isn't attached to a window, so don't apply the workaround.
|
||||
return;
|
||||
}
|
||||
surfaceSyncGroup = new SurfaceSyncGroup("exo-sync-b-334901521");
|
||||
Assertions.checkState(surfaceSyncGroup.add(rootSurfaceControl, () -> {}));
|
||||
invalidate.run();
|
||||
rootSurfaceControl.applyTransactionOnDraw(new SurfaceControl.Transaction());
|
||||
});
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public void maybeMarkSyncReadyAndClear() {
|
||||
if (surfaceSyncGroup != null) {
|
||||
surfaceSyncGroup.markSyncReady();
|
||||
surfaceSyncGroup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user