Merge "Don't rely on the system locale for converting to/from bytes."
diff --git a/common/java/com/android/common/speech/LoggingEvents.java b/common/java/com/android/common/speech/LoggingEvents.java
index 3b3ecb8..1f3c6ef 100644
--- a/common/java/com/android/common/speech/LoggingEvents.java
+++ b/common/java/com/android/common/speech/LoggingEvents.java
@@ -117,6 +117,12 @@
         public static final String EXTRA_N_BEST_CHOOSE_INDEX = "index";  // value should be int
 
         public static final int TEXT_MODIFIED = 17;
+        public static final String EXTRA_TEXT_MODIFIED_LENGTH = "length";  // value should be int
+        public static final String EXTRA_TEXT_MODIFIED_TYPE = "type";  // value should be int below
+        public static final int TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION = 1;
+        public static final int TEXT_MODIFIED_TYPE_TYPING_DELETION = 2;
+        public static final int TEXT_MODIFIED_TYPE_TYPING_INSERTION = 3;
+        public static final int TEXT_MODIFIED_TYPE_TYPING_INSERTION_PUNCTUATION = 4;
 
         public static final int INPUT_ENDED = 18;
 
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 0e796dc..b701ce7 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -631,6 +631,8 @@
 
     void restart();
 
+    const ResStringPool& getStrings() const;
+
     event_code_t getEventType() const;
     // Note, unlike XmlPullParser, the first call to next() will return
     // START_TAG of the first element.
@@ -716,8 +718,6 @@
 
     void uninit();
 
-    const ResStringPool& getStrings() const;
-
 private:
     friend class ResXMLParser;
 
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
index b68bfc1..870c0b8 100644
--- a/libs/audioflinger/Android.mk
+++ b/libs/audioflinger/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
-	libbinder \
+    libbinder \
     libmedia \
     libhardware_legacy
 
@@ -85,7 +85,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
-	libbinder \
+    libbinder \
     libmedia \
     libhardware_legacy
 
@@ -114,9 +114,17 @@
 endif
 
 ifeq ($(TARGET_SIMULATOR),true)
-	ifeq ($(HOST_OS),linux)
-		LOCAL_LDLIBS += -lrt -lpthread
-	endif
+    ifeq ($(HOST_OS),linux)
+        LOCAL_LDLIBS += -lrt -lpthread
+    endif
+endif
+
+ifeq ($(BOARD_USE_LVMX),true)
+    LOCAL_CFLAGS += -DLVMX
+    LOCAL_C_INCLUDES += vendor/nxp
+    LOCAL_STATIC_LIBRARIES += liblifevibes
+    LOCAL_SHARED_LIBRARIES += liblvmxservice
+#    LOCAL_SHARED_LIBRARIES += liblvmxipc
 endif
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 8089389..7902212 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -47,6 +47,10 @@
 #include "A2dpAudioInterface.h"
 #endif
 
+#ifdef LVMX
+#include "lifevibes.h"
+#endif
+
 // ----------------------------------------------------------------------------
 // the sim build doesn't have gettid
 
@@ -132,6 +136,9 @@
     } else {
         LOGE("Couldn't even initialize the stubbed audio hardware!");
     }
+#ifdef LVMX
+    LifeVibes::init();
+#endif
 }
 
 AudioFlinger::~AudioFlinger()
@@ -411,6 +418,11 @@
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_HW_SET_MODE;
     status_t ret = mAudioHardware->setMode(mode);
+#ifdef LVMX
+    if (NO_ERROR == ret) {
+        LifeVibes::setMode(mode);
+    }
+#endif
     mHardwareStatus = AUDIO_HW_IDLE;
     return ret;
 }
@@ -566,11 +578,37 @@
         return PERMISSION_DENIED;
     }
 
+#ifdef LVMX
+    AudioParameter param = AudioParameter(keyValuePairs);
+    LifeVibes::setParameters(ioHandle,keyValuePairs);
+    String8 key = String8(AudioParameter::keyRouting);
+    int device;
+    if (NO_ERROR != param.getInt(key, device)) {
+        device = -1;
+    }
+
+    key = String8(LifevibesTag);
+    String8 value;
+    int musicEnabled = -1;
+    if (NO_ERROR == param.get(key, value)) {
+        if (value == LifevibesEnable) {
+            musicEnabled = 1;
+        } else if (value == LifevibesDisable) {
+            musicEnabled = 0;
+        }
+    }
+#endif
+
     // ioHandle == 0 means the parameters are global to the audio hardware interface
     if (ioHandle == 0) {
         AutoMutex lock(mHardwareLock);
         mHardwareStatus = AUDIO_SET_PARAMETER;
         result = mAudioHardware->setParameters(keyValuePairs);
+#ifdef LVMX
+        if ((NO_ERROR == result) && (musicEnabled != -1)) {
+            LifeVibes::enableMusic((bool) musicEnabled);
+        }
+#endif
         mHardwareStatus = AUDIO_HW_IDLE;
         return result;
     }
