Skip to content

Commit

Permalink
changed speak() to cancel any voice instructions already queued (#539)
Browse files Browse the repository at this point in the history
* changed queueMode parameter form QUEUE_ADD to QUEUE_FLUSH to cancel any voice instructions already queued

* added an 'important' parameter to speak()

* added test cases for important messages to flush queue
  • Loading branch information
dan424gg authored Oct 15, 2023
1 parent 07e7cc7 commit 2a628f1
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.cyclestreets.liveride

import android.util.Log
import net.cyclestreets.routing.Journey
import net.cyclestreets.routing.Segment
import org.osmdroid.util.GeoPoint
Expand All @@ -9,7 +10,9 @@ internal class AdvanceToSegment @JvmOverloads constructor(previous: LiveRideStat
segment: Segment? = journey.segments[journey.activeSegmentIndex() + 1]) : LiveRideState(previous) {
init {
journey.setActiveSegment(segment!!)
notify(segment)
// this might not be an important message
Log.d("importantTest", "AdvanceToSegment Init: ${segment.toString()}")
notify(segment, true)
}

override fun update(journey: Journey, myLocation: GeoPoint, accuracy: Int): LiveRideState {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.cyclestreets.liveride

import android.util.Log
import net.cyclestreets.routing.Journey
import org.osmdroid.util.GeoPoint

Expand All @@ -10,7 +11,7 @@ internal class Arrivee(previous: LiveRideState) : LiveRideState(previous) {
}

init {
notify(ARRIVEE)
notify(ARRIVEE, important = true)
}

override fun update(journey: Journey, myLocation: GeoPoint, accuracy: Int): LiveRideState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.osmdroid.util.GeoPoint
internal class GoingOffCourse(previous: LiveRideState) : LiveRideState(previous) {

init {
notify("Moving away from route")
notify("Moving away from route", important = true)
}

override fun update(journey: Journey, myLocation: GeoPoint, accuracy: Int): LiveRideState {
Expand All @@ -32,7 +32,7 @@ internal class GoingOffCourse(previous: LiveRideState) : LiveRideState(previous)
return AdvanceToSegment(this, journey, nearestSeg)
}
if (distance <= CycleStreetsPreferences.offtrackDistance() - 5) {
notify("Getting back on track")
notify("Getting back on track", important = true)
return OnTheMove(this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package net.cyclestreets.liveride
import android.app.Service
import android.content.Context
import android.speech.tts.TextToSpeech
import android.util.Log
import net.cyclestreets.routing.Journey
import org.osmdroid.util.GeoPoint

Expand All @@ -15,7 +16,8 @@ internal class LiveRideStart(context: Context, tts: TextToSpeech?) : LiveRideSta

override fun update(journey: Journey, myLocation: GeoPoint, accuracy: Int): LiveRideState {
journey.setActiveSegmentIndex(0)
notify(journey.activeSegment()!!)
Log.d("importantTest", "LiveRideStart Update: ${journey.activeSegment()!!.toString()}")
notify(journey.activeSegment()!!, true)
return HuntForSegment(this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.content.Context
import android.content.Intent
import android.graphics.drawable.Icon
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.util.Log
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.toAndroidIconCompat
Expand Down Expand Up @@ -43,14 +44,15 @@ internal abstract class LiveRideState(protected val context: Context,
abstract fun isStopped(): Boolean
abstract fun arePedalling(): Boolean

protected fun notify(seg: Segment) {
protected fun notify(seg: Segment, important: Boolean = false) {
notification(seg.street() + " " + seg.formattedDistance(), seg.toString())

val instruction = turnInto(seg)
if (seg.turnInstruction().isNotEmpty()) {
instruction.append(". Continue ").append(seg.formattedDistance())
}
speak(instruction.toString())

speak(instruction.toString(), important)
}

protected fun turnInto(seg: Segment): StringBuilder {
Expand All @@ -62,21 +64,22 @@ internal abstract class LiveRideState(protected val context: Context,
return instruction
}

protected fun notify(text: String, directionIcon: Int) {
// checked
protected fun notify(text: String, directionIcon: Int, important: Boolean = false) {
notification(text, text, directionIcon)
speak(text)
speak(text, important)
}

@JvmOverloads
protected fun notify(text: String, ticker: String = text) {
protected fun notify(text: String, ticker: String = text, important: Boolean = false) {
notification(text, ticker)
speak(text)
speak(text, important)
}

protected fun notifyAndSetServiceForeground(service: Service, text: String) {
val notification = getNotification(text, text, null)
service.startForeground(NOTIFICATION_ID, notification)
speak(text)
speak(text, true)
}

private fun notification(text: String, ticker: String, directionIcon: Int? = null) {
Expand Down Expand Up @@ -117,8 +120,11 @@ internal abstract class LiveRideState(protected val context: Context,
return context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}

private fun speak(words: String) {
tts?.speak(speechify(words), TextToSpeech.QUEUE_ADD, null, UUID.randomUUID().toString())
private fun speak(words: String, important: Boolean = false) {
if (important) {
tts?.speak(speechify(words), TextToSpeech.QUEUE_FLUSH, null, UUID.randomUUID().toString())
} else {
tts?.speak(speechify(words), TextToSpeech.QUEUE_ADD, null, UUID.randomUUID().toString())
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class NearingTurn(previous: LiveRideState, journey: Journey) :
if (!segment.turnInstruction().isNullOrEmpty()) {
notify("Get ready to ${turnInto(segment)}", TurnIcons.iconId(segment.turn()))
} else {
notify("You are approaching the ${Arrivee.ARRIVEE}")
notify("You are approaching the ${Arrivee.ARRIVEE}", important = true)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.osmdroid.util.GeoPoint
internal class PassingWaypoint(previous: LiveRideState?) : LiveRideState(previous!!) {

init {
notify("Passing waypoint")
notify("Passing waypoint", important = true)
}

override fun update(journey: Journey, myLocation: GeoPoint, accuracy: Int): LiveRideState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal class ReplanFromHere(previous: LiveRideState, whereIam: GeoPoint) : Liv
private var next: LiveRideState? = null

init {
notify("Too far away. Re-planning the journey.")
notify("Too far away. Re-planning the journey.", important = true)

next = this

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.Menu;
Expand Down Expand Up @@ -80,8 +81,9 @@ public void onCreateContextMenu(final ContextMenu menu) {

public boolean onMenuItemSelected(final int featureId, final MenuItem item) {
for (final Iterator<MenuListener> overlays = menuOverlays(); overlays.hasNext(); )
if (overlays.next().onMenuItemSelected(featureId, item))
if (overlays.next().onMenuItemSelected(featureId, item)) {
return true;
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ class LiveRideVoiceTest {
move(0.126, 52.212)
verify("Get ready to Straight on into lcn (unknown cycle network) continuation")
move(0.12634, 52.21207)
verify("Straight on into lcn (unknown cycle network) continuation. Continue 5 metres")
verify("Straight on into lcn (unknown cycle network) continuation. Continue 5 metres", true)
move(0.12634, 52.21207)
// AdvanceToSegment advances the segment; we need another location update to trigger the next NearingTurn
move(0.12634, 52.21207)
verify("Get ready to Straight on into lcn (unknown cycle network)")
move(0.12634, 52.21207)
verify("Straight on into lcn (unknown cycle network). Continue 85 metres")
verify("Straight on into lcn (unknown cycle network). Continue 85 metres", true)
}

@Test
Expand All @@ -67,11 +67,11 @@ class LiveRideVoiceTest {
assertThat(journey.activeSegment()!!.street()).isEqualTo("Thoday Street")

move(0.14748, 52.19967)
verify("You are approaching the arreev eh")
verify("You are approaching the arreev eh", true)
move(0.14744, 52.19962)
verify("Destination Thoday+Street")
verify("Destination Thoday+Street", true)
move(0.14744, 52.19962)
verify("arreev eh")
verify("arreev eh", true)
}

@Test
Expand All @@ -83,7 +83,7 @@ class LiveRideVoiceTest {
move(-3.33022, 50.92086)
verify("Get ready to Turn right then turn left into Broad Path")
move(-3.33019, 50.92081)
verify("Turn right then turn left into Broad Path. Continue 1000 metres")
verify("Turn right then turn left into Broad Path. Continue 1000 metres", true)
}

@Test
Expand All @@ -95,7 +95,7 @@ class LiveRideVoiceTest {
move(-0.56665, 51.63393)
verify("Get ready to Bear left then bear right into London Road, A4 1 3")
move(-0.56667, 51.63401)
verify("Bear left then bear right into London Road, A4 1 3. Continue 1330 metres")
verify("Bear left then bear right into London Road, A4 1 3. Continue 1330 metres", true)
}

@Test
Expand All @@ -107,12 +107,12 @@ class LiveRideVoiceTest {
move(-2.26018, 50.74097)
verify("Get ready to Straight on over Bridge into Short unnamed link")
move(-2.26058, 50.74058)
verify("Straight on over Bridge into Short unnamed link. Continue 95 metres")
verify("Straight on over Bridge into Short unnamed link. Continue 95 metres", true)
move(-2.2612, 50.74025)
move(-2.2612, 50.74025)
verify("Get ready to Bear left over Bridge into Link with The Hollow")
move(-2.26148, 50.73993)
verify("Bear left over Bridge into Link with The Hollow. Continue 195 metres")
verify("Bear left over Bridge into Link with The Hollow. Continue 195 metres", true)
}

@Test
Expand All @@ -134,10 +134,15 @@ class LiveRideVoiceTest {
liveRideState = liveRideState.update(journey, GeoPoint(lat, lon), 5)
}

private fun verify(expectedSpeech: String) {
private fun verify(expectedSpeech: String, important: Boolean = false) {
try {
inOrder.verify(mockTts, times(1)).speak(eq(expectedSpeech), eq(TextToSpeech.QUEUE_ADD), isNull(), anyString())
inOrder.verifyNoMoreInteractions()
if (important) {
inOrder.verify(mockTts, times(1)).speak(eq(expectedSpeech), eq(TextToSpeech.QUEUE_FLUSH), isNull(), anyString())
inOrder.verifyNoMoreInteractions()
} else {
inOrder.verify(mockTts, times(1)).speak(eq(expectedSpeech), eq(TextToSpeech.QUEUE_ADD), isNull(), anyString())
inOrder.verifyNoMoreInteractions()
}
} catch (e: VerificationInOrderFailure) {
System.out.println(mockingDetails(mockTts).printInvocations())
throw e
Expand Down

0 comments on commit 2a628f1

Please sign in to comment.