( device: DeviceInfo, action: AndroidFingerprintAction, )
| 171 | } |
| 172 | |
| 173 | async function runAndroidFingerprintCommand( |
| 174 | device: DeviceInfo, |
| 175 | action: AndroidFingerprintAction, |
| 176 | ): Promise<void> { |
| 177 | const attempts = androidFingerprintCommandAttempts(device, action); |
| 178 | const failures: CommandAttemptFailure[] = []; |
| 179 | |
| 180 | for (const args of attempts) { |
| 181 | const result = await runAndroidAdb(device, args, { allowFailure: true }); |
| 182 | if (result.exitCode === 0) return; |
| 183 | failures.push({ |
| 184 | args, |
| 185 | stdout: result.stdout, |
| 186 | stderr: result.stderr, |
| 187 | exitCode: result.exitCode, |
| 188 | }); |
| 189 | } |
| 190 | |
| 191 | const attemptsPayload = summarizeCommandAttemptFailures(failures); |
| 192 | const capabilityMissing = |
| 193 | failures.length > 0 && |
| 194 | failures.every((failure) => |
| 195 | isAndroidFingerprintCapabilityMissing(failure.stdout, failure.stderr), |
| 196 | ); |
| 197 | if (capabilityMissing) { |
| 198 | throw new AppError( |
| 199 | 'UNSUPPORTED_OPERATION', |
| 200 | 'Android fingerprint simulation is not supported on this target/runtime.', |
| 201 | { |
| 202 | deviceId: device.id, |
| 203 | action, |
| 204 | hint: 'Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.', |
| 205 | attempts: attemptsPayload, |
| 206 | }, |
| 207 | ); |
| 208 | } |
| 209 | throw new AppError('COMMAND_FAILED', 'Failed to simulate Android fingerprint.', { |
| 210 | deviceId: device.id, |
| 211 | action, |
| 212 | attempts: attemptsPayload, |
| 213 | }); |
| 214 | } |
| 215 | |
| 216 | function androidFingerprintCommandAttempts( |
| 217 | device: DeviceInfo, |
no test coverage detected