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

Commit fcf671be authored by Przemyslaw Szczepaniak's avatar Przemyslaw Szczepaniak Committed by Android (Google) Code Review
Browse files

Fix EBADF in TTS synthesizeToFile method.

Recent TTS change altered how the TextToSpeech.synthesizeToFile method
operates. Previously, synthesis service was responsible for creating
output file. Now, client API creates a file and then sends opened file
descriptor using ParcelFileDescriptor.

On service side, I forgot to keep a reference to a ParcelFileDescriptor object.
When GC was removing it, it was closing underlying file descriptor, resulting
in a EBADF error for all following writes to the output file.

This change makes use of a ParcelFileDescriptor.AutoCloseOutputStream to keep a
reference to the ParcelFileDescriptor. It will be referenced until we are done
with writing.

Change-Id: I8327af0eaeabaebfbbd8816d959783e89086a7c5
parent f4d6f153
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.util.Log;

import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Set;
@@ -656,19 +657,18 @@ public abstract class TextToSpeechService extends Service {
        }
    }

    private class SynthesisToFileSpeechDescriptorItem extends SynthesisSpeechItem {
        private final FileDescriptor mFileDescriptor;
    private class SynthesisToFileOutputStreamSpeechItem extends SynthesisSpeechItem {
        private final FileOutputStream mFileOutputStream;

        public SynthesisToFileSpeechDescriptorItem(Object callerIdentity, int callerUid,
                int callerPid, Bundle params, String text, FileDescriptor fileDescriptor) {
                int callerPid, Bundle params, String text, FileOutputStream fileOutputStream) {
            super(callerIdentity, callerUid, callerPid, params, text);
            mFileDescriptor = fileDescriptor;
            mFileOutputStream = fileOutputStream;
        }

        @Override
        protected AbstractSynthesisCallback createSynthesisCallback() {
            FileOutputStream fileOutputStream = new FileOutputStream(mFileDescriptor);
            return new FileSynthesisCallback(fileOutputStream.getChannel());
            return new FileSynthesisCallback(mFileOutputStream.getChannel());
        }

        @Override
@@ -680,6 +680,11 @@ public abstract class TextToSpeechService extends Service {
            } else {
                dispatchOnError();
            }
            try {
              mFileOutputStream.close();
            } catch(IOException e) {
              Log.w(TAG, "Failed to close output file", e);
            }
            return status;
        }
    }
@@ -805,9 +810,9 @@ public abstract class TextToSpeechService extends Service {
                return TextToSpeech.ERROR;
            }

            SpeechItem item = new SynthesisToFileSpeechDescriptorItem(caller, Binder.getCallingUid(),
                    Binder.getCallingPid(), params, text,
                    fileDescriptor.getFileDescriptor());
            SpeechItem item = new SynthesisToFileOutputStreamSpeechItem(caller,
                    Binder.getCallingUid(), Binder.getCallingPid(), params, text,
                    new ParcelFileDescriptor.AutoCloseOutputStream(fileDescriptor));
            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
        }