Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SurfaceView inside Compose AndroidView often shown stretched/cropped on API 34 #1237

Closed
1 task
MykolaKosianchuk opened this issue Apr 2, 2024 · 28 comments
Closed
1 task
Assignees

Comments

@MykolaKosianchuk
Copy link

MykolaKosianchuk commented Apr 2, 2024

Version

Media3 main branch

More version details

1.3.0, 1.2.1, 1.1.1

Devices that reproduce the issue

Pixel running on Android 14 with updated to 5 March 2024 (important)

Devices that do not reproduce the issue

Pixel running on Android 14 without updated to 5 March 2024

Reproducible in the demo app?

Not tested

Reproduction steps

Here is code that could help to reproduce.

class MainActivity : ComponentActivity() {
    @OptIn(UnstableApi::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val context = LocalContext.current

            val exoPlayer = remember { ExoPlayer.Builder(context).build() }

            DisposableEffect(Unit) {
                onDispose {
                    exoPlayer.release()
                }
            }

            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight(0.5f) //important to have
//                    .height(500.dp) - also reproducible
                    .background(Color.Black),
                contentAlignment = Alignment.Center
            ) {
                AndroidView(
                    factory = { ctx ->
                        PlayerView(ctx).apply {
                            useController = false
                            resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
                        }
                    },
                    update = {
                        it.player = exoPlayer
                        exoPlayer.setMediaItem(
                            MediaItem.fromUri("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
                        )
                        exoPlayer.playWhenReady = true
                        exoPlayer.prepare()
                    },
                )
            }
        }
    }
}

Expected result

Media should be visible correctly

Actual result

Media shows with a wrong aspect ratio

Media

Here is how it looks

Screenshot 2024-04-02 at 15 52 20

Bug Report

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.
@phcannesson
Copy link

+1 this
We've spent days trying to understand issues we have with Android 14 devices recently.
Going back to our previous app versions doesn't fix anything, so we came up with the same conclusion as @MykolaKosianchuk , it's probably related to a recent Android patch.

@MykolaKosianchuk
Copy link
Author

@phcannesson Yes, we found this issue and tried to reproduce it on the device without the last patch but we can't. However, once we updated the phone, the issue appeared.

@harry248
Copy link

harry248 commented Apr 3, 2024

We have the same problem. We had already observed this in the QPR but unfortunately did not create an issue. Interestingly, we "only" have the problem if we use the AndroidView (which creates the PlayerView) in an if block, i.e. the composable is not called immediately.

@icbaker
Copy link
Collaborator

icbaker commented Apr 8, 2024

Reproducible in the demo app?

Not tested

Please can you test this? It would help us to debug if we know whether it can be reproduced in the demo app.


Interestingly, we "only" have the problem if we use the AndroidView (which creates the PlayerView) in an if block, i.e. the composable is not called immediately.

Is this true for everyone else that has commented on this bug? Is everyone else experiencing this only in Compose contexts, or also in conventional views? This looks like it might be a duplicate of #1123 but it's interesting to hear that the behaviour changes between Android 14 before the March 5th update and after it.

@phcannesson
Copy link

Reproducible in the demo app?

Not tested

Please can you test this? It would help us to debug if we know whether it can be reproduced in the demo app.

Interestingly, we "only" have the problem if we use the AndroidView (which creates the PlayerView) in an if block, i.e. the composable is not called immediately.

Is this true for everyone else that has commented on this bug? Is everyone else experiencing this only in Compose contexts, or also in conventional views? This looks like it might be a duplicate of #1123 but it's interesting to hear that the behaviour changes between Android 14 before the March 5th update and after it.

On our side we're using Compose.
We did not test with conventional views.

@promanowicz
Copy link

I have faced exact same issue, except I was using resizeMode with fixed height.
I addition I have noticed that the video gets right aspect ratio after I switched orientation to landscape and then back to portrait.

@MykolaKosianchuk
Copy link
Author

