React Native WebRTC local video resizes to fullscreen inside PiP after tapping PiP window on Android 14, works on Android 12
I am developing a React Native video calling application using WebRTC and Android Picture-in-Picture (PiP). I am facing a problem specifically on Android 14.
The same PiP/video-call implementation works correctly on Android 12, but the behavior is different on Android 14.
On Android 12:
- The app enters PiP correctly.
- Tapping the PiP window works correctly.
- The local and remote WebRTC video remain correctly sized inside the PiP window.
On Android 14:
1. User starts a video call.
2. User swipes home.
3. Android automatically enters PiP using `setAutoEnterEnabled(true)`.
4. `MainActivity.onPictureInPictureModeChanged(true)` is called.
5. The PiP window initially appears correctly.
6. When the user taps the PiP window, the local WebRTC video becomes visible.
7. After a few seconds, the video unexpectedly resizes to the full Activity/screen dimensions even though the app is still in PiP mode.
I am using:
- React Native
- Kotlin
- WebRTC
- Android Picture-in-Picture APIs
- `react-native-pip-android` / `PipAndroidModule`
In `MainActivity`, I call `PipAndroidModule.pipModeChanged()` from `onPictureInPictureModeChanged()`.
I suspect there may be a lifecycle/layout issue on Android 14. The PiP state event is sent from native Android to React Native, but the React Native JS thread may not process the event immediately while the app is in PiP. When the PiP window is tapped, the JS event is processed and the local video is moved/re-rendered. A few seconds later, the WebRTC renderer appears to receive fullscreen Activity dimensions instead of the actual PiP container dimensions.
I have also tried `window.decorView.requestLayout()`, but I am not sure whether this is contributing to the problem.
I do not want to stop or hide the local camera. The local and remote WebRTC streams should continue rendering correctly inside the PiP window.
Why does this happen on Android 14 but not Android 12, and what is the correct way to keep the WebRTC video renderer constrained to the PiP window bounds after the PiP window is tapped?
This is probably a layout issue around SurfaceViewRenderer, not a JS scheduling issue.
react-native-webrtc renders RTCView using SurfaceViewRenderer, and its size follows the bounds React Native gives the parent WebRTCView. If that parent is temporarily measured with the full Activity size during a PiP relayout, the renderer will happily resize to those dimensions.
On Android 14 I would check two things first:
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:supportsPictureInPicture="true"
Android recommends handling those configuration changes yourself so the Activity is not recreated during PiP transitions.
Also remove the manual:
window.decorView.requestLayout()
unless you have a specific reason for it. Forcing a full decor relayout while Android is resizing the PiP window can cause exactly the kind of stale/fullscreen measurement you describe.
Let Android resize the Activity and keep the RTCView constrained by its React Native container, for example width: '100%', height: '100%', inside a PiP-specific parent. Do not calculate its size from Dimensions.get("window") or cached fullscreen dimensions.
For PiP params, set the video view's actual bounds as sourceRectHint; Android explicitly recommends this for video content. setSeamlessResizeEnabled(true) is also intended for video surfaces.
Dmitry543