Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78bb22a1 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi Committed by Ytai Ben-tsvi
Browse files

Support back-to-back soundtrigger recognitions

This change allows the HAL driver, at its discretion, indicate that
recognition is still active after a success event.
This is achieved by an additional flag added to the event.
The behavior to support this case has already been in place, for the
sake of supporting a FORCED event. This change just generalizes this
behavior to be able to cover SUCCESS as well.
For b/w compat, when the status is FORCED, we override the new flag
with 'true', indicating that recognition is still active.
We do not allow the flag to be set for status codes other than FORCED
or SUCCESS.

Test: atest FrameworksServicesTests:{SoundTriggerMiddlewareImplTest,SoundHw2CompatTest}
Test: Manual verification of sound trigger operation by invoking the
      assistant and now playing multiple times.
Bug: 186031938
Change-Id: Ie4edf82607c72ccb0b8d90a828b04c93153ec8f3
parent 1f3c7fd8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -204,7 +204,7 @@ class ConversionUtil {
                aidlEvent.status,
                modelHandle, aidlEvent.captureAvailable, captureSession,
                aidlEvent.captureDelayMs, aidlEvent.capturePreambleMs, aidlEvent.triggerInData,
                audioFormat, aidlEvent.data);
                audioFormat, aidlEvent.data, aidlEvent.recognitionStillActive);
    }

    public static SoundTrigger.RecognitionEvent aidl2apiPhraseRecognitionEvent(
+59 −13
Original line number Diff line number Diff line
@@ -1175,6 +1175,11 @@ public class SoundTrigger {
        @UnsupportedAppUsage
        @NonNull
        public final byte[] data;
        /**
         * Is recognition still active after this event.
         * @hide
         */
        public final boolean recognitionStillActive;

        /** @hide */
        @TestApi
@@ -1182,6 +1187,16 @@ public class SoundTrigger {
        public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
                int captureSession, int captureDelayMs, int capturePreambleMs,
                boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data) {
            this(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
                    capturePreambleMs, triggerInData, captureFormat, data,
                    status == RECOGNITION_STATUS_GET_STATE_RESPONSE);
        }

        /** @hide */
        public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
                int captureSession, int captureDelayMs, int capturePreambleMs,
                boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
                boolean recognitionStillActive) {
            this.status = status;
            this.soundModelHandle = soundModelHandle;
            this.captureAvailable = captureAvailable;
@@ -1191,6 +1206,7 @@ public class SoundTrigger {
            this.triggerInData = triggerInData;
            this.captureFormat = requireNonNull(captureFormat);
            this.data = data != null ? data : new byte[0];
            this.recognitionStillActive = recognitionStillActive;
        }

        /**
@@ -1266,8 +1282,10 @@ public class SoundTrigger {
                        .build();
            }
            byte[] data = in.readBlob();
            boolean recognitionStillActive = in.readBoolean();
            return new RecognitionEvent(status, soundModelHandle, captureAvailable, captureSession,
                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data);
                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data,
                    recognitionStillActive);
        }

        /** @hide */
@@ -1293,8 +1311,8 @@ public class SoundTrigger {
                dest.writeByte((byte)0);
            }
            dest.writeBlob(data);
            dest.writeBoolean(recognitionStillActive);
        }

        @Override
        public int hashCode() {
            final int prime = 31;
@@ -1312,6 +1330,7 @@ public class SoundTrigger {
            result = prime * result + Arrays.hashCode(data);
            result = prime * result + soundModelHandle;
            result = prime * result + status;
            result = result + (recognitionStillActive ? 1289 : 1291);
            return result;
        }

@@ -1334,6 +1353,8 @@ public class SoundTrigger {
                return false;
            if (!Arrays.equals(data, other.data))
                return false;
            if (recognitionStillActive != other.recognitionStillActive)
                return false;
            if (soundModelHandle != other.soundModelHandle)
                return false;
            if (status != other.status)
@@ -1370,7 +1391,9 @@ public class SoundTrigger {
                        (", encoding=" + captureFormat.getEncoding()))
                    + ((captureFormat == null) ? "" :
                        (", channelMask=" + captureFormat.getChannelMask()))
                    + ", data=" + (data == null ? 0 : data.length) + "]";
                    + ", data=" + (data == null ? 0 : data.length)
                    + ", recognitionStillActive=" + recognitionStillActive
                    + "]";
        }
    }

@@ -1676,8 +1699,18 @@ public class SoundTrigger {
                int captureSession, int captureDelayMs, int capturePreambleMs,
                boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
                @Nullable KeyphraseRecognitionExtra[] keyphraseExtras) {
            this(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
                    capturePreambleMs, triggerInData, captureFormat, data, keyphraseExtras,
                    status == RECOGNITION_STATUS_GET_STATE_RESPONSE);
        }

        public KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
                int captureSession, int captureDelayMs, int capturePreambleMs,
                boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
                @Nullable KeyphraseRecognitionExtra[] keyphraseExtras,
                boolean recognitionStillActive) {
            super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
                  capturePreambleMs, triggerInData, captureFormat, data);
                    capturePreambleMs, triggerInData, captureFormat, data, recognitionStillActive);
            this.keyphraseExtras =
                    keyphraseExtras != null ? keyphraseExtras : new KeyphraseRecognitionExtra[0];
        }