@icbaker It is not reproducible in the demo app
Looks like it is related to the compose

@speedclaud
Copy link

speedclaud commented Apr 11, 2024

Hi @icbaker , I was also not able to reproduce the issue on your demo app on Pixel 7, Android 14, march 5th update, but we have the issue in our compose app using AndroidView. The issue is present in this sample app that uses compose, (press on the "Exo PlayerView" button):

compose-media.zip

This is what it looks like:

Screenshot_20240411_121959

@phcannesson
Copy link

phcannesson commented Apr 11, 2024

On our side, after some testing, we've detected that it seems to be related to the way the frame layout gets notified of changes in the player.
We've successfully "fixed" the issue by adding some delay before displaying the AndroidView.
That apparently allows the player to be fully ready when the view is loaded.

@speedclaud
Copy link

On our side, after some testing, we've detected that it seems to be related to the way the frame layout gets notified of changes in the player. We've successfully "fixed" the issue by adding some delay before displaying the AndroidView. That apparently allows the player to be fully ready when the view is loaded.

I've tried adding a delay to the sample app above (with a boolean mutable state and a LaunchedEffect), but the stretch is still present when It shows.

@speedclaud
Copy link

speedclaud commented Apr 11, 2024

I found a "fix", the stretch is gone when using app:surface_type="texture_view". So I assume there's something wrong with app:surface_type="surface_view" inside AndroidView on the latest android?

Is it true that texture_view drains more battery?

@icbaker
Copy link
Collaborator

icbaker commented Apr 11, 2024

Thanks for the repro app in #1237 (comment). I ran this on a Pixel 7a running lynx-userdebug AP1A.240405.002 and observed the problematic behaviour shown in your screenshot nearly every time (the first time i launched the app it seemed to work OK, but the subsequent ~10 times it shows the problem - even after swiping the app away from recents, and clearing app data).

