Skip to content

Commit 75a1ba3

Browse files
committed
fix: avoid Android exposure Harness hangs
1 parent b63adfc commit 75a1ba3

4 files changed

Lines changed: 140 additions & 24 deletions

File tree

.github/actions/collect-devicefarm-results/action.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ outputs:
1919
log-file:
2020
description: Copied harness log file path
2121
value: ${{ steps.find-harness-log.outputs.log_file }}
22+
xcodebuild-log-file:
23+
description: Copied iOS XCTest xcodebuild log file path
24+
value: ${{ steps.find-xcodebuild-log.outputs.log_file }}
25+
customer-artifacts-log-file:
26+
description: Copied Device Farm customer artifacts log file path
27+
value: ${{ steps.find-customer-artifacts-log.outputs.log_file }}
28+
test-spec-output-file:
29+
description: Copied Device Farm test spec output log file path
30+
value: ${{ steps.find-test-spec-output.outputs.log_file }}
31+
test-spec-timestamped-output-file:
32+
description: Copied Device Farm timestamped test spec output log file path
33+
value: ${{ steps.find-test-spec-timestamped-output.outputs.log_file }}
2234

2335
runs:
2436
using: composite
@@ -51,6 +63,74 @@ runs:
5163
"$WORKSPACE_LOG"
5264
echo "log_file=$WORKSPACE_LOG" >> "$GITHUB_OUTPUT"
5365
66+
- name: Find Harness XCTest log
67+
id: find-xcodebuild-log
68+
if: inputs.platform == 'ios'
69+
shell: bash
70+
run: |
71+
set -euo pipefail
72+
ARTIFACT_DIR="${{ inputs.artifact-folder }}"
73+
WORKSPACE_LOG=".github/test-results/harness-xcodebuild-ios.log"
74+
if bash "$GITHUB_ACTION_PATH/../../scripts/find-devicefarm-artifact.sh" \
75+
"$ARTIFACT_DIR" \
76+
'xcodebuild.log' \
77+
"$WORKSPACE_LOG"; then
78+
echo "log_file=$WORKSPACE_LOG" >> "$GITHUB_OUTPUT"
79+
else
80+
echo "log_file=" >> "$GITHUB_OUTPUT"
81+
fi
82+
83+
- name: Find Device Farm customer artifacts log
84+
id: find-customer-artifacts-log
85+
shell: bash
86+
run: |
87+
set -euo pipefail
88+
ARTIFACT_DIR="${{ inputs.artifact-folder }}"
89+
PLATFORM="${{ inputs.platform }}"
90+
WORKSPACE_LOG=".github/test-results/devicefarm-customer-artifacts-${PLATFORM}.log"
91+
if bash "$GITHUB_ACTION_PATH/../../scripts/find-devicefarm-artifact.sh" \
92+
"$ARTIFACT_DIR" \
93+
'*-Customer Artifacts Log.txt' \
94+
"$WORKSPACE_LOG"; then
95+
echo "log_file=$WORKSPACE_LOG" >> "$GITHUB_OUTPUT"
96+
else
97+
echo "log_file=" >> "$GITHUB_OUTPUT"
98+
fi
99+
100+
- name: Find Device Farm test spec output
101+
id: find-test-spec-output
102+
shell: bash
103+
run: |
104+
set -euo pipefail
105+
ARTIFACT_DIR="${{ inputs.artifact-folder }}"
106+
PLATFORM="${{ inputs.platform }}"
107+
WORKSPACE_LOG=".github/test-results/devicefarm-test-spec-output-${PLATFORM}.log"
108+
if bash "$GITHUB_ACTION_PATH/../../scripts/find-devicefarm-artifact.sh" \
109+
"$ARTIFACT_DIR" \
110+
'*-Test spec output.txt' \
111+
"$WORKSPACE_LOG"; then
112+
echo "log_file=$WORKSPACE_LOG" >> "$GITHUB_OUTPUT"
113+
else
114+
echo "log_file=" >> "$GITHUB_OUTPUT"
115+
fi
116+
117+
- name: Find Device Farm timestamped test spec output
118+
id: find-test-spec-timestamped-output
119+
shell: bash
120+
run: |
121+
set -euo pipefail
122+
ARTIFACT_DIR="${{ inputs.artifact-folder }}"
123+
PLATFORM="${{ inputs.platform }}"
124+
WORKSPACE_LOG=".github/test-results/devicefarm-test-spec-timestamped-output-${PLATFORM}.log"
125+
if bash "$GITHUB_ACTION_PATH/../../scripts/find-devicefarm-artifact.sh" \
126+
"$ARTIFACT_DIR" \
127+
'*-Test spec timestamped output.txt' \
128+
"$WORKSPACE_LOG"; then
129+
echo "log_file=$WORKSPACE_LOG" >> "$GITHUB_OUTPUT"
130+
else
131+
echo "log_file=" >> "$GITHUB_OUTPUT"
132+
fi
133+
54134
- name: Publish Harness test results
55135
id: publish-harness-results
56136
if: steps.find-harness-junit.outputs.junit_file != ''
@@ -77,6 +157,34 @@ runs:
77157
cat "$LOG_FILE"
78158
echo "===== End Harness ${PLATFORM} output log ====="
79159
160+
XCODEBUILD_LOG="${{ steps.find-xcodebuild-log.outputs.log_file }}"
161+
if [[ -n "$XCODEBUILD_LOG" && ( "$TEST_STEP_OUTCOME" == "failure" || "$PUBLISH_OUTCOME" == "failure" ) ]]; then
162+
echo "===== Harness ${PLATFORM} xcodebuild log ====="
163+
cat "$XCODEBUILD_LOG"
164+
echo "===== End Harness ${PLATFORM} xcodebuild log ====="
165+
fi
166+
167+
CUSTOMER_ARTIFACTS_LOG="${{ steps.find-customer-artifacts-log.outputs.log_file }}"
168+
if [[ -n "$CUSTOMER_ARTIFACTS_LOG" && "$TEST_STEP_OUTCOME" == "failure" ]]; then
169+
echo "===== Device Farm ${PLATFORM} customer artifacts log ====="
170+
cat "$CUSTOMER_ARTIFACTS_LOG"
171+
echo "===== End Device Farm ${PLATFORM} customer artifacts log ====="
172+
fi
173+
174+
TEST_SPEC_OUTPUT="${{ steps.find-test-spec-output.outputs.log_file }}"
175+
if [[ -n "$TEST_SPEC_OUTPUT" && "$TEST_STEP_OUTCOME" == "failure" ]]; then
176+
echo "===== Device Farm ${PLATFORM} test spec output ====="
177+
cat "$TEST_SPEC_OUTPUT"
178+
echo "===== End Device Farm ${PLATFORM} test spec output ====="
179+
fi
180+
181+
TEST_SPEC_TIMESTAMPED_OUTPUT="${{ steps.find-test-spec-timestamped-output.outputs.log_file }}"
182+
if [[ -n "$TEST_SPEC_TIMESTAMPED_OUTPUT" && "$TEST_STEP_OUTCOME" == "failure" ]]; then
183+
echo "===== Device Farm ${PLATFORM} timestamped test spec output ====="
184+
cat "$TEST_SPEC_TIMESTAMPED_OUTPUT"
185+
echo "===== End Device Farm ${PLATFORM} timestamped test spec output ====="
186+
fi
187+
80188
if [[ "$PUBLISH_OUTCOME" == "failure" ]]; then
81189
echo "Harness test result publication reported failures." >&2
82190
exit 1