@@ -1713,11 +1746,12 @@ public class SoundTrigger {
                    .build();
            }
            byte[] data = in.readBlob();
            boolean recognitionStillActive = in.readBoolean();
            KeyphraseRecognitionExtra[] keyphraseExtras =
                    in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
            return new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
                    captureSession, captureDelayMs, capturePreambleMs, triggerInData,
                    captureFormat, data, keyphraseExtras);
                    captureFormat, data, keyphraseExtras, recognitionStillActive);
        }

        @Override
@@ -1738,6 +1772,7 @@ public class SoundTrigger {
                dest.writeByte((byte)0);
            }
            dest.writeBlob(data);
            dest.writeBoolean(recognitionStillActive);
            dest.writeTypedArray(keyphraseExtras, flags);
        }

@@ -1782,7 +1817,9 @@ public class SoundTrigger {
                        (", encoding=" + captureFormat.getEncoding()))
                    + ((captureFormat == null) ? "" :
                        (", channelMask=" + captureFormat.getChannelMask()))
                    + ", data=" + (data == null ? 0 : data.length) + "]";
                    + ", data=" + (data == null ? 0 : data.length)
                    + ", recognitionStillActive=" + recognitionStillActive
                    + "]";
        }
    }

@@ -1798,9 +1835,17 @@ public class SoundTrigger {
                boolean captureAvailable, int captureSession, int captureDelayMs,
                int capturePreambleMs, boolean triggerInData, @NonNull AudioFormat captureFormat,
                @Nullable byte[] data) {
            super(status, soundModelHandle, captureAvailable, captureSession,
                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
                    data);
            this(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
                    capturePreambleMs, triggerInData, captureFormat, data,
                    status == RECOGNITION_STATUS_GET_STATE_RESPONSE);
        }

        public GenericRecognitionEvent(int status, int soundModelHandle,
                boolean captureAvailable, int captureSession, int captureDelayMs,
                int capturePreambleMs, boolean triggerInData, @NonNull AudioFormat captureFormat,
                @Nullable byte[] data, boolean recognitionStillActive) {
            super(status, soundModelHandle, captureAvailable, captureSession, captureDelayMs,
                    capturePreambleMs, triggerInData, captureFormat, data, recognitionStillActive);
        }

        public static final @android.annotation.NonNull Parcelable.Creator<GenericRecognitionEvent> CREATOR
@@ -1818,7 +1863,8 @@ public class SoundTrigger {
            RecognitionEvent event = RecognitionEvent.fromParcel(in);
            return new GenericRecognitionEvent(event.status, event.soundModelHandle,
                    event.captureAvailable, event.captureSession, event.captureDelayMs,
                    event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data);
                    event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data,
                    event.recognitionStillActive);
        }

        @Override
+9 −0
Original line number Diff line number Diff line
@@ -48,4 +48,13 @@ parcelable RecognitionEvent {
    @nullable AudioConfig audioConfig;
    /** Additional data. */
    byte[] data;
    /**
     * If true, recognition is still active after this event.
     * For compatibility with earlier versions of this data type, when the status field is set to
     * RecognitionStatus.FORCED, the value of this field should be treated as 'true', regardless of
     * the actual value.
     * When the status is RecognitionStatus.ABORTED or RecognitionStatus.FAILURE, this must be set
     * to false.
     */
     boolean recognitionStillActive;
}
+1 −0
Original line number Diff line number Diff line
@@ -43,4 +43,5 @@ parcelable RecognitionEvent {
  boolean triggerInData;
  @nullable android.media.audio.common.AudioConfig audioConfig;
  byte[] data;
  boolean recognitionStillActive;
}
+1 −0
Original line number Diff line number Diff line
@@ -310,6 +310,7 @@ class ConversionUtil {
        for (int i = 0; i < aidlEvent.data.length; ++i) {
            aidlEvent.data[i] = hidlEvent.data.get(i);
        }
        aidlEvent.recognitionStillActive = aidlEvent.status == RecognitionStatus.FORCED;
        return aidlEvent;
    }

Loading