Skip to content

Commit 9615697

Browse files
author
Jeff Brown
committed
Fix race in RecognizerService teardown.
Use a WeakReference to refer to the outer class to prevent leaks. Ensure atomicity of access to the reference. Bug: 17584947 Change-Id: I7ad7c7793b60fa125e04fc4d803ed905e8a00a95
1 parent 134b62e commit 9615697

1 file changed

Lines changed: 19 additions & 11 deletions

File tree

core/java/android/speech/RecognitionService.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import android.os.RemoteException;
2929
import android.util.Log;
3030

31+
import java.lang.ref.WeakReference;
32+
3133
/**
3234
* This class provides a base class for recognition service implementations. This class should be
3335
* extended only in case you wish to implement a new speech recognizer. Please note that the
@@ -315,40 +317,46 @@ public void rmsChanged(float rmsdB) throws RemoteException {
315317
}
316318

317319
/** Binder of the recognition service */
318-
private static class RecognitionServiceBinder extends IRecognitionService.Stub {
319-
private RecognitionService mInternalService;
320+
private static final class RecognitionServiceBinder extends IRecognitionService.Stub {
321+
private final WeakReference<RecognitionService> mServiceRef;
320322

321323
public RecognitionServiceBinder(RecognitionService service) {
322-
mInternalService = service;
324+
mServiceRef = new WeakReference<RecognitionService>(service);
323325
}
324326

327+
@Override
325328
public void startListening(Intent recognizerIntent, IRecognitionListener listener) {
326329
if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
327-
if (mInternalService != null && mInternalService.checkPermissions(listener)) {
328-
mInternalService.mHandler.sendMessage(Message.obtain(mInternalService.mHandler,
329-
MSG_START_LISTENING, mInternalService.new StartListeningArgs(
330+
final RecognitionService service = mServiceRef.get();
331+
if (service != null && service.checkPermissions(listener)) {
332+
service.mHandler.sendMessage(Message.obtain(service.mHandler,
333+
MSG_START_LISTENING, service.new StartListeningArgs(
330334
recognizerIntent, listener)));
331335
}
332336
}
333337

338+
@Override
334339
public void stopListening(IRecognitionListener listener) {
335340
if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder());
336-
if (mInternalService != null && mInternalService.checkPermissions(listener)) {
337-
mInternalService.mHandler.sendMessage(Message.obtain(mInternalService.mHandler,
341+
final RecognitionService service = mServiceRef.get();
342+
if (service != null && service.checkPermissions(listener)) {
343+
service.mHandler.sendMessage(Message.obtain(service.mHandler,
338344
MSG_STOP_LISTENING, listener));
339345
}
340346
}
341347

348+
@Override
342349
public void cancel(IRecognitionListener listener) {
343350
if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
344-
if (mInternalService != null && mInternalService.checkPermissions(listener)) {
345-
mInternalService.mHandler.sendMessage(Message.obtain(mInternalService.mHandler,
351+
final RecognitionService service = mServiceRef.get();
352+
if (service != null && service.checkPermissions(listener)) {
353+
service.mHandler.sendMessage(Message.obtain(service.mHandler,
346354
MSG_CANCEL, listener));
347355
}
348356
}
349357

350358
public void clearReference() {
351-
mInternalService = null;
359+
mServiceRef.clear();
352360
}
353361
}
354362
}

0 commit comments

Comments
 (0)