.github/workflows/harness-aws-device.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ on:
3535
- main
3636
paths:
3737
- ".github/workflows/harness-aws-device.yml"
38+
- ".github/actions/collect-devicefarm-results/**"
3839
- ".github/actions/upload-devicefarm-artifact/**"
40+
- ".github/scripts/find-devicefarm-artifact.sh"
3941
- "apps/simple-camera/**"
4042
- "packages/react-native-vision-camera/**"
4143
- "packages/react-native-vision-camera-barcode-scanner/**"
@@ -48,7 +50,9 @@ on:
4850
pull_request:
4951
paths:
5052
- ".github/workflows/harness-aws-device.yml"
53+
- ".github/actions/collect-devicefarm-results/**"
5154
- ".github/actions/upload-devicefarm-artifact/**"
55+
- ".github/scripts/find-devicefarm-artifact.sh"
5256
- "apps/simple-camera/**"
5357
- "packages/react-native-vision-camera/**"
5458
- "packages/react-native-vision-camera-barcode-scanner/**"
@@ -118,7 +122,9 @@ jobs:
118122
- '!packages/**/*.@(swift|mm)'
119123
- 'patches/**'
120124
- '.github/workflows/harness-aws-device.yml'
125+
- '.github/actions/collect-devicefarm-results/**'
121126
- '.github/actions/upload-devicefarm-artifact/**'
127+
- '.github/scripts/find-devicefarm-artifact.sh'
122128
- 'bun.lock'
123129
- 'package.json'
124130

