Merge change 3374 into donut

* changes:
  Fix tracking of backup participants across package remove/update
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index bf62995..d2aa30e 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -16,33 +16,45 @@
 #include <media/AudioSystem.h>
 
 // This header defines the interface used by the Android platform
-// to access Text-To-Speech functionality in shared libraries that implement speech
-// synthesis and the management of resources associated with the synthesis.
-// An example of the implementation of this interface can be found in 
+// to access Text-To-Speech functionality in shared libraries that implement
+// speech synthesis and the management of resources associated with the
+// synthesis.
+// An example of the implementation of this interface can be found in
 // FIXME: add path+name to implementation of default TTS engine
 // Libraries implementing this interface are used in:
 //  frameworks/base/tts/jni/android_tts_SpeechSynthesis.cpp
 
 namespace android {
 
+enum tts_synth_status {
+    TTS_SYNTH_DONE              = 0,
+    TTS_SYNTH_PENDING           = 1
+};
+
+enum tts_callback_status {
+    TTS_CALLBACK_HALT           = 0,
+    TTS_CALLBACK_CONTINUE       = 1
+};
+
 // The callback is used by the implementation of this interface to notify its
 // client, the Android TTS service, that the last requested synthesis has been
-// completed.
+// completed. // TODO reword
 // The callback for synthesis completed takes:
-//    void *       - The userdata pointer set in the original synth call
-//    uint32_t     - Track sampling rate in Hz
-//    audio_format - The AudioSystem::audio_format enum
-//    int          - The number of channels
-//    int8_t *     - A buffer of audio data only valid during the execution of the callback
-//    size_t       - The size of the buffer
-// Note about memory management:
-//    The implementation of TtsEngine is responsible for the management of the memory
-//    it allocates to store the synthesized speech. After the execution of the callback
-//    to hand the synthesized data to the client of TtsEngine, the TTS engine is
-//    free to reuse or free the previously allocated memory.
-//    This implies that the implementation of the "synthDoneCB" callback cannot use
-//    the pointer to the buffer of audio samples outside of the callback itself.
-typedef void (synthDoneCB_t)(void *, uint32_t, AudioSystem::audio_format, int, int8_t *, size_t);
+// @param [inout] void *&       - The userdata pointer set in the original
+//                                 synth call
+// @param [in]    uint32_t      - Track sampling rate in Hz
+// @param [in]    audio_format  - The AudioSystem::audio_format enum
+// @param [in]    int           - The number of channels
+// @param [inout] int8_t *&     - A buffer of audio data only valid during the
+//                                execution of the callback
+// @param [inout] size_t  &     - The size of the buffer
+// @param [in] tts_synth_status - indicate whether the synthesis is done, or
+//                                 if more data is to be synthesized.
+// @return TTS_CALLBACK_HALT to indicate the synthesis must stop,
+//         TTS_CALLBACK_CONTINUE to indicate the synthesis must continue if
+//            there is more data to produce.
+typedef tts_callback_status (synthDoneCB_t)(void *&, uint32_t,
+        AudioSystem::audio_format, int, int8_t *&, size_t&, tts_synth_status);
 
 class TtsEngine;
 extern "C" TtsEngine* getTtsEngine();
@@ -69,38 +81,41 @@
     // @return TTS_SUCCESS, or TTS_FAILURE
     virtual tts_result shutdown();
 
-    // Interrupt synthesis and flushes any synthesized data that hasn't been output yet.
-    // This will block until callbacks underway are completed.
+    // Interrupt synthesis and flushes any synthesized data that hasn't been
+    // output yet. This will block until callbacks underway are completed.
     // @return TTS_SUCCESS, or TTS_FAILURE
     virtual tts_result stop();
 
-    // Load the resources associated with the specified language. The loaded language will
-    // only be used once a call to setLanguage() with the same language value is issued.
-    // Language values are based on the Android conventions for localization as described in
-    // the Android platform documentation on internationalization. This implies that language
-    // data is specified in the format xx-rYY, where xx is a two letter ISO 639-1 language code
-    // in lowercase and rYY is a two letter ISO 3166-1-alpha-2 language code in uppercase
-    // preceded by a lowercase "r".
+    // Load the resources associated with the specified language. The loaded
+    // language will only be used once a call to setLanguage() with the same
+    // language value is issued. Language values are based on the Android
+    // conventions for localization as described in the Android platform
+    // documentation on internationalization. This implies that language
+    // data is specified in the format xx-rYY, where xx is a two letter
+    // ISO 639-1 language code in lowercase and rYY is a two letter
+    // ISO 3166-1-alpha-2 language code in uppercase preceded by a
+    // lowercase "r".
     // @param value pointer to the language value
     // @param size  length of the language value
     // @return TTS_SUCCESS, or TTS_FAILURE
     virtual tts_result loadLanguage(const char *value, const size_t size);
 
-    // Signal the engine to use the specified language. This will force the language to be
-    // loaded if it wasn't loaded previously with loadLanguage().
+    // Signal the engine to use the specified language. This will force the
+    // language to be loaded if it wasn't loaded previously with loadLanguage().
     // See loadLanguage for the specification of the language.
     // @param value pointer to the language value
     // @param size  length of the language value
     // @return TTS_SUCCESS, or TTS_FAILURE
     virtual tts_result setLanguage(const char *value, const size_t size);
 
-    // Retrieve the currently set language, or an empty "value" if no language has
-    // been set.
+    // Retrieve the currently set language, or an empty "value" if no language
+    // has been set.
     // @param[out]   value pointer to the retrieved language value
-    // @param[inout] iosize  in: stores the size available to store the language value in *value
-    //                       out: stores the size required to hold the language value if
-    //                         getLanguage() returned  TTS_PROPERTY_SIZE_TOO_SMALL,
-    //                         unchanged otherwise.
+    // @param[inout] iosize in: stores the size available to store the language
+    //                         value in *value
+    //                      out: stores the size required to hold the language
+    //                         value if  getLanguage() returned
+    //                         TTS_PROPERTY_SIZE_TOO_SMALL, unchanged otherwise.
     // @return TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL, or TTS_FAILURE
     virtual tts_result getLanguage(char *value, size_t *iosize);
 
@@ -109,23 +124,31 @@
     // @param property pointer to the property name
     // @param value    pointer to the property value
     // @param size     maximum size required to store this type of property
-    // @return         TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE, 
+    // @return         TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE,
     //                  or TTS_VALUE_INVALID
-    virtual tts_result setProperty(const char *property, const char *value, const size_t size);
+    virtual tts_result setProperty(const char *property, const char *value,
+            const size_t size);
 
     // Retrieve a property from the TTS engine
     // @param        property pointer to the property name
     // @param[out]   value    pointer to the retrieved language value
-    // @param[inout] iosize   in: stores the size available to store the property value
-    //                        out: stores the size required to hold the language value if
-    //                         getLanguage() returned  TTS_PROPERTY_SIZE_TOO_SMALL,
-    //                         unchanged otherwise.
-    // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL
-    virtual tts_result getProperty(const char *property, char *value, size_t *iosize);
+    // @param[inout] iosize   in: stores the size available to store the
+    //                          property value.
+    //                        out: stores the size required to hold the language
+    //                          value if getLanguage() returned
+    //                          TTS_PROPERTY_SIZE_TOO_SMALL, unchanged otherwise
+    // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS,
+    //         or TTS_PROPERTY_SIZE_TOO_SMALL
+    virtual tts_result getProperty(const char *property, char *value,
+            size_t *iosize);
 
     // Synthesize the text.
-    // When synthesis completes, the engine invokes the callback to notify the TTS framework.
-    // Note about the format of the input: the text parameter may use the following elements
+    // As the synthesis is performed, the engine invokes the callback to notify
+    // the TTS framework that it has filled the given buffer, and indicates how
+    // many bytes it wrote. The callback is called repeatedly until the engine
+    // has generated all the audio data corresponding to the text.
+    // Note about the format of the input: the text parameter may use the
+    // following elements
     // and their respective attributes as defined in the SSML 1.0 specification:
     //    * lang
     //    * say-as:
@@ -154,14 +177,25 @@
     // Text is coded in UTF-8.
     // @param text      the UTF-8 text to synthesize
     // @param userdata  pointer to be returned when the call is invoked
+    // @param buffer    the location where the synthesized data must be written
+    // @param bufferSize the number of bytes that can be written in buffer
     // @return          TTS_SUCCESS or TTS_FAILURE
-    virtual tts_result synthesizeText(const char *text, void *userdata);
+    virtual tts_result synthesizeText(const char *text, int8_t *buffer,
+            size_t bufferSize, void *userdata);
 
-    // Synthesize IPA text. When synthesis completes, the engine must call the given callback to notify the TTS API.
+    // Synthesize IPA text.
+    // As the synthesis is performed, the engine invokes the callback to notify
+    // the TTS framework that it has filled the given buffer, and indicates how
+    // many bytes it wrote. The callback is called repeatedly until the engine
+    // has generated all the audio data corresponding to the IPA data.
     // @param ipa      the IPA data to synthesize
     // @param userdata  pointer to be returned when the call is invoked
-    // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported, otherwise TTS_SUCCESS or TTS_FAILURE
-    virtual tts_result synthesizeIpa(const char *ipa, void *userdata);
+    // @param buffer    the location where the synthesized data must be written
+    // @param bufferSize the number of bytes that can be written in buffer
+    // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported,
+    //         otherwise TTS_SUCCESS or TTS_FAILURE
+    virtual tts_result synthesizeIpa(const char *ipa, int8_t *buffer,
+            size_t bufferSize, void *userdata);
 };
 
 } // namespace android