@@ -586,7 +624,13 @@
         }
     }
     if (thread != NULL) {
-        return thread->setParameters(keyValuePairs);
+        result = thread->setParameters(keyValuePairs);
+#ifdef LVMX
+        if ((NO_ERROR == result) && (device != -1)) {
+            LifeVibes::setDevice(LifeVibes::threadIdToAudioOutputType(thread->id()), device);
+        }
+#endif
+        return result;
     }
     return BAD_VALUE;
 }
@@ -1058,12 +1102,24 @@
 
 status_t AudioFlinger::PlaybackThread::setMasterVolume(float value)
 {
+#ifdef LVMX
+    int audioOutputType = LifeVibes::getMixerType(mId, mType);
+    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
+        LifeVibes::setMasterVolume(audioOutputType, value);
+    }
+#endif
     mMasterVolume = value;
     return NO_ERROR;
 }
 
 status_t AudioFlinger::PlaybackThread::setMasterMute(bool muted)
 {
+#ifdef LVMX
+    int audioOutputType = LifeVibes::getMixerType(mId, mType);
+    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
+        LifeVibes::setMasterMute(audioOutputType, muted);
+    }
+#endif
     mMasterMute = muted;
     return NO_ERROR;
 }
@@ -1080,12 +1136,24 @@
 
 status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
 {
+#ifdef LVMX
+    int audioOutputType = LifeVibes::getMixerType(mId, mType);
+    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
+        LifeVibes::setStreamVolume(audioOutputType, stream, value);
+    }
+#endif
     mStreamTypes[stream].volume = value;
     return NO_ERROR;
 }
 
 status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted)
 {
+#ifdef LVMX
+    int audioOutputType = LifeVibes::getMixerType(mId, mType);
+    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
+        LifeVibes::setStreamMute(audioOutputType, stream, muted);
+    }
+#endif
     mStreamTypes[stream].mute = muted;
     return NO_ERROR;
 }
@@ -1333,6 +1401,12 @@
             mLastWriteTime = systemTime();
             mInWrite = true;
             mBytesWritten += mixBufferSize;
+#ifdef LVMX
+            int audioOutputType = LifeVibes::getMixerType(mId, mType);
+            if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
+               LifeVibes::process(audioOutputType, curBuf, mixBufferSize);
+            }
+#endif
             int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
             if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
             mNumWrites++;
@@ -1376,6 +1450,29 @@
     uint32_t mixerStatus = MIXER_IDLE;
     // find out which tracks need to be processed
     size_t count = activeTracks.size();