apps/simple-camera/__tests__/visioncamera.controller.exposure.harness.ts

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,6 @@ describe('VisionCamera - Controller Exposure', () => {
99
let factory: CameraDeviceFactory
1010
let backDevice: CameraDevice
1111

12-
const createContinuousOutput = () =>
13-
VisionCamera.createFrameOutput({
14-
targetResolution: CommonResolutions.HD_16_9,
15-
pixelFormat: 'native',
16-
enablePreviewSizedOutputBuffers: false,
17-
enablePhysicalBufferRotation: false,
18-
enableCameraMatrixDelivery: false,
19-
allowDeferredStart: false,
20-
dropFramesWhileBusy: true,
21-
})
22-
2312
beforeAll(async () => {
2413
await VisionCamera.requestCameraPermission()
2514
expect(VisionCamera.cameraPermissionStatus).toBe('authorized')
@@ -41,14 +30,10 @@ describe('VisionCamera - Controller Exposure', () => {
4130
quality: 0.8,
4231
qualityPrioritization: 'balanced',
4332
})
44-
const frameOutput = createContinuousOutput()
4533
const [controller] = await session.configure([
4634
{
4735
input: backDevice,
48-
outputs: [
49-
{ output: photoOutput, mirrorMode: 'auto' },
50-
{ output: frameOutput, mirrorMode: 'auto' },
51-
],
36+
outputs: [{ output: photoOutput, mirrorMode: 'auto' }],
5237
constraints: [],
5338
},
5439
])
@@ -84,14 +69,10 @@ describe('VisionCamera - Controller Exposure', () => {
8469
quality: 0.8,
8570
qualityPrioritization: 'balanced',
8671
})
87-
const frameOutput = createContinuousOutput()
8872
const [controller] = await session.configure([
8973
{
9074
input: backDevice,
91-
outputs: [
92-
{ output: photoOutput, mirrorMode: 'auto' },
93-
{ output: frameOutput, mirrorMode: 'auto' },
94-
],
75+
outputs: [{ output: photoOutput, mirrorMode: 'auto' }],
9576
constraints: [],
9677
},
9778
])

packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/HybridCameraController.kt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,30 @@ class HybridCameraController(
191191

192192
override fun setExposureBias(exposure: Double): Promise<Unit> {
193193
return Promise.async {
194-
camera.cameraControl
195-
.setExposureCompensationIndex(exposure.toInt())
196-
.await()
194+
val exposureIndex = exposure.toInt()
195+
val exposureState = camera.cameraInfo.exposureState
196+
if (!exposureState.isExposureCompensationSupported) {
197+
throw Error("Exposure compensation is not supported on this CameraDevice!")
198+
}
199+
if (!exposureState.exposureCompensationRange.contains(exposureIndex)) {
200+
throw Error(
201+
"`exposure` is out of range! Expected value within " +
202+
"${exposureState.exposureCompensationRange.lower}...${exposureState.exposureCompensationRange.upper}, received $exposure.",
203+
)
204+
}
205+
206+
val result =
207+
camera.cameraControl
208+
.setExposureCompensationIndex(exposureIndex)
209+
210+
// CameraX's Future waits for AE convergence, which can legitimately never happen at
211+
// extreme exposure compensation values. Once ExposureState reflects our target index,
212+
// CameraX has accepted the request and the controller Promise can resolve.
213+
if (result.isDone) {
214+
result.await()
215+
} else if (camera.cameraInfo.exposureState.exposureCompensationIndex != exposureIndex) {
216+
throw Error("Failed to set exposure compensation index to $exposureIndex.")
217+
}
197218
}
198219
}
199220

0 commit comments

Comments
 (0)