Merge "Close audio source after getting callback from HotwordDetectionService" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8a66bf557f
@@ -270,14 +270,9 @@ final class HotwordDetectionConnection {
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "startListeningFromExternalSource");
|
Slog.d(TAG, "startListeningFromExternalSource");
|
||||||
}
|
}
|
||||||
|
handleExternalSourceHotwordDetection(
|
||||||
ParcelFileDescriptor.AutoCloseInputStream audioReader =
|
audioStream,
|
||||||
new ParcelFileDescriptor.AutoCloseInputStream(audioStream);
|
|
||||||
|
|
||||||
handleSoftwareHotwordDetection(
|
|
||||||
audioFormat,
|
audioFormat,
|
||||||
AudioReader.createFromInputStream(audioReader),
|
|
||||||
AUDIO_SOURCE_EXTERNAL,
|
|
||||||
options,
|
options,
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
@@ -556,14 +551,18 @@ final class HotwordDetectionConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSoftwareHotwordDetection(
|
private void handleExternalSourceHotwordDetection(
|
||||||
|
ParcelFileDescriptor audioStream,
|
||||||
AudioFormat audioFormat,
|
AudioFormat audioFormat,
|
||||||
AudioReader audioSource,
|
|
||||||
int audioSourceValue,
|
|
||||||
@Nullable PersistableBundle options,
|
@Nullable PersistableBundle options,
|
||||||
IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
|
IMicrophoneHotwordDetectionVoiceInteractionCallback callback) {
|
||||||
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "#handleExternalSourceHotwordDetection");
|
||||||
|
}
|
||||||
|
AudioReader audioSource = AudioReader.createFromInputStream(
|
||||||
|
new ParcelFileDescriptor.AutoCloseInputStream(audioStream));
|
||||||
|
|
||||||
|
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
|
||||||
if (clientPipe == null) {
|
if (clientPipe == null) {
|
||||||
// TODO: Need to propagate as unknown error or something?
|
// TODO: Need to propagate as unknown error or something?
|
||||||
return;
|
return;
|
||||||
@@ -579,8 +578,8 @@ final class HotwordDetectionConnection {
|
|||||||
try (AudioReader source = audioSource;
|
try (AudioReader source = audioSource;
|
||||||
OutputStream fos =
|
OutputStream fos =
|
||||||
new ParcelFileDescriptor.AutoCloseOutputStream(serviceAudioSink)) {
|
new ParcelFileDescriptor.AutoCloseOutputStream(serviceAudioSink)) {
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
while (true) {
|
while (true) {
|
||||||
int bytesRead = source.read(buffer, 0, 1024);
|
int bytesRead = source.read(buffer, 0, 1024);
|
||||||
|
|
||||||
@@ -608,76 +607,32 @@ final class HotwordDetectionConnection {
|
|||||||
service -> service.detectFromMicrophoneSource(
|
service -> service.detectFromMicrophoneSource(
|
||||||
serviceAudioSource,
|
serviceAudioSource,
|
||||||
// TODO: consider making a proxy callback + copy of audio format
|
// TODO: consider making a proxy callback + copy of audio format
|
||||||
audioSourceValue, audioFormat, options,
|
AUDIO_SOURCE_EXTERNAL,
|
||||||
|
audioFormat,
|
||||||
|
options,
|
||||||
new IDspHotwordDetectionCallback.Stub() {
|
new IDspHotwordDetectionCallback.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onRejected(@Nullable HotwordRejectedResult result)
|
public void onRejected(@Nullable HotwordRejectedResult result)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
|
bestEffortClose(serviceAudioSink);
|
||||||
|
bestEffortClose(serviceAudioSource);
|
||||||
|
bestEffortClose(audioSource);
|
||||||
|
|
||||||
// TODO: Propagate the HotwordRejectedResult.
|
// TODO: Propagate the HotwordRejectedResult.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetected(@Nullable HotwordDetectedResult triggerResult)
|
public void onDetected(@Nullable HotwordDetectedResult triggerResult)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
// Stop
|
|
||||||
bestEffortClose(serviceAudioSink);
|
bestEffortClose(serviceAudioSink);
|
||||||
|
bestEffortClose(serviceAudioSource);
|
||||||
if (audioSourceValue == AUDIO_SOURCE_EXTERNAL) {
|
|
||||||
callback.onDetected(triggerResult, null, null);
|
|
||||||
// TODO: Add a delay before closing.
|
|
||||||
bestEffortClose(audioSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe =
|
|
||||||
createPipe();
|
|
||||||
|
|
||||||
if (clientPipe == null) {
|
|
||||||
// Error.
|
|
||||||
// Need to propagate as unknown error or something?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ParcelFileDescriptor callbackAudioSink = clientPipe.second;
|
|
||||||
ParcelFileDescriptor callbackClientRead = clientPipe.first;
|
|
||||||
|
|
||||||
mAudioCopyExecutor.execute(() -> {
|
|
||||||
try (AudioReader source = audioSource;
|
|
||||||
OutputStream fos =
|
|
||||||
new ParcelFileDescriptor.AutoCloseOutputStream(
|
|
||||||
callbackAudioSink)) {
|
|
||||||
|
|
||||||
// TODO: get ring buffer suffix here
|
|
||||||
// fos.write(lastSeveralSeconds);
|
|
||||||
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
while (true) {
|
|
||||||
int bytesRead = source.read(buffer, 0, 1024);
|
|
||||||
|
|
||||||
if (bytesRead < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fos.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.w(TAG, "Failed supplying audio data to validator", e);
|
|
||||||
} finally {
|
|
||||||
synchronized (mLock) {
|
|
||||||
mCurrentAudioSink = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: noteOp here.
|
// TODO: noteOp here.
|
||||||
// Remove hotword offset from trigger result
|
callback.onDetected(triggerResult, null /* audioFormat */,
|
||||||
// TODO: consider propagating only capture session.
|
null /* audioStream */);
|
||||||
callback.onDetected(triggerResult, null, callbackClientRead);
|
|
||||||
// TODO: Add a delay before closing.
|
// TODO: Add a delay before closing.
|
||||||
bestEffortClose(callbackClientRead);
|
bestEffortClose(audioSource);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO: verify this is the right thing to do here.
|
|
||||||
bestEffortClose(serviceAudioSource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void bestEffortClose(Closeable closeable) {
|
private static void bestEffortClose(Closeable closeable) {
|
||||||
|
|||||||
@@ -477,6 +477,11 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (audioStream == null) {
|
||||||
|
Slog.w(TAG, "External source is null for hotword detector");
|
||||||
|
throw new IllegalStateException("External source is null for hotword detector");
|
||||||
|
}
|
||||||
|
|
||||||
mHotwordDetectionConnection
|
mHotwordDetectionConnection
|
||||||
.startListeningFromExternalSource(audioStream, audioFormat, options, callback);
|
.startListeningFromExternalSource(audioStream, audioFormat, options, callback);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user