+
+    float masterVolume = mMasterVolume;
+    bool  masterMute = mMasterMute;
+
+#ifdef LVMX
+    bool tracksConnectedChanged = false;
+    bool stateChanged = false;
+
+    int audioOutputType = LifeVibes::getMixerType(mId, mType);
+    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
+    {
+        int activeTypes = 0;
+        for (size_t i=0 ; i<count ; i++) {
+            sp<Track> t = activeTracks[i].promote();
+            if (t == 0) continue;
+            Track* const track = t.get();
+            int iTracktype=track->type();
+            activeTypes |= 1<<track->type();
+        }
+        LifeVibes::computeVolumes(audioOutputType, activeTypes, tracksConnectedChanged, stateChanged, masterVolume, masterMute);
+    }
+#endif
+
     for (size_t i=0 ; i<count ; i++) {
         sp<Track> t = activeTracks[i].promote();
         if (t == 0) continue;
@@ -1393,15 +1490,27 @@
 
             // compute volume for this track
             int16_t left, right;
-            if (track->isMuted() || mMasterMute || track->isPausing() ||
+            if (track->isMuted() || masterMute || track->isPausing() ||
                 mStreamTypes[track->type()].mute) {
                 left = right = 0;
                 if (track->isPausing()) {
                     track->setPaused();
                 }
             } else {
+                // read original volumes with volume control
                 float typeVolume = mStreamTypes[track->type()].volume;
-                float v = mMasterVolume * typeVolume;
+#ifdef LVMX
+                bool streamMute=false;
+                // read the volume from the LivesVibes audio engine.
+                if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
+                {
+                    LifeVibes::getStreamVolumes(audioOutputType, track->type(), &typeVolume, &streamMute);
+                    if (streamMute) {
+                        typeVolume = 0;
+                    }
+                }
+#endif
+                float v = masterVolume * typeVolume;
                 float v_clamped = v * cblk->volume[0];
                 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
                 left = int16_t(v_clamped);
@@ -1427,7 +1536,13 @@
                 // do not apply ramp
                 param = AudioMixer::RAMP_VOLUME;
             }
-
+#ifdef LVMX
+            if ( tracksConnectedChanged || stateChanged )
+            {
+                 // only do the ramp when the volume is changed by the user / application
+                 param = AudioMixer::VOLUME;
+            }
+#endif
             mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
             mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
             mAudioMixer->setParameter(
@@ -3652,6 +3767,18 @@
         } else {
             thread = new MixerThread(this, output, ++mNextThreadId);
             LOGV("openOutput() created mixer output: ID %d thread %p", mNextThreadId, thread);
+
+#ifdef LVMX
+            unsigned bitsPerSample =
+                (format == AudioSystem::PCM_16_BIT) ? 16 :
+                    ((format == AudioSystem::PCM_8_BIT) ? 8 : 0);
+            unsigned channelCount = (channels == AudioSystem::CHANNEL_OUT_STEREO) ? 2 : 1;
+            int audioOutputType = LifeVibes::threadIdToAudioOutputType(thread->id());
+
+            LifeVibes::init_aot(audioOutputType, samplingRate, bitsPerSample, channelCount);
+            LifeVibes::setDevice(audioOutputType, *pDevices);
+#endif
+
         }
         mPlaybackThreads.add(mNextThreadId, thread);
 
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index ae215d1..d481150 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -166,7 +166,7 @@
 // ----------------------------------------------------------------------------
 
 status_t AudioStreamInStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate,
-				AudioSystem::audio_in_acoustics acoustics)
+                AudioSystem::audio_in_acoustics acoustics)
 {
     return NO_ERROR;
 }
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
index cfcc3ea..2b0a6c8 100644
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ b/libs/audioflinger/AudioPolicyManagerBase.cpp
@@ -344,6 +344,7 @@
 {
     LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
 
+    bool forceVolumeReeval = false;
     switch(usage) {
     case AudioSystem::FOR_COMMUNICATION:
         if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
@@ -374,6 +375,7 @@
             config != AudioSystem::FORCE_BT_DESK_DOCK && config != AudioSystem::FORCE_WIRED_ACCESSORY) {
             LOGW("setForceUse() invalid config %d for FOR_DOCK", config);
         }
+        forceVolumeReeval = true;
         mForceUse[usage] = config;
         break;
     default:
@@ -388,6 +390,9 @@
 #endif
     updateDeviceForStrategy();
     setOutputDevice(mHardwareOutput, newDevice);
+    if (forceVolumeReeval) {
+        applyStreamVolumes(mHardwareOutput, newDevice);
+    }
 }
 
 AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
index 39656c0..2dfac76 100644
--- a/libs/audioflinger/AudioResampler.h
+++ b/libs/audioflinger/AudioResampler.h
@@ -76,8 +76,8 @@
     int32_t mInSampleRate;
     AudioBufferProvider::Buffer mBuffer;
     union {
-    	int16_t mVolume[2];
-    	uint32_t mVolumeRL;
+        int16_t mVolume[2];
+        uint32_t mVolumeRL;
     };
     int16_t mTargetVolume[2];
     format mFormat;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 38d8412..7e0f881 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -625,6 +625,10 @@
     mCurNode = NULL;
     mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
 }
+const ResStringPool& ResXMLParser::getStrings() const
+{
+    return mTree.mStrings;
+}
 
 ResXMLParser::event_code_t ResXMLParser::getEventType() const
 {
@@ -1149,11 +1153,6 @@
     restart();
 }
 
-const ResStringPool& ResXMLTree::getStrings() const
-{
-    return mStrings;
-}
-
 status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
 {
     const uint16_t eventCode = dtohs(node->header.type);