speech: Fix RemoteSpeechReco race condition

stopListening schedules a Runnable referring to mDelegatingListener.
mDelegatingListener can be set to null before the Runnable runs, causing
NullPointerException when it does run.

This CL defines a local alias for the current mDelegatingListener reference,
and uses this new alias in the Runnable closure.

After this CL, even if mDelegatingListener changes between stopListening
and run(), run() will always use the DelegatingListener
mDelegatingListener was pointing to at schedule-time rather than
run-time.

Bug: 193046622
Test: atest CtsVoiceRecognitionTestCases
Change-Id: I98b4fabf074873ce17e4046e243fe22f9e541f91
(cherry picked from commit a3312942cd)
This commit is contained in:
Andrea Ambu
2021-07-09 14:43:35 +01:00
parent be851a2ae3
commit b09de4738d

View File

@@ -125,10 +125,12 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
}
});
// Eager local evaluation to avoid reading a different or null value at closure-run-time
final DelegatingListener listenerToStart = this.mDelegatingListener;
run(service ->
service.startListening(
recognizerIntent,
mDelegatingListener,
listenerToStart,
attributionSource));
}
}
@@ -162,7 +164,9 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
}
mRecordingInProgress = false;
run(service -> service.stopListening(mDelegatingListener));
// Eager local evaluation to avoid reading a different or null value at closure-run-time
final DelegatingListener listenerToStop = this.mDelegatingListener;
run(service -> service.stopListening(listenerToStop));
}
}