From d579a8ee6ede74a1c5e0d571e358c8f02f815b1e Mon Sep 17 00:00:00 2001 From: Ahaan Ugale Date: Mon, 10 May 2021 14:43:44 -0700 Subject: [PATCH] Nullability fixes for HotwordDetectionService APIs. * Make the Hotword*Result payloads NonNull. HotwordDetectedResult on the VoiceInteraction side is still @Nullable since the EventPayload is used for other result types too. * Remove @NonNull for a primitive return type. Bug: 184962614 Test: atest CtsVoiceInteractionTestCases Change-Id: Ib57368dab442f80805233864dc8fd86249f677cf --- core/api/system-current.txt | 10 +++++----- .../service/voice/AbstractHotwordDetector.java | 4 +--- .../service/voice/AlwaysOnHotwordDetector.java | 4 ++-- .../service/voice/HotwordDetectionService.java | 15 +++++++++++---- .../android/service/voice/HotwordDetector.java | 2 +- .../HotwordDetectionConnection.java | 4 ++-- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 96a23b2a25ec3..5137e82083ad7 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10473,7 +10473,7 @@ package android.service.voice { method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int); method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int); method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(); - method @Nullable public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle); + method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle); method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition(); method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory); field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1 @@ -10498,7 +10498,7 @@ package android.service.voice { method public abstract void onAvailabilityChanged(int); method public void onHotwordDetectionServiceInitialized(int); method public void onHotwordDetectionServiceRestarted(); - method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult); + method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult); } public static class AlwaysOnHotwordDetector.EventPayload { @@ -10559,8 +10559,8 @@ package android.service.voice { } public static final class HotwordDetectionService.Callback { - method public void onDetected(@Nullable android.service.voice.HotwordDetectedResult); - method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult); + method public void onDetected(@NonNull android.service.voice.HotwordDetectedResult); + method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult); } public interface HotwordDetector { @@ -10581,7 +10581,7 @@ package android.service.voice { method public void onHotwordDetectionServiceRestarted(); method public void onRecognitionPaused(); method public void onRecognitionResumed(); - method public void onRejected(@Nullable android.service.voice.HotwordRejectedResult); + method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult); } public final class HotwordRejectedResult implements android.os.Parcelable { diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java index 48967482fbdfb..54ccf309a58eb 100644 --- a/core/java/android/service/voice/AbstractHotwordDetector.java +++ b/core/java/android/service/voice/AbstractHotwordDetector.java @@ -55,10 +55,8 @@ abstract class AbstractHotwordDetector implements HotwordDetector { /** * Detect hotword from an externally supplied stream of data. * - * @return a writeable file descriptor that clients can start writing data in the given format. - * In order to stop detection, clients can close the given stream. + * @return true if the request to start recognition succeeded */ - @Nullable @Override public boolean startRecognition( @NonNull ParcelFileDescriptor audioStream, diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index bacc6ec2227b1..e8130172221a5 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -524,7 +524,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { * @param result Info about the second stage detection result, provided by the * {@link HotwordDetectionService}. */ - public void onRejected(@Nullable HotwordRejectedResult result) { + public void onRejected(@NonNull HotwordRejectedResult result) { } /** @@ -1164,7 +1164,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { } @Override - public void onRejected(HotwordRejectedResult result) { + public void onRejected(@NonNull HotwordRejectedResult result) { if (DBG) { Slog.d(TAG, "onRejected(" + result + ")"); } else { diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java index 473e7ae76cc98..ea01e09ef0de6 100644 --- a/core/java/android/service/voice/HotwordDetectionService.java +++ b/core/java/android/service/voice/HotwordDetectionService.java @@ -16,6 +16,8 @@ package android.service.voice; +import static java.util.Objects.requireNonNull; + import android.annotation.DurationMillisLong; import android.annotation.IntDef; import android.annotation.NonNull; @@ -414,11 +416,15 @@ public abstract class HotwordDetectionService extends Service { } /** - * Called when the detected result is valid. + * Informs the {@link HotwordDetector} that the keyphrase was detected. + * + * @param result Info about the detection result. This is provided to the + * {@link HotwordDetector}. */ - public void onDetected(@Nullable HotwordDetectedResult hotwordDetectedResult) { + public void onDetected(@NonNull HotwordDetectedResult result) { + requireNonNull(result); try { - mRemoteCallback.onDetected(hotwordDetectedResult); + mRemoteCallback.onDetected(result); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -433,7 +439,8 @@ public abstract class HotwordDetectionService extends Service { * @param result Info about the second stage detection result. This is provided to * the {@link HotwordDetector}. */ - public void onRejected(@Nullable HotwordRejectedResult result) { + public void onRejected(@NonNull HotwordRejectedResult result) { + requireNonNull(result); try { mRemoteCallback.onRejected(result); } catch (RemoteException e) { diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java index 2fb4dbc835edf..d3c10ea7c6708 100644 --- a/core/java/android/service/voice/HotwordDetector.java +++ b/core/java/android/service/voice/HotwordDetector.java @@ -160,7 +160,7 @@ public interface HotwordDetector { * @param result Info about the second stage detection result, provided by the * {@link HotwordDetectionService}. */ - void onRejected(@Nullable HotwordRejectedResult result); + void onRejected(@NonNull HotwordRejectedResult result); /** * Called when the {@link HotwordDetectionService} is created by the system and given a diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index d1bd159ee7ff5..5df3d9c0db655 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -612,7 +612,7 @@ final class HotwordDetectionConnection { options, new IDspHotwordDetectionCallback.Stub() { @Override - public void onRejected(@Nullable HotwordRejectedResult result) + public void onRejected(HotwordRejectedResult result) throws RemoteException { bestEffortClose(serviceAudioSink); bestEffortClose(serviceAudioSource); @@ -622,7 +622,7 @@ final class HotwordDetectionConnection { } @Override - public void onDetected(@Nullable HotwordDetectedResult triggerResult) + public void onDetected(HotwordDetectedResult triggerResult) throws RemoteException { bestEffortClose(serviceAudioSink); bestEffortClose(serviceAudioSource);