ReviewOS

also looking at this

craft-native/craft

fix(android): answer the page from haptic, vibrate and the speech calls

#234
Merged glennmichael123 wants to merge fix/android-feedback-promises into main
7 files +364 -114
packages/android/src/index.test.tsmodified+36-0
Changes to packages/android/src/index.test.ts
@@ -377,6 +377,42 @@ describe('Craft Android builder', () => {
377377 expect(bridge).toContain('if (!keepAwakeEnabled && disabled("keepAwake", "setKeepAwake")) return false')
378378 })
379379
380 it('answers the page from haptic, vibrate and the speech calls', async () => {
381 // #219: all four returned Unit, so the page got undefined where iOS
382 // returns a promise, and a grant of RECORD_AUDIO went nowhere.
383 const output = mkdtempSync(join(tmpdir(), 'craft-android-feedback-answers-'))
384 await init({
385 name: 'WildLoop',
386 packageName: 'org.wildloop.app',
387 output,
388 config: { enableHaptics: true, enableSpeechRecognition: true },
389 })
390
391 const bridge = readFileSync(join(output, 'app/src/main/java/org/wildloop/app/CraftBridge.kt'), 'utf8')
392 for (const signature of [
393 'fun haptic(style: String): Boolean',
394 'fun vibrate(patternJson: String): Boolean',
395 'fun startListening(): Boolean',
396 'fun stopListening(): Boolean',
397 ]) {
398 expect(bridge).toContain(signature)
399 }
400
401 // The page reads that return value rather than dropping it.
402 expect(bridge).toContain("return CraftAndroid.haptic(style || 'medium') === true;")
403 expect(bridge).toContain('return CraftAndroid.startListening() === true;')
404
405 // The microphone grant starts the recogniser, the way iOS starts from
406 // inside its authorization callback, and a denial is not silence.
407 expect(bridge).toContain('private fun beginSpeechRecognition()')
408 expect(bridge).toContain('if (requestCode == REQUEST_SPEECH) {')
409 expect(bridge).toContain('if (isPermissionGranted(Manifest.permission.RECORD_AUDIO)) beginSpeechRecognition()')
410 expect(bridge).toContain('"Microphone permission denied"')
411
412 // And stopping says the session ended, once, as iOS does.
413 expect(bridge).toContain('sendEvent("craftSpeechEnd", emptyMap())')
414 })
415
380416 it('routes external Activity results back to every pending media promise', async () => {
381417 const output = mkdtempSync(join(tmpdir(), 'craft-android-activity-results-'))
382418 await init({ name: 'WildLoop', packageName: 'org.wildloop.app', output })