X Tutup
Skip to content

Android: Stabilize camera lifecycle handling#111871

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
shiena:fix/camera_android.2
Oct 23, 2025
Merged

Android: Stabilize camera lifecycle handling#111871
Repiteo merged 1 commit intogodotengine:masterfrom
shiena:fix/camera_android.2

Conversation

@shiena
Copy link
Contributor

@shiena shiena commented Oct 21, 2025

Split from #110720

  • Pause active Android camera feeds on renderer pause and restore them on resume to avoid crashes when the OS tears down camera resources.
  • Refresh camera metadata and recompute feed rotation using the app’s reported orientation so front/back cameras stay correctly aligned after configuration changes.
  • Forward Android configuration orientation updates through GodotLib.onScreenRotationChange() and guard image callbacks with a mutex to keep metadata refresh and frame delivery synchronized.

I wanted to split the rotation handling and lifecycle event handling, but both rely on refresh_camera_metadata(), so I couldn’t separate them.


This PR provides the following benefits:

  • Prevents camera preview crashes when auto-rotation is enabled.
  • Temporarily suspends camera functionality when the app is suspended to reduce battery consumption.


struct RotationResult {
int rotationAngle;
bool shouldMirror;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simplified it by using std::optional instead of a struct.


val newOrientation = newConfig.orientation
if (currentOrientation != -1 && currentOrientation != newOrientation) {
GodotLib.onScreenRotationChange()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ensures the screen rotation change callback is invoked on the render thread, similar to the renderer paused / resumed callbacks.

Suggested change
GodotLib.onScreenRotationChange()
runOnRenderThread {
GodotLib.onScreenRotationChange()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied

@m4gr3d m4gr3d requested a review from a team October 21, 2025 16:01
@m4gr3d m4gr3d added the bug label Oct 21, 2025
@m4gr3d m4gr3d modified the milestones: 4.x, 4.6 Oct 21, 2025
@shiena shiena force-pushed the fix/camera_android.2 branch from cffd798 to 289ed9b Compare October 21, 2025 19:13
@shiena
Copy link
Contributor Author

shiena commented Oct 21, 2025

Fixes compilation of camera handlers from 060d312.
Used undefined CAMERA_ENABLED macro instead of MODULE_CAMERA_ENABLED from modules_enabled.gen.h.

*/
private var renderViewInitialized = false
private var primaryHost: GodotHost? = null
private var currentOrientation = -1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace this with:

private var currentConfig = context.resources.configuration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied

Comment on lines +762 to +768
val newOrientation = newConfig.orientation
if (currentOrientation != -1 && currentOrientation != newOrientation) {
runOnRenderThread {
GodotLib.onScreenRotationChange()
}
}
currentOrientation = newOrientation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val newOrientation = newConfig.orientation
if (currentOrientation != -1 && currentOrientation != newOrientation) {
runOnRenderThread {
GodotLib.onScreenRotationChange()
}
}
currentOrientation = newOrientation
if (currentConfig != null && currentConfig.orientation != newConfig.orientation) {
runOnRenderThread {
GodotLib.onScreenRotationChange()
}
}
currentConfig = newConfig

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied

@shiena shiena force-pushed the fix/camera_android.2 branch from 289ed9b to a550b6f Compare October 22, 2025 03:15
}

#ifdef MODULE_CAMERA_ENABLED
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onScreenRotationChange(JNIEnv *env, jclass clazz) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method should be outside of the #ifdef, and be declared in java_godot_lib_jni.h like the other jni methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied

/**
* Invoked when the screen orientation changes.
*/
public static native void onScreenRotationChange();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static native void onScreenRotationChange();
static native void onScreenRotationChange();

Copy link
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Can you squash the commits, and take care of that last comment.

@shiena shiena force-pushed the fix/camera_android.2 branch from ad5623b to d3b5248 Compare October 22, 2025 15:53
@shiena shiena force-pushed the fix/camera_android.2 branch from d3b5248 to 1ff3303 Compare October 22, 2025 16:16
- Pause camera feeds during lifecycle transitions to avoid crashes
- Refresh camera metadata after rotation to keep orientation accurate
@shiena shiena force-pushed the fix/camera_android.2 branch from 1ff3303 to 4483871 Compare October 22, 2025 16:32
@shiena
Copy link
Contributor Author

shiena commented Oct 22, 2025

I have applied the reviews up to this point.

@Repiteo Repiteo merged commit a4607f4 into godotengine:master Oct 23, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Oct 23, 2025

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

X Tutup