I added an EventLogger (https://developer.android.com/media/media3/exoplayer/debug-logging) and grabbed the logcat filtered to EventLogger of a problematic repro.

I then flashed my device back to before the March feature release, to lynx-userdebug UQ1A.240205.002 and installed the app. The first time I launched the video it played fine. I grabbed the same filtered logcat, and diffed it against the problematic behaviour. Then subsequent launches of the video (without dismissing the app) showed the problem (and I grabbed the logcat). Swiping the app away and re-launching it seems to allow the playback to work correctly once, then subsequent launches are problematic.

I observed the following in logcat right at the start of playback in the problematic case on AP1A.240405.002:

timeline [eventTime=0.02, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
mediaItem [eventTime=0.02, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
state [eventTime=0.02, mediaPos=0.00, window=0, BUFFERING]
surfaceSize [eventTime=0.06, mediaPos=0.00, window=0, 0, 0]
surfaceSize [eventTime=0.08, mediaPos=0.00, window=0, 1080, 1080]
timeline [eventTime=0.09, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
positionDiscontinuity [eventTime=0.10, mediaPos=0.00, window=0, reason=REMOVE, PositionInfo:old [mediaItem=0, period=0, pos=0], PositionInfo:new [mediaItem=0, period=0, pos=0]]
mediaItem [eventTime=0.10, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
loading [eventTime=0.11, mediaPos=0.00, window=0, true]
timeline [eventTime=0.11, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [?]
  window [?, seekable=false, dynamic=false]
]
timeline [eventTime=1.15, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [634.40]
  window [634.40, seekable=true, dynamic=false]
]
videoEnabled [eventTime=1.16, mediaPos=0.00, window=0, period=0]
tracks [eventTime=1.16, mediaPos=0.00, window=0, period=0
  group [
    [X] Track:0, id=1, mimeType=video/av01, res=854x480, fps=29.999998, supported=YES
  ]
]
downstreamFormat [eventTime=1.16, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoDecoderInitialized [eventTime=1.20, mediaPos=0.00, window=0, period=0, c2.google.av1.decoder]
videoInputFormat [eventTime=1.21, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoSize [eventTime=1.33, mediaPos=0.00, window=0, period=0, 854, 480]
renderedFirstFrame [eventTime=1.34, mediaPos=0.00, window=0, period=0, Surface(name=null)/@0xe4d0ed2]
surfaceSize [eventTime=1.35, mediaPos=0.00, window=0, period=0, 1080, 607]
state [eventTime=1.36, mediaPos=0.02, window=0, period=0, READY]
isPlaying [eventTime=1.36, mediaPos=0.02, window=0, period=0, true]
loading [eventTime=1.91, mediaPos=0.56, window=0, period=0, false]
loading [eventTime=3.42, mediaPos=2.08, window=0, period=0, true]
loading [eventTime=3.48, mediaPos=2.14, window=0, period=0, false]

The same part of logcat in the working case on UQ1A.240205.002:

timeline [eventTime=0.03, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
mediaItem [eventTime=0.03, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
state [eventTime=0.03, mediaPos=0.00, window=0, BUFFERING]
surfaceSize [eventTime=0.07, mediaPos=0.00, window=0, 1080, 1080]
timeline [eventTime=0.09, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
positionDiscontinuity [eventTime=0.09, mediaPos=0.00, window=0, reason=REMOVE, PositionInfo:old [mediaItem=0, period=0, pos=0], PositionInfo:new [mediaItem=0, period=0, pos=0]]
mediaItem [eventTime=0.09, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
loading [eventTime=0.11, mediaPos=0.00, window=0, true]
timeline [eventTime=0.11, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [?]
  window [?, seekable=false, dynamic=false]
]
timeline [eventTime=1.26, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [634.40]
  window [634.40, seekable=true, dynamic=false]
]
videoEnabled [eventTime=1.45, mediaPos=0.00, window=0, period=0]
tracks [eventTime=1.46, mediaPos=0.00, window=0, period=0
  group [
    [X] Track:0, id=1, mimeType=video/av01, res=854x480, fps=29.999998, supported=YES
  ]
]
downstreamFormat [eventTime=1.46, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoDecoderInitialized [eventTime=1.49, mediaPos=0.00, window=0, period=0, c2.google.av1.decoder]
videoInputFormat [eventTime=1.49, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoSize [eventTime=1.52, mediaPos=0.00, window=0, period=0, 854, 480]
surfaceSize [eventTime=1.52, mediaPos=0.00, window=0, period=0, 1080, 607]
renderedFirstFrame [eventTime=1.53, mediaPos=0.00, window=0, period=0, Surface(name=null)/@0xb940abd]
state [eventTime=1.53, mediaPos=0.00, window=0, period=0, READY]
isPlaying [eventTime=1.53, mediaPos=0.00, window=0, period=0, true]
loading [eventTime=2.29, mediaPos=0.76, window=0, period=0, false]
loading [eventTime=3.61, mediaPos=2.08, window=0, period=0, true]
loading [eventTime=3.67, mediaPos=2.15, window=0, period=0, false]

And finally, the problematic case on UQ1A.240205.002:

timeline [eventTime=0.02, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
mediaItem [eventTime=0.02, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
state [eventTime=0.02, mediaPos=0.00, window=0, BUFFERING]
surfaceSize [eventTime=0.06, mediaPos=0.00, window=0, 0, 0]
surfaceSize [eventTime=0.07, mediaPos=0.00, window=0, 1080, 1080]
loading [eventTime=0.08, mediaPos=0.00, window=0, period=0, true]
timeline [eventTime=0.08, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [?]
  window [?, seekable=false, dynamic=false]
]
timeline [eventTime=0.08, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
positionDiscontinuity [eventTime=0.08, mediaPos=0.00, window=0, reason=REMOVE, PositionInfo:old [mediaItem=0, period=0, pos=0], PositionInfo:new [mediaItem=0, period=0, pos=0]]
mediaItem [eventTime=0.08, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
timeline [eventTime=0.09, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [?]
  window [?, seekable=false, dynamic=false]
]
timeline [eventTime=1.30, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [634.40]
  window [634.40, seekable=true, dynamic=false]
]
videoEnabled [eventTime=1.31, mediaPos=0.00, window=0, period=0]
tracks [eventTime=1.31, mediaPos=0.00, window=0, period=0
  group [
    [X] Track:0, id=1, mimeType=video/av01, res=854x480, fps=29.999998, supported=YES
  ]
]
downstreamFormat [eventTime=1.31, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoDecoderInitialized [eventTime=1.36, mediaPos=0.00, window=0, period=0, c2.google.av1.decoder]
videoInputFormat [eventTime=1.36, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, fps=29.999998]
videoSize [eventTime=1.51, mediaPos=0.00, window=0, period=0, 854, 480]
renderedFirstFrame [eventTime=1.51, mediaPos=0.00, window=0, period=0, Surface(name=null)/@0x4a7b0d3]
surfaceSize [eventTime=1.53, mediaPos=0.00, window=0, period=0, 1080, 607]
state [eventTime=1.53, mediaPos=0.02, window=0, period=0, READY]
isPlaying [eventTime=1.54, mediaPos=0.02, window=0, period=0, true]
loading [eventTime=2.21, mediaPos=0.70, window=0, period=0, false]
loading [eventTime=3.60, mediaPos=2.08, window=0, period=0, true]
loading [eventTime=3.67, mediaPos=2.15, window=0, period=0, false]

There are two key differences between the working and problematic cases:

  1. The problematic cases both have an additional surfaceSize [eventTime=0.06, mediaPos=0.00, window=0, 0, 0] before surfaceSize [eventTime=0.07, mediaPos=0.00, window=0, 1080, 1080]
  2. The problematic cases both see renderedFirstFrame before surfaceSize [eventTime=1.52, mediaPos=0.00, window=0, period=0, 1080, 607], whereas in the working case the surfaceSize arrives before renderedFirstFrame.

@phcannesson
Copy link

I found a "fix", the stretch is gone when using app:surface_type="texture_view". So I assume there's something wrong with app:surface_type="surface_view" inside AndroidView on the latest android?

Is it true that texture_view drains more battery?

I can confirm that it seems to fix.

I've created a public repo to reproduce and play with the configuration :
https://github.com/phcannesson/AspectFrameLayoutDemo

The player with app:surface_type="texture_view" works well.

@phcannesson
Copy link

While digging in AOSP code, I've noticed this change :
https://cs.android.com/android/_/android/platform/frameworks/base/+/1b152e712159c0b82831a7567ce2f3c49cdc11bf
It apparently modified how SurfaceView is clipped.

It seemed to have been released in Android 14 QPR2.

It's a wild guess, but I thought it was worth mentioning.

@icbaker
Copy link
Collaborator

icbaker commented Apr 12, 2024

Trying the same video in the main ExoPlayer demo app on the same device + build (lynx-userdebug UQ1A.240205.002), I see the 'problematic sequence' in logcat (surfaceSize(0,0) near the start, and then renderedFirstFrame before surfaceSize), but not the problematic symptoms.

This is perhaps obvious, but it adds more weight to the theory that the problem is related to how AspectRatioFrameLayout (or perhaps SurfaceView) behaves specifically in a Compose context.

Full logcat:

playWhenReady [eventTime=0.00, mediaPos=0.00, window=0, true, USER_REQUEST]
surfaceSize [eventTime=0.00, mediaPos=0.00, window=0, 0, 0]
timeline [eventTime=0.00, mediaPos=0.00, window=0, periodCount=1, windowCount=1, reason=PLAYLIST_CHANGED
  period [?]
  window [?, seekable=false, dynamic=true]
]
mediaItem [eventTime=0.01, mediaPos=0.00, window=0, reason=PLAYLIST_CHANGED]
state [eventTime=0.01, mediaPos=0.00, window=0, BUFFERING]
surfaceSize [eventTime=0.04, mediaPos=0.00, window=0, 1080, 2219]
loading [eventTime=0.04, mediaPos=0.00, window=0, period=0, true]
timeline [eventTime=0.04, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [?]
  window [?, seekable=false, dynamic=false]
]
timeline [eventTime=0.77, mediaPos=0.00, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
  period [634.40]
  window [634.40, seekable=true, dynamic=false]
]
videoEnabled [eventTime=0.79, mediaPos=0.00, window=0, period=0]
tracks [eventTime=0.79, mediaPos=0.00, window=0, period=0
  group [
    [X] Track:0, id=1, mimeType=video/av01, res=854x480, color=BT709/Limited range/SDR SMPTE 170M/8/8, fps=29.999998, supported=YES
  ]
  Metadata [
    TSSE: description=null: values=[Google]
    Mp4Timestamp: creation time=0, modification time=0, timescale=1000
  ]
]
downstreamFormat [eventTime=0.81, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, color=BT709/Limited range/SDR SMPTE 170M/8/8, fps=29.999998]
videoDecoderInitialized [eventTime=0.84, mediaPos=0.00, window=0, period=0, c2.google.av1.decoder]
videoInputFormat [eventTime=0.84, mediaPos=0.00, window=0, period=0, id=1, mimeType=video/av01, res=854x480, color=BT709/Limited range/SDR SMPTE 170M/8/8, fps=29.999998]
videoSize [eventTime=1.07, mediaPos=0.00, window=0, period=0, 854, 480]
renderedFirstFrame [eventTime=1.07, mediaPos=0.00, window=0, period=0, Surface(name=null)/@0x12990bc]
surfaceSize [eventTime=1.09, mediaPos=0.00, window=0, period=0, 1080, 607]
state [eventTime=1.09, mediaPos=0.01, window=0, period=0, READY]
isPlaying [eventTime=1.10, mediaPos=0.02, window=0, period=0, true]
loading [eventTime=1.78, mediaPos=0.70, window=0, period=0, false]
loading [eventTime=3.17, mediaPos=2.09, window=0, period=0, true]

@harry248
Copy link

While digging in AOSP code, I've noticed this change : https://cs.android.com/android/_/android/platform/frameworks/base/+/1b152e712159c0b82831a7567ce2f3c49cdc11bf It apparently modified how SurfaceView is clipped.

It seemed to have been released in Android 14 QPR2.

It's a wild guess, but I thought it was worth mentioning.

With QPR2 our QA also started to report the issue, so very likely related.

@fpitterstv2
Copy link

We are seeing this now when migrating to compose :(
Using RESIZE_MODE_FIT inside a fillMaxSize composable

@jdelga
Copy link

jdelga commented Apr 17, 2024

This seems a duplicate of #1123

@fpitterstv2
Copy link

Also reproducible on an emulator using VanillaIceCream

@icbaker
Copy link
Collaborator

icbaker commented Apr 19, 2024

I have filed an issue internally to ask for assistance from the Window Manager team (who own SurfaceView) and Compose folks: b/334901521

@MGaetan89
Copy link

I have filed an issue internally to ask for assistance from the Window Manager team (who own SurfaceView) and Compose folks: b/334901521

Any chance to make the issue public to follow the discussion? Or it (may) contains confidential information?

@rbugajewski
Copy link

I want to report that at our company we face the same issue on some Google Pixel 8 Pro devices. We’ve identified the regression back to the clipping calculation of the SurfaceView on 5th, March 2024. We also tried the mentioned workarounds, but switching to a TextureView is not possible for us due to DRM, and disabling hardware acceleration (which would bypass the check) is also not possible as this would heavily degrade the user experience.

We would greatly appreciate if the vendor could keep us updated on the issue if we do not have any chances to follow the discussion on b/334901521.

@jreck
Copy link

jreck commented May 3, 2024

While digging in AOSP code, I've noticed this change : https://cs.android.com/android/_/android/platform/frameworks/base/+/1b152e712159c0b82831a7567ce2f3c49cdc11bf It apparently modified how SurfaceView is clipped.

It seemed to have been released in Android 14 QPR2.

It's a wild guess, but I thought it was worth mentioning.

Very plausible but that behavior is still flag-disabled (note all the new paths are guarded by Flags.clipSurfaceviews() which is still false and never shipped as true). It's possible a path was missed there, but it's supposed to not be doing anything at the moment.

@jreck
Copy link

jreck commented May 3, 2024

I can confirm that the clipping change is not the cause of this issue.

@rbugajewski
Copy link

@jreck This is very interesting, thanks for your investigation. So there seems to be another cause of the issue that was introduced on the 5th, March 2024, that is somehow correlated to hardware acceleration, Jetpack Compose, and Google Pixel phones.

@jreck
Copy link

jreck commented May 6, 2024

The issue is that somehow this transaction isn't happening: https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/view/SurfaceView.java;drc=a7ba109ec6c7c1ca82f96651863b3d2c10c6bc34;l=2113

In the repro app the transaction that updates the bounds of the SurfaceView is just getting dropped on the floor, so the compositor still thinks it's the original square dimensions thus the stretching. But it's not clear yet why or why Compose specifically seems to trigger this. We have a platform workaround, though, but no guidance yet on a Compose workaround since the root cause isn't understood yet.

@icbaker
Copy link
Collaborator

icbaker commented Jun 14, 2024

I've done a bit more testing on different Android versions. This is on Pixel 7a and Pixel Fold (folded). My observations:

  • I haven't managed to repro on Android 13
  • On Android 14 before the March 2024 update (specifically I tested UP1A.231005.007 (the first stable Android 14 build) and UQ1A.240205.002.B1 (just before the March release))
    • I observe the issue at a high repro rate (~90%)
    • As soon as you tap on the playback to make the controls appear, the issue is resolved
  • On Android 14 after the March 2024 update (specifically I tested AP1A.240305.019.A1)
    • The repro rate appears to be about the same
    • Tapping the playback to make the controls appear doesn't resolve the issue

I suspect this may be why the issue has become more obvious since the March 2024 release. Before this point it was quickly resolved as soon as something else changed (in this case the controls appearing), but after this the problem persists.

@icbaker icbaker changed the title AspectRatioFrameLayout problem SurfaceView inside Compose AndroidView often shown stretched/cropped on API 34 Jun 19, 2024
copybara-service bot pushed a commit that referenced this issue Jun 19, 2024
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: #1237

#cherrypick

PiperOrigin-RevId: 644729909
@icbaker
Copy link
Collaborator

icbaker commented Jun 19, 2024

I've updated the title of this issue to reflect that this isn't specific to AspectRatioFrameLayout, and it's more related to SurfaceView inside a Compose AndroidView on Android 14.

With the support of the graphics team, I've also submitted a workaround (linked above) to PlayerView, which resolves this issue for users of this class. This will be included in 1.4.0-rc01. I'm going to close this issue, since that should resolve the issue for users of media3's UI components. Those who have written their own UI components may be able to adopt a similar workaround.

@icbaker icbaker closed this as completed Jun 19, 2024
copybara-service bot pushed a commit that referenced this issue Jun 20, 2024
Previously we assumed that `surfaceSyncGroupV34` was always non-null on
API 34, but this isn't true in edit mode. Instead we add an explicit
null-check before accessing it. We don't need to null-check it at the
other usage site because we are already null-checking `surfaceView` (via
`instanceof` check).

Issue: #1237

#cherrypick

PiperOrigin-RevId: 645008049
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests