Repository navigation
sync Preview.targetRotation with TransientSessionSettings.windowRotation #656
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
base: kim/adaptive/layout-rotation
Are you sure you want to change the base?
Changes from all commits
14865b7
e6110df
77e05ad
2c81c84
fc26682
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,7 +302,8 @@ internal suspend fun runSingleCameraSession( | |
| imageFormat = sessionSettings.imageFormat, | ||
| captureMode = sessionSettings.captureMode, | ||
| effect = effect, | ||
| captureResults = captureResults | ||
| captureResults = captureResults, | ||
| windowRotation = currentTransientSettings.windowRotation | ||
|
Comment on lines
+305
to
+306
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| ) | ||
| }.apply { | ||
| attachPreviewSurfaceProvider(useCaseGroup = this) | ||
|
|
@@ -333,6 +334,7 @@ internal suspend fun runSingleCameraSession( | |
| } | ||
|
|
||
| applyDeviceRotation(currentTransientSettings.deviceRotation, useCaseGroup) | ||
| applyWindowRotation(currentTransientSettings.windowRotation, useCaseGroup) | ||
|
|
||
| if (videoCaptureUseCase != null) { | ||
| val resolutionInfo = videoCaptureUseCase.resolutionInfo | ||
|
|
@@ -613,6 +615,16 @@ suspend fun processTransientSettingEvents( | |
| } | ||
| } | ||
|
|
||
| if (prevTransientSettings.windowRotation != newTransientSettings.windowRotation) { | ||
| Log.d( | ||
| TAG, | ||
| "Updating window rotation from " + | ||
| "${prevTransientSettings.windowRotation} -> " + | ||
| "${newTransientSettings.windowRotation}" | ||
| ) | ||
| applyWindowRotation(newTransientSettings.windowRotation, useCaseGroup) | ||
| } | ||
|
|
||
| // setzoomratio when the primary zoom value changes. | ||
| if (prevTransientSettings.primaryLensFacing == newTransientSettings.primaryLensFacing && | ||
| prevTransientSettings.zoomRatios[prevTransientSettings.primaryLensFacing] != | ||
|
|
@@ -740,11 +752,8 @@ fun CameraSessionContext.applyDeviceRotation( | |
| useCaseGroup.useCases.forEach { | ||
| when (it) { | ||
| is Preview -> { | ||
| // Preview's target rotation should not be updated with device rotation. | ||
| // Instead, preview rotation should match the display rotation. | ||
| // When Preview is created, it is initialized with the display rotation. | ||
| // This will need to be updated separately if the display rotation is not | ||
| // locked. Currently the app is locked to portrait orientation. | ||
| // Preview's target rotation tracks TransientSessionSettings.windowRotation via | ||
| // applyWindowRotation rather than physical device gravity rotation. | ||
| } | ||
|
|
||
| is ImageCapture -> { | ||
|
|
@@ -758,6 +767,27 @@ fun CameraSessionContext.applyDeviceRotation( | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Updates [Preview.setTargetRotation] in place when [TransientSessionSettings.windowRotation] | ||
| * changes, without rebinding the camera session. | ||
| * | ||
| * Depends on CameraX fixes `aosp/4408335`, `aosp/4408336`, and `aosp/4408337`, which dynamically | ||
| * recalculate [ViewPort] and StreamSharing crop/rotation when [Preview.setTargetRotation] is | ||
| * updated on a bound use case. | ||
| */ | ||
| @InternalCameraApi | ||
| fun applyWindowRotation( | ||
| windowRotation: DeviceRotation, | ||
| useCaseGroup: UseCaseGroup | ||
| ) { | ||
| val targetRotation = windowRotation.toUiSurfaceRotation() | ||
| useCaseGroup.useCases.forEach { useCase -> | ||
| if (useCase is Preview) { | ||
| useCase.targetRotation = targetRotation | ||
| } | ||
| } | ||
|
Comment on lines
+784
to
+788
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using useCaseGroup.useCases.filterIsInstance<Preview>().forEach { preview ->
preview.targetRotation = targetRotation
}References
|
||
| } | ||
|
|
||
| context(CameraSessionContext) | ||
| @InternalCameraApi | ||
| fun createUseCaseGroup( | ||
|
|
@@ -770,15 +800,17 @@ fun createUseCaseGroup( | |
| captureMode: CaptureMode, | ||
| effect: CameraEffect? = null, | ||
| captureResults: MutableStateFlow<TotalCaptureResult?>? = null, | ||
| previewMirrorMode: Int = CX_SINGLE_CAMERA_PREVIEW_MIRROR_MODE | ||
| previewMirrorMode: Int = CX_SINGLE_CAMERA_PREVIEW_MIRROR_MODE, | ||
| windowRotation: DeviceRotation = initialTransientSettings.windowRotation | ||
| ): UseCaseGroup { | ||
| val previewUseCase = | ||
| createPreviewUseCase( | ||
| cameraInfo, | ||
| aspectRatio, | ||
| stabilizationMode, | ||
| previewMirrorMode, | ||
| captureResults | ||
| cameraInfo = cameraInfo, | ||
| aspectRatio = aspectRatio, | ||
| stabilizationMode = stabilizationMode, | ||
| previewMirrorMode = previewMirrorMode, | ||
| captureResults = captureResults, | ||
| windowRotation = windowRotation | ||
| ) | ||
|
|
||
| // only create image use case in image or standard | ||
|
|
@@ -799,12 +831,14 @@ fun createUseCaseGroup( | |
| return UseCaseGroup.Builder().apply { | ||
| Log.d( | ||
| TAG, | ||
| "Setting initial device rotation to ${initialTransientSettings.deviceRotation}" | ||
| "Setting initial device rotation to ${initialTransientSettings.deviceRotation}, " + | ||
| "window rotation to $windowRotation" | ||
| ) | ||
| // TODO(#592): Plumb windowRotation into PR #592's getViewPortAspectRatio / | ||
| // isPreviewLandscape once #592 merges into main. | ||
| setViewPort( | ||
| ViewPort.Builder( | ||
| Rational(aspectRatio.numerator, aspectRatio.denominator), | ||
| // Initialize rotation to Preview's rotation, which comes from Display rotation | ||
| previewUseCase.targetRotation | ||
| ).build() | ||
| ) | ||
|
|
@@ -818,6 +852,12 @@ fun createUseCaseGroup( | |
| }.build() | ||
| } | ||
|
|
||
| /** | ||
| * Applies [windowRotation] as the target rotation of this [Preview.Builder]. | ||
| */ | ||
| internal fun Preview.Builder.applyWindowRotation(windowRotation: DeviceRotation): Preview.Builder = | ||
| setTargetRotation(windowRotation.toUiSurfaceRotation()) | ||
|
|
||
| /** | ||
| * Maps a given resolution [Size] to its corresponding [VideoQuality] based on the short edge. | ||
| * | ||
|
|
@@ -946,8 +986,11 @@ private fun createPreviewUseCase( | |
| aspectRatio: AspectRatio, | ||
| stabilizationMode: StabilizationMode, | ||
| previewMirrorMode: Int, | ||
| captureResults: MutableStateFlow<TotalCaptureResult?>? = null | ||
| captureResults: MutableStateFlow<TotalCaptureResult?>? = null, | ||
| windowRotation: DeviceRotation = DeviceRotation.Natural | ||
| ): Preview = Preview.Builder().apply { | ||
| applyWindowRotation(windowRotation) | ||
|
|
||
| updateCameraStateWithCaptureResults( | ||
| targetCameraInfo = cameraInfo, | ||
| captureResults = captureResults | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
windowRotationargument is redundant here becausecreateUseCaseGroupalready defaultswindowRotationtoinitialTransientSettings.windowRotation. We can omit it to simplify the call.