diff --git a/tts/jni/android_tts_SynthProxy.cpp b/tts/jni/android_tts_SynthProxy.cpp
old mode 100755
new mode 100644
index d8f1bf3..582e621
--- a/tts/jni/android_tts_SynthProxy.cpp
+++ b/tts/jni/android_tts_SynthProxy.cpp
@@ -32,6 +32,7 @@
 #define DEFAULT_TTS_RATE        16000
 #define DEFAULT_TTS_FORMAT      AudioSystem::PCM_16_BIT
 #define DEFAULT_TTS_NB_CHANNELS 1
+#define DEFAULT_TTS_BUFFERSIZE  1024
 
 #define USAGEMODE_PLAY_IMMEDIATELY 0
 #define USAGEMODE_WRITE_TO_FILE    1
@@ -64,6 +65,8 @@
         uint32_t                  mSampleRate;
         AudioSystem::audio_format mAudFormat;
         int                       mNbChannels;
+        int8_t *                  mBuffer;
+        size_t                    mBufferSize;
 
         SynthProxyJniStorage() {
             //tts_class = NULL;
@@ -73,6 +76,8 @@
             mSampleRate = DEFAULT_TTS_RATE;
             mAudFormat  = DEFAULT_TTS_FORMAT;
             mNbChannels = DEFAULT_TTS_NB_CHANNELS;
+            mBufferSize = DEFAULT_TTS_BUFFERSIZE;
+            mBuffer = new int8_t[mBufferSize];
         }
 
         ~SynthProxyJniStorage() {
@@ -81,6 +86,7 @@
                 mNativeSynthInterface->shutdown();
                 mNativeSynthInterface = NULL;
             }
+            delete mBuffer;
         }
 
         void killAudio() {
@@ -159,23 +165,27 @@
  * Callback from TTS engine.
  * Directly speaks using AudioTrack or write to file
  */
-static void ttsSynthDoneCB(void * userdata, uint32_t rate,
+static tts_callback_status ttsSynthDoneCB(void *& userdata, uint32_t rate,
                            AudioSystem::audio_format format, int channel,
-                           int8_t *wav, size_t bufferSize) {
+                           int8_t *&wav, size_t &bufferSize, tts_synth_status status) {
     LOGI("ttsSynthDoneCallback: %d bytes", bufferSize);
 
+    if (userdata == NULL){
+        LOGE("userdata == NULL");
+        return TTS_CALLBACK_HALT;
+    }
     afterSynthData_t* pForAfter = (afterSynthData_t*)userdata;
+    SynthProxyJniStorage* pJniData = (SynthProxyJniStorage*)(pForAfter->jniStorage);
 
     if (pForAfter->usageMode == USAGEMODE_PLAY_IMMEDIATELY){
         LOGI("Direct speech");
 
         if (wav == NULL) {
+            delete pForAfter;
             LOGI("Null: speech has completed");
         }
 
         if (bufferSize > 0) {
-            SynthProxyJniStorage* pJniData =
-                    (SynthProxyJniStorage*)(pForAfter->jniStorage);
             prepAudioTrack(pJniData, rate, format, channel);
             if (pJniData->mAudioOut) {
                 pJniData->mAudioOut->write(wav, bufferSize);
@@ -187,6 +197,7 @@
     } else  if (pForAfter->usageMode == USAGEMODE_WRITE_TO_FILE) {
         LOGI("Save to file");
         if (wav == NULL) {
+            delete pForAfter;
             LOGI("Null: speech has completed");
         }
         if (bufferSize > 0){
@@ -195,10 +206,17 @@
     }
     // TODO update to call back into the SynthProxy class through the
     //      javaTTSFields.synthProxyMethodPost methode to notify
-    //      playback has completed
+    //      playback has completed if the synthesis is done, i.e.
+    //      if status == TTS_SYNTH_DONE
+    //delete pForAfter;
 
-    delete pForAfter;
-    return;
+    // we don't update the wav (output) parameter as we'll let the next callback
+    // write at the same location, we've consumed the data already, but we need
+    // to update bufferSize to let the TTS engine know how much it can write the
+    // next time it calls this function.
+    bufferSize = pJniData->mBufferSize;
+
+    return TTS_CALLBACK_CONTINUE;
 }
 
 
@@ -223,7 +241,9 @@
     } else {
         TtsEngine *(*get_TtsEngine)() =
             reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine"));
+
         pJniStorage->mNativeSynthInterface = (*get_TtsEngine)();
+
         if (pJniStorage->mNativeSynthInterface) {
             pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
         }
@@ -323,7 +343,7 @@
 
     // TODO check return codes
     if (pSynthData->mNativeSynthInterface) {
-        pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
+        pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
                 (void *)pForAfter);
     }
 
@@ -395,7 +415,7 @@
 
     if (pSynthData->mNativeSynthInterface) {
         const char *textNativeString = env->GetStringUTFChars(textJavaString, 0);
-        pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
+        pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
                 (void *)pForAfter);
         env->ReleaseStringUTFChars(textJavaString, textNativeString);
     }
@@ -442,6 +462,7 @@
 android_tts_SynthProxy_playAudioBuffer(JNIEnv *env, jobject thiz, jint jniData,
         int bufferPointer, int bufferSize)
 {
+LOGI("android_tts_SynthProxy_playAudioBuffer");
     if (jniData == 0) {
         LOGE("android_tts_SynthProxy_playAudioBuffer(): invalid JNI data");
         return;