diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index a92cea8..0559812 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -14,8 +14,8 @@
 base := $(LOCAL_PATH)/../..
 
 LOCAL_C_INCLUDES := \
-    $(base)/libs/audioflinger \
-    $(base)/camera/libcameraservice \
+    $(base)/services/audioflinger \
+    $(base)/services/camera/libcameraservice \
     $(base)/media/libmediaplayerservice
 
 LOCAL_MODULE:= mediaserver
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp
new file mode 100644
index 0000000..995e31c
--- /dev/null
+++ b/services/audioflinger/A2dpAudioInterface.cpp
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "A2dpAudioInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "A2dpAudioInterface.h"
+#include "audio/liba2dp.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
+//{
+//    AudioHardwareInterface* hw = 0;
+//
+//    hw = AudioHardwareInterface::create();
+//    LOGD("new A2dpAudioInterface(hw: %p)", hw);
+//    hw = new A2dpAudioInterface(hw);
+//    return hw;
+//}
+
+A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) :
+    mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false)
+{
+}
+
+A2dpAudioInterface::~A2dpAudioInterface()
+{
+    closeOutputStream((AudioStreamOut *)mOutput);
+    delete mHardwareInterface;
+}
+
+status_t A2dpAudioInterface::initCheck()
+{
+    if (mHardwareInterface == 0) return NO_INIT;
+    return mHardwareInterface->initCheck();
+}
+
+AudioStreamOut* A2dpAudioInterface::openOutputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
+{
+    if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
+        LOGV("A2dpAudioInterface::openOutputStream() open HW device: %x", devices);
+        return mHardwareInterface->openOutputStream(devices, format, channels, sampleRate, status);
+    }
+
+    status_t err = 0;
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status)
+            *status = -1;
+        return NULL;
+    }
+
+    // create new output stream
+    A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
+    if ((err = out->set(devices, format, channels, sampleRate)) == NO_ERROR) {
+        mOutput = out;
+        mOutput->setBluetoothEnabled(mBluetoothEnabled);
+        mOutput->setSuspended(mSuspended);
+    } else {
+        delete out;
+    }
+
+    if (status)
+        *status = err;
+    return mOutput;
+}
+
+void A2dpAudioInterface::closeOutputStream(AudioStreamOut* out) {
+    if (mOutput == 0 || mOutput != out) {
+        mHardwareInterface->closeOutputStream(out);
+    }
+    else {
+        delete mOutput;
+        mOutput = 0;
+    }
+}
+
+
+AudioStreamIn* A2dpAudioInterface::openInputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    return mHardwareInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
+}
+
+void A2dpAudioInterface::closeInputStream(AudioStreamIn* in)
+{
+    return mHardwareInterface->closeInputStream(in);
+}
+
+status_t A2dpAudioInterface::setMode(int mode)
+{
+    return mHardwareInterface->setMode(mode);
+}
+
+status_t A2dpAudioInterface::setMicMute(bool state)
+{
+    return mHardwareInterface->setMicMute(state);
+}
+
+status_t A2dpAudioInterface::getMicMute(bool* state)
+{
+    return mHardwareInterface->getMicMute(state);
+}
+
+status_t A2dpAudioInterface::setParameters(const String8& keyValuePairs)
+{
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 value;
+    String8 key;
+    status_t status = NO_ERROR;
+
+    LOGV("setParameters() %s", keyValuePairs.string());
+
+    key = "bluetooth_enabled";
+    if (param.get(key, value) == NO_ERROR) {
+        mBluetoothEnabled = (value == "true");
+        if (mOutput) {
+            mOutput->setBluetoothEnabled(mBluetoothEnabled);
+        }
+        param.remove(key);
+    }
+    key = String8("A2dpSuspended");
+    if (param.get(key, value) == NO_ERROR) {
+        mSuspended = (value == "true");
+        if (mOutput) {
+            mOutput->setSuspended(mSuspended);
+        }
+        param.remove(key);
+    }
+
+    if (param.size()) {
+        status_t hwStatus = mHardwareInterface->setParameters(param.toString());
+        if (status == NO_ERROR) {
+            status = hwStatus;
+        }
+    }
+
+    return status;
+}
+
+String8 A2dpAudioInterface::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    AudioParameter a2dpParam = AudioParameter();
+    String8 value;
+    String8 key;
+
+    key = "bluetooth_enabled";
+    if (param.get(key, value) == NO_ERROR) {
+        value = mBluetoothEnabled ? "true" : "false";
+        a2dpParam.add(key, value);
+        param.remove(key);
+    }
+    key = "A2dpSuspended";
+    if (param.get(key, value) == NO_ERROR) {
+        value = mSuspended ? "true" : "false";
+        a2dpParam.add(key, value);
+        param.remove(key);
+    }
+
+    String8 keyValuePairs  = a2dpParam.toString();
+
+    if (param.size()) {
+        if (keyValuePairs != "") {
+            keyValuePairs += ";";
+        }
+        keyValuePairs += mHardwareInterface->getParameters(param.toString());
+    }
+
+    LOGV("getParameters() %s", keyValuePairs.string());
+    return keyValuePairs;
+}
+
+size_t A2dpAudioInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    return mHardwareInterface->getInputBufferSize(sampleRate, format, channelCount);
+}
+
+status_t A2dpAudioInterface::setVoiceVolume(float v)
+{
+    return mHardwareInterface->setVoiceVolume(v);
+}
+
+status_t A2dpAudioInterface::setMasterVolume(float v)
+{
+    return mHardwareInterface->setMasterVolume(v);
+}
+
+status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
+{
+    return mHardwareInterface->dumpState(fd, args);
+}
+
+// ----------------------------------------------------------------------------
+
+A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
+    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
+    // assume BT enabled to start, this is safe because its only the
+    // enabled->disabled transition we are worried about
+    mBluetoothEnabled(true), mDevice(0), mClosing(false), mSuspended(false)
+{
+    // use any address by default
+    strcpy(mA2dpAddress, "00:00:00:00:00:00");
+    init();
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
+        uint32_t device, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
+{
+    int lFormat = pFormat ? *pFormat : 0;
+    uint32_t lChannels = pChannels ? *pChannels : 0;
+    uint32_t lRate = pRate ? *pRate : 0;
+
+    LOGD("A2dpAudioStreamOut::set %x, %d, %d, %d\n", device, lFormat, lChannels, lRate);
+
+    // fix up defaults
+    if (lFormat == 0) lFormat = format();
+    if (lChannels == 0) lChannels = channels();
+    if (lRate == 0) lRate = sampleRate();
+
+    // check values
+    if ((lFormat != format()) ||
+            (lChannels != channels()) ||
+            (lRate != sampleRate())){
+        if (pFormat) *pFormat = format();
+        if (pChannels) *pChannels = channels();
+        if (pRate) *pRate = sampleRate();
+        return BAD_VALUE;
+    }
+
+    if (pFormat) *pFormat = lFormat;
+    if (pChannels) *pChannels = lChannels;
+    if (pRate) *pRate = lRate;
+
+    mDevice = device;
+    return NO_ERROR;
+}
+
+A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
+{
+    LOGV("A2dpAudioStreamOut destructor");
+    standby();
+    close();
+    LOGV("A2dpAudioStreamOut destructor returning from close()");
+}
+
+ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
+{
+    Mutex::Autolock lock(mLock);
+
+    size_t remaining = bytes;
+    status_t status = -1;
+
+    if (!mBluetoothEnabled || mClosing || mSuspended) {
+        LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
+               mBluetoothEnabled %d, mClosing %d, mSuspended %d",
+                mBluetoothEnabled, mClosing, mSuspended);
+        goto Error;
+    }
+
+    status = init();
+    if (status < 0)
+        goto Error;
+
+    while (remaining > 0) {
+        status = a2dp_write(mData, buffer, remaining);
+        if (status <= 0) {
+            LOGE("a2dp_write failed err: %d\n", status);
+            goto Error;
+        }
+        remaining -= status;
+        buffer = ((char *)buffer) + status;
+    }
+
+    mStandby = false;
+
+    return bytes;
+
+Error:
+    // Simulate audio output timing in case of error
+    usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
+
+    return status;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
+{
+    if (!mData) {
+        status_t status = a2dp_init(44100, 2, &mData);
+        if (status < 0) {
+            LOGE("a2dp_init failed err: %d\n", status);
+            mData = NULL;
+            return status;
+        }
+        a2dp_set_sink(mData, mA2dpAddress);
+    }
+
+    return 0;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
+{
+    int result = 0;
+
+    if (mClosing) {
+        LOGV("Ignore standby, closing");
+        return result;
+    }
+
+    Mutex::Autolock lock(mLock);
+
+    if (!mStandby) {
+        result = a2dp_stop(mData);
+        if (result == 0)
+            mStandby = true;
+    }
+
+    return result;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& keyValuePairs)
+{
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 value;
+    String8 key = String8("a2dp_sink_address");
+    status_t status = NO_ERROR;
+    int device;
+    LOGV("A2dpAudioStreamOut::setParameters() %s", keyValuePairs.string());
+
+    if (param.get(key, value) == NO_ERROR) {
+        if (value.length() != strlen("00:00:00:00:00:00")) {
+            status = BAD_VALUE;
+        } else {
+            setAddress(value.string());
+        }
+        param.remove(key);
+    }
+    key = String8("closing");
+    if (param.get(key, value) == NO_ERROR) {
+        mClosing = (value == "true");
+        param.remove(key);
+    }
+    key = AudioParameter::keyRouting;
+    if (param.getInt(key, device) == NO_ERROR) {
+        if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device)) {
+            mDevice = device;
+            status = NO_ERROR;
+        } else {
+            status = BAD_VALUE;
+        }
+        param.remove(key);
+    }
+
+    if (param.size()) {
+        status = BAD_VALUE;
+    }
+    return status;
+}
+
+String8 A2dpAudioInterface::A2dpAudioStreamOut::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    String8 value;
+    String8 key = String8("a2dp_sink_address");
+
+    if (param.get(key, value) == NO_ERROR) {
+        value = mA2dpAddress;
+        param.add(key, value);
+    }
+    key = AudioParameter::keyRouting;
+    if (param.get(key, value) == NO_ERROR) {
+        param.addInt(key, (int)mDevice);
+    }
+
+    LOGV("A2dpAudioStreamOut::getParameters() %s", param.toString().string());
+    return param.toString();
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
+{
+    Mutex::Autolock lock(mLock);
+
+    if (strlen(address) != strlen("00:00:00:00:00:00"))
+        return -EINVAL;
+
+    strcpy(mA2dpAddress, address);
+    if (mData)
+        a2dp_set_sink(mData, mA2dpAddress);
+
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled(bool enabled)
+{
+    LOGD("setBluetoothEnabled %d", enabled);
+
+    Mutex::Autolock lock(mLock);
+
+    mBluetoothEnabled = enabled;
+    if (!enabled) {
+        return close_l();
+    }
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setSuspended(bool onOff)
+{
+    LOGV("setSuspended %d", onOff);
+    mSuspended = onOff;
+    standby();
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
+{
+    Mutex::Autolock lock(mLock);
+    LOGV("A2dpAudioStreamOut::close() calling close_l()");
+    return close_l();
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
+{
+    if (mData) {
+        LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
+        a2dp_cleanup(mData);
+        mData = NULL;
+    }
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::getRenderPosition(uint32_t *driverFrames)
+{
+    //TODO: enable when supported by driver
+    return INVALID_OPERATION;
+}
+
+}; // namespace android
diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h
new file mode 100644
index 0000000..48154f9
--- /dev/null
+++ b/services/audioflinger/A2dpAudioInterface.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A2DP_AUDIO_HARDWARE_H
+#define A2DP_AUDIO_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+
+namespace android {
+
+class A2dpAudioInterface : public AudioHardwareBase
+{
+    class A2dpAudioStreamOut;
+
+public:
+                        A2dpAudioInterface(AudioHardwareInterface* hw);
+    virtual             ~A2dpAudioInterface();
+    virtual status_t    initCheck();
+
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    virtual status_t    setMode(int mode);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+
+    virtual size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                uint32_t devices,
+                                int *format=0,
+                                uint32_t *channels=0,
+                                uint32_t *sampleRate=0,
+                                status_t *status=0);
+    virtual    void        closeOutputStream(AudioStreamOut* out);
+
+    virtual AudioStreamIn* openInputStream(
+                                uint32_t devices,
+                                int *format,
+                                uint32_t *channels,
+                                uint32_t *sampleRate,
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
+    virtual    void        closeInputStream(AudioStreamIn* in);
+//    static AudioHardwareInterface* createA2dpInterface();
+
+protected:
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    class A2dpAudioStreamOut : public AudioStreamOut {
+    public:
+                            A2dpAudioStreamOut();
+        virtual             ~A2dpAudioStreamOut();
+                status_t    set(uint32_t device,
+                                int *pFormat,
+                                uint32_t *pChannels,
+                                uint32_t *pRate);
+        virtual uint32_t    sampleRate() const { return 44100; }
+        // SBC codec wants a multiple of 512
+        virtual size_t      bufferSize() const { return 512 * 20; }
+        virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
+        virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+        virtual uint32_t    latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
+        virtual status_t    setVolume(float left, float right) { return INVALID_OPERATION; }
+        virtual ssize_t     write(const void* buffer, size_t bytes);
+                status_t    standby();
+        virtual status_t    dump(int fd, const Vector<String16>& args);
+        virtual status_t    setParameters(const String8& keyValuePairs);
+        virtual String8     getParameters(const String8& keys);
+        virtual status_t    getRenderPosition(uint32_t *dspFrames);
+
+    private:
+        friend class A2dpAudioInterface;
+                status_t    init();
+                status_t    close();
+                status_t    close_l();
+                status_t    setAddress(const char* address);
+                status_t    setBluetoothEnabled(bool enabled);
+                status_t    setSuspended(bool onOff);
+
+    private:
+                int         mFd;
+                bool        mStandby;
+                int         mStartCount;
+                int         mRetryCount;
+                char        mA2dpAddress[20];
+                void*       mData;
+                Mutex       mLock;
+                bool        mBluetoothEnabled;
+                uint32_t    mDevice;
+                bool        mClosing;
+                bool        mSuspended;
+    };
+
+    friend class A2dpAudioStreamOut;
+
+    A2dpAudioStreamOut*     mOutput;
+    AudioHardwareInterface  *mHardwareInterface;
+    char        mA2dpAddress[20];
+    bool        mBluetoothEnabled;
+    bool        mSuspended;
+};
+
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
new file mode 100644
index 0000000..870c0b8
--- /dev/null
+++ b/services/audioflinger/Android.mk
@@ -0,0 +1,130 @@
+LOCAL_PATH:= $(call my-dir)
+
+#AUDIO_POLICY_TEST := true
+#ENABLE_AUDIO_DUMP := true
+
+include $(CLEAR_VARS)
+
+
+ifeq ($(AUDIO_POLICY_TEST),true)
+  ENABLE_AUDIO_DUMP := true
+endif
+
+
+LOCAL_SRC_FILES:= \
+    AudioHardwareGeneric.cpp \
+    AudioHardwareStub.cpp \
+    AudioHardwareInterface.cpp
+
+ifeq ($(ENABLE_AUDIO_DUMP),true)
+  LOCAL_SRC_FILES += AudioDumpInterface.cpp
+  LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libbinder \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_CFLAGS += -DGENERIC_AUDIO
+endif
+
+LOCAL_MODULE:= libaudiointerface
+
+ifeq ($(BOARD_HAVE_BLUETOOTH),true)
+  LOCAL_SRC_FILES += A2dpAudioInterface.cpp
+  LOCAL_SHARED_LIBRARIES += liba2dp
+  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez)
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    AudioPolicyManagerBase.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_MODULE:= libaudiopolicybase
+
+ifeq ($(BOARD_HAVE_BLUETOOTH),true)
+  LOCAL_CFLAGS += -DWITH_A2DP
+endif
+
+ifeq ($(AUDIO_POLICY_TEST),true)
+  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    AudioFlinger.cpp            \
+    AudioMixer.cpp.arm          \
+    AudioResampler.cpp.arm      \
+    AudioResamplerSinc.cpp.arm  \
+    AudioResamplerCubic.cpp.arm \
+    AudioPolicyService.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libbinder \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
+  LOCAL_CFLAGS += -DGENERIC_AUDIO
+else
+  LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
+endif
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_MODULE:= libaudioflinger
+
+ifeq ($(BOARD_HAVE_BLUETOOTH),true)
+  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
+  LOCAL_SHARED_LIBRARIES += liba2dp
+endif
+
+ifeq ($(AUDIO_POLICY_TEST),true)
+  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
+endif
+
+ifeq ($(TARGET_SIMULATOR),true)
+    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/services/audioflinger/AudioBufferProvider.h b/services/audioflinger/AudioBufferProvider.h
new file mode 100644
index 0000000..81c5c39
--- /dev/null
+++ b/services/audioflinger/AudioBufferProvider.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_BUFFER_PROVIDER_H
+#define ANDROID_AUDIO_BUFFER_PROVIDER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioBufferProvider
+{
+public:
+
+    struct Buffer {
+        union {
+            void*       raw;
+            short*      i16;
+            int8_t*     i8;
+        };
+        size_t frameCount;
+    };
+
+    virtual ~AudioBufferProvider() {}
+    
+    virtual status_t getNextBuffer(Buffer* buffer) = 0;
+    virtual void releaseBuffer(Buffer* buffer) = 0;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/services/audioflinger/AudioDumpInterface.cpp b/services/audioflinger/AudioDumpInterface.cpp
new file mode 100644
index 0000000..a018b4c
--- /dev/null
+++ b/services/audioflinger/AudioDumpInterface.cpp
@@ -0,0 +1,531 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "AudioFlingerDump"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "AudioDumpInterface.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
+    : mFirstHwOutput(true), mPolicyCommands(String8("")), mFileName(String8(""))
+{
+    if(hw == 0) {
+        LOGE("Dump construct hw = 0");
+    }
+    mFinalInterface = hw;
+    LOGV("Constructor %p, mFinalInterface %p", this, mFinalInterface);
+}
+
+
+AudioDumpInterface::~AudioDumpInterface()
+{
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        closeOutputStream((AudioStreamOut *)mOutputs[i]);
+    }
+    if(mFinalInterface) delete mFinalInterface;
+}
+
+
+AudioStreamOut* AudioDumpInterface::openOutputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
+{
+    AudioStreamOut* outFinal = NULL;
+    int lFormat = AudioSystem::PCM_16_BIT;
+    uint32_t lChannels = AudioSystem::CHANNEL_OUT_STEREO;
+    uint32_t lRate = 44100;
+
+
+    if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices) || mFirstHwOutput) {
+        outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
+        if (outFinal != 0) {
+            lFormat = outFinal->format();
+            lChannels = outFinal->channels();
+            lRate = outFinal->sampleRate();
+            if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
+                mFirstHwOutput = false;
+            }
+        }
+    } else {
+        if (format != 0 && *format != 0) {
+            lFormat = *format;
+        } else {
+            lFormat = AudioSystem::PCM_16_BIT;
+        }
+        if (channels != 0 && *channels != 0) {
+            lChannels = *channels;
+        } else {
+            lChannels = AudioSystem::CHANNEL_OUT_STEREO;
+        }
+        if (sampleRate != 0 && *sampleRate != 0) {
+            lRate = *sampleRate;
+        } else {
+            lRate = 44100;
+        }
+        if (status) *status = NO_ERROR;
+    }
+    LOGV("openOutputStream(), outFinal %p", outFinal);
+
+    AudioStreamOutDump *dumOutput = new AudioStreamOutDump(this, mOutputs.size(), outFinal,
+            devices, lFormat, lChannels, lRate);
+    mOutputs.add(dumOutput);
+
+    return dumOutput;
+}
+
+void AudioDumpInterface::closeOutputStream(AudioStreamOut* out)
+{
+    AudioStreamOutDump *dumpOut = (AudioStreamOutDump *)out;
+
+    if (mOutputs.indexOf(dumpOut) < 0) {
+        LOGW("Attempt to close invalid output stream");
+        return;
+    }
+
+    LOGV("closeOutputStream() output %p", out);
+
+    dumpOut->standby();
+    if (dumpOut->finalStream() != NULL) {
+        mFinalInterface->closeOutputStream(dumpOut->finalStream());
+        mFirstHwOutput = true;
+    }
+
+    mOutputs.remove(dumpOut);
+    delete dumpOut;
+}
+
+AudioStreamIn* AudioDumpInterface::openInputStream(uint32_t devices, int *format, uint32_t *channels,
+        uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
+{
+    AudioStreamIn* inFinal = NULL;
+    int lFormat = AudioSystem::PCM_16_BIT;
+    uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
+    uint32_t lRate = 8000;
+
+
+    if (mInputs.size() == 0) {
+        inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
+        if (inFinal == 0) return 0;
+
+        lFormat = inFinal->format();
+        lChannels = inFinal->channels();
+        lRate = inFinal->sampleRate();
+    } else {
+        if (format != 0 && *format != 0) lFormat = *format;
+        if (channels != 0 && *channels != 0) lChannels = *channels;
+        if (sampleRate != 0 && *sampleRate != 0) lRate = *sampleRate;
+        if (status) *status = NO_ERROR;
+    }
+    LOGV("openInputStream(), inFinal %p", inFinal);
+
+    AudioStreamInDump *dumInput = new AudioStreamInDump(this, mInputs.size(), inFinal,
+            devices, lFormat, lChannels, lRate);
+    mInputs.add(dumInput);
+
+    return dumInput;
+}
+void AudioDumpInterface::closeInputStream(AudioStreamIn* in)
+{
+    AudioStreamInDump *dumpIn = (AudioStreamInDump *)in;
+
+    if (mInputs.indexOf(dumpIn) < 0) {
+        LOGW("Attempt to close invalid input stream");
+        return;
+    }
+    dumpIn->standby();
+    if (dumpIn->finalStream() != NULL) {
+        mFinalInterface->closeInputStream(dumpIn->finalStream());
+    }
+
+    mInputs.remove(dumpIn);
+    delete dumpIn;
+}
+
+
+status_t AudioDumpInterface::setParameters(const String8& keyValuePairs)
+{
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 value;
+    int valueInt;
+    LOGV("setParameters %s", keyValuePairs.string());
+
+    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
+        mFileName = value;
+        param.remove(String8("test_cmd_file_name"));
+    }
+    if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
+        Mutex::Autolock _l(mLock);
+        param.remove(String8("test_cmd_policy"));
+        mPolicyCommands = param.toString();
+        LOGV("test_cmd_policy command %s written", mPolicyCommands.string());
+        return NO_ERROR;
+    }
+
+    if (mFinalInterface != 0 ) return mFinalInterface->setParameters(keyValuePairs);
+    return NO_ERROR;
+}
+
+String8 AudioDumpInterface::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    AudioParameter response;
+    String8 value;
+
+//    LOGV("getParameters %s", keys.string());
+    if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
+        Mutex::Autolock _l(mLock);
+        if (mPolicyCommands.length() != 0) {
+            response = AudioParameter(mPolicyCommands);
+            response.addInt(String8("test_cmd_policy"), 1);
+        } else {
+            response.addInt(String8("test_cmd_policy"), 0);
+        }
+        param.remove(String8("test_cmd_policy"));
+//        LOGV("test_cmd_policy command %s read", mPolicyCommands.string());
+    }
+
+    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
+        response.add(String8("test_cmd_file_name"), mFileName);
+        param.remove(String8("test_cmd_file_name"));
+    }
+
+    String8 keyValuePairs = response.toString();
+
+    if (param.size() && mFinalInterface != 0 ) {
+        keyValuePairs += ";";
+        keyValuePairs += mFinalInterface->getParameters(param.toString());
+    }
+
+    return keyValuePairs;
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioStreamOutDump::AudioStreamOutDump(AudioDumpInterface *interface,
+                                        int id,
+                                        AudioStreamOut* finalStream,
+                                        uint32_t devices,
+                                        int format,
+                                        uint32_t channels,
+                                        uint32_t sampleRate)
+    : mInterface(interface), mId(id),
+      mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
+      mBufferSize(1024), mFinalStream(finalStream), mOutFile(0), mFileCount(0)
+{
+    LOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
+}
+
+
+AudioStreamOutDump::~AudioStreamOutDump()
+{
+    LOGV("AudioStreamOutDump destructor");
+    Close();
+}
+
+ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
+{
+    ssize_t ret;
+
+    if (mFinalStream) {
+        ret = mFinalStream->write(buffer, bytes);
+    } else {
+        usleep((bytes * 1000000) / frameSize() / sampleRate());
+        ret = bytes;
+    }
+    if(!mOutFile) {
+        if (mInterface->fileName() != "") {
+            char name[255];
+            sprintf(name, "%s_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
+            mOutFile = fopen(name, "wb");
+            LOGV("Opening dump file %s, fh %p", name, mOutFile);
+        }
+    }
+    if (mOutFile) {
+        fwrite(buffer, bytes, 1, mOutFile);
+    }
+    return ret;
+}
+
+status_t AudioStreamOutDump::standby()
+{
+    LOGV("AudioStreamOutDump standby(), mOutFile %p, mFinalStream %p", mOutFile, mFinalStream);
+
+    Close();
+    if (mFinalStream != 0 ) return mFinalStream->standby();
+    return NO_ERROR;
+}
+
+uint32_t AudioStreamOutDump::sampleRate() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->sampleRate();
+    return mSampleRate;
+}
+
+size_t AudioStreamOutDump::bufferSize() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->bufferSize();
+    return mBufferSize;
+}
+
+uint32_t AudioStreamOutDump::channels() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->channels();
+    return mChannels;
+}
+int AudioStreamOutDump::format() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->format();
+    return mFormat;
+}
+uint32_t AudioStreamOutDump::latency() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->latency();
+    return 0;
+}
+status_t AudioStreamOutDump::setVolume(float left, float right)
+{
+    if (mFinalStream != 0 ) return mFinalStream->setVolume(left, right);
+    return NO_ERROR;
+}
+status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
+{
+    LOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
+
+    if (mFinalStream != 0 ) {
+        return mFinalStream->setParameters(keyValuePairs);
+    }
+
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 value;
+    int valueInt;
+    status_t status = NO_ERROR;
+
+    if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
+        mId = valueInt;
+    }
+
+    if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
+        if (mOutFile == 0) {
+            mFormat = valueInt;
+        } else {
+            status = INVALID_OPERATION;
+        }
+    }
+    if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
+        if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
+            mChannels = valueInt;
+        } else {
+            status = BAD_VALUE;
+        }
+    }
+    if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
+        if (valueInt > 0 && valueInt <= 48000) {
+            if (mOutFile == 0) {
+                mSampleRate = valueInt;
+            } else {
+                status = INVALID_OPERATION;
+            }
+        } else {
+            status = BAD_VALUE;
+        }
+    }
+    return status;
+}
+
+String8 AudioStreamOutDump::getParameters(const String8& keys)
+{
+    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
+
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
+}
+
+status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
+{
+    if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
+    return NO_ERROR;
+}
+
+void AudioStreamOutDump::Close()
+{
+    if(mOutFile) {
+        fclose(mOutFile);
+        mOutFile = 0;
+    }
+}
+
+status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
+{
+    if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
+    return INVALID_OPERATION;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
+                                        int id,
+                                        AudioStreamIn* finalStream,
+                                        uint32_t devices,
+                                        int format,
+                                        uint32_t channels,
+                                        uint32_t sampleRate)
+    : mInterface(interface), mId(id),
+      mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
+      mBufferSize(1024), mFinalStream(finalStream), mInFile(0)
+{
+    LOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
+}
+
+
+AudioStreamInDump::~AudioStreamInDump()
+{
+    Close();
+}
+
+ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
+{
+    if (mFinalStream) {
+        return mFinalStream->read(buffer, bytes);
+    }
+
+    usleep((bytes * 1000000) / frameSize() / sampleRate());
+
+    if(!mInFile) {
+        char name[255];
+        strcpy(name, "/sdcard/music/sine440");
+        if (channels() == AudioSystem::CHANNEL_IN_MONO) {
+            strcat(name, "_mo");
+        } else {
+            strcat(name, "_st");
+        }
+        if (format() == AudioSystem::PCM_16_BIT) {
+            strcat(name, "_16b");
+        } else {
+            strcat(name, "_8b");
+        }
+        if (sampleRate() < 16000) {
+            strcat(name, "_8k");
+        } else if (sampleRate() < 32000) {
+            strcat(name, "_22k");
+        } else if (sampleRate() < 48000) {
+            strcat(name, "_44k");
+        } else {
+            strcat(name, "_48k");
+        }
+        strcat(name, ".wav");
+        mInFile = fopen(name, "rb");
+        LOGV("Opening dump file %s, fh %p", name, mInFile);
+        if (mInFile) {
+            fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
+        }
+
+    }
+    if (mInFile) {
+        ssize_t bytesRead = fread(buffer, bytes, 1, mInFile);
+        if (bytesRead != bytes) {
+            fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
+            fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mInFile);
+        }
+    }
+    return bytes;
+}
+
+status_t AudioStreamInDump::standby()
+{
+    LOGV("AudioStreamInDump standby(), mInFile %p, mFinalStream %p", mInFile, mFinalStream);
+
+    Close();
+    if (mFinalStream != 0 ) return mFinalStream->standby();
+    return NO_ERROR;
+}
+
+status_t AudioStreamInDump::setGain(float gain)
+{
+    if (mFinalStream != 0 ) return mFinalStream->setGain(gain);
+    return NO_ERROR;
+}
+
+uint32_t AudioStreamInDump::sampleRate() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->sampleRate();
+    return mSampleRate;
+}
+
+size_t AudioStreamInDump::bufferSize() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->bufferSize();
+    return mBufferSize;
+}
+
+uint32_t AudioStreamInDump::channels() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->channels();
+    return mChannels;
+}
+
+int AudioStreamInDump::format() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->format();
+    return mFormat;
+}
+
+status_t AudioStreamInDump::setParameters(const String8& keyValuePairs)
+{
+    LOGV("AudioStreamInDump::setParameters()");
+    if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
+    return NO_ERROR;
+}
+
+String8 AudioStreamInDump::getParameters(const String8& keys)
+{
+    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
+
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
+}
+
+unsigned int AudioStreamInDump::getInputFramesLost() const
+{
+    if (mFinalStream != 0 ) return mFinalStream->getInputFramesLost();
+    return 0;
+}
+
+status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
+{
+    if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
+    return NO_ERROR;
+}
+
+void AudioStreamInDump::Close()
+{
+    if(mInFile) {
+        fclose(mInFile);
+        mInFile = 0;
+    }
+}
+}; // namespace android
diff --git a/services/audioflinger/AudioDumpInterface.h b/services/audioflinger/AudioDumpInterface.h
new file mode 100644
index 0000000..4c62b3e
--- /dev/null
+++ b/services/audioflinger/AudioDumpInterface.h
@@ -0,0 +1,166 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_AUDIO_DUMP_INTERFACE_H
+#define ANDROID_AUDIO_DUMP_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+#define AUDIO_DUMP_WAVE_HDR_SIZE 44
+
+class AudioDumpInterface;
+
+class AudioStreamOutDump : public AudioStreamOut {
+public:
+                        AudioStreamOutDump(AudioDumpInterface *interface,
+                                            int id,
+                                            AudioStreamOut* finalStream,
+                                            uint32_t devices,
+                                            int format,
+                                            uint32_t channels,
+                                            uint32_t sampleRate);
+                        ~AudioStreamOutDump();
+
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual uint32_t    sampleRate() const;
+    virtual size_t      bufferSize() const;
+    virtual uint32_t    channels() const;
+    virtual int         format() const;
+    virtual uint32_t    latency() const;
+    virtual status_t    setVolume(float left, float right);
+    virtual status_t    standby();
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    void                Close(void);
+    AudioStreamOut*     finalStream() { return mFinalStream; }
+    uint32_t            device() { return mDevice; }
+    int                 getId()  { return mId; }
+    virtual status_t    getRenderPosition(uint32_t *dspFrames);
+
+private:
+    AudioDumpInterface *mInterface;
+    int                  mId;
+    uint32_t mSampleRate;               //
+    uint32_t mFormat;                   //
+    uint32_t mChannels;                 // output configuration
+    uint32_t mLatency;                  //
+    uint32_t mDevice;                   // current device this output is routed to
+    size_t  mBufferSize;
+    AudioStreamOut      *mFinalStream;
+    FILE                *mOutFile;      // output file
+    int                 mFileCount;
+};
+
+class AudioStreamInDump : public AudioStreamIn {
+public:
+                        AudioStreamInDump(AudioDumpInterface *interface,
+                                            int id,
+                                            AudioStreamIn* finalStream,
+                                            uint32_t devices,
+                                            int format,
+                                            uint32_t channels,
+                                            uint32_t sampleRate);
+                        ~AudioStreamInDump();
+
+    virtual uint32_t    sampleRate() const;
+    virtual size_t      bufferSize() const;
+    virtual uint32_t    channels() const;
+    virtual int         format() const;
+
+    virtual status_t    setGain(float gain);
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    standby();
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+    virtual unsigned int  getInputFramesLost() const;
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    void                Close(void);
+    AudioStreamIn*     finalStream() { return mFinalStream; }
+    uint32_t            device() { return mDevice; }
+
+private:
+    AudioDumpInterface *mInterface;
+    int                  mId;
+    uint32_t mSampleRate;               //
+    uint32_t mFormat;                   //
+    uint32_t mChannels;                 // output configuration
+    uint32_t mDevice;                   // current device this output is routed to
+    size_t  mBufferSize;
+    AudioStreamIn      *mFinalStream;
+    FILE                *mInFile;      // output file
+};
+
+class AudioDumpInterface : public AudioHardwareBase
+{
+
+public:
+                        AudioDumpInterface(AudioHardwareInterface* hw);
+    virtual AudioStreamOut* openOutputStream(
+                                uint32_t devices,
+                                int *format=0,
+                                uint32_t *channels=0,
+                                uint32_t *sampleRate=0,
+                                status_t *status=0);
+    virtual    void        closeOutputStream(AudioStreamOut* out);
+
+    virtual             ~AudioDumpInterface();
+
+    virtual status_t    initCheck()
+                            {return mFinalInterface->initCheck();}
+    virtual status_t    setVoiceVolume(float volume)
+                            {return mFinalInterface->setVoiceVolume(volume);}
+    virtual status_t    setMasterVolume(float volume)
+                            {return mFinalInterface->setMasterVolume(volume);}
+
+    // mic mute
+    virtual status_t    setMicMute(bool state)
+                            {return mFinalInterface->setMicMute(state);}
+    virtual status_t    getMicMute(bool* state)
+                            {return mFinalInterface->getMicMute(state);}
+
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+
+    virtual AudioStreamIn* openInputStream(uint32_t devices, int *format, uint32_t *channels,
+            uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics);
+    virtual    void        closeInputStream(AudioStreamIn* in);
+
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
+
+            String8     fileName() const { return mFileName; }
+protected:
+
+    AudioHardwareInterface          *mFinalInterface;
+    SortedVector<AudioStreamOutDump *>    mOutputs;
+    bool                            mFirstHwOutput;
+    SortedVector<AudioStreamInDump *>    mInputs;
+    Mutex                           mLock;
+    String8                         mPolicyCommands;
+    String8                         mFileName;
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
new file mode 100644
index 0000000..2414e8d
--- /dev/null
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -0,0 +1,4055 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.cpp
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+
+#define LOG_TAG "AudioFlinger"
+//#define LOG_NDEBUG 0
+
+#include <math.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+
+#include <cutils/properties.h>
+
+#include <media/AudioTrack.h>
+#include <media/AudioRecord.h>
+
+#include <private/media/AudioTrackShared.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioMixer.h"
+#include "AudioFlinger.h"
+
+#ifdef WITH_A2DP
+#include "A2dpAudioInterface.h"
+#endif
+
+#ifdef LVMX
+#include "lifevibes.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
+static const char* kHardwareLockedString = "Hardware lock is taken\n";
+
+//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const float MAX_GAIN = 4096.0f;
+
+// retry counts for buffer fill timeout
+// 50 * ~20msecs = 1 second
+static const int8_t kMaxTrackRetries = 50;
+static const int8_t kMaxTrackStartupRetries = 50;
+// allow less retry attempts on direct output thread.
+// direct outputs can be a scarce resource in audio hardware and should
+// be released as quickly as possible.
+static const int8_t kMaxTrackRetriesDirect = 2;
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 20000;
+
+static const nsecs_t kWarningThrottle = seconds(5);
+
+
+#define AUDIOFLINGER_SECURITY_ENABLED 1
+
+// ----------------------------------------------------------------------------
+
+static bool recordingAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
+    if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
+        LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
+    return true;
+#endif
+}
+
+static bool settingsAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
+    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
+        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
+    return true;
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::AudioFlinger()
+    : BnAudioFlinger(),
+        mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextThreadId(0)
+{
+    mHardwareStatus = AUDIO_HW_IDLE;
+
+    mAudioHardware = AudioHardwareInterface::create();
+
+    mHardwareStatus = AUDIO_HW_INIT;
+    if (mAudioHardware->initCheck() == NO_ERROR) {
+        // open 16-bit output stream for s/w mixer
+
+        setMode(AudioSystem::MODE_NORMAL);
+
+        setMasterVolume(1.0f);
+        setMasterMute(false);
+    } else {
+        LOGE("Couldn't even initialize the stubbed audio hardware!");
+    }
+#ifdef LVMX
+    LifeVibes::init();
+#endif
+}
+
+AudioFlinger::~AudioFlinger()
+{
+    while (!mRecordThreads.isEmpty()) {
+        // closeInput() will remove first entry from mRecordThreads
+        closeInput(mRecordThreads.keyAt(0));
+    }
+    while (!mPlaybackThreads.isEmpty()) {
+        // closeOutput() will remove first entry from mPlaybackThreads
+        closeOutput(mPlaybackThreads.keyAt(0));
+    }
+    if (mAudioHardware) {
+        delete mAudioHardware;
+    }
+}
+
+
+
+status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    result.append("Clients:\n");
+    for (size_t i = 0; i < mClients.size(); ++i) {
+        wp<Client> wClient = mClients.valueAt(i);
+        if (wClient != 0) {
+            sp<Client> client = wClient.promote();
+            if (client != 0) {
+                snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+
+status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    int hardwareStatus = mHardwareStatus;
+
+    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "Permission Denial: "
+            "can't dump AudioFlinger from pid=%d, uid=%d\n",
+            IPCThreadState::self()->getCallingPid(),
+            IPCThreadState::self()->getCallingUid());
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+static bool tryLock(Mutex& mutex)
+{
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
+{
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        dumpPermissionDenial(fd, args);
+    } else {
+        // get state of hardware lock
+        bool hardwareLocked = tryLock(mHardwareLock);
+        if (!hardwareLocked) {
+            String8 result(kHardwareLockedString);
+            write(fd, result.string(), result.size());
+        } else {
+            mHardwareLock.unlock();
+        }
+
+        bool locked = tryLock(mLock);
+
+        // failed to lock - AudioFlinger is probably deadlocked
+        if (!locked) {
+            String8 result(kDeadlockedString);
+            write(fd, result.string(), result.size());
+        }
+
+        dumpClients(fd, args);
+        dumpInternals(fd, args);
+
+        // dump playback threads
+        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+            mPlaybackThreads.valueAt(i)->dump(fd, args);
+        }
+
+        // dump record threads
+        for (size_t i = 0; i < mRecordThreads.size(); i++) {
+            mRecordThreads.valueAt(i)->dump(fd, args);
+        }
+
+        if (mAudioHardware) {
+            mAudioHardware->dumpState(fd, args);
+        }
+        if (locked) mLock.unlock();
+    }
+    return NO_ERROR;
+}
+
+
+// IAudioFlinger interface
+
+
+sp<IAudioTrack> AudioFlinger::createTrack(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        const sp<IMemory>& sharedBuffer,
+        int output,
+        status_t *status)
+{
+    sp<PlaybackThread::Track> track;
+    sp<TrackHandle> trackHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    status_t lStatus;
+
+    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+        PlaybackThread *thread = checkPlaybackThread_l(output);
+        if (thread == NULL) {
+            LOGE("unknown output thread");
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+
+        wclient = mClients.valueFor(pid);
+
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+        track = thread->createTrack_l(client, streamType, sampleRate, format,
+                channelCount, frameCount, sharedBuffer, &lStatus);
+    }
+    if (lStatus == NO_ERROR) {
+        trackHandle = new TrackHandle(track);
+    } else {
+        // remove local strong reference to Client before deleting the Track so that the Client
+        // destructor is called by the TrackBase destructor with mLock held
+        client.clear();
+        track.clear();
+    }
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return trackHandle;
+}
+
+uint32_t AudioFlinger::sampleRate(int output) const
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread == NULL) {
+        LOGW("sampleRate() unknown thread %d", output);
+        return 0;
+    }
+    return thread->sampleRate();
+}
+
+int AudioFlinger::channelCount(int output) const
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread == NULL) {
+        LOGW("channelCount() unknown thread %d", output);
+        return 0;
+    }
+    return thread->channelCount();
+}
+
+int AudioFlinger::format(int output) const
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread == NULL) {
+        LOGW("format() unknown thread %d", output);
+        return 0;
+    }
+    return thread->format();
+}
+
+size_t AudioFlinger::frameCount(int output) const
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread == NULL) {
+        LOGW("frameCount() unknown thread %d", output);
+        return 0;
+    }
+    return thread->frameCount();
+}
+
+uint32_t AudioFlinger::latency(int output) const
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread == NULL) {
+        LOGW("latency() unknown thread %d", output);
+        return 0;
+    }
+    return thread->latency();
+}
+
+status_t AudioFlinger::setMasterVolume(float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    // when hw supports master volume, don't scale in sw mixer
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+        value = 1.0f;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+
+    mMasterVolume = value;
+    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
+       mPlaybackThreads.valueAt(i)->setMasterVolume(value);
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setMode(int mode)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setMode(%d)", mode);
+        return BAD_VALUE;
+    }
+
+    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;
+}
+
+status_t AudioFlinger::setMicMute(bool state)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
+    status_t ret = mAudioHardware->setMicMute(state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+bool AudioFlinger::getMicMute() const
+{
+    bool state = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
+    mAudioHardware->getMicMute(&state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return state;
+}
+
+status_t AudioFlinger::setMasterMute(bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    mMasterMute = muted;
+    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
+       mPlaybackThreads.valueAt(i)->setMasterMute(muted);
+
+    return NO_ERROR;
+}
+
+float AudioFlinger::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::masterMute() const
+{
+    return mMasterMute;
+}
+
+status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+
+    AutoMutex lock(mLock);
+    PlaybackThread *thread = NULL;
+    if (output) {
+        thread = checkPlaybackThread_l(output);
+        if (thread == NULL) {
+            return BAD_VALUE;
+        }
+    }
+
+    mStreamTypes[stream].volume = value;
+
+    if (thread == NULL) {
+        for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
+           mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
+        }
+    } else {
+        thread->setStreamVolume(stream, value);
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setStreamMute(int stream, bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
+        uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
+        return BAD_VALUE;
+    }
+
+    mStreamTypes[stream].mute = muted;
+    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
+       mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
+
+    return NO_ERROR;
+}
+
+float AudioFlinger::streamVolume(int stream, int output) const
+{
+    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return 0.0f;
+    }
+
+    AutoMutex lock(mLock);
+    float volume;
+    if (output) {
+        PlaybackThread *thread = checkPlaybackThread_l(output);
+        if (thread == NULL) {
+            return 0.0f;
+        }
+        volume = thread->streamVolume(stream);
+    } else {
+        volume = mStreamTypes[stream].volume;
+    }
+
+    return volume;
+}
+
+bool AudioFlinger::streamMute(int stream) const
+{
+    if (stream < 0 || stream >= (int)AudioSystem::NUM_STREAM_TYPES) {
+        return true;
+    }
+
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::isStreamActive(int stream) const
+{
+    Mutex::Autolock _l(mLock);
+    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
+        if (mPlaybackThreads.valueAt(i)->isStreamActive(stream)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
+{
+    status_t result;
+
+    LOGV("setParameters(): io %d, keyvalue %s, tid %d, calling tid %d",
+            ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
+    // check calling permissions
+    if (!settingsAllowed()) {
+        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;
+    }
+
+    // hold a strong ref on thread in case closeOutput() or closeInput() is called
+    // and the thread is exited once the lock is released
+    sp<ThreadBase> thread;
+    {
+        Mutex::Autolock _l(mLock);
+        thread = checkPlaybackThread_l(ioHandle);
+        if (thread == NULL) {
+            thread = checkRecordThread_l(ioHandle);
+        }
+    }
+    if (thread != NULL) {
+        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;
+}
+
+String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
+{
+//    LOGV("getParameters() io %d, keys %s, tid %d, calling tid %d",
+//            ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
+
+    if (ioHandle == 0) {
+        return mAudioHardware->getParameters(keys);
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
+    if (playbackThread != NULL) {
+        return playbackThread->getParameters(keys);
+    }
+    RecordThread *recordThread = checkRecordThread_l(ioHandle);
+    if (recordThread != NULL) {
+        return recordThread->getParameters(keys);
+    }
+    return String8("");
+}
+
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+}
+
+unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
+{
+    if (ioHandle == 0) {
+        return 0;
+    }
+
+    Mutex::Autolock _l(mLock);
+
+    RecordThread *recordThread = checkRecordThread_l(ioHandle);
+    if (recordThread != NULL) {
+        return recordThread->getInputFramesLost();
+    }
+    return 0;
+}
+
+status_t AudioFlinger::setVoiceVolume(float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+    status_t ret = mAudioHardware->setVoiceVolume(value);
+    mHardwareStatus = AUDIO_HW_IDLE;
+
+    return ret;
+}
+
+status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
+{
+    status_t status;
+
+    Mutex::Autolock _l(mLock);
+
+    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
+    if (playbackThread != NULL) {
+        return playbackThread->getRenderPosition(halFrames, dspFrames);
+    }
+
+    return BAD_VALUE;
+}
+
+void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
+{
+
+    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    sp<IBinder> binder = client->asBinder();
+    if (mNotificationClients.indexOf(binder) < 0) {
+        LOGV("Adding notification client %p", binder.get());
+        binder->linkToDeath(this);
+        mNotificationClients.add(binder);
+    }
+
+    // the config change is always sent from playback or record threads to avoid deadlock
+    // with AudioSystem::gLock
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        mPlaybackThreads.valueAt(i)->sendConfigEvent(AudioSystem::OUTPUT_OPENED);
+    }
+
+    for (size_t i = 0; i < mRecordThreads.size(); i++) {
+        mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
+    }
+}
+
+void AudioFlinger::binderDied(const wp<IBinder>& who) {
+
+    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    IBinder *binder = who.unsafe_get();
+
+    if (binder != NULL) {
+        int index = mNotificationClients.indexOf(binder);
+        if (index >= 0) {
+            LOGV("Removing notification client %p", binder);
+            mNotificationClients.removeAt(index);
+        }
+    }
+}
+
+// audioConfigChanged_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) {
+    size_t size = mNotificationClients.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<IBinder> binder = mNotificationClients.itemAt(i);
+        LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
+        sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
+        client->ioConfigChanged(event, ioHandle, param2);
+    }
+}
+
+// removeClient_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::removeClient_l(pid_t pid)
+{
+    LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
+    mClients.removeItem(pid);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
+    :   Thread(false),
+        mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
+        mFormat(0), mFrameSize(1), mStandby(false), mId(id), mExiting(false)
+{
+}
+
+AudioFlinger::ThreadBase::~ThreadBase()
+{
+    mParamCond.broadcast();
+    mNewParameters.clear();
+}
+
+void AudioFlinger::ThreadBase::exit()
+{
+    // keep a strong ref on ourself so that we wont get
+    // destroyed in the middle of requestExitAndWait()
+    sp <ThreadBase> strongMe = this;
+
+    LOGV("ThreadBase::exit");
+    {
+        AutoMutex lock(&mLock);
+        mExiting = true;
+        requestExit();
+        mWaitWorkCV.signal();
+    }
+    requestExitAndWait();
+}
+
+uint32_t AudioFlinger::ThreadBase::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioFlinger::ThreadBase::channelCount() const
+{
+    return mChannelCount;
+}
+
+int AudioFlinger::ThreadBase::format() const
+{
+    return mFormat;
+}
+
+size_t AudioFlinger::ThreadBase::frameCount() const
+{
+    return mFrameCount;
+}
+
+status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
+{
+    status_t status;
+
+    LOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
+    Mutex::Autolock _l(mLock);
+
+    mNewParameters.add(keyValuePairs);
+    mWaitWorkCV.signal();
+    // wait condition with timeout in case the thread loop has exited
+    // before the request could be processed
+    if (mParamCond.waitRelative(mLock, seconds(2)) == NO_ERROR) {
+        status = mParamStatus;
+        mWaitWorkCV.signal();
+    } else {
+        status = TIMED_OUT;
+    }
+    return status;
+}
+
+void AudioFlinger::ThreadBase::sendConfigEvent(int event, int param)
+{
+    Mutex::Autolock _l(mLock);
+    sendConfigEvent_l(event, param);
+}
+
+// sendConfigEvent_l() must be called with ThreadBase::mLock held
+void AudioFlinger::ThreadBase::sendConfigEvent_l(int event, int param)
+{
+    ConfigEvent *configEvent = new ConfigEvent();
+    configEvent->mEvent = event;
+    configEvent->mParam = param;
+    mConfigEvents.add(configEvent);
+    LOGV("sendConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param);
+    mWaitWorkCV.signal();
+}
+
+void AudioFlinger::ThreadBase::processConfigEvents()
+{
+    mLock.lock();
+    while(!mConfigEvents.isEmpty()) {
+        LOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
+        ConfigEvent *configEvent = mConfigEvents[0];
+        mConfigEvents.removeAt(0);
+        // release mLock because audioConfigChanged() will lock AudioFlinger mLock
+        // before calling Audioflinger::audioConfigChanged_l() thus creating
+        // potential cross deadlock between AudioFlinger::mLock and mLock
+        mLock.unlock();
+        audioConfigChanged(configEvent->mEvent, configEvent->mParam);
+        delete configEvent;
+        mLock.lock();
+    }
+    mLock.unlock();
+}
+
+status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    bool locked = tryLock(mLock);
+    if (!locked) {
+        snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
+        write(fd, buffer, strlen(buffer));
+    }
+
+    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Frame count: %d\n", mFrameCount);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
+    result.append(buffer);
+
+    snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
+    result.append(buffer);
+    result.append(" Index Command");
+    for (size_t i = 0; i < mNewParameters.size(); ++i) {
+        snprintf(buffer, SIZE, "\n %02d    ", i);
+        result.append(buffer);
+        result.append(mNewParameters[i]);
+    }
+
+    snprintf(buffer, SIZE, "\n\nPending config events: \n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Index event param\n");
+    result.append(buffer);
+    for (size_t i = 0; i < mConfigEvents.size(); i++) {
+        snprintf(buffer, SIZE, " %02d    %02d    %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam);
+        result.append(buffer);
+    }
+    result.append("\n");
+
+    write(fd, result.string(), result.size());
+
+    if (locked) {
+        mLock.unlock();
+    }
+    return NO_ERROR;
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+    :   ThreadBase(audioFlinger, id),
+        mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
+        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
+{
+    readOutputParameters();
+
+    mMasterVolume = mAudioFlinger->masterVolume();
+    mMasterMute = mAudioFlinger->masterMute();
+
+    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+        mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream);
+        mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream);
+    }
+    // notify client processes that a new input has been opened
+    sendConfigEvent(AudioSystem::OUTPUT_OPENED);
+}
+
+AudioFlinger::PlaybackThread::~PlaybackThread()
+{
+    delete [] mMixBuffer;
+}
+
+status_t AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    dumpTracks(fd, args);
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf  S M F SRate  LeftV RighV Serv     User\n");
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        sp<Track> track = mTracks[i];
+        if (track != 0) {
+            track->dump(buffer, SIZE);
+            result.append(buffer);
+        }
+    }
+
+    snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf  S M F SRate  LeftV RighV Serv     User\n");
+    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
+        wp<Track> wTrack = mActiveTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    result.append(buffer);
+    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "suspend count: %d\n", mSuspended);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    dumpBase(fd, args);
+
+    return NO_ERROR;
+}
+
+// Thread virtuals
+status_t AudioFlinger::PlaybackThread::readyToRun()
+{
+    if (mSampleRate == 0) {
+        LOGE("No working audio driver found.");
+        return NO_INIT;
+    }
+    LOGI("AudioFlinger's thread %p ready to run", this);
+    return NO_ERROR;
+}
+
+void AudioFlinger::PlaybackThread::onFirstRef()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+
+    snprintf(buffer, SIZE, "Playback Thread %p", this);
+
+    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::PlaybackThread::Track>  AudioFlinger::PlaybackThread::createTrack_l(
+        const sp<AudioFlinger::Client>& client,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<Track> track;
+    status_t lStatus;
+
+    if (mType == DIRECT) {
+        if (sampleRate != mSampleRate || format != mFormat || channelCount != mChannelCount) {
+            LOGE("createTrack_l() Bad parameter:  sampleRate %d format %d, channelCount %d for output %p",
+                 sampleRate, format, channelCount, mOutput);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+    } else {
+        // Resampler implementation limits input sampling rate to 2 x output sampling rate.
+        if (sampleRate > mSampleRate*2) {
+            LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+    }
+
+    if (mOutput == 0) {
+        LOGE("Audio driver not initialized.");
+        lStatus = NO_INIT;
+        goto Exit;
+    }
+
+    { // scope for mLock
+        Mutex::Autolock _l(mLock);
+        track = new Track(this, client, streamType, sampleRate, format,
+                channelCount, frameCount, sharedBuffer);
+        if (track->getCblk() == NULL || track->name() < 0) {
+            lStatus = NO_MEMORY;
+            goto Exit;
+        }
+        mTracks.add(track);
+    }
+    lStatus = NO_ERROR;
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return track;
+}
+
+uint32_t AudioFlinger::PlaybackThread::latency() const
+{
+    if (mOutput) {
+        return mOutput->latency();
+    }
+    else {
+        return 0;
+    }
+}
+
+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;
+}
+
+float AudioFlinger::PlaybackThread::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::PlaybackThread::masterMute() const
+{
+    return mMasterMute;
+}
+
+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;
+}
+
+float AudioFlinger::PlaybackThread::streamVolume(int stream) const
+{
+    return mStreamTypes[stream].volume;
+}
+
+bool AudioFlinger::PlaybackThread::streamMute(int stream) const
+{
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::PlaybackThread::isStreamActive(int stream) const
+{
+    Mutex::Autolock _l(mLock);
+    size_t count = mActiveTracks.size();
+    for (size_t i = 0 ; i < count ; ++i) {
+        sp<Track> t = mActiveTracks[i].promote();
+        if (t == 0) continue;
+        Track* const track = t.get();
+        if (t->type() == stream)
+            return true;
+    }
+    return false;
+}
+
+// addTrack_l() must be called with ThreadBase::mLock held
+status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
+{
+    status_t status = ALREADY_EXISTS;
+
+    // set retry count for buffer fill
+    track->mRetryCount = kMaxTrackStartupRetries;
+    if (mActiveTracks.indexOf(track) < 0) {
+        // the track is newly added, make sure it fills up all its
+        // buffers before playing. This is to ensure the client will
+        // effectively get the latency it requested.
+        track->mFillingUpStatus = Track::FS_FILLING;
+        track->mResetDone = false;
+        mActiveTracks.add(track);
+        status = NO_ERROR;
+    }
+
+    LOGV("mWaitWorkCV.broadcast");
+    mWaitWorkCV.broadcast();
+
+    return status;
+}
+
+// destroyTrack_l() must be called with ThreadBase::mLock held
+void AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
+{
+    track->mState = TrackBase::TERMINATED;
+    if (mActiveTracks.indexOf(track) < 0) {
+        mTracks.remove(track);
+        deleteTrackName_l(track->name());
+    }
+}
+
+String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
+{
+    return mOutput->getParameters(keys);
+}
+
+void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) {
+    AudioSystem::OutputDescriptor desc;
+    void *param2 = 0;
+
+    LOGV("PlaybackThread::audioConfigChanged, thread %p, event %d, param %d", this, event, param);
+
+    switch (event) {
+    case AudioSystem::OUTPUT_OPENED:
+    case AudioSystem::OUTPUT_CONFIG_CHANGED:
+        desc.channels = mChannelCount;
+        desc.samplingRate = mSampleRate;
+        desc.format = mFormat;
+        desc.frameCount = mFrameCount;
+        desc.latency = latency();
+        param2 = &desc;
+        break;
+
+    case AudioSystem::STREAM_CONFIG_CHANGED:
+        param2 = &param;
+    case AudioSystem::OUTPUT_CLOSED:
+    default:
+        break;
+    }
+    Mutex::Autolock _l(mAudioFlinger->mLock);
+    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
+}
+
+void AudioFlinger::PlaybackThread::readOutputParameters()
+{
+    mSampleRate = mOutput->sampleRate();
+    mChannelCount = AudioSystem::popCount(mOutput->channels());
+
+    mFormat = mOutput->format();
+    mFrameSize = mOutput->frameSize();
+    mFrameCount = mOutput->bufferSize() / mFrameSize;
+
+    // FIXME - Current mixer implementation only supports stereo output: Always
+    // Allocate a stereo buffer even if HW output is mono.
+    if (mMixBuffer != NULL) delete mMixBuffer;
+    mMixBuffer = new int16_t[mFrameCount * 2];
+    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
+}
+
+status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
+{
+    if (halFrames == 0 || dspFrames == 0) {
+        return BAD_VALUE;
+    }
+    if (mOutput == 0) {
+        return INVALID_OPERATION;
+    }
+    *halFrames = mBytesWritten/mOutput->frameSize();
+
+    return mOutput->getRenderPosition(dspFrames);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+    :   PlaybackThread(audioFlinger, output, id),
+        mAudioMixer(0)
+{
+    mType = PlaybackThread::MIXER;
+    mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
+
+    // FIXME - Current mixer implementation only supports stereo output
+    if (mChannelCount == 1) {
+        LOGE("Invalid audio hardware channel count");
+    }
+}
+
+AudioFlinger::MixerThread::~MixerThread()
+{
+    delete mAudioMixer;
+}
+
+bool AudioFlinger::MixerThread::threadLoop()
+{
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    uint32_t mixerStatus = MIXER_IDLE;
+    nsecs_t standbyTime = systemTime();
+    size_t mixBufferSize = mFrameCount * mFrameSize;
+    // FIXME: Relaxed timing because of a certain device that can't meet latency
+    // Should be reduced to 2x after the vendor fixes the driver issue
+    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
+    nsecs_t lastWarning = 0;
+    bool longStandbyExit = false;
+    uint32_t activeSleepTime = activeSleepTimeUs();
+    uint32_t idleSleepTime = idleSleepTimeUs();
+    uint32_t sleepTime = idleSleepTime;
+
+    while (!exitPending())
+    {
+        processConfigEvents();
+
+        mixerStatus = MIXER_IDLE;
+        { // scope for mLock
+
+            Mutex::Autolock _l(mLock);
+
+            if (checkForNewParameters_l()) {
+                mixBufferSize = mFrameCount * mFrameSize;
+                // FIXME: Relaxed timing because of a certain device that can't meet latency
+                // Should be reduced to 2x after the vendor fixes the driver issue
+                maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
+                activeSleepTime = activeSleepTimeUs();
+                idleSleepTime = idleSleepTimeUs();
+            }
+
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
+                        mSuspended) {
+                if (!mStandby) {
+                    LOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended);
+                    mOutput->standby();
+                    mStandby = true;
+                    mBytesWritten = 0;
+                }
+
+                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+                    // we're about to wait, flush the binder command buffer
+                    IPCThreadState::self()->flushCommands();
+
+                    if (exitPending()) break;
+
+                    // wait until we have something to do...
+                    LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
+                    mWaitWorkCV.wait(mLock);
+                    LOGV("MixerThread %p TID %d waking up\n", this, gettid());
+
+                    if (mMasterMute == false) {
+                        char value[PROPERTY_VALUE_MAX];
+                        property_get("ro.audio.silent", value, "0");
+                        if (atoi(value)) {
+                            LOGD("Silence is golden");
+                            setMasterMute(true);
+                        }
+                    }
+
+                    standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = idleSleepTime;
+                    continue;
+                }
+            }
+
+            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+       }
+
+        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
+        } else {
+            // If no tracks are ready, sleep once for the duration of an output
+            // buffer size, then write 0s to the output
+            if (sleepTime == 0) {
+                if (mixerStatus == MIXER_TRACKS_ENABLED) {
+                    sleepTime = activeSleepTime;
+                } else {
+                    sleepTime = idleSleepTime;
+                }
+            } else if (mBytesWritten != 0 ||
+                       (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
+                memset (curBuf, 0, mixBufferSize);
+                sleepTime = 0;
+                LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
+            }
+        }
+
+        if (mSuspended) {
+            sleepTime = idleSleepTime;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            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++;
+            mInWrite = false;
+            nsecs_t now = systemTime();
+            nsecs_t delta = now - mLastWriteTime;
+            if (delta > maxPeriod) {
+                mNumDelayedWrites++;
+                if ((now - lastWarning) > kWarningThrottle) {
+                    LOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
+                            ns2ms(delta), mNumDelayedWrites, this);
+                    lastWarning = now;
+                }
+                if (mStandby) {
+                    longStandbyExit = true;
+                }
+            }
+            mStandby = false;
+        } else {
+            usleep(sleepTime);
+        }
+
+        // finally let go of all our tracks, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        tracksToRemove.clear();
+    }
+
+    if (!mStandby) {
+        mOutput->standby();
+    }
+
+    LOGV("MixerThread %p exiting", this);
+    return false;
+}
+
+// prepareTracks_l() must be called with ThreadBase::mLock held
+uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
+{
+
+    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;
+
+        Track* const track = t.get();
+        audio_track_cblk_t* cblk = track->cblk();
+
+        // The first time a track is added we wait
+        // for all its buffers to be filled before processing it
+        mAudioMixer->setActiveTrack(track->name());
+        if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+                !track->isPaused() && !track->isTerminated())
+        {
+            //LOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
+
+            // compute volume for this track
+            int16_t left, right;
+            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;
+#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);
+                v_clamped = v * cblk->volume[1];
+                if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                right = int16_t(v_clamped);
+            }
+
+            // XXX: these things DON'T need to be done each time
+            mAudioMixer->setBufferProvider(track);
+            mAudioMixer->enable(AudioMixer::MIXING);
+
+            int param = AudioMixer::VOLUME;
+            if (track->mFillingUpStatus == Track::FS_FILLED) {
+                // no ramp for the first volume setting
+                track->mFillingUpStatus = Track::FS_ACTIVE;
+                if (track->mState == TrackBase::RESUMING) {
+                    track->mState = TrackBase::ACTIVE;
+                    param = AudioMixer::RAMP_VOLUME;
+                }
+            } else if (cblk->server != 0) {
+                // If the track is stopped before the first frame was mixed,
+                // 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(
+                AudioMixer::TRACK,
+                AudioMixer::FORMAT, track->format());
+            mAudioMixer->setParameter(
+                AudioMixer::TRACK,
+                AudioMixer::CHANNEL_COUNT, track->channelCount());
+            mAudioMixer->setParameter(
+                AudioMixer::RESAMPLE,
+                AudioMixer::SAMPLE_RATE,
+                int(cblk->sampleRate));
+
+            // reset retry count
+            track->mRetryCount = kMaxTrackRetries;
+            mixerStatus = MIXER_TRACKS_READY;
+        } else {
+            //LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
+            if (track->isStopped()) {
+                track->reset();
+            }
+            if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                // We have consumed all the buffers of this track.
+                // Remove it from the list of active tracks.
+                tracksToRemove->add(track);
+                mAudioMixer->disable(AudioMixer::MIXING);
+            } else {
+                // No buffers for this track. Give it a few chances to
+                // fill a buffer, then remove it from active list.
+                if (--(track->mRetryCount) <= 0) {
+                    LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
+                    tracksToRemove->add(track);
+                } else if (mixerStatus != MIXER_TRACKS_READY) {
+                    mixerStatus = MIXER_TRACKS_ENABLED;
+                }
+
+                mAudioMixer->disable(AudioMixer::MIXING);
+            }
+        }
+    }
+
+    // remove all the tracks that need to be...
+    count = tracksToRemove->size();
+    if (UNLIKELY(count)) {
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<Track>& track = tracksToRemove->itemAt(i);
+            mActiveTracks.remove(track);
+            if (track->isTerminated()) {
+                mTracks.remove(track);
+                deleteTrackName_l(track->mName);
+            }
+        }
+    }
+
+    return mixerStatus;
+}
+
+void AudioFlinger::MixerThread::getTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks,
+        int streamType)
+{
+    LOGV ("MixerThread::getTracks() mixer %p, mTracks.size %d, mActiveTracks.size %d", this,  mTracks.size(), mActiveTracks.size());
+    Mutex::Autolock _l(mLock);
+    size_t size = mTracks.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = mTracks[i];
+        if (t->type() == streamType) {
+            tracks.add(t);
+            int j = mActiveTracks.indexOf(t);
+            if (j >= 0) {
+                t = mActiveTracks[j].promote();
+                if (t != NULL) {
+                    activeTracks.add(t);
+                }
+            }
+        }
+    }
+
+    size = activeTracks.size();
+    for (size_t i = 0; i < size; i++) {
+        mActiveTracks.remove(activeTracks[i]);
+    }
+
+    size = tracks.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = tracks[i];
+        mTracks.remove(t);
+        deleteTrackName_l(t->name());
+    }
+}
+
+void AudioFlinger::MixerThread::putTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+    LOGV ("MixerThread::putTracks() mixer %p, tracks.size %d, activeTracks.size %d", this,  tracks.size(), activeTracks.size());
+    Mutex::Autolock _l(mLock);
+    size_t size = tracks.size();
+    for (size_t i = 0; i < size ; i++) {
+        sp<Track> t = tracks[i];
+        int name = getTrackName_l();
+
+        if (name < 0) return;
+
+        t->mName = name;
+        t->mThread = this;
+        mTracks.add(t);
+
+        int j = activeTracks.indexOf(t);
+        if (j >= 0) {
+            mActiveTracks.add(t);
+            // force buffer refilling and no ramp volume when the track is mixed for the first time
+            t->mFillingUpStatus = Track::FS_FILLING;
+        }
+    }
+}
+
+// getTrackName_l() must be called with ThreadBase::mLock held
+int AudioFlinger::MixerThread::getTrackName_l()
+{
+    return mAudioMixer->getTrackName();
+}
+
+// deleteTrackName_l() must be called with ThreadBase::mLock held
+void AudioFlinger::MixerThread::deleteTrackName_l(int name)
+{
+    LOGV("remove track (%d) and delete from mixer", name);
+    mAudioMixer->deleteTrackName(name);
+}
+
+// checkForNewParameters_l() must be called with ThreadBase::mLock held
+bool AudioFlinger::MixerThread::checkForNewParameters_l()
+{
+    bool reconfig = false;
+
+    while (!mNewParameters.isEmpty()) {
+        status_t status = NO_ERROR;
+        String8 keyValuePair = mNewParameters[0];
+        AudioParameter param = AudioParameter(keyValuePair);
+        int value;
+
+        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
+            reconfig = true;
+        }
+        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
+            if (value != AudioSystem::PCM_16_BIT) {
+                status = BAD_VALUE;
+            } else {
+                reconfig = true;
+            }
+        }
+        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
+            if (value != AudioSystem::CHANNEL_OUT_STEREO) {
+                status = BAD_VALUE;
+            } else {
+                reconfig = true;
+            }
+        }
+        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
+            // do not accept frame count changes if tracks are open as the track buffer
+            // size depends on frame count and correct behavior would not be garantied
+            // if frame count is changed after track creation
+            if (!mTracks.isEmpty()) {
+                status = INVALID_OPERATION;
+            } else {
+                reconfig = true;
+            }
+        }
+        if (status == NO_ERROR) {
+            status = mOutput->setParameters(keyValuePair);
+            if (!mStandby && status == INVALID_OPERATION) {
+               mOutput->standby();
+               mStandby = true;
+               mBytesWritten = 0;
+               status = mOutput->setParameters(keyValuePair);
+            }
+            if (status == NO_ERROR && reconfig) {
+                delete mAudioMixer;
+                readOutputParameters();
+                mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
+                for (size_t i = 0; i < mTracks.size() ; i++) {
+                    int name = getTrackName_l();
+                    if (name < 0) break;
+                    mTracks[i]->mName = name;
+                    // limit track sample rate to 2 x new output sample rate
+                    if (mTracks[i]->mCblk->sampleRate > 2 * sampleRate()) {
+                        mTracks[i]->mCblk->sampleRate = 2 * sampleRate();
+                    }
+                }
+                sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
+            }
+        }
+
+        mNewParameters.removeAt(0);
+
+        mParamStatus = status;
+        mParamCond.signal();
+        mWaitWorkCV.wait(mLock);
+    }
+    return reconfig;
+}
+
+status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    PlaybackThread::dumpInternals(fd, args);
+
+    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
+{
+    return (uint32_t)(mOutput->latency() * 1000) / 2;
+}
+
+uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
+{
+    return (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
+}
+
+// ----------------------------------------------------------------------------
+AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+    :   PlaybackThread(audioFlinger, output, id),
+    mLeftVolume (1.0), mRightVolume(1.0)
+{
+    mType = PlaybackThread::DIRECT;
+}
+
+AudioFlinger::DirectOutputThread::~DirectOutputThread()
+{
+}
+
+
+bool AudioFlinger::DirectOutputThread::threadLoop()
+{
+    uint32_t mixerStatus = MIXER_IDLE;
+    sp<Track> trackToRemove;
+    sp<Track> activeTrack;
+    nsecs_t standbyTime = systemTime();
+    int8_t *curBuf;
+    size_t mixBufferSize = mFrameCount*mFrameSize;
+    uint32_t activeSleepTime = activeSleepTimeUs();
+    uint32_t idleSleepTime = idleSleepTimeUs();
+    uint32_t sleepTime = idleSleepTime;
+    // use shorter standby delay as on normal output to release
+    // hardware resources as soon as possible
+    nsecs_t standbyDelay = microseconds(activeSleepTime*2);
+
+
+    while (!exitPending())
+    {
+        processConfigEvents();
+
+        mixerStatus = MIXER_IDLE;
+
+        { // scope for the mLock
+
+            Mutex::Autolock _l(mLock);
+
+            if (checkForNewParameters_l()) {
+                mixBufferSize = mFrameCount*mFrameSize;
+                activeSleepTime = activeSleepTimeUs();
+                idleSleepTime = idleSleepTimeUs();
+                standbyDelay = microseconds(activeSleepTime*2);
+            }
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+                        mSuspended) {
+                // wait until we have something to do...
+                if (!mStandby) {
+                    LOGV("Audio hardware entering standby, mixer %p\n", this);
+                    mOutput->standby();
+                    mStandby = true;
+                    mBytesWritten = 0;
+                }
+
+                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
+                    // we're about to wait, flush the binder command buffer
+                    IPCThreadState::self()->flushCommands();
+
+                    if (exitPending()) break;
+
+                    LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
+                    mWaitWorkCV.wait(mLock);
+                    LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
+
+                    if (mMasterMute == false) {
+                        char value[PROPERTY_VALUE_MAX];
+                        property_get("ro.audio.silent", value, "0");
+                        if (atoi(value)) {
+                            LOGD("Silence is golden");
+                            setMasterMute(true);
+                        }
+                    }
+
+                    standbyTime = systemTime() + standbyDelay;
+                    sleepTime = idleSleepTime;
+                    continue;
+                }
+            }
+
+            // find out which tracks need to be processed
+            if (mActiveTracks.size() != 0) {
+                sp<Track> t = mActiveTracks[0].promote();
+                if (t == 0) continue;
+
+                Track* const track = t.get();
+                audio_track_cblk_t* cblk = track->cblk();
+
+                // The first time a track is added we wait
+                // for all its buffers to be filled before processing it
+                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+                        !track->isPaused() && !track->isTerminated())
+                {
+                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
+
+                    // compute volume for this track
+                    float left, right;
+                    if (track->isMuted() || mMasterMute || track->isPausing() ||
+                        mStreamTypes[track->type()].mute) {
+                        left = right = 0;
+                        if (track->isPausing()) {
+                            track->setPaused();
+                        }
+                    } else {
+                        float typeVolume = mStreamTypes[track->type()].volume;
+                        float v = mMasterVolume * typeVolume;
+                        float v_clamped = v * cblk->volume[0];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        left = v_clamped/MAX_GAIN;
+                        v_clamped = v * cblk->volume[1];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        right = v_clamped/MAX_GAIN;
+                    }
+
+                    if (left != mLeftVolume || right != mRightVolume) {
+                        mOutput->setVolume(left, right);
+                        left = mLeftVolume;
+                        right = mRightVolume;
+                    }
+
+                    if (track->mFillingUpStatus == Track::FS_FILLED) {
+                        track->mFillingUpStatus = Track::FS_ACTIVE;
+                        if (track->mState == TrackBase::RESUMING) {
+                            track->mState = TrackBase::ACTIVE;
+                        }
+                    }
+
+                    // reset retry count
+                    track->mRetryCount = kMaxTrackRetriesDirect;
+                    activeTrack = t;
+                    mixerStatus = MIXER_TRACKS_READY;
+                } else {
+                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
+                    if (track->isStopped()) {
+                        track->reset();
+                    }
+                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                        // We have consumed all the buffers of this track.
+                        // Remove it from the list of active tracks.
+                        trackToRemove = track;
+                    } else {
+                        // No buffers for this track. Give it a few chances to
+                        // fill a buffer, then remove it from active list.
+                        if (--(track->mRetryCount) <= 0) {
+                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                            trackToRemove = track;
+                        } else {
+                            mixerStatus = MIXER_TRACKS_ENABLED;
+                        }
+                    }
+                }
+            }
+
+            // remove all the tracks that need to be...
+            if (UNLIKELY(trackToRemove != 0)) {
+                mActiveTracks.remove(trackToRemove);
+                if (trackToRemove->isTerminated()) {
+                    mTracks.remove(trackToRemove);
+                    deleteTrackName_l(trackToRemove->mName);
+                }
+            }
+       }
+
+        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+            AudioBufferProvider::Buffer buffer;
+            size_t frameCount = mFrameCount;
+            curBuf = (int8_t *)mMixBuffer;
+            // output audio to hardware
+            while(frameCount) {
+                buffer.frameCount = frameCount;
+                activeTrack->getNextBuffer(&buffer);
+                if (UNLIKELY(buffer.raw == 0)) {
+                    memset(curBuf, 0, frameCount * mFrameSize);
+                    break;
+                }
+                memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
+                frameCount -= buffer.frameCount;
+                curBuf += buffer.frameCount * mFrameSize;
+                activeTrack->releaseBuffer(&buffer);
+            }
+            sleepTime = 0;
+            standbyTime = systemTime() + standbyDelay;
+        } else {
+            if (sleepTime == 0) {
+                if (mixerStatus == MIXER_TRACKS_ENABLED) {
+                    sleepTime = activeSleepTime;
+                } else {
+                    sleepTime = idleSleepTime;
+                }
+            } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
+                memset (mMixBuffer, 0, mFrameCount * mFrameSize);
+                sleepTime = 0;
+            }
+        }
+
+        if (mSuspended) {
+            sleepTime = idleSleepTime;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            mBytesWritten += mixBufferSize;
+            int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+            if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+        } else {
+            usleep(sleepTime);
+        }
+
+        // finally let go of removed track, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        trackToRemove.clear();
+        activeTrack.clear();
+    }
+
+    if (!mStandby) {
+        mOutput->standby();
+    }
+
+    LOGV("DirectOutputThread %p exiting", this);
+    return false;
+}
+
+// getTrackName_l() must be called with ThreadBase::mLock held
+int AudioFlinger::DirectOutputThread::getTrackName_l()
+{
+    return 0;
+}
+
+// deleteTrackName_l() must be called with ThreadBase::mLock held
+void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name)
+{
+}
+
+// checkForNewParameters_l() must be called with ThreadBase::mLock held
+bool AudioFlinger::DirectOutputThread::checkForNewParameters_l()
+{
+    bool reconfig = false;
+
+    while (!mNewParameters.isEmpty()) {
+        status_t status = NO_ERROR;
+        String8 keyValuePair = mNewParameters[0];
+        AudioParameter param = AudioParameter(keyValuePair);
+        int value;
+
+        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
+            // do not accept frame count changes if tracks are open as the track buffer
+            // size depends on frame count and correct behavior would not be garantied
+            // if frame count is changed after track creation
+            if (!mTracks.isEmpty()) {
+                status = INVALID_OPERATION;
+            } else {
+                reconfig = true;
+            }
+        }
+        if (status == NO_ERROR) {
+            status = mOutput->setParameters(keyValuePair);
+            if (!mStandby && status == INVALID_OPERATION) {
+               mOutput->standby();
+               mStandby = true;
+               mBytesWritten = 0;
+               status = mOutput->setParameters(keyValuePair);
+            }
+            if (status == NO_ERROR && reconfig) {
+                readOutputParameters();
+                sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
+            }
+        }
+
+        mNewParameters.removeAt(0);
+
+        mParamStatus = status;
+        mParamCond.signal();
+        mWaitWorkCV.wait(mLock);
+    }
+    return reconfig;
+}
+
+uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs()
+{
+    uint32_t time;
+    if (AudioSystem::isLinearPCM(mFormat)) {
+        time = (uint32_t)(mOutput->latency() * 1000) / 2;
+    } else {
+        time = 10000;
+    }
+    return time;
+}
+
+uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs()
+{
+    uint32_t time;
+    if (AudioSystem::isLinearPCM(mFormat)) {
+        time = (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
+    } else {
+        time = 10000;
+    }
+    return time;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
+    :   MixerThread(audioFlinger, mainThread->getOutput(), id), mWaitTimeMs(UINT_MAX)
+{
+    mType = PlaybackThread::DUPLICATING;
+    addOutputTrack(mainThread);
+}
+
+AudioFlinger::DuplicatingThread::~DuplicatingThread()
+{
+    for (size_t i = 0; i < mOutputTracks.size(); i++) {
+        mOutputTracks[i]->destroy();
+    }
+    mOutputTracks.clear();
+}
+
+bool AudioFlinger::DuplicatingThread::threadLoop()
+{
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    uint32_t mixerStatus = MIXER_IDLE;
+    nsecs_t standbyTime = systemTime();
+    size_t mixBufferSize = mFrameCount*mFrameSize;
+    SortedVector< sp<OutputTrack> > outputTracks;
+    uint32_t writeFrames = 0;
+    uint32_t activeSleepTime = activeSleepTimeUs();
+    uint32_t idleSleepTime = idleSleepTimeUs();
+    uint32_t sleepTime = idleSleepTime;
+
+    while (!exitPending())
+    {
+        processConfigEvents();
+
+        mixerStatus = MIXER_IDLE;
+        { // scope for the mLock
+
+            Mutex::Autolock _l(mLock);
+
+            if (checkForNewParameters_l()) {
+                mixBufferSize = mFrameCount*mFrameSize;
+                updateWaitTime();
+                activeSleepTime = activeSleepTimeUs();
+                idleSleepTime = idleSleepTimeUs();
+            }
+
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            for (size_t i = 0; i < mOutputTracks.size(); i++) {
+                outputTracks.add(mOutputTracks[i]);
+            }
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
+                         mSuspended) {
+                if (!mStandby) {
+                    for (size_t i = 0; i < outputTracks.size(); i++) {
+                        outputTracks[i]->stop();
+                    }
+                    mStandby = true;
+                    mBytesWritten = 0;
+                }
+
+                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+                    // we're about to wait, flush the binder command buffer
+                    IPCThreadState::self()->flushCommands();
+                    outputTracks.clear();
+
+                    if (exitPending()) break;
+
+                    LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
+                    mWaitWorkCV.wait(mLock);
+                    LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
+                    if (mMasterMute == false) {
+                        char value[PROPERTY_VALUE_MAX];
+                        property_get("ro.audio.silent", value, "0");
+                        if (atoi(value)) {
+                            LOGD("Silence is golden");
+                            setMasterMute(true);
+                        }
+                    }
+
+                    standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = idleSleepTime;
+                    continue;
+                }
+            }
+
+            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+        }
+
+        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+            // mix buffers...
+            if (outputsReady(outputTracks)) {
+                mAudioMixer->process(curBuf);
+            } else {
+                memset(curBuf, 0, mixBufferSize);
+            }
+            sleepTime = 0;
+            writeFrames = mFrameCount;
+        } else {
+            if (sleepTime == 0) {
+                if (mixerStatus == MIXER_TRACKS_ENABLED) {
+                    sleepTime = activeSleepTime;
+                } else {
+                    sleepTime = idleSleepTime;
+                }
+            } else if (mBytesWritten != 0) {
+                // flush remaining overflow buffers in output tracks
+                for (size_t i = 0; i < outputTracks.size(); i++) {
+                    if (outputTracks[i]->isActive()) {
+                        sleepTime = 0;
+                        writeFrames = 0;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (mSuspended) {
+            sleepTime = idleSleepTime;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
+            for (size_t i = 0; i < outputTracks.size(); i++) {
+                outputTracks[i]->write(curBuf, writeFrames);
+            }
+            mStandby = false;
+            mBytesWritten += mixBufferSize;
+        } else {
+            usleep(sleepTime);
+        }
+
+        // finally let go of all our tracks, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        tracksToRemove.clear();
+        outputTracks.clear();
+    }
+
+    return false;
+}
+
+void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
+{
+    int frameCount = (3 * mFrameCount * mSampleRate) / thread->sampleRate();
+    OutputTrack *outputTrack = new OutputTrack((ThreadBase *)thread,
+                                            this,
+                                            mSampleRate,
+                                            mFormat,
+                                            mChannelCount,
+                                            frameCount);
+    if (outputTrack->cblk() != NULL) {
+        thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
+        mOutputTracks.add(outputTrack);
+        LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
+        updateWaitTime();
+    }
+}
+
+void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
+{
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mOutputTracks.size(); i++) {
+        if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
+            mOutputTracks[i]->destroy();
+            mOutputTracks.removeAt(i);
+            updateWaitTime();
+            return;
+        }
+    }
+    LOGV("removeOutputTrack(): unkonwn thread: %p", thread);
+}
+
+void AudioFlinger::DuplicatingThread::updateWaitTime()
+{
+    mWaitTimeMs = UINT_MAX;
+    for (size_t i = 0; i < mOutputTracks.size(); i++) {
+        sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
+        if (strong != NULL) {
+            uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
+            if (waitTimeMs < mWaitTimeMs) {
+                mWaitTimeMs = waitTimeMs;
+            }
+        }
+    }
+}
+
+
+bool AudioFlinger::DuplicatingThread::outputsReady(SortedVector< sp<OutputTrack> > &outputTracks)
+{
+    for (size_t i = 0; i < outputTracks.size(); i++) {
+        sp <ThreadBase> thread = outputTracks[i]->thread().promote();
+        if (thread == 0) {
+            LOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", outputTracks[i].get());
+            return false;
+        }
+        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        if (playbackThread->standby() && !playbackThread->isSuspended()) {
+            LOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
+            return false;
+        }
+    }
+    return true;
+}
+
+uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
+{
+    return (mWaitTimeMs * 1000) / 2;
+}
+
+// ----------------------------------------------------------------------------
+
+// TrackBase constructor must be called with AudioFlinger::mLock held
+AudioFlinger::ThreadBase::TrackBase::TrackBase(
+            const wp<ThreadBase>& thread,
+            const sp<Client>& client,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags,
+            const sp<IMemory>& sharedBuffer)
+    :   RefBase(),
+        mThread(thread),
+        mClient(client),
+        mCblk(0),
+        mFrameCount(0),
+        mState(IDLE),
+        mClientTid(-1),
+        mFormat(format),
+        mFlags(flags & ~SYSTEM_FLAGS_MASK)
+{
+    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+
+    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
+   size_t size = sizeof(audio_track_cblk_t);
+   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
+   if (sharedBuffer == 0) {
+       size += bufferSize;
+   }
+
+   if (client != NULL) {
+        mCblkMemory = client->heap()->allocate(size);
+        if (mCblkMemory != 0) {
+            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
+            if (mCblk) { // construct the shared structure in-place.
+                new(mCblk) audio_track_cblk_t();
+                // clear all buffers
+                mCblk->frameCount = frameCount;
+                mCblk->sampleRate = sampleRate;
+                mCblk->channels = (uint8_t)channelCount;
+                if (sharedBuffer == 0) {
+                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+                    // Force underrun condition to avoid false underrun callback until first data is
+                    // written to buffer
+                    mCblk->flowControlFlag = 1;
+                } else {
+                    mBuffer = sharedBuffer->pointer();
+                }
+                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+            }
+        } else {
+            LOGE("not enough memory for AudioTrack size=%u", size);
+            client->heap()->dump("AudioTrack");
+            return;
+        }
+   } else {
+       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
+       if (mCblk) { // construct the shared structure in-place.
+           new(mCblk) audio_track_cblk_t();
+           // clear all buffers
+           mCblk->frameCount = frameCount;
+           mCblk->sampleRate = sampleRate;
+           mCblk->channels = (uint8_t)channelCount;
+           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+           // Force underrun condition to avoid false underrun callback until first data is
+           // written to buffer
+           mCblk->flowControlFlag = 1;
+           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+       }
+   }
+}
+
+AudioFlinger::ThreadBase::TrackBase::~TrackBase()
+{
+    if (mCblk) {
+        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
+        if (mClient == NULL) {
+            delete mCblk;
+        }
+    }
+    mCblkMemory.clear();            // and free the shared memory
+    if (mClient != NULL) {
+        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
+        mClient.clear();
+    }
+}
+
+void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    buffer->raw = 0;
+    mFrameCount = buffer->frameCount;
+    step();
+    buffer->frameCount = 0;
+}
+
+bool AudioFlinger::ThreadBase::TrackBase::step() {
+    bool result;
+    audio_track_cblk_t* cblk = this->cblk();
+
+    result = cblk->stepServer(mFrameCount);
+    if (!result) {
+        LOGV("stepServer failed acquiring cblk mutex");
+        mFlags |= STEPSERVER_FAILED;
+    }
+    return result;
+}
+
+void AudioFlinger::ThreadBase::TrackBase::reset() {
+    audio_track_cblk_t* cblk = this->cblk();
+
+    cblk->user = 0;
+    cblk->server = 0;
+    cblk->userBase = 0;
+    cblk->serverBase = 0;
+    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
+    LOGV("TrackBase::reset");
+}
+
+sp<IMemory> AudioFlinger::ThreadBase::TrackBase::getCblk() const
+{
+    return mCblkMemory;
+}
+
+int AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
+    return (int)mCblk->sampleRate;
+}
+
+int AudioFlinger::ThreadBase::TrackBase::channelCount() const {
+    return (int)mCblk->channels;
+}
+
+void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
+    audio_track_cblk_t* cblk = this->cblk();
+    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*cblk->frameSize;
+    int8_t *bufferEnd = bufferStart + frames * cblk->frameSize;
+
+    // Check validity of returned pointer in case the track control block would have been corrupted.
+    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
+        ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) {
+        LOGE("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
+                server %d, serverBase %d, user %d, userBase %d, channels %d",
+                bufferStart, bufferEnd, mBuffer, mBufferEnd,
+                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
+        return 0;
+    }
+
+    return bufferStart;
+}
+
+// ----------------------------------------------------------------------------
+
+// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
+AudioFlinger::PlaybackThread::Track::Track(
+            const wp<ThreadBase>& thread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            const sp<IMemory>& sharedBuffer)
+    :   TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer),
+    mMute(false), mSharedBuffer(sharedBuffer), mName(-1)
+{
+    if (mCblk != NULL) {
+        sp<ThreadBase> baseThread = thread.promote();
+        if (baseThread != 0) {
+            PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
+            mName = playbackThread->getTrackName_l();
+        }
+        LOGV("Track constructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+        if (mName < 0) {
+            LOGE("no more track names available");
+        }
+        mVolume[0] = 1.0f;
+        mVolume[1] = 1.0f;
+        mStreamType = streamType;
+        // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
+        // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
+        mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
+    }
+}
+
+AudioFlinger::PlaybackThread::Track::~Track()
+{
+    LOGV("PlaybackThread::Track destructor");
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        Mutex::Autolock _l(thread->mLock);
+        mState = TERMINATED;
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::destroy()
+{
+    // NOTE: destroyTrack_l() can remove a strong reference to this Track
+    // by removing it from mTracks vector, so there is a risk that this Tracks's
+    // desctructor is called. As the destructor needs to lock mLock,
+    // we must acquire a strong reference on this Track before locking mLock
+    // here so that the destructor is called only when exiting this function.
+    // On the other hand, as long as Track::destroy() is only called by
+    // TrackHandle destructor, the TrackHandle still holds a strong ref on
+    // this Track with its member mTrack.
+    sp<Track> keep(this);
+    { // scope for mLock
+        sp<ThreadBase> thread = mThread.promote();
+        if (thread != 0) {
+            if (!isOutputTrack()) {
+                if (mState == ACTIVE || mState == RESUMING) {
+                    AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+                }
+                AudioSystem::releaseOutput(thread->id());
+            }
+            Mutex::Autolock _l(thread->mLock);
+            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+            playbackThread->destroyTrack_l(this);
+        }
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %04u %1d %1d %1d %5u %5u %5u  %08x %08x\n",
+            mName - AudioMixer::TRACK0,
+            (mClient == NULL) ? getpid() : mClient->pid(),
+            mStreamType,
+            mFormat,
+            mCblk->channels,
+            mFrameCount,
+            mState,
+            mMute,
+            mFillingUpStatus,
+            mCblk->sampleRate,
+            mCblk->volume[0],
+            mCblk->volume[1],
+            mCblk->server,
+            mCblk->user);
+}
+
+status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+     audio_track_cblk_t* cblk = this->cblk();
+     uint32_t framesReady;
+     uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+     if (mFlags & TrackBase::STEPSERVER_FAILED) {
+         if (!step())  goto getNextBuffer_exit;
+         LOGV("stepServer recovered");
+         mFlags &= ~TrackBase::STEPSERVER_FAILED;
+     }
+
+     framesReady = cblk->framesReady();
+
+     if (LIKELY(framesReady)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
+        if (framesReq > framesReady) {
+            framesReq = framesReady;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+         buffer->raw = getBuffer(s, framesReq);
+         if (buffer->raw == 0) goto getNextBuffer_exit;
+
+         buffer->frameCount = framesReq;
+        return NO_ERROR;
+     }
+
+getNextBuffer_exit:
+     buffer->raw = 0;
+     buffer->frameCount = 0;
+     LOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
+     return NOT_ENOUGH_DATA;
+}
+
+bool AudioFlinger::PlaybackThread::Track::isReady() const {
+    if (mFillingUpStatus != FS_FILLING) return true;
+
+    if (mCblk->framesReady() >= mCblk->frameCount ||
+        mCblk->forceReady) {
+        mFillingUpStatus = FS_FILLED;
+        mCblk->forceReady = 0;
+        return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::PlaybackThread::Track::start()
+{
+    status_t status = NO_ERROR;
+    LOGV("start(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        Mutex::Autolock _l(thread->mLock);
+        int state = mState;
+        // here the track could be either new, or restarted
+        // in both cases "unstop" the track
+        if (mState == PAUSED) {
+            mState = TrackBase::RESUMING;
+            LOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
+        } else {
+            mState = TrackBase::ACTIVE;
+            LOGV("? => ACTIVE (%d) on thread %p", mName, this);
+        }
+
+        if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
+            thread->mLock.unlock();
+            status = AudioSystem::startOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+            thread->mLock.lock();
+        }
+        if (status == NO_ERROR) {
+            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+            playbackThread->addTrack_l(this);
+        } else {
+            mState = state;
+        }
+    } else {
+        status = BAD_VALUE;
+    }
+    return status;
+}
+
+void AudioFlinger::PlaybackThread::Track::stop()
+{
+    LOGV("stop(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        Mutex::Autolock _l(thread->mLock);
+        int state = mState;
+        if (mState > STOPPED) {
+            mState = STOPPED;
+            // If the track is not active (PAUSED and buffers full), flush buffers
+            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
+                reset();
+            }
+            LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread);
+        }
+        if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
+            thread->mLock.unlock();
+            AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+            thread->mLock.lock();
+        }
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::pause()
+{
+    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        Mutex::Autolock _l(thread->mLock);
+        if (mState == ACTIVE || mState == RESUMING) {
+            mState = PAUSING;
+            LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
+            if (!isOutputTrack()) {
+                thread->mLock.unlock();
+                AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+                thread->mLock.lock();
+            }
+        }
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::flush()
+{
+    LOGV("flush(%d)", mName);
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        Mutex::Autolock _l(thread->mLock);
+        if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
+            return;
+        }
+        // No point remaining in PAUSED state after a flush => go to
+        // STOPPED state
+        mState = STOPPED;
+
+        mCblk->lock.lock();
+        // NOTE: reset() will reset cblk->user and cblk->server with
+        // the risk that at the same time, the AudioMixer is trying to read
+        // data. In this case, getNextBuffer() would return a NULL pointer
+        // as audio buffer => the AudioMixer code MUST always test that pointer
+        // returned by getNextBuffer() is not NULL!
+        reset();
+        mCblk->lock.unlock();
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::reset()
+{
+    // Do not reset twice to avoid discarding data written just after a flush and before
+    // the audioflinger thread detects the track is stopped.
+    if (!mResetDone) {
+        TrackBase::reset();
+        // Force underrun condition to avoid false underrun callback until first data is
+        // written to buffer
+        mCblk->flowControlFlag = 1;
+        mCblk->forceReady = 0;
+        mFillingUpStatus = FS_FILLING;
+        mResetDone = true;
+    }
+}
+
+void AudioFlinger::PlaybackThread::Track::mute(bool muted)
+{
+    mMute = muted;
+}
+
+void AudioFlinger::PlaybackThread::Track::setVolume(float left, float right)
+{
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+// RecordTrack constructor must be called with AudioFlinger::mLock held
+AudioFlinger::RecordThread::RecordTrack::RecordTrack(
+            const wp<ThreadBase>& thread,
+            const sp<Client>& client,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags)
+    :   TrackBase(thread, client, sampleRate, format,
+                  channelCount, frameCount, flags, 0),
+        mOverflow(false)
+{
+    if (mCblk != NULL) {
+       LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
+       if (format == AudioSystem::PCM_16_BIT) {
+           mCblk->frameSize = channelCount * sizeof(int16_t);
+       } else if (format == AudioSystem::PCM_8_BIT) {
+           mCblk->frameSize = channelCount * sizeof(int8_t);
+       } else {
+           mCblk->frameSize = sizeof(int8_t);
+       }
+    }
+}
+
+AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        AudioSystem::releaseInput(thread->id());
+    }
+}
+
+status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    audio_track_cblk_t* cblk = this->cblk();
+    uint32_t framesAvail;
+    uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+    if (mFlags & TrackBase::STEPSERVER_FAILED) {
+        if (!step()) goto getNextBuffer_exit;
+        LOGV("stepServer recovered");
+        mFlags &= ~TrackBase::STEPSERVER_FAILED;
+    }
+
+    framesAvail = cblk->framesAvailable_l();
+
+    if (LIKELY(framesAvail)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        if (framesReq > framesAvail) {
+            framesReq = framesAvail;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+        buffer->raw = getBuffer(s, framesReq);
+        if (buffer->raw == 0) goto getNextBuffer_exit;
+
+        buffer->frameCount = framesReq;
+        return NO_ERROR;
+    }
+
+getNextBuffer_exit:
+    buffer->raw = 0;
+    buffer->frameCount = 0;
+    return NOT_ENOUGH_DATA;
+}
+
+status_t AudioFlinger::RecordThread::RecordTrack::start()
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        RecordThread *recordThread = (RecordThread *)thread.get();
+        return recordThread->start(this);
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+void AudioFlinger::RecordThread::RecordTrack::stop()
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        RecordThread *recordThread = (RecordThread *)thread.get();
+        recordThread->stop(this);
+        TrackBase::reset();
+        // Force overerrun condition to avoid false overrun callback until first data is
+        // read from buffer
+        mCblk->flowControlFlag = 1;
+    }
+}
+
+void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "   %05d %03u %03u %04u %01d %05u  %08x %08x\n",
+            (mClient == NULL) ? getpid() : mClient->pid(),
+            mFormat,
+            mCblk->channels,
+            mFrameCount,
+            mState,
+            mCblk->sampleRate,
+            mCblk->server,
+            mCblk->user);
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
+            const wp<ThreadBase>& thread,
+            DuplicatingThread *sourceThread,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount)
+    :   Track(thread, NULL, AudioSystem::NUM_STREAM_TYPES, sampleRate, format, channelCount, frameCount, NULL),
+    mActive(false), mSourceThread(sourceThread)
+{
+
+    PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
+    if (mCblk != NULL) {
+        mCblk->out = 1;
+        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+        mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+        mOutBuffer.frameCount = 0;
+        playbackThread->mTracks.add(this);
+        LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
+                mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
+    } else {
+        LOGW("Error creating output track on thread %p", playbackThread);
+    }
+}
+
+AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
+{
+    clearBufferQueue();
+}
+
+status_t AudioFlinger::PlaybackThread::OutputTrack::start()
+{
+    status_t status = Track::start();
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    mActive = true;
+    mRetryCount = 127;
+    return status;
+}
+
+void AudioFlinger::PlaybackThread::OutputTrack::stop()
+{
+    Track::stop();
+    clearBufferQueue();
+    mOutBuffer.frameCount = 0;
+    mActive = false;
+}
+
+bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
+{
+    Buffer *pInBuffer;
+    Buffer inBuffer;
+    uint32_t channels = mCblk->channels;
+    bool outputBufferFull = false;
+    inBuffer.frameCount = frames;
+    inBuffer.i16 = data;
+
+    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
+
+    if (!mActive && frames != 0) {
+        start();
+        sp<ThreadBase> thread = mThread.promote();
+        if (thread != 0) {
+            MixerThread *mixerThread = (MixerThread *)thread.get();
+            if (mCblk->frameCount > frames){
+                if (mBufferQueue.size() < kMaxOverFlowBuffers) {
+                    uint32_t startFrames = (mCblk->frameCount - frames);
+                    pInBuffer = new Buffer;
+                    pInBuffer->mBuffer = new int16_t[startFrames * channels];
+                    pInBuffer->frameCount = startFrames;
+                    pInBuffer->i16 = pInBuffer->mBuffer;
+                    memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
+                    mBufferQueue.add(pInBuffer);
+                } else {
+                    LOGW ("OutputTrack::write() %p no more buffers in queue", this);
+                }
+            }
+        }
+    }
+
+    while (waitTimeLeftMs) {
+        // First write pending buffers, then new data
+        if (mBufferQueue.size()) {
+            pInBuffer = mBufferQueue.itemAt(0);
+        } else {
+            pInBuffer = &inBuffer;
+        }
+
+        if (pInBuffer->frameCount == 0) {
+            break;
+        }
+
+        if (mOutBuffer.frameCount == 0) {
+            mOutBuffer.frameCount = pInBuffer->frameCount;
+            nsecs_t startTime = systemTime();
+            if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
+                LOGV ("OutputTrack::write() %p thread %p no more output buffers", this, mThread.unsafe_get());
+                outputBufferFull = true;
+                break;
+            }
+            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
+            if (waitTimeLeftMs >= waitTimeMs) {
+                waitTimeLeftMs -= waitTimeMs;
+            } else {
+                waitTimeLeftMs = 0;
+            }
+        }
+
+        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
+        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
+        mCblk->stepUser(outFrames);
+        pInBuffer->frameCount -= outFrames;
+        pInBuffer->i16 += outFrames * channels;
+        mOutBuffer.frameCount -= outFrames;
+        mOutBuffer.i16 += outFrames * channels;
+
+        if (pInBuffer->frameCount == 0) {
+            if (mBufferQueue.size()) {
+                mBufferQueue.removeAt(0);
+                delete [] pInBuffer->mBuffer;
+                delete pInBuffer;
+                LOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
+            } else {
+                break;
+            }
+        }
+    }
+
+    // If we could not write all frames, allocate a buffer and queue it for next time.
+    if (inBuffer.frameCount) {
+        sp<ThreadBase> thread = mThread.promote();
+        if (thread != 0 && !thread->standby()) {
+            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
+                pInBuffer = new Buffer;
+                pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
+                pInBuffer->frameCount = inBuffer.frameCount;
+                pInBuffer->i16 = pInBuffer->mBuffer;
+                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
+                mBufferQueue.add(pInBuffer);
+                LOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
+            } else {
+                LOGW("OutputTrack::write() %p thread %p no more overflow buffers", mThread.unsafe_get(), this);
+            }
+        }
+    }
+
+    // Calling write() with a 0 length buffer, means that no more data will be written:
+    // If no more buffers are pending, fill output track buffer to make sure it is started
+    // by output mixer.
+    if (frames == 0 && mBufferQueue.size() == 0) {
+        if (mCblk->user < mCblk->frameCount) {
+            frames = mCblk->frameCount - mCblk->user;
+            pInBuffer = new Buffer;
+            pInBuffer->mBuffer = new int16_t[frames * channels];
+            pInBuffer->frameCount = frames;
+            pInBuffer->i16 = pInBuffer->mBuffer;
+            memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
+            mBufferQueue.add(pInBuffer);
+        } else if (mActive) {
+            stop();
+        }
+    }
+
+    return outputBufferFull;
+}
+
+status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
+{
+    int active;
+    status_t result;
+    audio_track_cblk_t* cblk = mCblk;
+    uint32_t framesReq = buffer->frameCount;
+
+//    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
+    buffer->frameCount  = 0;
+
+    uint32_t framesAvail = cblk->framesAvailable();
+
+
+    if (framesAvail == 0) {
+        Mutex::Autolock _l(cblk->lock);
+        goto start_loop_here;
+        while (framesAvail == 0) {
+            active = mActive;
+            if (UNLIKELY(!active)) {
+                LOGV("Not active and NO_MORE_BUFFERS");
+                return AudioTrack::NO_MORE_BUFFERS;
+            }
+            result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
+            if (result != NO_ERROR) {
+                return AudioTrack::NO_MORE_BUFFERS;
+            }
+            // read the server count again
+        start_loop_here:
+            framesAvail = cblk->framesAvailable_l();
+        }
+    }
+
+//    if (framesAvail < framesReq) {
+//        return AudioTrack::NO_MORE_BUFFERS;
+//    }
+
+    if (framesReq > framesAvail) {
+        framesReq = framesAvail;
+    }
+
+    uint32_t u = cblk->user;
+    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+
+    if (u + framesReq > bufferEnd) {
+        framesReq = bufferEnd - u;
+    }
+
+    buffer->frameCount  = framesReq;
+    buffer->raw         = (void *)cblk->buffer(u);
+    return NO_ERROR;
+}
+
+
+void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
+{
+    size_t size = mBufferQueue.size();
+    Buffer *pBuffer;
+
+    for (size_t i = 0; i < size; i++) {
+        pBuffer = mBufferQueue.itemAt(i);
+        delete [] pBuffer->mBuffer;
+        delete pBuffer;
+    }
+    mBufferQueue.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
+        mPid(pid)
+{
+    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+}
+
+// Client destructor must be called with AudioFlinger::mLock held
+AudioFlinger::Client::~Client()
+{
+    mAudioFlinger->removeClient_l(mPid);
+}
+
+const sp<MemoryDealer>& AudioFlinger::Client::heap() const
+{
+    return mMemoryDealer;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
+    : BnAudioTrack(),
+      mTrack(track)
+{
+}
+
+AudioFlinger::TrackHandle::~TrackHandle() {
+    // just stop the track on deletion, associated resources
+    // will be freed from the main thread once all pending buffers have
+    // been played. Unless it's not in the active track list, in which
+    // case we free everything now...
+    mTrack->destroy();
+}
+
+status_t AudioFlinger::TrackHandle::start() {
+    return mTrack->start();
+}
+
+void AudioFlinger::TrackHandle::stop() {
+    mTrack->stop();
+}
+
+void AudioFlinger::TrackHandle::flush() {
+    mTrack->flush();
+}
+
+void AudioFlinger::TrackHandle::mute(bool e) {
+    mTrack->mute(e);
+}
+
+void AudioFlinger::TrackHandle::pause() {
+    mTrack->pause();
+}
+
+void AudioFlinger::TrackHandle::setVolume(float left, float right) {
+    mTrack->setVolume(left, right);
+}
+
+sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
+    return mTrack->getCblk();
+}
+
+status_t AudioFlinger::TrackHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioTrack::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+sp<IAudioRecord> AudioFlinger::openRecord(
+        pid_t pid,
+        int input,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        status_t *status)
+{
+    sp<RecordThread::RecordTrack> recordTrack;
+    sp<RecordHandle> recordHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    status_t lStatus;
+    RecordThread *thread;
+    size_t inFrameCount;
+
+    // check calling permissions
+    if (!recordingAllowed()) {
+        lStatus = PERMISSION_DENIED;
+        goto Exit;
+    }
+
+    // add client to list
+    { // scope for mLock
+        Mutex::Autolock _l(mLock);
+        thread = checkRecordThread_l(input);
+        if (thread == NULL) {
+            lStatus = BAD_VALUE;
+            goto Exit;
+        }
+
+        wclient = mClients.valueFor(pid);
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+
+        // create new record track. The record track uses one track in mHardwareMixerThread by convention.
+        recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate,
+                                                   format, channelCount, frameCount, flags);
+    }
+    if (recordTrack->getCblk() == NULL) {
+        // remove local strong reference to Client before deleting the RecordTrack so that the Client
+        // destructor is called by the TrackBase destructor with mLock held
+        client.clear();
+        recordTrack.clear();
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
+
+    // return to handle to client
+    recordHandle = new RecordHandle(recordTrack);
+    lStatus = NO_ERROR;
+
+Exit:
+    if (status) {
+        *status = lStatus;
+    }
+    return recordHandle;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
+    : BnAudioRecord(),
+    mRecordTrack(recordTrack)
+{
+}
+
+AudioFlinger::RecordHandle::~RecordHandle() {
+    stop();
+}
+
+status_t AudioFlinger::RecordHandle::start() {
+    LOGV("RecordHandle::start()");
+    return mRecordTrack->start();
+}
+
+void AudioFlinger::RecordHandle::stop() {
+    LOGV("RecordHandle::stop()");
+    mRecordTrack->stop();
+}
+
+sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
+    return mRecordTrack->getCblk();
+}
+
+status_t AudioFlinger::RecordHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioRecord::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
+    ThreadBase(audioFlinger, id),
+    mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
+{
+    mReqChannelCount = AudioSystem::popCount(channels);
+    mReqSampleRate = sampleRate;
+    readInputParameters();
+    sendConfigEvent(AudioSystem::INPUT_OPENED);
+}
+
+
+AudioFlinger::RecordThread::~RecordThread()
+{
+    delete[] mRsmpInBuffer;
+    if (mResampler != 0) {
+        delete mResampler;
+        delete[] mRsmpOutBuffer;
+    }
+}
+
+void AudioFlinger::RecordThread::onFirstRef()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+
+    snprintf(buffer, SIZE, "Record Thread %p", this);
+
+    run(buffer, PRIORITY_URGENT_AUDIO);
+}
+
+bool AudioFlinger::RecordThread::threadLoop()
+{
+    AudioBufferProvider::Buffer buffer;
+    sp<RecordTrack> activeTrack;
+
+    // start recording
+    while (!exitPending()) {
+
+        processConfigEvents();
+
+        { // scope for mLock
+            Mutex::Autolock _l(mLock);
+            checkForNewParameters_l();
+            if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
+                if (!mStandby) {
+                    mInput->standby();
+                    mStandby = true;
+                }
+
+                if (exitPending()) break;
+
+                LOGV("RecordThread: loop stopping");
+                // go to sleep
+                mWaitWorkCV.wait(mLock);
+                LOGV("RecordThread: loop starting");
+                continue;
+            }
+            if (mActiveTrack != 0) {
+                if (mActiveTrack->mState == TrackBase::PAUSING) {
+                    if (!mStandby) {
+                        mInput->standby();
+                        mStandby = true;
+                    }
+                    mActiveTrack.clear();
+                    mStartStopCond.broadcast();
+                } else if (mActiveTrack->mState == TrackBase::RESUMING) {
+                    if (mReqChannelCount != mActiveTrack->channelCount()) {
+                        mActiveTrack.clear();
+                        mStartStopCond.broadcast();
+                    } else if (mBytesRead != 0) {
+                        // record start succeeds only if first read from audio input
+                        // succeeds
+                        if (mBytesRead > 0) {
+                            mActiveTrack->mState = TrackBase::ACTIVE;
+                        } else {
+                            mActiveTrack.clear();
+                        }
+                        mStartStopCond.broadcast();
+                    }
+                    mStandby = false;
+                }
+            }
+        }
+
+        if (mActiveTrack != 0) {
+            if (mActiveTrack->mState != TrackBase::ACTIVE &&
+                mActiveTrack->mState != TrackBase::RESUMING) {
+                usleep(5000);
+                continue;
+            }
+            buffer.frameCount = mFrameCount;
+            if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+                size_t framesOut = buffer.frameCount;
+                if (mResampler == 0) {
+                    // no resampling
+                    while (framesOut) {
+                        size_t framesIn = mFrameCount - mRsmpInIndex;
+                        if (framesIn) {
+                            int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
+                            int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) * mActiveTrack->mCblk->frameSize;
+                            if (framesIn > framesOut)
+                                framesIn = framesOut;
+                            mRsmpInIndex += framesIn;
+                            framesOut -= framesIn;
+                            if (mChannelCount == mReqChannelCount ||
+                                mFormat != AudioSystem::PCM_16_BIT) {
+                                memcpy(dst, src, framesIn * mFrameSize);
+                            } else {
+                                int16_t *src16 = (int16_t *)src;
+                                int16_t *dst16 = (int16_t *)dst;
+                                if (mChannelCount == 1) {
+                                    while (framesIn--) {
+                                        *dst16++ = *src16;
+                                        *dst16++ = *src16++;
+                                    }
+                                } else {
+                                    while (framesIn--) {
+                                        *dst16++ = (int16_t)(((int32_t)*src16 + (int32_t)*(src16 + 1)) >> 1);
+                                        src16 += 2;
+                                    }
+                                }
+                            }
+                        }
+                        if (framesOut && mFrameCount == mRsmpInIndex) {
+                            if (framesOut == mFrameCount &&
+                                (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
+                                mBytesRead = mInput->read(buffer.raw, mInputBytes);
+                                framesOut = 0;
+                            } else {
+                                mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+                                mRsmpInIndex = 0;
+                            }
+                            if (mBytesRead < 0) {
+                                LOGE("Error reading audio input");
+                                if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                                    // Force input into standby so that it tries to
+                                    // recover at next read attempt
+                                    mInput->standby();
+                                    usleep(5000);
+                                }
+                                mRsmpInIndex = mFrameCount;
+                                framesOut = 0;
+                                buffer.frameCount = 0;
+                            }
+                        }
+                    }
+                } else {
+                    // resampling
+
+                    memset(mRsmpOutBuffer, 0, framesOut * 2 * sizeof(int32_t));
+                    // alter output frame count as if we were expecting stereo samples
+                    if (mChannelCount == 1 && mReqChannelCount == 1) {
+                        framesOut >>= 1;
+                    }
+                    mResampler->resample(mRsmpOutBuffer, framesOut, this);
+                    // ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer()
+                    // are 32 bit aligned which should be always true.
+                    if (mChannelCount == 2 && mReqChannelCount == 1) {
+                        AudioMixer::ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
+                        // the resampler always outputs stereo samples: do post stereo to mono conversion
+                        int16_t *src = (int16_t *)mRsmpOutBuffer;
+                        int16_t *dst = buffer.i16;
+                        while (framesOut--) {
+                            *dst++ = (int16_t)(((int32_t)*src + (int32_t)*(src + 1)) >> 1);
+                            src += 2;
+                        }
+                    } else {
+                        AudioMixer::ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut);
+                    }
+
+                }
+                mActiveTrack->releaseBuffer(&buffer);
+                mActiveTrack->overflow();
+            }
+            // client isn't retrieving buffers fast enough
+            else {
+                if (!mActiveTrack->setOverflow())
+                    LOGW("RecordThread: buffer overflow");
+                // Release the processor for a while before asking for a new buffer.
+                // This will give the application more chance to read from the buffer and
+                // clear the overflow.
+                usleep(5000);
+            }
+        }
+    }
+
+    if (!mStandby) {
+        mInput->standby();
+    }
+    mActiveTrack.clear();
+
+    mStartStopCond.broadcast();
+
+    LOGV("RecordThread %p exiting", this);
+    return false;
+}
+
+status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
+{
+    LOGV("RecordThread::start");
+    sp <ThreadBase> strongMe = this;
+    status_t status = NO_ERROR;
+    {
+        AutoMutex lock(&mLock);
+        if (mActiveTrack != 0) {
+            if (recordTrack != mActiveTrack.get()) {
+                status = -EBUSY;
+            } else if (mActiveTrack->mState == TrackBase::PAUSING) {
+                mActiveTrack->mState = TrackBase::ACTIVE;
+            }
+            return status;
+        }
+
+        recordTrack->mState = TrackBase::IDLE;
+        mActiveTrack = recordTrack;
+        mLock.unlock();
+        status_t status = AudioSystem::startInput(mId);
+        mLock.lock();
+        if (status != NO_ERROR) {
+            mActiveTrack.clear();
+            return status;
+        }
+        mActiveTrack->mState = TrackBase::RESUMING;
+        mRsmpInIndex = mFrameCount;
+        mBytesRead = 0;
+        // signal thread to start
+        LOGV("Signal record thread");
+        mWaitWorkCV.signal();
+        // do not wait for mStartStopCond if exiting
+        if (mExiting) {
+            mActiveTrack.clear();
+            status = INVALID_OPERATION;
+            goto startError;
+        }
+        mStartStopCond.wait(mLock);
+        if (mActiveTrack == 0) {
+            LOGV("Record failed to start");
+            status = BAD_VALUE;
+            goto startError;
+        }
+        LOGV("Record started OK");
+        return status;
+    }
+startError:
+    AudioSystem::stopInput(mId);
+    return status;
+}
+
+void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
+    LOGV("RecordThread::stop");
+    sp <ThreadBase> strongMe = this;
+    {
+        AutoMutex lock(&mLock);
+        if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
+            mActiveTrack->mState = TrackBase::PAUSING;
+            // do not wait for mStartStopCond if exiting
+            if (mExiting) {
+                return;
+            }
+            mStartStopCond.wait(mLock);
+            // if we have been restarted, recordTrack == mActiveTrack.get() here
+            if (mActiveTrack == 0 || recordTrack != mActiveTrack.get()) {
+                mLock.unlock();
+                AudioSystem::stopInput(mId);
+                mLock.lock();
+                LOGV("Record stopped OK");
+            }
+        }
+    }
+}
+
+status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    pid_t pid = 0;
+
+    snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
+    result.append(buffer);
+
+    if (mActiveTrack != 0) {
+        result.append("Active Track:\n");
+        result.append("   Clien Fmt Chn Buf  S SRate  Serv     User\n");
+        mActiveTrack->dump(buffer, SIZE);
+        result.append(buffer);
+
+        snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
+        result.append(buffer);
+        snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
+        result.append(buffer);
+        snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0));
+        result.append(buffer);
+        snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
+        result.append(buffer);
+        snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
+        result.append(buffer);
+
+
+    } else {
+        result.append("No record client\n");
+    }
+    write(fd, result.string(), result.size());
+
+    dumpBase(fd, args);
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    size_t framesReq = buffer->frameCount;
+    size_t framesReady = mFrameCount - mRsmpInIndex;
+    int channelCount;
+
+    if (framesReady == 0) {
+        mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+        if (mBytesRead < 0) {
+            LOGE("RecordThread::getNextBuffer() Error reading audio input");
+            if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                // Force input into standby so that it tries to
+                // recover at next read attempt
+                mInput->standby();
+                usleep(5000);
+            }
+            buffer->raw = 0;
+            buffer->frameCount = 0;
+            return NOT_ENOUGH_DATA;
+        }
+        mRsmpInIndex = 0;
+        framesReady = mFrameCount;
+    }
+
+    if (framesReq > framesReady) {
+        framesReq = framesReady;
+    }
+
+    if (mChannelCount == 1 && mReqChannelCount == 2) {
+        channelCount = 1;
+    } else {
+        channelCount = 2;
+    }
+    buffer->raw = mRsmpInBuffer + mRsmpInIndex * channelCount;
+    buffer->frameCount = framesReq;
+    return NO_ERROR;
+}
+
+void AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    mRsmpInIndex += buffer->frameCount;
+    buffer->frameCount = 0;
+}
+
+bool AudioFlinger::RecordThread::checkForNewParameters_l()
+{
+    bool reconfig = false;
+
+    while (!mNewParameters.isEmpty()) {
+        status_t status = NO_ERROR;
+        String8 keyValuePair = mNewParameters[0];
+        AudioParameter param = AudioParameter(keyValuePair);
+        int value;
+        int reqFormat = mFormat;
+        int reqSamplingRate = mReqSampleRate;
+        int reqChannelCount = mReqChannelCount;
+
+        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
+            reqSamplingRate = value;
+            reconfig = true;
+        }
+        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
+            reqFormat = value;
+            reconfig = true;
+        }
+        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
+            reqChannelCount = AudioSystem::popCount(value);
+            reconfig = true;
+        }
+        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
+            // do not accept frame count changes if tracks are open as the track buffer
+            // size depends on frame count and correct behavior would not be garantied
+            // if frame count is changed after track creation
+            if (mActiveTrack != 0) {
+                status = INVALID_OPERATION;
+            } else {
+                reconfig = true;
+            }
+        }
+        if (status == NO_ERROR) {
+            status = mInput->setParameters(keyValuePair);
+            if (status == INVALID_OPERATION) {
+               mInput->standby();
+               status = mInput->setParameters(keyValuePair);
+            }
+            if (reconfig) {
+                if (status == BAD_VALUE &&
+                    reqFormat == mInput->format() && reqFormat == AudioSystem::PCM_16_BIT &&
+                    ((int)mInput->sampleRate() <= 2 * reqSamplingRate) &&
+                    (AudioSystem::popCount(mInput->channels()) < 3) && (reqChannelCount < 3)) {
+                    status = NO_ERROR;
+                }
+                if (status == NO_ERROR) {
+                    readInputParameters();
+                    sendConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED);
+                }
+            }
+        }
+
+        mNewParameters.removeAt(0);
+
+        mParamStatus = status;
+        mParamCond.signal();
+        mWaitWorkCV.wait(mLock);
+    }
+    return reconfig;
+}
+
+String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
+{
+    return mInput->getParameters(keys);
+}
+
+void AudioFlinger::RecordThread::audioConfigChanged(int event, int param) {
+    AudioSystem::OutputDescriptor desc;
+    void *param2 = 0;
+
+    switch (event) {
+    case AudioSystem::INPUT_OPENED:
+    case AudioSystem::INPUT_CONFIG_CHANGED:
+        desc.channels = mChannelCount;
+        desc.samplingRate = mSampleRate;
+        desc.format = mFormat;
+        desc.frameCount = mFrameCount;
+        desc.latency = 0;
+        param2 = &desc;
+        break;
+
+    case AudioSystem::INPUT_CLOSED:
+    default:
+        break;
+    }
+    Mutex::Autolock _l(mAudioFlinger->mLock);
+    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
+}
+
+void AudioFlinger::RecordThread::readInputParameters()
+{
+    if (mRsmpInBuffer) delete mRsmpInBuffer;
+    if (mRsmpOutBuffer) delete mRsmpOutBuffer;
+    if (mResampler) delete mResampler;
+    mResampler = 0;
+
+    mSampleRate = mInput->sampleRate();
+    mChannelCount = AudioSystem::popCount(mInput->channels());
+    mFormat = mInput->format();
+    mFrameSize = mInput->frameSize();
+    mInputBytes = mInput->bufferSize();
+    mFrameCount = mInputBytes / mFrameSize;
+    mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
+
+    if (mSampleRate != mReqSampleRate && mChannelCount < 3 && mReqChannelCount < 3)
+    {
+        int channelCount;
+         // optmization: if mono to mono, use the resampler in stereo to stereo mode to avoid
+         // stereo to mono post process as the resampler always outputs stereo.
+        if (mChannelCount == 1 && mReqChannelCount == 2) {
+            channelCount = 1;
+        } else {
+            channelCount = 2;
+        }
+        mResampler = AudioResampler::create(16, channelCount, mReqSampleRate);
+        mResampler->setSampleRate(mSampleRate);
+        mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
+        mRsmpOutBuffer = new int32_t[mFrameCount * 2];
+
+        // optmization: if mono to mono, alter input frame count as if we were inputing stereo samples
+        if (mChannelCount == 1 && mReqChannelCount == 1) {
+            mFrameCount >>= 1;
+        }
+
+    }
+    mRsmpInIndex = mFrameCount;
+}
+
+unsigned int AudioFlinger::RecordThread::getInputFramesLost()
+{
+    return mInput->getInputFramesLost();
+}
+
+// ----------------------------------------------------------------------------
+
+int AudioFlinger::openOutput(uint32_t *pDevices,
+                                uint32_t *pSamplingRate,
+                                uint32_t *pFormat,
+                                uint32_t *pChannels,
+                                uint32_t *pLatencyMs,
+                                uint32_t flags)
+{
+    status_t status;
+    PlaybackThread *thread = NULL;
+    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
+    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
+    uint32_t format = pFormat ? *pFormat : 0;
+    uint32_t channels = pChannels ? *pChannels : 0;
+    uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
+
+    LOGV("openOutput(), Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
+            pDevices ? *pDevices : 0,
+            samplingRate,
+            format,
+            channels,
+            flags);
+
+    if (pDevices == NULL || *pDevices == 0) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+
+    AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices,
+                                                             (int *)&format,
+                                                             &channels,
+                                                             &samplingRate,
+                                                             &status);
+    LOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
+            output,
+            samplingRate,
+            format,
+            channels,
+            status);
+
+    mHardwareStatus = AUDIO_HW_IDLE;
+    if (output != 0) {
+        if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
+            (format != AudioSystem::PCM_16_BIT) ||
+            (channels != AudioSystem::CHANNEL_OUT_STEREO)) {
+            thread = new DirectOutputThread(this, output, ++mNextThreadId);
+            LOGV("openOutput() created direct output: ID %d thread %p", mNextThreadId, thread);
+        } 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);
+
+        if (pSamplingRate) *pSamplingRate = samplingRate;
+        if (pFormat) *pFormat = format;
+        if (pChannels) *pChannels = channels;
+        if (pLatencyMs) *pLatencyMs = thread->latency();
+
+        return mNextThreadId;
+    }
+
+    return 0;
+}
+
+int AudioFlinger::openDuplicateOutput(int output1, int output2)
+{
+    Mutex::Autolock _l(mLock);
+    MixerThread *thread1 = checkMixerThread_l(output1);
+    MixerThread *thread2 = checkMixerThread_l(output2);
+
+    if (thread1 == NULL || thread2 == NULL) {
+        LOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1, output2);
+        return 0;
+    }
+
+
+    DuplicatingThread *thread = new DuplicatingThread(this, thread1, ++mNextThreadId);
+    thread->addOutputTrack(thread2);
+    mPlaybackThreads.add(mNextThreadId, thread);
+    return mNextThreadId;
+}
+
+status_t AudioFlinger::closeOutput(int output)
+{
+    // keep strong reference on the playback thread so that
+    // it is not destroyed while exit() is executed
+    sp <PlaybackThread> thread;
+    {
+        Mutex::Autolock _l(mLock);
+        thread = checkPlaybackThread_l(output);
+        if (thread == NULL) {
+            return BAD_VALUE;
+        }
+
+        LOGV("closeOutput() %d", output);
+
+        if (thread->type() == PlaybackThread::MIXER) {
+            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+                if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
+                    DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
+                    dupThread->removeOutputTrack((MixerThread *)thread.get());
+                }
+            }
+        }
+        void *param2 = 0;
+        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
+        mPlaybackThreads.removeItem(output);
+    }
+    thread->exit();
+
+    if (thread->type() != PlaybackThread::DUPLICATING) {
+        mAudioHardware->closeOutputStream(thread->getOutput());
+    }
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::suspendOutput(int output)
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+
+    if (thread == NULL) {
+        return BAD_VALUE;
+    }
+
+    LOGV("suspendOutput() %d", output);
+    thread->suspend();
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::restoreOutput(int output)
+{
+    Mutex::Autolock _l(mLock);
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+
+    if (thread == NULL) {
+        return BAD_VALUE;
+    }
+
+    LOGV("restoreOutput() %d", output);
+
+    thread->restore();
+
+    return NO_ERROR;
+}
+
+int AudioFlinger::openInput(uint32_t *pDevices,
+                                uint32_t *pSamplingRate,
+                                uint32_t *pFormat,
+                                uint32_t *pChannels,
+                                uint32_t acoustics)
+{
+    status_t status;
+    RecordThread *thread = NULL;
+    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
+    uint32_t format = pFormat ? *pFormat : 0;
+    uint32_t channels = pChannels ? *pChannels : 0;
+    uint32_t reqSamplingRate = samplingRate;
+    uint32_t reqFormat = format;
+    uint32_t reqChannels = channels;
+
+    if (pDevices == NULL || *pDevices == 0) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+
+    AudioStreamIn *input = mAudioHardware->openInputStream(*pDevices,
+                                                             (int *)&format,
+                                                             &channels,
+                                                             &samplingRate,
+                                                             &status,
+                                                             (AudioSystem::audio_in_acoustics)acoustics);
+    LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d",
+            input,
+            samplingRate,
+            format,
+            channels,
+            acoustics,
+            status);
+
+    // If the input could not be opened with the requested parameters and we can handle the conversion internally,
+    // try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
+    // or stereo to mono conversions on 16 bit PCM inputs.
+    if (input == 0 && status == BAD_VALUE &&
+        reqFormat == format && format == AudioSystem::PCM_16_BIT &&
+        (samplingRate <= 2 * reqSamplingRate) &&
+        (AudioSystem::popCount(channels) < 3) && (AudioSystem::popCount(reqChannels) < 3)) {
+        LOGV("openInput() reopening with proposed sampling rate and channels");
+        input = mAudioHardware->openInputStream(*pDevices,
+                                                 (int *)&format,
+                                                 &channels,
+                                                 &samplingRate,
+                                                 &status,
+                                                 (AudioSystem::audio_in_acoustics)acoustics);
+    }
+
+    if (input != 0) {
+         // Start record thread
+        thread = new RecordThread(this, input, reqSamplingRate, reqChannels, ++mNextThreadId);
+        mRecordThreads.add(mNextThreadId, thread);
+        LOGV("openInput() created record thread: ID %d thread %p", mNextThreadId, thread);
+        if (pSamplingRate) *pSamplingRate = reqSamplingRate;
+        if (pFormat) *pFormat = format;
+        if (pChannels) *pChannels = reqChannels;
+
+        input->standby();
+
+        return mNextThreadId;
+    }
+
+    return 0;
+}
+
+status_t AudioFlinger::closeInput(int input)
+{
+    // keep strong reference on the record thread so that
+    // it is not destroyed while exit() is executed
+    sp <RecordThread> thread;
+    {
+        Mutex::Autolock _l(mLock);
+        thread = checkRecordThread_l(input);
+        if (thread == NULL) {
+            return BAD_VALUE;
+        }
+
+        LOGV("closeInput() %d", input);
+        void *param2 = 0;
+        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2);
+        mRecordThreads.removeItem(input);
+    }
+    thread->exit();
+
+    mAudioHardware->closeInputStream(thread->getInput());
+
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
+{
+    Mutex::Autolock _l(mLock);
+    MixerThread *dstThread = checkMixerThread_l(output);
+    if (dstThread == NULL) {
+        LOGW("setStreamOutput() bad output id %d", output);
+        return BAD_VALUE;
+    }
+
+    LOGV("setStreamOutput() stream %d to output %d", stream, output);
+
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+        if (thread != dstThread &&
+            thread->type() != PlaybackThread::DIRECT) {
+            MixerThread *srcThread = (MixerThread *)thread;
+            SortedVector < sp<MixerThread::Track> > tracks;
+            SortedVector < wp<MixerThread::Track> > activeTracks;
+            srcThread->getTracks(tracks, activeTracks, stream);
+            if (tracks.size()) {
+                dstThread->putTracks(tracks, activeTracks);
+            }
+        }
+    }
+
+    dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
+
+    return NO_ERROR;
+}
+
+// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
+AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const
+{
+    PlaybackThread *thread = NULL;
+    if (mPlaybackThreads.indexOfKey(output) >= 0) {
+        thread = (PlaybackThread *)mPlaybackThreads.valueFor(output).get();
+    }
+    return thread;
+}
+
+// checkMixerThread_l() must be called with AudioFlinger::mLock held
+AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const
+{
+    PlaybackThread *thread = checkPlaybackThread_l(output);
+    if (thread != NULL) {
+        if (thread->type() == PlaybackThread::DIRECT) {
+            thread = NULL;
+        }
+    }
+    return (MixerThread *)thread;
+}
+
+// checkRecordThread_l() must be called with AudioFlinger::mLock held
+AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const
+{
+    RecordThread *thread = NULL;
+    if (mRecordThreads.indexOfKey(input) >= 0) {
+        thread = (RecordThread *)mRecordThreads.valueFor(input).get();
+    }
+    return thread;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioFlinger::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+void AudioFlinger::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.audio_flinger"), new AudioFlinger());
+}
+
+}; // namespace android
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
new file mode 100644
index 0000000..739ec33
--- /dev/null
+++ b/services/audioflinger/AudioFlinger.h
@@ -0,0 +1,807 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.h
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_AUDIO_FLINGER_H
+#define ANDROID_AUDIO_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IAudioFlingerClient.h>
+#include <media/IAudioTrack.h>
+#include <media/IAudioRecord.h>
+#include <media/AudioTrack.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <binder/MemoryDealer.h>
+#include <utils/SortedVector.h>
+#include <utils/Vector.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+
+class audio_track_cblk_t;
+class AudioMixer;
+class AudioBuffer;
+class AudioResampler;
+
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+
+// ----------------------------------------------------------------------------
+
+static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+
+class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
+{
+public:
+    static void instantiate();
+
+    virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+    // IAudioFlinger interface
+    virtual sp<IAudioTrack> createTrack(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                const sp<IMemory>& sharedBuffer,
+                                int output,
+                                status_t *status);
+
+    virtual     uint32_t    sampleRate(int output) const;
+    virtual     int         channelCount(int output) const;
+    virtual     int         format(int output) const;
+    virtual     size_t      frameCount(int output) const;
+    virtual     uint32_t    latency(int output) const;
+
+    virtual     status_t    setMasterVolume(float value);
+    virtual     status_t    setMasterMute(bool muted);
+
+    virtual     float       masterVolume() const;
+    virtual     bool        masterMute() const;
+
+    virtual     status_t    setStreamVolume(int stream, float value, int output);
+    virtual     status_t    setStreamMute(int stream, bool muted);
+
+    virtual     float       streamVolume(int stream, int output) const;
+    virtual     bool        streamMute(int stream) const;
+
+    virtual     status_t    setMode(int mode);
+
+    virtual     status_t    setMicMute(bool state);
+    virtual     bool        getMicMute() const;
+
+    virtual     bool        isStreamActive(int stream) const;
+
+    virtual     status_t    setParameters(int ioHandle, const String8& keyValuePairs);
+    virtual     String8     getParameters(int ioHandle, const String8& keys);
+
+    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
+
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+    virtual     unsigned int  getInputFramesLost(int ioHandle);
+
+    virtual int openOutput(uint32_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    uint32_t *pFormat,
+                                    uint32_t *pChannels,
+                                    uint32_t *pLatencyMs,
+                                    uint32_t flags);
+
+    virtual int openDuplicateOutput(int output1, int output2);
+
+    virtual status_t closeOutput(int output);
+
+    virtual status_t suspendOutput(int output);
+
+    virtual status_t restoreOutput(int output);
+
+    virtual int openInput(uint32_t *pDevices,
+                            uint32_t *pSamplingRate,
+                            uint32_t *pFormat,
+                            uint32_t *pChannels,
+                            uint32_t acoustics);
+
+    virtual status_t closeInput(int input);
+
+    virtual status_t setStreamOutput(uint32_t stream, int output);
+
+    virtual status_t setVoiceVolume(float volume);
+
+    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);
+
+    // IBinder::DeathRecipient
+    virtual     void        binderDied(const wp<IBinder>& who);
+
+    enum hardware_call_state {
+        AUDIO_HW_IDLE = 0,
+        AUDIO_HW_INIT,
+        AUDIO_HW_OUTPUT_OPEN,
+        AUDIO_HW_OUTPUT_CLOSE,
+        AUDIO_HW_INPUT_OPEN,
+        AUDIO_HW_INPUT_CLOSE,
+        AUDIO_HW_STANDBY,
+        AUDIO_HW_SET_MASTER_VOLUME,
+        AUDIO_HW_GET_ROUTING,
+        AUDIO_HW_SET_ROUTING,
+        AUDIO_HW_GET_MODE,
+        AUDIO_HW_SET_MODE,
+        AUDIO_HW_GET_MIC_MUTE,
+        AUDIO_HW_SET_MIC_MUTE,
+        AUDIO_SET_VOICE_VOLUME,
+        AUDIO_SET_PARAMETER,
+    };
+
+    // record interface
+    virtual sp<IAudioRecord> openRecord(
+                                pid_t pid,
+                                int input,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                status_t *status);
+
+    virtual     status_t    onTransact(
+                                uint32_t code,
+                                const Parcel& data,
+                                Parcel* reply,
+                                uint32_t flags);
+
+private:
+                            AudioFlinger();
+    virtual                 ~AudioFlinger();
+
+
+    // Internal dump utilites.
+    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
+    status_t dumpClients(int fd, const Vector<String16>& args);
+    status_t dumpInternals(int fd, const Vector<String16>& args);
+
+    // --- Client ---
+    class Client : public RefBase {
+    public:
+                            Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+        virtual             ~Client();
+        const sp<MemoryDealer>&     heap() const;
+        pid_t               pid() const { return mPid; }
+        sp<AudioFlinger>    audioFlinger() { return mAudioFlinger; }
+
+    private:
+                            Client(const Client&);
+                            Client& operator = (const Client&);
+        sp<AudioFlinger>    mAudioFlinger;
+        sp<MemoryDealer>    mMemoryDealer;
+        pid_t               mPid;
+    };
+
+
+    class TrackHandle;
+    class RecordHandle;
+    class RecordThread;
+    class PlaybackThread;
+    class MixerThread;
+    class DirectOutputThread;
+    class DuplicatingThread;
+    class Track;
+    class RecordTrack;
+
+    class ThreadBase : public Thread {
+    public:
+        ThreadBase (const sp<AudioFlinger>& audioFlinger, int id);
+        virtual             ~ThreadBase();
+
+        status_t dumpBase(int fd, const Vector<String16>& args);
+
+        // base for record and playback
+        class TrackBase : public AudioBufferProvider, public RefBase {
+
+        public:
+            enum track_state {
+                IDLE,
+                TERMINATED,
+                STOPPED,
+                RESUMING,
+                ACTIVE,
+                PAUSING,
+                PAUSED
+            };
+
+            enum track_flags {
+                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
+                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+                // The upper 16 bits are used for track-specific flags.
+            };
+
+                                TrackBase(const wp<ThreadBase>& thread,
+                                        const sp<Client>& client,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~TrackBase();
+
+            virtual status_t    start() = 0;
+            virtual void        stop() = 0;
+                    sp<IMemory> getCblk() const;
+                    audio_track_cblk_t* cblk() const { return mCblk; }
+
+        protected:
+            friend class ThreadBase;
+            friend class RecordHandle;
+            friend class PlaybackThread;
+            friend class RecordThread;
+            friend class MixerThread;
+            friend class DirectOutputThread;
+
+                                TrackBase(const TrackBase&);
+                                TrackBase& operator = (const TrackBase&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+            int format() const {
+                return mFormat;
+            }
+
+            int channelCount() const ;
+
+            int sampleRate() const;
+
+            void* getBuffer(uint32_t offset, uint32_t frames) const;
+
+            bool isStopped() const {
+                return mState == STOPPED;
+            }
+
+            bool isTerminated() const {
+                return mState == TERMINATED;
+            }
+
+            bool step();
+            void reset();
+
+            wp<ThreadBase>      mThread;
+            sp<Client>          mClient;
+            sp<IMemory>         mCblkMemory;
+            audio_track_cblk_t* mCblk;
+            void*               mBuffer;
+            void*               mBufferEnd;
+            uint32_t            mFrameCount;
+            // we don't really need a lock for these
+            int                 mState;
+            int                 mClientTid;
+            uint8_t             mFormat;
+            uint32_t            mFlags;
+        };
+
+        class ConfigEvent {
+        public:
+            ConfigEvent() : mEvent(0), mParam(0) {}
+
+            int mEvent;
+            int mParam;
+        };
+
+                    uint32_t    sampleRate() const;
+                    int         channelCount() const;
+                    int         format() const;
+                    size_t      frameCount() const;
+                    void        wakeUp()    { mWaitWorkCV.broadcast(); }
+                    void        exit();
+        virtual     bool        checkForNewParameters_l() = 0;
+        virtual     status_t    setParameters(const String8& keyValuePairs);
+        virtual     String8     getParameters(const String8& keys) = 0;
+        virtual     void        audioConfigChanged(int event, int param = 0) = 0;
+                    void        sendConfigEvent(int event, int param = 0);
+                    void        sendConfigEvent_l(int event, int param = 0);
+                    void        processConfigEvents();
+                    int         id() const { return mId;}
+                    bool        standby() { return mStandby; }
+
+        mutable     Mutex                   mLock;
+
+    protected:
+
+        friend class Track;
+        friend class TrackBase;
+        friend class PlaybackThread;
+        friend class MixerThread;
+        friend class DirectOutputThread;
+        friend class DuplicatingThread;
+        friend class RecordThread;
+        friend class RecordTrack;
+
+                    Condition               mWaitWorkCV;
+                    sp<AudioFlinger>        mAudioFlinger;
+                    uint32_t                mSampleRate;
+                    size_t                  mFrameCount;
+                    int                     mChannelCount;
+                    int                     mFormat;
+                    uint32_t                mFrameSize;
+                    Condition               mParamCond;
+                    Vector<String8>         mNewParameters;
+                    status_t                mParamStatus;
+                    Vector<ConfigEvent *>   mConfigEvents;
+                    bool                    mStandby;
+                    int                     mId;
+                    bool                    mExiting;
+    };
+
+    // --- PlaybackThread ---
+    class PlaybackThread : public ThreadBase {
+    public:
+
+        enum type {
+            MIXER,
+            DIRECT,
+            DUPLICATING
+        };
+
+        enum mixer_state {
+            MIXER_IDLE,
+            MIXER_TRACKS_ENABLED,
+            MIXER_TRACKS_READY
+        };
+
+        // playback track
+        class Track : public TrackBase {
+        public:
+                                Track(  const wp<ThreadBase>& thread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~Track();
+
+                    void        dump(char* buffer, size_t size);
+            virtual status_t    start();
+            virtual void        stop();
+                    void        pause();
+
+                    void        flush();
+                    void        destroy();
+                    void        mute(bool);
+                    void        setVolume(float left, float right);
+                    int name() const {
+                        return mName;
+                    }
+
+                    int type() const {
+                        return mStreamType;
+                    }
+
+
+        protected:
+            friend class ThreadBase;
+            friend class AudioFlinger;
+            friend class TrackHandle;
+            friend class PlaybackThread;
+            friend class MixerThread;
+            friend class DirectOutputThread;
+
+                                Track(const Track&);
+                                Track& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+            bool isMuted() { return mMute; }
+            bool isPausing() const {
+                return mState == PAUSING;
+            }
+            bool isPaused() const {
+                return mState == PAUSED;
+            }
+            bool isReady() const;
+            void setPaused() { mState = PAUSED; }
+            void reset();
+
+            bool isOutputTrack() const {
+                return (mStreamType == AudioSystem::NUM_STREAM_TYPES);
+            }
+
+            // we don't really need a lock for these
+            float               mVolume[2];
+            volatile bool       mMute;
+            // FILLED state is used for suppressing volume ramp at begin of playing
+            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+            mutable uint8_t     mFillingUpStatus;
+            int8_t              mRetryCount;
+            sp<IMemory>         mSharedBuffer;
+            bool                mResetDone;
+            int                 mStreamType;
+            int                 mName;
+        };  // end of Track
+
+
+        // playback track
+        class OutputTrack : public Track {
+        public:
+
+            class Buffer: public AudioBufferProvider::Buffer {
+            public:
+                int16_t *mBuffer;
+            };
+
+                                OutputTrack(  const wp<ThreadBase>& thread,
+                                        DuplicatingThread *sourceThread,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~OutputTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+                    bool        write(int16_t* data, uint32_t frames);
+                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
+                    bool        isActive() { return mActive; }
+            wp<ThreadBase>&     thread()  { return mThread; }
+
+        private:
+
+            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs);
+            void                clearBufferQueue();
+
+            // Maximum number of pending buffers allocated by OutputTrack::write()
+            static const uint8_t kMaxOverFlowBuffers = 10;
+
+            Vector < Buffer* >          mBufferQueue;
+            AudioBufferProvider::Buffer mOutBuffer;
+            bool                        mActive;
+            DuplicatingThread*          mSourceThread;
+        };  // end of OutputTrack
+
+        PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
+        virtual             ~PlaybackThread();
+
+        virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+        // Thread virtuals
+        virtual     status_t    readyToRun();
+        virtual     void        onFirstRef();
+
+        virtual     uint32_t    latency() const;
+
+        virtual     status_t    setMasterVolume(float value);
+        virtual     status_t    setMasterMute(bool muted);
+
+        virtual     float       masterVolume() const;
+        virtual     bool        masterMute() const;
+
+        virtual     status_t    setStreamVolume(int stream, float value);
+        virtual     status_t    setStreamMute(int stream, bool muted);
+
+        virtual     float       streamVolume(int stream) const;
+        virtual     bool        streamMute(int stream) const;
+
+                    bool        isStreamActive(int stream) const;
+
+                    sp<Track>   createTrack_l(
+                                    const sp<AudioFlinger::Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int frameCount,
+                                    const sp<IMemory>& sharedBuffer,
+                                    status_t *status);
+
+                    AudioStreamOut* getOutput() { return mOutput; }
+
+        virtual     int         type() const { return mType; }
+                    void        suspend() { mSuspended++; }
+                    void        restore() { if (mSuspended) mSuspended--; }
+                    bool        isSuspended() { return (mSuspended != 0); }
+        virtual     String8     getParameters(const String8& keys);
+        virtual     void        audioConfigChanged(int event, int param = 0);
+        virtual     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
+
+        struct  stream_type_t {
+            stream_type_t()
+                :   volume(1.0f),
+                    mute(false)
+            {
+            }
+            float       volume;
+            bool        mute;
+        };
+
+    protected:
+        int                             mType;
+        int16_t*                        mMixBuffer;
+        int                             mSuspended;
+        int                             mBytesWritten;
+        bool                            mMasterMute;
+        SortedVector< wp<Track> >       mActiveTracks;
+
+        virtual int             getTrackName_l() = 0;
+        virtual void            deleteTrackName_l(int name) = 0;
+        virtual uint32_t        activeSleepTimeUs() = 0;
+        virtual uint32_t        idleSleepTimeUs() = 0;
+
+    private:
+
+        friend class AudioFlinger;
+        friend class OutputTrack;
+        friend class Track;
+        friend class TrackBase;
+        friend class MixerThread;
+        friend class DirectOutputThread;
+        friend class DuplicatingThread;
+
+        PlaybackThread(const Client&);
+        PlaybackThread& operator = (const PlaybackThread&);
+
+        status_t    addTrack_l(const sp<Track>& track);
+        void        destroyTrack_l(const sp<Track>& track);
+
+        void        readOutputParameters();
+
+        virtual status_t    dumpInternals(int fd, const Vector<String16>& args);
+        status_t    dumpTracks(int fd, const Vector<String16>& args);
+
+        SortedVector< sp<Track> >       mTracks;
+        // mStreamTypes[] uses 1 additionnal stream type internally for the OutputTrack used by DuplicatingThread
+        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES + 1];
+        AudioStreamOut*                 mOutput;
+        float                           mMasterVolume;
+        nsecs_t                         mLastWriteTime;
+        int                             mNumWrites;
+        int                             mNumDelayedWrites;
+        bool                            mInWrite;
+    };
+
+    class MixerThread : public PlaybackThread {
+    public:
+        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
+        virtual             ~MixerThread();
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+
+                    void        getTracks(SortedVector < sp<Track> >& tracks,
+                                      SortedVector < wp<Track> >& activeTracks,
+                                      int streamType);
+                    void        putTracks(SortedVector < sp<Track> >& tracks,
+                                      SortedVector < wp<Track> >& activeTracks);
+        virtual     bool        checkForNewParameters_l();
+        virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
+
+    protected:
+                    uint32_t    prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove);
+        virtual     int         getTrackName_l();
+        virtual     void        deleteTrackName_l(int name);
+        virtual     uint32_t    activeSleepTimeUs();
+        virtual     uint32_t    idleSleepTimeUs();
+
+        AudioMixer*                     mAudioMixer;
+    };
+
+    class DirectOutputThread : public PlaybackThread {
+    public:
+
+        DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
+        ~DirectOutputThread();
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+
+        virtual     bool        checkForNewParameters_l();
+
+    protected:
+        virtual     int         getTrackName_l();
+        virtual     void        deleteTrackName_l(int name);
+        virtual     uint32_t    activeSleepTimeUs();
+        virtual     uint32_t    idleSleepTimeUs();
+
+    private:
+        float mLeftVolume;
+        float mRightVolume;
+    };
+
+    class DuplicatingThread : public MixerThread {
+    public:
+        DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id);
+        ~DuplicatingThread();
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+                    void        addOutputTrack(MixerThread* thread);
+                    void        removeOutputTrack(MixerThread* thread);
+                    uint32_t    waitTimeMs() { return mWaitTimeMs; }
+    protected:
+        virtual     uint32_t    activeSleepTimeUs();
+
+    private:
+                    bool        outputsReady(SortedVector< sp<OutputTrack> > &outputTracks);
+                    void        updateWaitTime();
+
+        SortedVector < sp<OutputTrack> >  mOutputTracks;
+                    uint32_t    mWaitTimeMs;
+    };
+
+              PlaybackThread *checkPlaybackThread_l(int output) const;
+              MixerThread *checkMixerThread_l(int output) const;
+              RecordThread *checkRecordThread_l(int input) const;
+              float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
+              void audioConfigChanged_l(int event, int ioHandle, void *param2);
+
+    friend class AudioBuffer;
+
+    class TrackHandle : public android::BnAudioTrack {
+    public:
+                            TrackHandle(const sp<PlaybackThread::Track>& track);
+        virtual             ~TrackHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual void        flush();
+        virtual void        mute(bool);
+        virtual void        pause();
+        virtual void        setVolume(float left, float right);
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<PlaybackThread::Track> mTrack;
+    };
+
+    friend class Client;
+    friend class PlaybackThread::Track;
+
+
+                void        removeClient_l(pid_t pid);
+
+
+    // record thread
+    class RecordThread : public ThreadBase, public AudioBufferProvider
+    {
+    public:
+
+        // record track
+        class RecordTrack : public TrackBase {
+        public:
+                                RecordTrack(const wp<ThreadBase>& thread,
+                                        const sp<Client>& client,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags);
+                                ~RecordTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+
+                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
+                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+
+                    void        dump(char* buffer, size_t size);
+        private:
+            friend class AudioFlinger;
+            friend class RecordThread;
+
+                                RecordTrack(const RecordTrack&);
+                                RecordTrack& operator = (const RecordTrack&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool                mOverflow;
+        };
+
+
+                RecordThread(const sp<AudioFlinger>& audioFlinger,
+                        AudioStreamIn *input,
+                        uint32_t sampleRate,
+                        uint32_t channels,
+                        int id);
+                ~RecordThread();
+
+        virtual bool        threadLoop();
+        virtual status_t    readyToRun() { return NO_ERROR; }
+        virtual void        onFirstRef();
+
+                status_t    start(RecordTrack* recordTrack);
+                void        stop(RecordTrack* recordTrack);
+                status_t    dump(int fd, const Vector<String16>& args);
+                AudioStreamIn* getInput() { return mInput; }
+
+        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer);
+        virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer);
+        virtual bool        checkForNewParameters_l();
+        virtual String8     getParameters(const String8& keys);
+        virtual void        audioConfigChanged(int event, int param = 0);
+                void        readInputParameters();
+        virtual unsigned int  getInputFramesLost();
+
+    private:
+                RecordThread();
+                AudioStreamIn                       *mInput;
+                sp<RecordTrack>                     mActiveTrack;
+                Condition                           mStartStopCond;
+                AudioResampler                      *mResampler;
+                int32_t                             *mRsmpOutBuffer;
+                int16_t                             *mRsmpInBuffer;
+                size_t                              mRsmpInIndex;
+                size_t                              mInputBytes;
+                int                                 mReqChannelCount;
+                uint32_t                            mReqSampleRate;
+                ssize_t                             mBytesRead;
+    };
+
+    class RecordHandle : public android::BnAudioRecord {
+    public:
+        RecordHandle(const sp<RecordThread::RecordTrack>& recordTrack);
+        virtual             ~RecordHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<RecordThread::RecordTrack> mRecordTrack;
+    };
+
+    friend class RecordThread;
+    friend class PlaybackThread;
+
+
+    mutable     Mutex                               mLock;
+
+                DefaultKeyedVector< pid_t, wp<Client> >     mClients;
+
+                mutable     Mutex                   mHardwareLock;
+                AudioHardwareInterface*             mAudioHardware;
+    mutable     int                                 mHardwareStatus;
+
+
+                DefaultKeyedVector< int, sp<PlaybackThread> >  mPlaybackThreads;
+                PlaybackThread::stream_type_t       mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+                float                               mMasterVolume;
+                bool                                mMasterMute;
+
+                DefaultKeyedVector< int, sp<RecordThread> >    mRecordThreads;
+
+                SortedVector< sp<IBinder> >         mNotificationClients;
+                int                                 mNextThreadId;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/services/audioflinger/AudioHardwareGeneric.cpp b/services/audioflinger/AudioHardwareGeneric.cpp
new file mode 100644
index 0000000..d63c031
--- /dev/null
+++ b/services/audioflinger/AudioHardwareGeneric.cpp
@@ -0,0 +1,411 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#define LOG_TAG "AudioHardware"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareGeneric.h"
+#include <media/AudioRecord.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static char const * const kAudioDeviceName = "/dev/eac";
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareGeneric::AudioHardwareGeneric()
+    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
+{
+    mFd = ::open(kAudioDeviceName, O_RDWR);
+}
+
+AudioHardwareGeneric::~AudioHardwareGeneric()
+{
+    if (mFd >= 0) ::close(mFd);
+    closeOutputStream((AudioStreamOut *)mOutput);
+    closeInputStream((AudioStreamIn *)mInput);
+}
+
+status_t AudioHardwareGeneric::initCheck()
+{
+    if (mFd >= 0) {
+        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
+            return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+AudioStreamOut* AudioHardwareGeneric::openOutputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
+{
+    AutoMutex lock(mLock);
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
+    status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    return mOutput;
+}
+
+void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
+    if (mOutput && out == mOutput) {
+        delete mOutput;
+        mOutput = 0;
+    }
+}
+
+AudioStreamIn* AudioHardwareGeneric::openInputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
+{
+    // check for valid input source
+    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
+        return 0;
+    }
+
+    AutoMutex lock(mLock);
+
+    // only one input stream allowed
+    if (mInput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamInGeneric* in = new AudioStreamInGeneric();
+    status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mInput = in;
+    } else {
+        delete in;
+    }
+    return mInput;
+}
+
+void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
+    if (mInput && in == mInput) {
+        delete mInput;
+        mInput = 0;
+    }
+}
+
+status_t AudioHardwareGeneric::setVoiceVolume(float v)
+{
+    // Implement: set voice volume
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::setMasterVolume(float v)
+{
+    // Implement: set master volume
+    // return error - software mixer will handle it
+    return INVALID_OPERATION;
+}
+
+status_t AudioHardwareGeneric::setMicMute(bool state)
+{
+    mMicMute = state;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::getMicMute(bool* state)
+{
+    *state = mMicMute;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append("AudioHardwareGeneric::dumpInternals\n");
+    snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    if (mInput) {
+        mInput->dump(fd, args);
+    }
+    if (mOutput) {
+        mOutput->dump(fd, args);
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        uint32_t devices,
+        int *pFormat,
+        uint32_t *pChannels,
+        uint32_t *pRate)
+{
+    int lFormat = pFormat ? *pFormat : 0;
+    uint32_t lChannels = pChannels ? *pChannels : 0;
+    uint32_t lRate = pRate ? *pRate : 0;
+
+    // fix up defaults
+    if (lFormat == 0) lFormat = format();
+    if (lChannels == 0) lChannels = channels();
+    if (lRate == 0) lRate = sampleRate();
+
+    // check values
+    if ((lFormat != format()) ||
+            (lChannels != channels()) ||
+            (lRate != sampleRate())) {
+        if (pFormat) *pFormat = format();
+        if (pChannels) *pChannels = channels();
+        if (pRate) *pRate = sampleRate();
+        return BAD_VALUE;
+    }
+
+    if (pFormat) *pFormat = lFormat;
+    if (pChannels) *pChannels = lChannels;
+    if (pRate) *pRate = lRate;
+
+    mAudioHardware = hw;
+    mFd = fd;
+    mDevice = devices;
+    return NO_ERROR;
+}
+
+AudioStreamOutGeneric::~AudioStreamOutGeneric()
+{
+}
+
+ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
+{
+    Mutex::Autolock _l(mLock);
+    return ssize_t(::write(mFd, buffer, bytes));
+}
+
+status_t AudioStreamOutGeneric::standby()
+{
+    // Implement: audio hardware to standby mode
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
+{
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 key = String8(AudioParameter::keyRouting);
+    status_t status = NO_ERROR;
+    int device;
+    LOGV("setParameters() %s", keyValuePairs.string());
+
+    if (param.getInt(key, device) == NO_ERROR) {
+        mDevice = device;
+        param.remove(key);
+    }
+
+    if (param.size()) {
+        status = BAD_VALUE;
+    }
+    return status;
+}
+
+String8 AudioStreamOutGeneric::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    String8 value;
+    String8 key = String8(AudioParameter::keyRouting);
+
+    if (param.get(key, value) == NO_ERROR) {
+        param.addInt(key, (int)mDevice);
+    }
+
+    LOGV("getParameters() %s", param.toString().string());
+    return param.toString();
+}
+
+status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
+{
+    return INVALID_OPERATION;
+}
+
+// ----------------------------------------------------------------------------
+
+// record functions
+status_t AudioStreamInGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        uint32_t devices,
+        int *pFormat,
+        uint32_t *pChannels,
+        uint32_t *pRate,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
+    LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
+    // check values
+    if ((*pFormat != format()) ||
+        (*pChannels != channels()) ||
+        (*pRate != sampleRate())) {
+        LOGE("Error opening input channel");
+        *pFormat = format();
+        *pChannels = channels();
+        *pRate = sampleRate();
+        return BAD_VALUE;
+    }
+
+    mAudioHardware = hw;
+    mFd = fd;
+    mDevice = devices;
+    return NO_ERROR;
+}
+
+AudioStreamInGeneric::~AudioStreamInGeneric()
+{
+}
+
+ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
+{
+    AutoMutex lock(mLock);
+    if (mFd < 0) {
+        LOGE("Attempt to read from unopened device");
+        return NO_INIT;
+    }
+    return ::read(mFd, buffer, bytes);
+}
+
+status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
+{
+    AudioParameter param = AudioParameter(keyValuePairs);
+    String8 key = String8(AudioParameter::keyRouting);
+    status_t status = NO_ERROR;
+    int device;
+    LOGV("setParameters() %s", keyValuePairs.string());
+
+    if (param.getInt(key, device) == NO_ERROR) {
+        mDevice = device;
+        param.remove(key);
+    }
+
+    if (param.size()) {
+        status = BAD_VALUE;
+    }
+    return status;
+}
+
+String8 AudioStreamInGeneric::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    String8 value;
+    String8 key = String8(AudioParameter::keyRouting);
+
+    if (param.get(key, value) == NO_ERROR) {
+        param.addInt(key, (int)mDevice);
+    }
+
+    LOGV("getParameters() %s", param.toString().string());
+    return param.toString();
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/audioflinger/AudioHardwareGeneric.h b/services/audioflinger/AudioHardwareGeneric.h
new file mode 100644
index 0000000..aa4e78d
--- /dev/null
+++ b/services/audioflinger/AudioHardwareGeneric.h
@@ -0,0 +1,151 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_AUDIO_HARDWARE_GENERIC_H
+#define ANDROID_AUDIO_HARDWARE_GENERIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioHardwareGeneric;
+
+class AudioStreamOutGeneric : public AudioStreamOut {
+public:
+                        AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamOutGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            uint32_t devices,
+            int *pFormat,
+            uint32_t *pChannels,
+            uint32_t *pRate);
+
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual uint32_t    latency() const { return 20; }
+    virtual status_t    setVolume(float left, float right) { return INVALID_OPERATION; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+    virtual status_t    getRenderPosition(uint32_t *dspFrames);
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+    uint32_t mDevice;
+};
+
+class AudioStreamInGeneric : public AudioStreamIn {
+public:
+                        AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamInGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            uint32_t devices,
+            int *pFormat,
+            uint32_t *pChannels,
+            uint32_t *pRate,
+            AudioSystem::audio_in_acoustics acoustics);
+
+    virtual uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_IN_MONO; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setGain(float gain) { return INVALID_OPERATION; }
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    standby() { return NO_ERROR; }
+    virtual status_t    setParameters(const String8& keyValuePairs);
+    virtual String8     getParameters(const String8& keys);
+    virtual unsigned int  getInputFramesLost() const { return 0; }
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+    uint32_t mDevice;
+};
+
+
+class AudioHardwareGeneric : public AudioHardwareBase
+{
+public:
+                        AudioHardwareGeneric();
+    virtual             ~AudioHardwareGeneric();
+    virtual status_t    initCheck();
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+            uint32_t devices,
+            int *format=0,
+            uint32_t *channels=0,
+            uint32_t *sampleRate=0,
+            status_t *status=0);
+    virtual    void        closeOutputStream(AudioStreamOut* out);
+
+    virtual AudioStreamIn* openInputStream(
+            uint32_t devices,
+            int *format,
+            uint32_t *channels,
+            uint32_t *sampleRate,
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
+    virtual    void        closeInputStream(AudioStreamIn* in);
+
+            void            closeOutputStream(AudioStreamOutGeneric* out);
+            void            closeInputStream(AudioStreamInGeneric* in);
+protected:
+    virtual status_t        dump(int fd, const Vector<String16>& args);
+
+private:
+    status_t                dumpInternals(int fd, const Vector<String16>& args);
+
+    Mutex                   mLock;
+    AudioStreamOutGeneric   *mOutput;
+    AudioStreamInGeneric    *mInput;
+    int                     mFd;
+    bool                    mMicMute;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
diff --git a/services/audioflinger/AudioHardwareInterface.cpp b/services/audioflinger/AudioHardwareInterface.cpp
new file mode 100644
index 0000000..9a4a7f9
--- /dev/null
+++ b/services/audioflinger/AudioHardwareInterface.cpp
@@ -0,0 +1,182 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include <cutils/properties.h>
+#include <string.h>
+#include <unistd.h>
+//#define LOG_NDEBUG 0
+
+#define LOG_TAG "AudioHardwareInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+#include "AudioHardwareGeneric.h"
+#ifdef WITH_A2DP
+#include "A2dpAudioInterface.h"
+#endif
+
+#ifdef ENABLE_AUDIO_DUMP
+#include "AudioDumpInterface.h"
+#endif
+
+
+// change to 1 to log routing calls
+#define LOG_ROUTING_CALLS 1
+
+namespace android {
+
+#if LOG_ROUTING_CALLS
+static const char* routingModeStrings[] =
+{
+    "OUT OF RANGE",
+    "INVALID",
+    "CURRENT",
+    "NORMAL",
+    "RINGTONE",
+    "IN_CALL"
+};
+
+static const char* routeNone = "NONE";
+
+static const char* displayMode(int mode)
+{
+    if ((mode < -2) || (mode > 2))
+        return routingModeStrings[0];
+    return routingModeStrings[mode+3];
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareInterface* AudioHardwareInterface::create()
+{
+    /*
+     * FIXME: This code needs to instantiate the correct audio device
+     * interface. For now - we use compile-time switches.
+     */
+    AudioHardwareInterface* hw = 0;
+    char value[PROPERTY_VALUE_MAX];
+
+#ifdef GENERIC_AUDIO
+    hw = new AudioHardwareGeneric();
+#else
+    // if running in emulation - use the emulator driver
+    if (property_get("ro.kernel.qemu", value, 0)) {
+        LOGD("Running in emulation - using generic audio driver");
+        hw = new AudioHardwareGeneric();
+    }
+    else {
+        LOGV("Creating Vendor Specific AudioHardware");
+        hw = createAudioHardware();
+    }
+#endif
+    if (hw->initCheck() != NO_ERROR) {
+        LOGW("Using stubbed audio hardware. No sound will be produced.");
+        delete hw;
+        hw = new AudioHardwareStub();
+    }
+    
+#ifdef WITH_A2DP
+    hw = new A2dpAudioInterface(hw);
+#endif
+
+#ifdef ENABLE_AUDIO_DUMP
+    // This code adds a record of buffers in a file to write calls made by AudioFlinger.
+    // It replaces the current AudioHardwareInterface object by an intermediate one which
+    // will record buffers in a file (after sending them to hardware) for testing purpose.
+    // This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
+    // The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file.
+    LOGV("opening PCM dump interface");
+    hw = new AudioDumpInterface(hw);    // replace interface
+#endif
+    return hw;
+}
+
+AudioStreamOut::~AudioStreamOut()
+{
+}
+
+AudioStreamIn::~AudioStreamIn() {}
+
+AudioHardwareBase::AudioHardwareBase()
+{
+    mMode = 0;
+}
+
+status_t AudioHardwareBase::setMode(int mode)
+{
+#if LOG_ROUTING_CALLS
+    LOGD("setMode(%s)", displayMode(mode));
+#endif
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    if (mMode == mode)
+        return ALREADY_EXISTS;
+    mMode = mode;
+    return NO_ERROR;
+}
+
+// default implementation
+status_t AudioHardwareBase::setParameters(const String8& keyValuePairs)
+{
+    return NO_ERROR;
+}
+
+// default implementation
+String8 AudioHardwareBase::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
+}
+
+// default implementation
+size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    if (sampleRate != 8000) {
+        LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
+        return 0;
+    }
+    if (format != AudioSystem::PCM_16_BIT) {
+        LOGW("getInputBufferSize bad format: %d", format);
+        return 0;
+    }
+    if (channelCount != 1) {
+        LOGW("getInputBufferSize bad channel count: %d", channelCount);
+        return 0;
+    }
+
+    return 320;
+}
+
+status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    dump(fd, args);  // Dump the state of the concrete child.
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/audioflinger/AudioHardwareStub.cpp b/services/audioflinger/AudioHardwareStub.cpp
new file mode 100644
index 0000000..d481150
--- /dev/null
+++ b/services/audioflinger/AudioHardwareStub.cpp
@@ -0,0 +1,209 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+#include <media/AudioRecord.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
+{
+}
+
+AudioHardwareStub::~AudioHardwareStub()
+{
+}
+
+status_t AudioHardwareStub::initCheck()
+{
+    return NO_ERROR;
+}
+
+AudioStreamOut* AudioHardwareStub::openOutputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
+{
+    AudioStreamOutStub* out = new AudioStreamOutStub();
+    status_t lStatus = out->set(format, channels, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR)
+        return out;
+    delete out;
+    return 0;
+}
+
+void AudioHardwareStub::closeOutputStream(AudioStreamOut* out)
+{
+    delete out;
+}
+
+AudioStreamIn* AudioHardwareStub::openInputStream(
+        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
+{
+    // check for valid input source
+    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
+        return 0;
+    }
+
+    AudioStreamInStub* in = new AudioStreamInStub();
+    status_t lStatus = in->set(format, channels, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR)
+        return in;
+    delete in;
+    return 0;
+}
+
+void AudioHardwareStub::closeInputStream(AudioStreamIn* in)
+{
+    delete in;
+}
+
+status_t AudioHardwareStub::setVoiceVolume(float volume)
+{
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::setMasterVolume(float volume)
+{
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append("AudioHardwareStub::dumpInternals\n");
+    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate)
+{
+    if (pFormat) *pFormat = format();
+    if (pChannels) *pChannels = channels();
+    if (pRate) *pRate = sampleRate();
+
+    return NO_ERROR;
+}
+
+ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
+{
+    // fake timing for audio output
+    usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
+    return bytes;
+}
+
+status_t AudioStreamOutStub::standby()
+{
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+String8 AudioStreamOutStub::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
+}
+
+status_t AudioStreamOutStub::getRenderPosition(uint32_t *dspFrames)
+{
+    return INVALID_OPERATION;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamInStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate,
+                AudioSystem::audio_in_acoustics acoustics)
+{
+    return NO_ERROR;
+}
+
+ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
+{
+    // fake timing for audio input
+    usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
+    memset(buffer, 0, bytes);
+    return bytes;
+}
+
+status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+String8 AudioStreamInStub::getParameters(const String8& keys)
+{
+    AudioParameter param = AudioParameter(keys);
+    return param.toString();
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/audioflinger/AudioHardwareStub.h b/services/audioflinger/AudioHardwareStub.h
new file mode 100644
index 0000000..06a29de
--- /dev/null
+++ b/services/audioflinger/AudioHardwareStub.h
@@ -0,0 +1,106 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.h
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_AUDIO_HARDWARE_STUB_H
+#define ANDROID_AUDIO_HARDWARE_STUB_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioStreamOutStub : public AudioStreamOut {
+public:
+    virtual status_t    set(int *pFormat, uint32_t *pChannels, uint32_t *pRate);
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual uint32_t    latency() const { return 0; }
+    virtual status_t    setVolume(float left, float right) { return NO_ERROR; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    setParameters(const String8& keyValuePairs) { return NO_ERROR;}
+    virtual String8     getParameters(const String8& keys);
+    virtual status_t    getRenderPosition(uint32_t *dspFrames);
+};
+
+class AudioStreamInStub : public AudioStreamIn {
+public:
+    virtual status_t    set(int *pFormat, uint32_t *pChannels, uint32_t *pRate, AudioSystem::audio_in_acoustics acoustics);
+    virtual uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_IN_MONO; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setGain(float gain) { return NO_ERROR; }
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    standby() { return NO_ERROR; }
+    virtual status_t    setParameters(const String8& keyValuePairs) { return NO_ERROR;}
+    virtual String8     getParameters(const String8& keys);
+    virtual unsigned int  getInputFramesLost() const { return 0; }
+};
+
+class AudioHardwareStub : public  AudioHardwareBase
+{
+public:
+                        AudioHardwareStub();
+    virtual             ~AudioHardwareStub();
+    virtual status_t    initCheck();
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state) { mMicMute = state;  return  NO_ERROR; }
+    virtual status_t    getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                uint32_t devices,
+                                int *format=0,
+                                uint32_t *channels=0,
+                                uint32_t *sampleRate=0,
+                                status_t *status=0);
+    virtual    void        closeOutputStream(AudioStreamOut* out);
+
+    virtual AudioStreamIn* openInputStream(
+                                uint32_t devices,
+                                int *format,
+                                uint32_t *channels,
+                                uint32_t *sampleRate,
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
+    virtual    void        closeInputStream(AudioStreamIn* in);
+
+protected:
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+            bool        mMicMute;
+private:
+    status_t            dumpInternals(int fd, const Vector<String16>& args);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_STUB_H
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
new file mode 100644
index 0000000..19a442a
--- /dev/null
+++ b/services/audioflinger/AudioMixer.cpp
@@ -0,0 +1,915 @@
+/* //device/include/server/AudioFlinger/AudioMixer.cpp
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "AudioMixer"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "AudioMixer.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+static inline int16_t clamp16(int32_t sample)
+{
+    if ((sample>>15) ^ (sample>>31))
+        sample = 0x7FFF ^ (sample>>31);
+    return sample;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
+    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
+{
+    mState.enabledTracks= 0;
+    mState.needsChanged = 0;
+    mState.frameCount   = frameCount;
+    mState.outputTemp   = 0;
+    mState.resampleTemp = 0;
+    mState.hook         = process__nop;
+    track_t* t = mState.tracks;
+    for (int i=0 ; i<32 ; i++) {
+        t->needs = 0;
+        t->volume[0] = UNITY_GAIN;
+        t->volume[1] = UNITY_GAIN;
+        t->volumeInc[0] = 0;
+        t->volumeInc[1] = 0;
+        t->channelCount = 2;
+        t->enabled = 0;
+        t->format = 16;
+        t->buffer.raw = 0;
+        t->bufferProvider = 0;
+        t->hook = 0;
+        t->resampler = 0;
+        t->sampleRate = mSampleRate;
+        t->in = 0;
+        t++;
+    }
+}
+
+ AudioMixer::~AudioMixer()
+ {
+     track_t* t = mState.tracks;
+     for (int i=0 ; i<32 ; i++) {
+         delete t->resampler;
+         t++;
+     }
+     delete [] mState.outputTemp;
+     delete [] mState.resampleTemp;
+ }
+
+ int AudioMixer::getTrackName()
+ {
+    uint32_t names = mTrackNames;
+    uint32_t mask = 1;
+    int n = 0;
+    while (names & mask) {
+        mask <<= 1;
+        n++;
+    }
+    if (mask) {
+        LOGV("add track (%d)", n);
+        mTrackNames |= mask;
+        return TRACK0 + n;
+    }
+    return -1;
+ }
+
+ void AudioMixer::invalidateState(uint32_t mask)
+ {
+    if (mask) {
+        mState.needsChanged |= mask;
+        mState.hook = process__validate;
+    }
+ }
+
+ void AudioMixer::deleteTrackName(int name)
+ {
+    name -= TRACK0;
+    if (uint32_t(name) < MAX_NUM_TRACKS) {
+        LOGV("deleteTrackName(%d)", name);
+        track_t& track(mState.tracks[ name ]);
+        if (track.enabled != 0) {
+            track.enabled = 0;
+            invalidateState(1<<name);
+        }
+        if (track.resampler) {
+            // delete  the resampler
+            delete track.resampler;
+            track.resampler = 0;
+            track.sampleRate = mSampleRate;
+            invalidateState(1<<name);
+        }
+        track.volumeInc[0] = 0;
+        track.volumeInc[1] = 0;
+        mTrackNames &= ~(1<<name);
+    }
+ }
+
+status_t AudioMixer::enable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 1) {
+                mState.tracks[ mActiveTrack ].enabled = 1;
+                LOGV("enable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::disable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 0) {
+                mState.tracks[ mActiveTrack ].enabled = 0;
+                LOGV("disable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setActiveTrack(int track)
+{
+    if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
+        return BAD_VALUE;
+    }
+    mActiveTrack = track - TRACK0;
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setParameter(int target, int name, int value)
+{
+    switch (target) {
+    case TRACK:
+        if (name == CHANNEL_COUNT) {
+            if ((uint32_t(value) <= MAX_NUM_CHANNELS) && (value)) {
+                if (mState.tracks[ mActiveTrack ].channelCount != value) {
+                    mState.tracks[ mActiveTrack ].channelCount = value;
+                    LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", value);
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RESAMPLE:
+        if (name == SAMPLE_RATE) {
+            if (value > 0) {
+                track_t& track = mState.tracks[ mActiveTrack ];
+                if (track.setResampler(uint32_t(value), mSampleRate)) {
+                    LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
+                            uint32_t(value));
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RAMP_VOLUME:
+    case VOLUME:
+        if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
+            track_t& track = mState.tracks[ mActiveTrack ];
+            if (track.volume[name-VOLUME0] != value) {
+                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
+                track.volume[name-VOLUME0] = value;
+                if (target == VOLUME) {
+                    track.prevVolume[name-VOLUME0] = value << 16;
+                    track.volumeInc[name-VOLUME0] = 0;
+                } else {
+                    int32_t d = (value<<16) - track.prevVolume[name-VOLUME0];
+                    int32_t volInc = d / int32_t(mState.frameCount);
+                    track.volumeInc[name-VOLUME0] = volInc;
+                    if (volInc == 0) {
+                        track.prevVolume[name-VOLUME0] = value << 16;
+                    }
+                }
+                invalidateState(1<<mActiveTrack);
+            }
+            return NO_ERROR;
+        }
+        break;
+    }
+    return BAD_VALUE;
+}
+
+bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
+{
+    if (value!=devSampleRate || resampler) {
+        if (sampleRate != value) {
+            sampleRate = value;
+            if (resampler == 0) {
+                resampler = AudioResampler::create(
+                        format, channelCount, devSampleRate);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioMixer::track_t::doesResample() const
+{
+    return resampler != 0;
+}
+
+inline
+void AudioMixer::track_t::adjustVolumeRamp()
+{
+    for (int i=0 ; i<2 ; i++) {
+        if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
+            ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
+            volumeInc[i] = 0;
+            prevVolume[i] = volume[i]<<16;
+        }
+    }
+}
+
+
+status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+{
+    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
+    return NO_ERROR;
+}
+
+
+
+void AudioMixer::process(void* output)
+{
+    mState.hook(&mState, output);
+}
+
+
+void AudioMixer::process__validate(state_t* state, void* output)
+{
+    LOGW_IF(!state->needsChanged,
+        "in process__validate() but nothing's invalid");
+
+    uint32_t changed = state->needsChanged;
+    state->needsChanged = 0; // clear the validation flag
+
+    // recompute which tracks are enabled / disabled
+    uint32_t enabled = 0;
+    uint32_t disabled = 0;
+    while (changed) {
+        const int i = 31 - __builtin_clz(changed);
+        const uint32_t mask = 1<<i;
+        changed &= ~mask;
+        track_t& t = state->tracks[i];
+        (t.enabled ? enabled : disabled) |= mask;
+    }
+    state->enabledTracks &= ~disabled;
+    state->enabledTracks |=  enabled;
+
+    // compute everything we need...
+    int countActiveTracks = 0;
+    int all16BitsStereoNoResample = 1;
+    int resampling = 0;
+    int volumeRamp = 0;
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+
+        countActiveTracks++;
+        track_t& t = state->tracks[i];
+        uint32_t n = 0;
+        n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
+        n |= NEEDS_FORMAT_16;
+        n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
+       
+        if (t.volumeInc[0]|t.volumeInc[1]) {
+            volumeRamp = 1;
+        } else if (!t.doesResample() && t.volumeRL == 0) {
+            n |= NEEDS_MUTE_ENABLED;
+        }
+        t.needs = n;
+
+        if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
+            t.hook = track__nop;
+        } else {
+            if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+                all16BitsStereoNoResample = 0;
+                resampling = 1;
+                t.hook = track__genericResample;
+            } else {
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
+                    t.hook = track__16BitsMono;
+                    all16BitsStereoNoResample = 0;
+                }
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
+                    t.hook = track__16BitsStereo;
+                }
+            }
+        }
+    }
+
+    // select the processing hooks
+    state->hook = process__nop;
+    if (countActiveTracks) {
+        if (resampling) {
+            if (!state->outputTemp) {
+                state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            if (!state->resampleTemp) {
+                state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            state->hook = process__genericResampling;
+        } else {
+            if (state->outputTemp) {
+                delete [] state->outputTemp;
+                state->outputTemp = 0;
+            }
+            if (state->resampleTemp) {
+                delete [] state->resampleTemp;
+                state->resampleTemp = 0;
+            }
+            state->hook = process__genericNoResampling;
+            if (all16BitsStereoNoResample && !volumeRamp) {
+                if (countActiveTracks == 1) {
+                    state->hook = process__OneTrack16BitsStereoNoResampling;
+                }
+            }
+        }
+    }
+
+    LOGV("mixer configuration change: %d activeTracks (%08x) "
+        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
+        countActiveTracks, state->enabledTracks,
+        all16BitsStereoNoResample, resampling, volumeRamp);
+
+   state->hook(state, output);
+
+   // Now that the volume ramp has been done, set optimal state and
+   // track hooks for subsequent mixer process
+   if (countActiveTracks) {
+       int allMuted = 1;
+       uint32_t en = state->enabledTracks;
+       while (en) {
+           const int i = 31 - __builtin_clz(en);
+           en &= ~(1<<i);
+           track_t& t = state->tracks[i];
+           if (!t.doesResample() && t.volumeRL == 0)
+           {
+               t.needs |= NEEDS_MUTE_ENABLED;
+               t.hook = track__nop;
+           } else {
+               allMuted = 0;
+           }
+       }
+       if (allMuted) {
+           state->hook = process__nop;
+       } else if (!resampling && all16BitsStereoNoResample) {
+           if (countActiveTracks == 1) {
+              state->hook = process__OneTrack16BitsStereoNoResampling;
+           }
+       }
+   }
+}
+
+static inline
+int32_t mulAdd(int16_t in, int16_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlabb %[out], %[in], %[v], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mul(int16_t in, int16_t v)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smulbb %[out], %[in], %[v] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v)
+         : );
+    return out;
+#else
+    return in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return a + int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smulbb %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+
+void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+    t->resampler->setSampleRate(t->sampleRate);
+
+    // ramp gain - resample to temp buffer and scale/mix in 2nd step
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
+        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
+        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
+        volumeRampStereo(t, out, outFrameCount, temp);
+    }
+
+    // constant gain
+    else {
+        t->resampler->setVolume(t->volume[0], t->volume[1]);
+        t->resampler->resample(out, outFrameCount, t->bufferProvider);
+    }
+}
+
+void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+}
+
+void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int32_t vl = t->prevVolume[0];
+    int32_t vr = t->prevVolume[1];
+    const int32_t vlInc = t->volumeInc[0];
+    const int32_t vrInc = t->volumeInc[1];
+
+    //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+    //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
+   
+    // ramp volume
+    do {
+        *out++ += (vl >> 16) * (*temp++ >> 12);
+        *out++ += (vr >> 16) * (*temp++ >> 12);
+        vl += vlInc;
+        vr += vrInc;
+    } while (--frameCount);
+
+    t->prevVolume[0] = vl;
+    t->prevVolume[1] = vr;
+    t->adjustVolumeRamp();
+}
+
+void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //        (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            *out++ += (vl >> 16) * (int32_t) *in++;
+            *out++ += (vr >> 16) * (int32_t) *in++;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+
+    // constant gain
+    else {
+        const uint32_t vrl = t->volumeRL;
+        do {
+            uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+            in += 2;
+            out[0] = mulAddRL(1, rl, vrl, out[0]);
+            out[1] = mulAddRL(0, rl, vrl, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //         (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            int32_t l = *in++;
+            *out++ += (vl >> 16) * l;
+            *out++ += (vr >> 16) * l;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+    // constant gain
+    else {
+        const int16_t vl = t->volume[0];
+        const int16_t vr = t->volume[1];
+        do {
+            int16_t l = *in++;
+            out[0] = mulAdd(l, vl, out[0]);
+            out[1] = mulAdd(l, vr, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
+{
+    for (size_t i=0 ; i<c ; i++) {
+        int32_t l = *sums++;
+        int32_t r = *sums++;
+        int32_t nl = l >> 12;
+        int32_t nr = r >> 12;
+        l = clamp16(nl);
+        r = clamp16(nr);
+        *out++ = (r<<16) | (l & 0xFFFF);
+    }
+}
+
+// no-op case
+void AudioMixer::process__nop(state_t* state, void* output)
+{
+    // this assumes output 16 bits stereo, no resampling
+    memset(output, 0, state->frameCount*4);
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        size_t outFrames = state->frameCount;
+        while (outFrames) {
+            t.buffer.frameCount = outFrames;
+            t.bufferProvider->getNextBuffer(&t.buffer);
+            if (!t.buffer.raw) break;
+            outFrames -= t.buffer.frameCount;
+            t.bufferProvider->releaseBuffer(&t.buffer);
+        }
+    }
+}
+
+// generic code without resampling
+void AudioMixer::process__genericNoResampling(state_t* state, void* output)
+{
+    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
+
+    // acquire each track's buffer
+    uint32_t enabledTracks = state->enabledTracks;
+    uint32_t en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.buffer.frameCount = state->frameCount;
+        t.bufferProvider->getNextBuffer(&t.buffer);
+        t.frameCount = t.buffer.frameCount;
+        t.in = t.buffer.raw;
+        // t.in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (t.in == NULL)
+            enabledTracks &= ~(1<<i);
+    }
+
+    // this assumes output 16 bits stereo, no resampling
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    do {
+        memset(outTemp, 0, sizeof(outTemp));
+
+        en = enabledTracks;
+        while (en) {
+            const int i = 31 - __builtin_clz(en);
+            en &= ~(1<<i);
+            track_t& t = state->tracks[i];
+            size_t outFrames = BLOCKSIZE;
+           
+            while (outFrames) {
+                size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
+                if (inFrames) {
+                    (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp);
+                    t.frameCount -= inFrames;
+                    outFrames -= inFrames;
+                }
+                if (t.frameCount == 0 && outFrames) {
+                    t.bufferProvider->releaseBuffer(&t.buffer);
+                    t.buffer.frameCount = numFrames - (BLOCKSIZE - outFrames);
+                    t.bufferProvider->getNextBuffer(&t.buffer);
+                    t.in = t.buffer.raw;
+                    if (t.in == NULL) {
+                        enabledTracks &= ~(1<<i);
+                        break;
+                    }
+                    t.frameCount = t.buffer.frameCount;
+                 }
+            }
+        }
+
+        ditherAndClamp(out, outTemp, BLOCKSIZE);
+        out += BLOCKSIZE;
+        numFrames -= BLOCKSIZE;
+    } while (numFrames);
+
+
+    // release each track's buffer
+    en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.bufferProvider->releaseBuffer(&t.buffer);
+    }
+}
+
+// generic code with resampling
+void AudioMixer::process__genericResampling(state_t* state, void* output)
+{
+    int32_t* const outTemp = state->outputTemp;
+    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
+    memset(outTemp, 0, size);
+
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+
+        // this is a little goofy, on the resampling case we don't
+        // acquire/release the buffers because it's done by
+        // the resampler.
+        if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+            (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
+        } else {
+
+            size_t outFrames = numFrames;
+           
+            while (outFrames) {
+                t.buffer.frameCount = outFrames;
+                t.bufferProvider->getNextBuffer(&t.buffer);
+                t.in = t.buffer.raw;
+                // t.in == NULL can happen if the track was flushed just after having
+                // been enabled for mixing.
+                if (t.in == NULL) break;
+
+                (t.hook)(&t, outTemp + (numFrames-outFrames)*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp);
+                outFrames -= t.buffer.frameCount;
+                t.bufferProvider->releaseBuffer(&t.buffer);
+            }
+        }
+    }
+
+    ditherAndClamp(out, outTemp, numFrames);
+}
+
+// one track, 16 bits stereo without resampling is the most common case
+void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void* output)
+{
+    const int i = 31 - __builtin_clz(state->enabledTracks);
+    const track_t& t = state->tracks[i];
+
+    AudioBufferProvider::Buffer& b(t.buffer);
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+  
+    const int16_t vl = t.volume[0];
+    const int16_t vr = t.volume[1];
+    const uint32_t vrl = t.volumeRL;
+    while (numFrames) {
+        b.frameCount = numFrames;
+        t.bufferProvider->getNextBuffer(&b);
+        int16_t const *in = b.i16;
+
+        // in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (in == NULL || ((unsigned long)in & 3)) {
+            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
+            LOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
+                    in, i, t.channelCount, t.needs);
+            return;
+        }
+        size_t outFrames = b.frameCount;
+       
+        if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
+            // volume is boosted, so we might need to clamp even though
+            // we process only one track.
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                // clamping...
+                l = clamp16(l);
+                r = clamp16(r);
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        } else {
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        }
+        numFrames -= b.frameCount;
+        t.bufferProvider->releaseBuffer(&b);
+    }
+}
+
+// 2 tracks is also a common case
+void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output)
+{
+    int i;
+    uint32_t en = state->enabledTracks;
+
+    i = 31 - __builtin_clz(en);
+    const track_t& t0 = state->tracks[i];
+    AudioBufferProvider::Buffer& b0(t0.buffer);
+
+    en &= ~(1<<i);
+    i = 31 - __builtin_clz(en);
+    const track_t& t1 = state->tracks[i];
+    AudioBufferProvider::Buffer& b1(t1.buffer);
+   
+    int16_t const *in0;
+    const int16_t vl0 = t0.volume[0];
+    const int16_t vr0 = t0.volume[1];
+    size_t frameCount0 = 0;
+  
+    int16_t const *in1;
+    const int16_t vl1 = t1.volume[0];
+    const int16_t vr1 = t1.volume[1];
+    size_t frameCount1 = 0;
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    int16_t const *buff = NULL;
+
+  
+    while (numFrames) {
+   
+        if (frameCount0 == 0) {
+            b0.frameCount = numFrames;
+            t0.bufferProvider->getNextBuffer(&b0);
+            if (b0.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in0 = buff;
+                b0.frameCount = numFrames;
+            } else {
+                in0 = b0.i16;
+            }
+            frameCount0 = b0.frameCount;
+        }
+        if (frameCount1 == 0) {
+            b1.frameCount = numFrames;
+            t1.bufferProvider->getNextBuffer(&b1);
+            if (b1.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in1 = buff;
+                b1.frameCount = numFrames;
+               } else {
+                in1 = b1.i16;
+            }
+            frameCount1 = b1.frameCount;
+        }
+       
+        size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
+
+        numFrames -= outFrames;
+        frameCount0 -= outFrames;
+        frameCount1 -= outFrames;
+       
+        do {
+            int32_t l0 = *in0++;
+            int32_t r0 = *in0++;
+            l0 = mul(l0, vl0);
+            r0 = mul(r0, vr0);
+            int32_t l = *in1++;
+            int32_t r = *in1++;
+            l = mulAdd(l, vl1, l0) >> 12;
+            r = mulAdd(r, vr1, r0) >> 12;
+            // clamping...
+            l = clamp16(l);
+            r = clamp16(r);
+            *out++ = (r<<16) | (l & 0xFFFF);
+        } while (--outFrames);
+       
+        if (frameCount0 == 0) {
+            t0.bufferProvider->releaseBuffer(&b0);
+        }
+        if (frameCount1 == 0) {
+            t1.bufferProvider->releaseBuffer(&b1);
+        }
+    }   
+       
+    if (buff != NULL) {
+        delete [] buff;       
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
new file mode 100644
index 0000000..15766cd
--- /dev/null
+++ b/services/audioflinger/AudioMixer.h
@@ -0,0 +1,193 @@
+/* //device/include/server/AudioFlinger/AudioMixer.h
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_AUDIO_MIXER_H
+#define ANDROID_AUDIO_MIXER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+
+class AudioMixer
+{
+public:
+                            AudioMixer(size_t frameCount, uint32_t sampleRate);
+
+                            ~AudioMixer();
+
+    static const uint32_t MAX_NUM_TRACKS = 32;
+    static const uint32_t MAX_NUM_CHANNELS = 2;
+
+    static const uint16_t UNITY_GAIN = 0x1000;
+
+    enum { // names
+
+        // track units (32 units)
+        TRACK0          = 0x1000,
+
+        // enable/disable
+        MIXING          = 0x2000,
+
+        // setParameter targets
+        TRACK           = 0x3000,
+        RESAMPLE        = 0x3001,
+        RAMP_VOLUME     = 0x3002, // ramp to new volume
+        VOLUME          = 0x3003, // don't ramp
+
+        // set Parameter names
+        // for target TRACK
+        CHANNEL_COUNT   = 0x4000,
+        FORMAT          = 0x4001,
+        // for TARGET RESAMPLE
+        SAMPLE_RATE     = 0x4100,
+        // for TARGET VOLUME (8 channels max)
+        VOLUME0         = 0x4200,
+        VOLUME1         = 0x4201,
+    };
+
+
+    int         getTrackName();
+    void        deleteTrackName(int name);
+
+    status_t    enable(int name);
+    status_t    disable(int name);
+
+    status_t    setActiveTrack(int track);
+    status_t    setParameter(int target, int name, int value);
+
+    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
+    void        process(void* output);
+
+    uint32_t    trackNames() const { return mTrackNames; }
+
+    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
+
+private:
+
+    enum {
+        NEEDS_CHANNEL_COUNT__MASK   = 0x00000003,
+        NEEDS_FORMAT__MASK          = 0x000000F0,
+        NEEDS_MUTE__MASK            = 0x00000100,
+        NEEDS_RESAMPLE__MASK        = 0x00001000,
+    };
+
+    enum {
+        NEEDS_CHANNEL_1             = 0x00000000,
+        NEEDS_CHANNEL_2             = 0x00000001,
+
+        NEEDS_FORMAT_16             = 0x00000010,
+
+        NEEDS_MUTE_DISABLED         = 0x00000000,
+        NEEDS_MUTE_ENABLED          = 0x00000100,
+
+        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
+        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
+    };
+
+    static inline int32_t applyVolume(int32_t in, int32_t v) {
+        return in * v;
+    }
+
+
+    struct state_t;
+
+    typedef void (*mix_t)(state_t* state, void* output);
+
+    static const int BLOCKSIZE = 16; // 4 cache lines
+
+    struct track_t {
+        uint32_t    needs;
+
+        union {
+        int16_t     volume[2];      // [0]3.12 fixed point
+        int32_t     volumeRL;
+        };
+
+        int32_t     prevVolume[2];
+
+        int32_t     volumeInc[2];
+
+        uint16_t    frameCount;
+
+        uint8_t     channelCount : 4;
+        uint8_t     enabled      : 1;
+        uint8_t     reserved0    : 3;
+        uint8_t     format;
+
+        AudioBufferProvider*                bufferProvider;
+        mutable AudioBufferProvider::Buffer buffer;
+
+        void (*hook)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp);
+        void const* in;             // current location in buffer
+
+        AudioResampler*     resampler;
+        uint32_t            sampleRate;
+
+        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
+        bool        doesResample() const;
+        void        adjustVolumeRamp();
+    };
+
+    // pad to 32-bytes to fill cache line
+    struct state_t {
+        uint32_t        enabledTracks;
+        uint32_t        needsChanged;
+        size_t          frameCount;
+        mix_t           hook;
+        int32_t         *outputTemp;
+        int32_t         *resampleTemp;
+        int32_t         reserved[2];
+        track_t         tracks[32]; __attribute__((aligned(32)));
+    };
+
+    int             mActiveTrack;
+    uint32_t        mTrackNames;
+    const uint32_t  mSampleRate;
+
+    state_t         mState __attribute__((aligned(32)));
+
+    void invalidateState(uint32_t mask);
+
+    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp);
+    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+
+    static void process__validate(state_t* state, void* output);
+    static void process__nop(state_t* state, void* output);
+    static void process__genericNoResampling(state_t* state, void* output);
+    static void process__genericResampling(state_t* state, void* output);
+    static void process__OneTrack16BitsStereoNoResampling(state_t* state, void* output);
+    static void process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_MIXER_H
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
new file mode 100644
index 0000000..c8b3f48
--- /dev/null
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -0,0 +1,1972 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioPolicyManagerBase"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <hardware_legacy/AudioPolicyManagerBase.h>
+#include <media/mediarecorder.h>
+
+namespace android {
+
+
+// ----------------------------------------------------------------------------
+// AudioPolicyInterface implementation
+// ----------------------------------------------------------------------------
+
+
+status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device,
+                                                  AudioSystem::device_connection_state state,
+                                                  const char *device_address)
+{
+
+    LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
+
+    // connect/disconnect only 1 device at a time
+    if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
+
+    if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
+        LOGE("setDeviceConnectionState() invalid address: %s", device_address);
+        return BAD_VALUE;
+    }
+
+    // handle output devices
+    if (AudioSystem::isOutputDevice(device)) {
+
+#ifndef WITH_A2DP
+        if (AudioSystem::isA2dpDevice(device)) {
+            LOGE("setDeviceConnectionState() invalid device: %x", device);
+            return BAD_VALUE;
+        }
+#endif
+
+        switch (state)
+        {
+        // handle output device connection
+        case AudioSystem::DEVICE_STATE_AVAILABLE:
+            if (mAvailableOutputDevices & device) {
+                LOGW("setDeviceConnectionState() device already connected: %x", device);
+                return INVALID_OPERATION;
+            }
+            LOGV("setDeviceConnectionState() connecting device %x", device);
+
+            // register new device as available
+            mAvailableOutputDevices |= device;
+
+#ifdef WITH_A2DP
+            // handle A2DP device connection
+            if (AudioSystem::isA2dpDevice(device)) {
+                status_t status = handleA2dpConnection(device, device_address);
+                if (status != NO_ERROR) {
+                    mAvailableOutputDevices &= ~device;
+                    return status;
+                }
+            } else
+#endif
+            {
+                if (AudioSystem::isBluetoothScoDevice(device)) {
+                    LOGV("setDeviceConnectionState() BT SCO  device, address %s", device_address);
+                    // keep track of SCO device address
+                    mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+#ifdef WITH_A2DP
+                    if (mA2dpOutput != 0 &&
+                        mPhoneState != AudioSystem::MODE_NORMAL) {
+                        mpClientInterface->suspendOutput(mA2dpOutput);
+                    }
+#endif
+                }
+            }
+            break;
+        // handle output device disconnection
+        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
+            if (!(mAvailableOutputDevices & device)) {
+                LOGW("setDeviceConnectionState() device not connected: %x", device);
+                return INVALID_OPERATION;
+            }
+
+
+            LOGV("setDeviceConnectionState() disconnecting device %x", device);
+            // remove device from available output devices
+            mAvailableOutputDevices &= ~device;
+
+#ifdef WITH_A2DP
+            // handle A2DP device disconnection
+            if (AudioSystem::isA2dpDevice(device)) {
+                status_t status = handleA2dpDisconnection(device, device_address);
+                if (status != NO_ERROR) {
+                    mAvailableOutputDevices |= device;
+                    return status;
+                }
+            } else
+#endif
+            {
+                if (AudioSystem::isBluetoothScoDevice(device)) {
+                    mScoDeviceAddress = "";
+#ifdef WITH_A2DP
+                    if (mA2dpOutput != 0 &&
+                        mPhoneState != AudioSystem::MODE_NORMAL) {
+                        mpClientInterface->restoreOutput(mA2dpOutput);
+                    }
+#endif
+                }
+            }
+            } break;
+
+        default:
+            LOGE("setDeviceConnectionState() invalid state: %x", state);
+            return BAD_VALUE;
+        }
+
+        // request routing change if necessary
+        uint32_t newDevice = getNewDevice(mHardwareOutput, false);
+#ifdef WITH_A2DP
+        checkOutputForAllStrategies(newDevice);
+        // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
+        if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
+            closeA2dpOutputs();
+        }
+#endif
+        updateDeviceForStrategy();
+        setOutputDevice(mHardwareOutput, newDevice);
+
+        if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
+            device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
+        } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
+                   device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
+                   device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
+            device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        } else {
+            return NO_ERROR;
+        }
+    }
+    // handle input devices
+    if (AudioSystem::isInputDevice(device)) {
+
+        switch (state)
+        {
+        // handle input device connection
+        case AudioSystem::DEVICE_STATE_AVAILABLE: {
+            if (mAvailableInputDevices & device) {
+                LOGW("setDeviceConnectionState() device already connected: %d", device);
+                return INVALID_OPERATION;
+            }
+            mAvailableInputDevices |= device;
+            }
+            break;
+
+        // handle input device disconnection
+        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
+            if (!(mAvailableInputDevices & device)) {
+                LOGW("setDeviceConnectionState() device not connected: %d", device);
+                return INVALID_OPERATION;
+            }
+            mAvailableInputDevices &= ~device;
+            } break;
+
+        default:
+            LOGE("setDeviceConnectionState() invalid state: %x", state);
+            return BAD_VALUE;
+        }
+
+        audio_io_handle_t activeInput = getActiveInput();
+        if (activeInput != 0) {
+            AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
+            uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
+            if (newDevice != inputDesc->mDevice) {
+                LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
+                        inputDesc->mDevice, newDevice, activeInput);
+                inputDesc->mDevice = newDevice;
+                AudioParameter param = AudioParameter();
+                param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
+                mpClientInterface->setParameters(activeInput, param.toString());
+            }
+        }
+
+        return NO_ERROR;
+    }
+
+    LOGW("setDeviceConnectionState() invalid device: %x", device);
+    return BAD_VALUE;
+}
+
+AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device,
+                                                  const char *device_address)
+{
+    AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
+    String8 address = String8(device_address);
+    if (AudioSystem::isOutputDevice(device)) {
+        if (device & mAvailableOutputDevices) {
+#ifdef WITH_A2DP
+            if (AudioSystem::isA2dpDevice(device) &&
+                address != "" && mA2dpDeviceAddress != address) {
+                return state;
+            }
+#endif
+            if (AudioSystem::isBluetoothScoDevice(device) &&
+                address != "" && mScoDeviceAddress != address) {
+                return state;
+            }
+            state = AudioSystem::DEVICE_STATE_AVAILABLE;
+        }
+    } else if (AudioSystem::isInputDevice(device)) {
+        if (device & mAvailableInputDevices) {
+            state = AudioSystem::DEVICE_STATE_AVAILABLE;
+        }
+    }
+
+    return state;
+}
+
+void AudioPolicyManagerBase::setPhoneState(int state)
+{
+    LOGV("setPhoneState() state %d", state);
+    uint32_t newDevice = 0;
+    if (state < 0 || state >= AudioSystem::NUM_MODES) {
+        LOGW("setPhoneState() invalid state %d", state);
+        return;
+    }
+
+    if (state == mPhoneState ) {
+        LOGW("setPhoneState() setting same state %d", state);
+        return;
+    }
+
+    // if leaving call state, handle special case of active streams
+    // pertaining to sonification strategy see handleIncallSonification()
+    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+        LOGV("setPhoneState() in call state management: new state is %d", state);
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, false, true);
+        }
+    }
+
+    // store previous phone state for management of sonification strategy below
+    int oldState = mPhoneState;
+    mPhoneState = state;
+    bool force = false;
+
+    // are we entering or starting a call
+    if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) {
+        LOGV("  Entering call in setPhoneState()");
+        // force routing command to audio hardware when starting a call
+        // even if no device change is needed
+        force = true;
+    } else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) {
+        LOGV("  Exiting call in setPhoneState()");
+        // force routing command to audio hardware when exiting a call
+        // even if no device change is needed
+        force = true;
+    }
+
+    // check for device and output changes triggered by new phone state
+    newDevice = getNewDevice(mHardwareOutput, false);
+#ifdef WITH_A2DP
+    checkOutputForAllStrategies(newDevice);
+    // suspend A2DP output if a SCO device is present.
+    if (mA2dpOutput != 0 && mScoDeviceAddress != "") {
+        if (oldState == AudioSystem::MODE_NORMAL) {
+            mpClientInterface->suspendOutput(mA2dpOutput);
+        } else if (state == AudioSystem::MODE_NORMAL) {
+            mpClientInterface->restoreOutput(mA2dpOutput);
+        }
+    }
+#endif
+    updateDeviceForStrategy();
+
+    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
+
+    // force routing command to audio hardware when ending call
+    // even if no device change is needed
+    if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) {
+        newDevice = hwOutputDesc->device();
+    }
+
+    // when changing from ring tone to in call mode, mute the ringing tone
+    // immediately and delay the route change to avoid sending the ring tone
+    // tail into the earpiece or headset.
+    int delayMs = 0;
+    if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
+        // delay the device change command by twice the output latency to have some margin
+        // and be sure that audio buffers not yet affected by the mute are out when
+        // we actually apply the route change
+        delayMs = hwOutputDesc->mLatency*2;
+        setStreamMute(AudioSystem::RING, true, mHardwareOutput);
+    }
+
+    // change routing is necessary
+    setOutputDevice(mHardwareOutput, newDevice, force, delayMs);
+
+    // if entering in call state, handle special case of active streams
+    // pertaining to sonification strategy see handleIncallSonification()
+    if (state == AudioSystem::MODE_IN_CALL) {
+        LOGV("setPhoneState() in call state management: new state is %d", state);
+        // unmute the ringing tone after a sufficient delay if it was muted before
+        // setting output device above
+        if (oldState == AudioSystem::MODE_RINGTONE) {
+            setStreamMute(AudioSystem::RING, false, mHardwareOutput, MUTE_TIME_MS);
+        }
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, true, true);
+        }
+    }
+
+    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
+    if (state == AudioSystem::MODE_RINGTONE &&
+        (hwOutputDesc->mRefCount[AudioSystem::MUSIC] ||
+        (systemTime() - mMusicStopTime) < seconds(SONIFICATION_HEADSET_MUSIC_DELAY))) {
+        mLimitRingtoneVolume = true;
+    } else {
+        mLimitRingtoneVolume = false;
+    }
+}
+
+void AudioPolicyManagerBase::setRingerMode(uint32_t mode, uint32_t mask)
+{
+    LOGV("setRingerMode() mode %x, mask %x", mode, mask);
+
+    mRingerMode = mode;
+}
+
+void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
+{
+    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 &&
+            config != AudioSystem::FORCE_NONE) {
+            LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
+            return;
+        }
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_MEDIA:
+        if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
+            config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) {
+            LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
+            return;
+        }
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_RECORD:
+        if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
+            config != AudioSystem::FORCE_NONE) {
+            LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
+            return;
+        }
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_DOCK:
+        if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
+            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:
+        LOGW("setForceUse() invalid usage %d", usage);
+        break;
+    }
+
+    // check for device and output changes triggered by new phone state
+    uint32_t newDevice = getNewDevice(mHardwareOutput, false);
+#ifdef WITH_A2DP
+    checkOutputForAllStrategies(newDevice);
+#endif
+    updateDeviceForStrategy();
+    setOutputDevice(mHardwareOutput, newDevice);
+    if (forceVolumeReeval) {
+        applyStreamVolumes(mHardwareOutput, newDevice);
+    }
+}
+
+AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
+{
+    return mForceUse[usage];
+}
+
+void AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value)
+{
+    LOGV("setSystemProperty() property %s, value %s", property, value);
+    if (strcmp(property, "ro.camera.sound.forced") == 0) {
+        if (atoi(value)) {
+            LOGV("ENFORCED_AUDIBLE cannot be muted");
+            mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
+        } else {
+            LOGV("ENFORCED_AUDIBLE can be muted");
+            mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
+        }
+    }
+}
+
+audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channels,
+                                    AudioSystem::output_flags flags)
+{
+    audio_io_handle_t output = 0;
+    uint32_t latency = 0;
+    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
+    uint32_t device = getDeviceForStrategy(strategy);
+    LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
+
+#ifdef AUDIO_POLICY_TEST
+    if (mCurOutput != 0) {
+        LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
+                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
+
+        if (mTestOutputs[mCurOutput] == 0) {
+            LOGV("getOutput() opening test output");
+            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+            outputDesc->mDevice = mTestDevice;
+            outputDesc->mSamplingRate = mTestSamplingRate;
+            outputDesc->mFormat = mTestFormat;
+            outputDesc->mChannels = mTestChannels;
+            outputDesc->mLatency = mTestLatencyMs;
+            outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
+            outputDesc->mRefCount[stream] = 0;
+            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                            &outputDesc->mSamplingRate,
+                                            &outputDesc->mFormat,
+                                            &outputDesc->mChannels,
+                                            &outputDesc->mLatency,
+                                            outputDesc->mFlags);
+            if (mTestOutputs[mCurOutput]) {
+                AudioParameter outputCmd = AudioParameter();
+                outputCmd.addInt(String8("set_id"),mCurOutput);
+                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
+                addOutput(mTestOutputs[mCurOutput], outputDesc);
+            }
+        }
+        return mTestOutputs[mCurOutput];
+    }
+#endif //AUDIO_POLICY_TEST
+
+    // open a direct output if required by specified parameters
+    if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
+
+        LOGV("getOutput() opening direct output device %x", device);
+        AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+        outputDesc->mDevice = device;
+        outputDesc->mSamplingRate = samplingRate;
+        outputDesc->mFormat = format;
+        outputDesc->mChannels = channels;
+        outputDesc->mLatency = 0;
+        outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
+        outputDesc->mRefCount[stream] = 0;
+        output = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                        &outputDesc->mSamplingRate,
+                                        &outputDesc->mFormat,
+                                        &outputDesc->mChannels,
+                                        &outputDesc->mLatency,
+                                        outputDesc->mFlags);
+
+        // only accept an output with the requeted parameters
+        if (output == 0 ||
+            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
+            (format != 0 && format != outputDesc->mFormat) ||
+            (channels != 0 && channels != outputDesc->mChannels)) {
+            LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
+                    samplingRate, format, channels);
+            if (output != 0) {
+                mpClientInterface->closeOutput(output);
+            }
+            delete outputDesc;
+            return 0;
+        }
+        addOutput(output, outputDesc);
+        return output;
+    }
+
+    if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
+        channels != AudioSystem::CHANNEL_OUT_STEREO) {
+        return 0;
+    }
+    // open a non direct output
+
+    // get which output is suitable for the specified stream. The actual routing change will happen
+    // when startOutput() will be called
+    uint32_t a2dpDevice = device & AudioSystem::DEVICE_OUT_ALL_A2DP;
+    if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
+#ifdef WITH_A2DP
+        if (a2dpUsedForSonification() && a2dpDevice != 0) {
+            // if playing on 2 devices among which one is A2DP, use duplicated output
+            LOGV("getOutput() using duplicated output");
+            LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
+            output = mDuplicatedOutput;
+        } else
+#endif
+        {
+            // if playing on 2 devices among which none is A2DP, use hardware output
+            output = mHardwareOutput;
+        }
+        LOGV("getOutput() using output %d for 2 devices %x", output, device);
+    } else {
+#ifdef WITH_A2DP
+        if (a2dpDevice != 0) {
+            // if playing on A2DP device, use a2dp output
+            LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
+            output = mA2dpOutput;
+        } else
+#endif
+        {
+            // if playing on not A2DP device, use hardware output
+            output = mHardwareOutput;
+        }
+    }
+
+
+    LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
+                stream, samplingRate, format, channels, flags);
+
+    return output;
+}
+
+status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+{
+    LOGV("startOutput() output %d, stream %d", output, stream);
+    ssize_t index = mOutputs.indexOfKey(output);
+    if (index < 0) {
+        LOGW("startOutput() unknow output %d", output);
+        return BAD_VALUE;
+    }
+
+    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
+
+#ifdef WITH_A2DP
+    if (mA2dpOutput != 0  && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
+        setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
+    }
+#endif
+
+    // incremenent usage count for this stream on the requested output:
+    // NOTE that the usage count is the same for duplicated output and hardware output which is
+    // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
+    outputDesc->changeRefCount(stream, 1);
+
+    setOutputDevice(output, getNewDevice(output));
+
+    // handle special case for sonification while in call
+    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+        handleIncallSonification(stream, true, false);
+    }
+
+    // apply volume rules for current stream and device if necessary
+    checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+{
+    LOGV("stopOutput() output %d, stream %d", output, stream);
+    ssize_t index = mOutputs.indexOfKey(output);
+    if (index < 0) {
+        LOGW("stopOutput() unknow output %d", output);
+        return BAD_VALUE;
+    }
+
+    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
+
+    // handle special case for sonification while in call
+    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+        handleIncallSonification(stream, false, false);
+    }
+
+    if (outputDesc->mRefCount[stream] > 0) {
+        // decrement usage count of this stream on the output
+        outputDesc->changeRefCount(stream, -1);
+        // store time at which the last music track was stopped - see computeVolume()
+        if (stream == AudioSystem::MUSIC) {
+            mMusicStopTime = systemTime();
+        }
+
+        setOutputDevice(output, getNewDevice(output));
+
+#ifdef WITH_A2DP
+        if (mA2dpOutput != 0 && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
+            setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
+        }
+#endif
+        if (output != mHardwareOutput) {
+            setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
+        }
+        return NO_ERROR;
+    } else {
+        LOGW("stopOutput() refcount is already 0 for output %d", output);
+        return INVALID_OPERATION;
+    }
+}
+
+void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output)
+{
+    LOGV("releaseOutput() %d", output);
+    ssize_t index = mOutputs.indexOfKey(output);
+    if (index < 0) {
+        LOGW("releaseOutput() releasing unknown output %d", output);
+        return;
+    }
+
+#ifdef AUDIO_POLICY_TEST
+    int testIndex = testOutputIndex(output);
+    if (testIndex != 0) {
+        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+        if (outputDesc->refCount() == 0) {
+            mpClientInterface->closeOutput(output);
+            delete mOutputs.valueAt(index);
+            mOutputs.removeItem(output);
+            mTestOutputs[testIndex] = 0;
+        }
+        return;
+    }
+#endif //AUDIO_POLICY_TEST
+
+    if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
+        mpClientInterface->closeOutput(output);
+        delete mOutputs.valueAt(index);
+        mOutputs.removeItem(output);
+    }
+}
+
+audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channels,
+                                    AudioSystem::audio_in_acoustics acoustics)
+{
+    audio_io_handle_t input = 0;
+    uint32_t device = getDeviceForInputSource(inputSource);
+
+    LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
+
+    if (device == 0) {
+        return 0;
+    }
+
+    // adapt channel selection to input source
+    switch(inputSource) {
+    case AUDIO_SOURCE_VOICE_UPLINK:
+        channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
+        break;
+    case AUDIO_SOURCE_VOICE_DOWNLINK:
+        channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
+        break;
+    case AUDIO_SOURCE_VOICE_CALL:
+        channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
+        break;
+    default:
+        break;
+    }
+
+    AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
+
+    inputDesc->mInputSource = inputSource;
+    inputDesc->mDevice = device;
+    inputDesc->mSamplingRate = samplingRate;
+    inputDesc->mFormat = format;
+    inputDesc->mChannels = channels;
+    inputDesc->mAcoustics = acoustics;
+    inputDesc->mRefCount = 0;
+    input = mpClientInterface->openInput(&inputDesc->mDevice,
+                                    &inputDesc->mSamplingRate,
+                                    &inputDesc->mFormat,
+                                    &inputDesc->mChannels,
+                                    inputDesc->mAcoustics);
+
+    // only accept input with the exact requested set of parameters
+    if (input == 0 ||
+        (samplingRate != inputDesc->mSamplingRate) ||
+        (format != inputDesc->mFormat) ||
+        (channels != inputDesc->mChannels)) {
+        LOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d",
+                samplingRate, format, channels);
+        if (input != 0) {
+            mpClientInterface->closeInput(input);
+        }
+        delete inputDesc;
+        return 0;
+    }
+    mInputs.add(input, inputDesc);
+    return input;
+}
+
+status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input)
+{
+    LOGV("startInput() input %d", input);
+    ssize_t index = mInputs.indexOfKey(input);
+    if (index < 0) {
+        LOGW("startInput() unknow input %d", input);
+        return BAD_VALUE;
+    }
+    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
+
+#ifdef AUDIO_POLICY_TEST
+    if (mTestInput == 0)
+#endif //AUDIO_POLICY_TEST
+    {
+        // refuse 2 active AudioRecord clients at the same time
+        if (getActiveInput() != 0) {
+            LOGW("startInput() input %d failed: other input already started", input);
+            return INVALID_OPERATION;
+        }
+    }
+
+    AudioParameter param = AudioParameter();
+    param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
+
+    // use Voice Recognition mode or not for this input based on input source
+    int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
+    param.addInt(String8("vr_mode"), vr_enabled);
+    LOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
+
+    mpClientInterface->setParameters(input, param.toString());
+
+    inputDesc->mRefCount = 1;
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input)
+{
+    LOGV("stopInput() input %d", input);
+    ssize_t index = mInputs.indexOfKey(input);
+    if (index < 0) {
+        LOGW("stopInput() unknow input %d", input);
+        return BAD_VALUE;
+    }
+    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
+
+    if (inputDesc->mRefCount == 0) {
+        LOGW("stopInput() input %d already stopped", input);
+        return INVALID_OPERATION;
+    } else {
+        AudioParameter param = AudioParameter();
+        param.addInt(String8(AudioParameter::keyRouting), 0);
+        mpClientInterface->setParameters(input, param.toString());
+        inputDesc->mRefCount = 0;
+        return NO_ERROR;
+    }
+}
+
+void AudioPolicyManagerBase::releaseInput(audio_io_handle_t input)
+{
+    LOGV("releaseInput() %d", input);
+    ssize_t index = mInputs.indexOfKey(input);
+    if (index < 0) {
+        LOGW("releaseInput() releasing unknown input %d", input);
+        return;
+    }
+    mpClientInterface->closeInput(input);
+    delete mInputs.valueAt(index);
+    mInputs.removeItem(input);
+    LOGV("releaseInput() exit");
+}
+
+void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream,
+                                            int indexMin,
+                                            int indexMax)
+{
+    LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
+    if (indexMin < 0 || indexMin >= indexMax) {
+        LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
+        return;
+    }
+    mStreams[stream].mIndexMin = indexMin;
+    mStreams[stream].mIndexMax = indexMax;
+}
+
+status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
+{
+
+    if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
+        return BAD_VALUE;
+    }
+
+    // Force max volume if stream cannot be muted
+    if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
+
+    LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
+    mStreams[stream].mIndexCur = index;
+
+    // compute and apply stream volume on all outputs according to connected device
+    status_t status = NO_ERROR;
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
+        if (volStatus != NO_ERROR) {
+            status = volStatus;
+        }
+    }
+    return status;
+}
+
+status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
+{
+    if (index == 0) {
+        return BAD_VALUE;
+    }
+    LOGV("getStreamVolumeIndex() stream %d", stream);
+    *index =  mStreams[stream].mIndexCur;
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManagerBase::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
+    result.append(buffer);
+#ifdef WITH_A2DP
+    snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
+    result.append(buffer);
+#endif
+    snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    snprintf(buffer, SIZE, "\nOutputs dump:\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
+        write(fd, buffer, strlen(buffer));
+        mOutputs.valueAt(i)->dump(fd);
+    }
+
+    snprintf(buffer, SIZE, "\nInputs dump:\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
+        write(fd, buffer, strlen(buffer));
+        mInputs.valueAt(i)->dump(fd);
+    }
+
+    snprintf(buffer, SIZE, "\nStreams dump:\n");
+    write(fd, buffer, strlen(buffer));
+    snprintf(buffer, SIZE, " Stream  Index Min  Index Max  Index Cur  Can be muted\n");
+    write(fd, buffer, strlen(buffer));
+    for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+        snprintf(buffer, SIZE, " %02d", i);
+        mStreams[i].dump(buffer + 3, SIZE);
+        write(fd, buffer, strlen(buffer));
+    }
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+// AudioPolicyManagerBase
+// ----------------------------------------------------------------------------
+
+AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
+    :
+#ifdef AUDIO_POLICY_TEST
+    Thread(false),
+#endif //AUDIO_POLICY_TEST
+    mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false)
+{
+    mpClientInterface = clientInterface;
+
+    for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
+        mForceUse[i] = AudioSystem::FORCE_NONE;
+    }
+
+    // devices available by default are speaker, ear piece and microphone
+    mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
+                        AudioSystem::DEVICE_OUT_SPEAKER;
+    mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
+
+#ifdef WITH_A2DP
+    mA2dpOutput = 0;
+    mDuplicatedOutput = 0;
+    mA2dpDeviceAddress = String8("");
+#endif
+    mScoDeviceAddress = String8("");
+
+    // open hardware output
+    AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+    outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
+    mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                    &outputDesc->mSamplingRate,
+                                    &outputDesc->mFormat,
+                                    &outputDesc->mChannels,
+                                    &outputDesc->mLatency,
+                                    outputDesc->mFlags);
+
+    if (mHardwareOutput == 0) {
+        LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
+                outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
+    } else {
+        addOutput(mHardwareOutput, outputDesc);
+        setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
+    }
+
+    updateDeviceForStrategy();
+#ifdef AUDIO_POLICY_TEST
+    AudioParameter outputCmd = AudioParameter();
+    outputCmd.addInt(String8("set_id"), 0);
+    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+
+    mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
+    mTestSamplingRate = 44100;
+    mTestFormat = AudioSystem::PCM_16_BIT;
+    mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
+    mTestLatencyMs = 0;
+    mCurOutput = 0;
+    mDirectOutput = false;
+    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
+        mTestOutputs[i] = 0;
+    }
+
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "AudioPolicyManagerTest");
+    run(buffer, ANDROID_PRIORITY_AUDIO);
+#endif //AUDIO_POLICY_TEST
+}
+
+AudioPolicyManagerBase::~AudioPolicyManagerBase()
+{
+#ifdef AUDIO_POLICY_TEST
+    exit();
+#endif //AUDIO_POLICY_TEST
+   for (size_t i = 0; i < mOutputs.size(); i++) {
+        mpClientInterface->closeOutput(mOutputs.keyAt(i));
+        delete mOutputs.valueAt(i);
+   }
+   mOutputs.clear();
+   for (size_t i = 0; i < mInputs.size(); i++) {
+        mpClientInterface->closeInput(mInputs.keyAt(i));
+        delete mInputs.valueAt(i);
+   }
+   mInputs.clear();
+}
+
+#ifdef AUDIO_POLICY_TEST
+bool AudioPolicyManagerBase::threadLoop()
+{
+    LOGV("entering threadLoop()");
+    while (!exitPending())
+    {
+        String8 command;
+        int valueInt;
+        String8 value;
+
+        Mutex::Autolock _l(mLock);
+        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
+
+        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
+        AudioParameter param = AudioParameter(command);
+
+        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
+            valueInt != 0) {
+            LOGV("Test command %s received", command.string());
+            String8 target;
+            if (param.get(String8("target"), target) != NO_ERROR) {
+                target = "Manager";
+            }
+            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_output"));
+                mCurOutput = valueInt;
+            }
+            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_direct"));
+                if (value == "false") {
+                    mDirectOutput = false;
+                } else if (value == "true") {
+                    mDirectOutput = true;
+                }
+            }
+            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_input"));
+                mTestInput = valueInt;
+            }
+
+            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_format"));
+                int format = AudioSystem::INVALID_FORMAT;
+                if (value == "PCM 16 bits") {
+                    format = AudioSystem::PCM_16_BIT;
+                } else if (value == "PCM 8 bits") {
+                    format = AudioSystem::PCM_8_BIT;
+                } else if (value == "Compressed MP3") {
+                    format = AudioSystem::MP3;
+                }
+                if (format != AudioSystem::INVALID_FORMAT) {
+                    if (target == "Manager") {
+                        mTestFormat = format;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("format"), format);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
+                }
+            }
+            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_channels"));
+                int channels = 0;
+
+                if (value == "Channels Stereo") {
+                    channels =  AudioSystem::CHANNEL_OUT_STEREO;
+                } else if (value == "Channels Mono") {
+                    channels =  AudioSystem::CHANNEL_OUT_MONO;
+                }
+                if (channels != 0) {
+                    if (target == "Manager") {
+                        mTestChannels = channels;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("channels"), channels);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
+                }
+            }
+            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_sampleRate"));
+                if (valueInt >= 0 && valueInt <= 96000) {
+                    int samplingRate = valueInt;
+                    if (target == "Manager") {
+                        mTestSamplingRate = samplingRate;
+                    } else if (mTestOutputs[mCurOutput] != 0) {
+                        AudioParameter outputParam = AudioParameter();
+                        outputParam.addInt(String8("sampling_rate"), samplingRate);
+                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
+                    }
+                }
+            }
+
+            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
+                param.remove(String8("test_cmd_policy_reopen"));
+
+                mpClientInterface->closeOutput(mHardwareOutput);
+                delete mOutputs.valueFor(mHardwareOutput);
+                mOutputs.removeItem(mHardwareOutput);
+
+                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+                outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
+                mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                                &outputDesc->mSamplingRate,
+                                                &outputDesc->mFormat,
+                                                &outputDesc->mChannels,
+                                                &outputDesc->mLatency,
+                                                outputDesc->mFlags);
+                if (mHardwareOutput == 0) {
+                    LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
+                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
+                } else {
+                    AudioParameter outputCmd = AudioParameter();
+                    outputCmd.addInt(String8("set_id"), 0);
+                    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+                    addOutput(mHardwareOutput, outputDesc);
+                }
+            }
+
+
+            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
+        }
+    }
+    return false;
+}
+
+void AudioPolicyManagerBase::exit()
+{
+    {
+        AutoMutex _l(mLock);
+        requestExit();
+        mWaitWorkCV.signal();
+    }
+    requestExitAndWait();
+}
+
+int AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output)
+{
+    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
+        if (output == mTestOutputs[i]) return i;
+    }
+    return 0;
+}
+#endif //AUDIO_POLICY_TEST
+
+// ---
+
+void AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc)
+{
+    outputDesc->mId = id;
+    mOutputs.add(id, outputDesc);
+}
+
+
+#ifdef WITH_A2DP
+status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices device,
+                                                 const char *device_address)
+{
+    // when an A2DP device is connected, open an A2DP and a duplicated output
+    LOGV("opening A2DP output for device %s", device_address);
+    AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
+    outputDesc->mDevice = device;
+    mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
+                                            &outputDesc->mSamplingRate,
+                                            &outputDesc->mFormat,
+                                            &outputDesc->mChannels,
+                                            &outputDesc->mLatency,
+                                            outputDesc->mFlags);
+    if (mA2dpOutput) {
+        // add A2DP output descriptor
+        addOutput(mA2dpOutput, outputDesc);
+        // set initial stream volume for A2DP device
+        applyStreamVolumes(mA2dpOutput, device);
+        if (a2dpUsedForSonification()) {
+            mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput);
+        }
+        if (mDuplicatedOutput != 0 ||
+            !a2dpUsedForSonification()) {
+            // If both A2DP and duplicated outputs are open, send device address to A2DP hardware
+            // interface
+            AudioParameter param;
+            param.add(String8("a2dp_sink_address"), String8(device_address));
+            mpClientInterface->setParameters(mA2dpOutput, param.toString());
+            mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+
+            if (a2dpUsedForSonification()) {
+                // add duplicated output descriptor
+                AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor();
+                dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput);
+                dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput);
+                dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
+                dupOutputDesc->mFormat = outputDesc->mFormat;
+                dupOutputDesc->mChannels = outputDesc->mChannels;
+                dupOutputDesc->mLatency = outputDesc->mLatency;
+                addOutput(mDuplicatedOutput, dupOutputDesc);
+                applyStreamVolumes(mDuplicatedOutput, device);
+            }
+        } else {
+            LOGW("getOutput() could not open duplicated output for %d and %d",
+                    mHardwareOutput, mA2dpOutput);
+            mpClientInterface->closeOutput(mA2dpOutput);
+            mOutputs.removeItem(mA2dpOutput);
+            mA2dpOutput = 0;
+            delete outputDesc;
+            return NO_INIT;
+        }
+    } else {
+        LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
+        delete outputDesc;
+        return NO_INIT;
+    }
+    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
+
+    if (mScoDeviceAddress != "") {
+        // It is normal to suspend twice if we are both in call,
+        // and have the hardware audio output routed to BT SCO
+        if (mPhoneState != AudioSystem::MODE_NORMAL) {
+            mpClientInterface->suspendOutput(mA2dpOutput);
+        }
+        if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
+            mpClientInterface->suspendOutput(mA2dpOutput);
+        }
+    }
+
+    if (!a2dpUsedForSonification()) {
+        // mute music on A2DP output if a notification or ringtone is playing
+        uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION);
+        for (uint32_t i = 0; i < refCount; i++) {
+            setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devices device,
+                                                    const char *device_address)
+{
+    if (mA2dpOutput == 0) {
+        LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
+        return INVALID_OPERATION;
+    }
+
+    if (mA2dpDeviceAddress != device_address) {
+        LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
+        return INVALID_OPERATION;
+    }
+
+    // mute media strategy to avoid outputting sound on hardware output while music stream
+    // is switched from A2DP output and before music is paused by music application
+    setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
+    setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, MUTE_TIME_MS);
+
+    if (!a2dpUsedForSonification()) {
+        // unmute music on A2DP output if a notification or ringtone is playing
+        uint32_t refCount = mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_SONIFICATION);
+        for (uint32_t i = 0; i < refCount; i++) {
+            setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput);
+        }
+    }
+    mA2dpDeviceAddress = "";
+    return NO_ERROR;
+}
+
+void AudioPolicyManagerBase::closeA2dpOutputs()
+{
+    LOGV("setDeviceConnectionState() closing A2DP and duplicated output!");
+
+    if (mDuplicatedOutput != 0) {
+        mpClientInterface->closeOutput(mDuplicatedOutput);
+        delete mOutputs.valueFor(mDuplicatedOutput);
+        mOutputs.removeItem(mDuplicatedOutput);
+        mDuplicatedOutput = 0;
+    }
+    if (mA2dpOutput != 0) {
+        AudioParameter param;
+        param.add(String8("closing"), String8("true"));
+        mpClientInterface->setParameters(mA2dpOutput, param.toString());
+        mpClientInterface->closeOutput(mA2dpOutput);
+        delete mOutputs.valueFor(mA2dpOutput);
+        mOutputs.removeItem(mA2dpOutput);
+        mA2dpOutput = 0;
+    }
+}
+
+void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy, uint32_t &newDevice)
+{
+    uint32_t prevDevice = getDeviceForStrategy(strategy);
+    uint32_t curDevice = getDeviceForStrategy(strategy, false);
+    bool a2dpWasUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(prevDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
+    bool a2dpIsUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(curDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
+    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
+    AudioOutputDescriptor *a2dpOutputDesc;
+
+    if (a2dpWasUsed && !a2dpIsUsed) {
+        bool dupUsed = a2dpUsedForSonification() && a2dpWasUsed && (AudioSystem::popCount(prevDevice) == 2);
+
+        if (dupUsed) {
+            LOGV("checkOutputForStrategy() moving strategy %d to duplicated", strategy);
+            a2dpOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
+        } else {
+            LOGV("checkOutputForStrategy() moving strategy %d to a2dp", strategy);
+            a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
+        }
+
+        for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+            if (getStrategy((AudioSystem::stream_type)i) == strategy) {
+                mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
+                int refCount = a2dpOutputDesc->mRefCount[i];
+                // in the case of duplicated output, the ref count is first incremented
+                // and then decremented on hardware output tus keeping its value
+                hwOutputDesc->changeRefCount((AudioSystem::stream_type)i, refCount);
+                a2dpOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
+            }
+        }
+        // do not change newDevice if it was already set before this call by a previous call to
+        // getNewDevice() or checkOutputForStrategy() for a strategy with higher priority
+        if (newDevice == 0 && hwOutputDesc->isUsedByStrategy(strategy)) {
+            newDevice = getDeviceForStrategy(strategy, false);
+        }
+    }
+    if (a2dpIsUsed && !a2dpWasUsed) {
+        bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2);
+        audio_io_handle_t a2dpOutput;
+
+        if (dupUsed) {
+            LOGV("checkOutputForStrategy() moving strategy %d from duplicated", strategy);
+            a2dpOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
+            a2dpOutput = mDuplicatedOutput;
+        } else {
+            LOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy);
+            a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
+            a2dpOutput = mA2dpOutput;
+        }
+
+        for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+            if (getStrategy((AudioSystem::stream_type)i) == strategy) {
+                mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, a2dpOutput);
+                int refCount = hwOutputDesc->mRefCount[i];
+                // in the case of duplicated output, the ref count is first incremented
+                // and then decremented on hardware output tus keeping its value
+                a2dpOutputDesc->changeRefCount((AudioSystem::stream_type)i, refCount);
+                hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
+            }
+        }
+    }
+}
+
+void AudioPolicyManagerBase::checkOutputForAllStrategies(uint32_t &newDevice)
+{
+    // Check strategies in order of priority so that once newDevice is set
+    // for a given strategy it is not modified by subsequent calls to
+    // checkOutputForStrategy()
+    checkOutputForStrategy(STRATEGY_PHONE, newDevice);
+    checkOutputForStrategy(STRATEGY_SONIFICATION, newDevice);
+    checkOutputForStrategy(STRATEGY_MEDIA, newDevice);
+    checkOutputForStrategy(STRATEGY_DTMF, newDevice);
+}
+
+#endif
+
+uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache)
+{
+    uint32_t device = 0;
+
+    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    // check the following by order of priority to request a routing change if necessary:
+    // 1: we are in call or the strategy phone is active on the hardware output:
+    //      use device for strategy phone
+    // 2: the strategy sonification is active on the hardware output:
+    //      use device for strategy sonification
+    // 3: the strategy media is active on the hardware output:
+    //      use device for strategy media
+    // 4: the strategy DTMF is active on the hardware output:
+    //      use device for strategy DTMF
+    if (mPhoneState == AudioSystem::MODE_IN_CALL ||
+        outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
+        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
+    } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
+        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
+    } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
+        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
+    } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
+        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
+    }
+
+    LOGV("getNewDevice() selected device %x", device);
+    return device;
+}
+
+AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(AudioSystem::stream_type stream)
+{
+    // stream to strategy mapping
+    switch (stream) {
+    case AudioSystem::VOICE_CALL:
+    case AudioSystem::BLUETOOTH_SCO:
+        return STRATEGY_PHONE;
+    case AudioSystem::RING:
+    case AudioSystem::NOTIFICATION:
+    case AudioSystem::ALARM:
+    case AudioSystem::ENFORCED_AUDIBLE:
+        return STRATEGY_SONIFICATION;
+    case AudioSystem::DTMF:
+        return STRATEGY_DTMF;
+    default:
+        LOGE("unknown stream type");
+    case AudioSystem::SYSTEM:
+        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
+        // while key clicks are played produces a poor result
+    case AudioSystem::TTS:
+    case AudioSystem::MUSIC:
+        return STRATEGY_MEDIA;
+    }
+}
+
+uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
+{
+    uint32_t device = 0;
+
+    if (fromCache) {
+        LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
+        return mDeviceForStrategy[strategy];
+    }
+
+    switch (strategy) {
+    case STRATEGY_DTMF:
+        if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+            // when off call, DTMF strategy follows the same rules as MEDIA strategy
+            device = getDeviceForStrategy(STRATEGY_MEDIA, false);
+            break;
+        }
+        // when in call, DTMF and PHONE strategies follow the same rules
+        // FALL THROUGH
+
+    case STRATEGY_PHONE:
+        // for phone strategy, we first consider the forced use and then the available devices by order
+        // of priority
+        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
+        case AudioSystem::FORCE_BT_SCO:
+            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
+                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                if (device) break;
+            }
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+            if (device) break;
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
+            if (device) break;
+            // if SCO device is requested but no SCO device is available, fall back to default case
+            // FALL THROUGH
+
+        default:    // FORCE_NONE
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
+            if (device) break;
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
+            if (device) break;
+#ifdef WITH_A2DP
+            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
+            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
+                if (device) break;
+                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+                if (device) break;
+            }
+#endif
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
+            if (device == 0) {
+                LOGE("getDeviceForStrategy() earpiece device not found");
+            }
+            break;
+
+        case AudioSystem::FORCE_SPEAKER:
+            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
+                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                if (device) break;
+            }
+#ifdef WITH_A2DP
+            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
+            // A2DP speaker when forcing to speaker output
+            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+                if (device) break;
+            }
+#endif
+            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
+            if (device == 0) {
+                LOGE("getDeviceForStrategy() speaker device not found");
+            }
+            break;
+        }
+    break;
+
+    case STRATEGY_SONIFICATION:
+
+        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
+        // handleIncallSonification().
+        if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+            device = getDeviceForStrategy(STRATEGY_PHONE, false);
+            break;
+        }
+        device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
+        if (device == 0) {
+            LOGE("getDeviceForStrategy() speaker device not found");
+        }
+        // The second device used for sonification is the same as the device used by media strategy
+        // FALL THROUGH
+
+    case STRATEGY_MEDIA: {
+        uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
+        if (device2 == 0) {
+            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
+        }
+        if (device2 == 0) {
+            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
+        }
+#ifdef WITH_A2DP
+        if (mA2dpOutput != 0) {
+            if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
+                break;
+            }
+            if (device2 == 0) {
+                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
+            }
+            if (device2 == 0) {
+                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+            }
+            if (device2 == 0) {
+                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+            }
+        }
+#endif
+        if (device2 == 0) {
+            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
+        }
+
+        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
+        device |= device2;
+        if (device == 0) {
+            LOGE("getDeviceForStrategy() speaker device not found");
+        }
+        } break;
+
+    default:
+        LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
+        break;
+    }
+
+    LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
+    return device;
+}
+
+void AudioPolicyManagerBase::updateDeviceForStrategy()
+{
+    for (int i = 0; i < NUM_STRATEGIES; i++) {
+        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false);
+    }
+}
+
+void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
+{
+    LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
+    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+
+
+    if (outputDesc->isDuplicated()) {
+        setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
+        setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
+        return;
+    }
+#ifdef WITH_A2DP
+    // filter devices according to output selected
+    if (output == mA2dpOutput) {
+        device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
+    } else {
+        device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
+    }
+#endif
+
+    uint32_t prevDevice = (uint32_t)outputDesc->device();
+    // Do not change the routing if:
+    //  - the requestede device is 0
+    //  - the requested device is the same as current device and force is not specified.
+    // Doing this check here allows the caller to call setOutputDevice() without conditions
+    if ((device == 0 || device == prevDevice) && !force) {
+        LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
+        return;
+    }
+
+    outputDesc->mDevice = device;
+    // mute media streams if both speaker and headset are selected
+    if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) {
+        setStrategyMute(STRATEGY_MEDIA, true, output);
+        // wait for the PCM output buffers to empty before proceeding with the rest of the command
+        usleep(outputDesc->mLatency*2*1000);
+    }
+#ifdef WITH_A2DP
+    // suspend A2DP output if SCO device is selected
+    if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
+         if (mA2dpOutput != 0) {
+             mpClientInterface->suspendOutput(mA2dpOutput);
+         }
+    }
+#endif
+    // do the routing
+    AudioParameter param = AudioParameter();
+    param.addInt(String8(AudioParameter::keyRouting), (int)device);
+    mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
+    // update stream volumes according to new device
+    applyStreamVolumes(output, device, delayMs);
+
+#ifdef WITH_A2DP
+    // if disconnecting SCO device, restore A2DP output
+    if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)prevDevice)) {
+         if (mA2dpOutput != 0) {
+             LOGV("restore A2DP output");
+             mpClientInterface->restoreOutput(mA2dpOutput);
+         }
+    }
+#endif
+    // if changing from a combined headset + speaker route, unmute media streams
+    if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {
+        setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
+    }
+}
+
+uint32_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
+{
+    uint32_t device;
+
+    switch(inputSource) {
+    case AUDIO_SOURCE_DEFAULT:
+    case AUDIO_SOURCE_MIC:
+    case AUDIO_SOURCE_VOICE_RECOGNITION:
+        if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
+            mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
+            device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
+            device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
+        } else {
+            device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
+        }
+        break;
+    case AUDIO_SOURCE_CAMCORDER:
+        if (hasBackMicrophone()) {
+            device = AudioSystem::DEVICE_IN_BACK_MIC;
+        } else {
+            device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
+        }
+        break;
+    case AUDIO_SOURCE_VOICE_UPLINK:
+    case AUDIO_SOURCE_VOICE_DOWNLINK:
+    case AUDIO_SOURCE_VOICE_CALL:
+        device = AudioSystem::DEVICE_IN_VOICE_CALL;
+        break;
+    default:
+        LOGW("getInput() invalid input source %d", inputSource);
+        device = 0;
+        break;
+    }
+    LOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
+    return device;
+}
+
+audio_io_handle_t AudioPolicyManagerBase::getActiveInput()
+{
+    for (size_t i = 0; i < mInputs.size(); i++) {
+        if (mInputs.valueAt(i)->mRefCount > 0) {
+            return mInputs.keyAt(i);
+        }
+    }
+    return 0;
+}
+
+float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
+{
+    float volume = 1.0;
+    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+    StreamDescriptor &streamDesc = mStreams[stream];
+
+    if (device == 0) {
+        device = outputDesc->device();
+    }
+
+    int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
+    volume = AudioSystem::linearToLog(volInt);
+
+    // if a headset is connected, apply the following rules to ring tones and notifications
+    // to avoid sound level bursts in user's ears:
+    // - always attenuate ring tones and notifications volume by 6dB
+    // - if music is playing, always limit the volume to current music volume,
+    // with a minimum threshold at -36dB so that notification is always perceived.
+    if ((device &
+        (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
+        AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+        AudioSystem::DEVICE_OUT_WIRED_HEADSET |
+        AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) &&
+        (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) &&
+        streamDesc.mCanBeMuted) {
+        volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
+        // when the phone is ringing we must consider that music could have been paused just before
+        // by the music application and behave as if music was active if the last music track was
+        // just stopped
+        if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) {
+            float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
+            float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
+            if (volume > minVol) {
+                volume = minVol;
+                LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
+            }
+        }
+    }
+
+    return volume;
+}
+
+status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
+{
+
+    // do not change actual stream volume if the stream is muted
+    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
+        LOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]);
+        return NO_ERROR;
+    }
+
+    // do not change in call volume if bluetooth is connected and vice versa
+    if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
+        (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
+        LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
+             stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
+        return INVALID_OPERATION;
+    }
+
+    float volume = computeVolume(stream, index, output, device);
+    // do not set volume if the float value did not change
+    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || force) {
+        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
+        LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
+        if (stream == AudioSystem::VOICE_CALL ||
+            stream == AudioSystem::DTMF ||
+            stream == AudioSystem::BLUETOOTH_SCO) {
+            float voiceVolume = -1.0;
+            // offset value to reflect actual hardware volume that never reaches 0
+            // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
+            volume = 0.01 + 0.99 * volume;
+            if (stream == AudioSystem::VOICE_CALL) {
+                voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
+            } else if (stream == AudioSystem::BLUETOOTH_SCO) {
+                voiceVolume = 1.0;
+            }
+            if (voiceVolume >= 0 && output == mHardwareOutput) {
+                mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
+            }
+        }
+        mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
+    }
+
+    return NO_ERROR;
+}
+
+void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
+{
+    LOGV("applyStreamVolumes() for output %d and device %x", output, device);
+
+    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+        checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
+    }
+}
+
+void AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
+{
+    LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
+    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+        if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
+            setStreamMute(stream, on, output, delayMs);
+        }
+    }
+}
+
+void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
+{
+    StreamDescriptor &streamDesc = mStreams[stream];
+    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+
+    LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]);
+
+    if (on) {
+        if (outputDesc->mMuteCount[stream] == 0) {
+            if (streamDesc.mCanBeMuted) {
+                checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs);
+            }
+        }
+        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
+        outputDesc->mMuteCount[stream]++;
+    } else {
+        if (outputDesc->mMuteCount[stream] == 0) {
+            LOGW("setStreamMute() unmuting non muted stream!");
+            return;
+        }
+        if (--outputDesc->mMuteCount[stream] == 0) {
+            checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs);
+        }
+    }
+}
+
+void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange)
+{
+    // if the stream pertains to sonification strategy and we are in call we must
+    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
+    // in the device used for phone strategy and play the tone if the selected device does not
+    // interfere with the device used for phone strategy
+    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
+    // many times as there are active tracks on the output
+
+    if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
+        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
+        LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
+                stream, starting, outputDesc->mDevice, stateChange);
+        if (outputDesc->mRefCount[stream]) {
+            int muteCount = 1;
+            if (stateChange) {
+                muteCount = outputDesc->mRefCount[stream];
+            }
+            if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
+                LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
+                for (int i = 0; i < muteCount; i++) {
+                    setStreamMute(stream, starting, mHardwareOutput);
+                }
+            } else {
+                LOGV("handleIncallSonification() high visibility");
+                if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) {
+                    LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
+                    for (int i = 0; i < muteCount; i++) {
+                        setStreamMute(stream, starting, mHardwareOutput);
+                    }
+                }
+                if (starting) {
+                    mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
+                } else {
+                    mpClientInterface->stopTone();
+                }
+            }
+        }
+    }
+}
+
+bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channels,
+                                    AudioSystem::output_flags flags,
+                                    uint32_t device)
+{
+   return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
+          (format !=0 && !AudioSystem::isLinearPCM(format)));
+}
+
+// --- AudioOutputDescriptor class implementation
+
+AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
+    : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
+    mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
+{
+    // clear usage count for all stream types
+    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+        mRefCount[i] = 0;
+        mCurVolume[i] = -1.0;
+        mMuteCount[i] = 0;
+    }
+}
+
+uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::device()
+{
+    uint32_t device = 0;
+    if (isDuplicated()) {
+        device = mOutput1->mDevice | mOutput2->mDevice;
+    } else {
+        device = mDevice;
+    }
+    return device;
+}
+
+void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
+{
+    // forward usage count change to attached outputs
+    if (isDuplicated()) {
+        mOutput1->changeRefCount(stream, delta);
+        mOutput2->changeRefCount(stream, delta);
+    }
+    if ((delta + (int)mRefCount[stream]) < 0) {
+        LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
+        mRefCount[stream] = 0;
+        return;
+    }
+    mRefCount[stream] += delta;
+    LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
+}
+
+uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount()
+{
+    uint32_t refcount = 0;
+    for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+        refcount += mRefCount[i];
+    }
+    return refcount;
+}
+
+uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy)
+{
+    uint32_t refCount = 0;
+    for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+        if (getStrategy((AudioSystem::stream_type)i) == strategy) {
+            refCount += mRefCount[i];
+        }
+    }
+    return refCount;
+}
+
+
+status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", device());
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
+    result.append(buffer);
+    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+// --- AudioInputDescriptor class implementation
+
+AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor()
+    : mSamplingRate(0), mFormat(0), mChannels(0),
+     mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
+{
+}
+
+status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+// --- StreamDescriptor class implementation
+
+void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "      %02d         %02d         %02d         %d\n",
+            mIndexMin,
+            mIndexMax,
+            mIndexCur,
+            mCanBeMuted);
+}
+
+
+}; // namespace android
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
new file mode 100644
index 0000000..bb3905c
--- /dev/null
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -0,0 +1,924 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioPolicyService"
+//#define LOG_NDEBUG 0
+
+#undef __STRICT_ANSI__
+#define __STDINT_LIMITS
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
+#include <sys/time.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include <cutils/properties.h>
+#include <binder/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+#include "AudioPolicyService.h"
+#include <hardware_legacy/AudioPolicyManagerBase.h>
+#include <cutils/properties.h>
+#include <dlfcn.h>
+#include <hardware_legacy/power.h>
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+namespace android {
+
+
+static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
+static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 20000;
+
+static bool checkPermission() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
+    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
+    return ok;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioPolicyService::AudioPolicyService()
+    : BnAudioPolicyService() , mpPolicyManager(NULL)
+{
+    char value[PROPERTY_VALUE_MAX];
+
+    // start tone playback thread
+    mTonePlaybackThread = new AudioCommandThread(String8(""));
+    // start audio commands thread
+    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
+
+#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
+    mpPolicyManager = new AudioPolicyManagerBase(this);
+    LOGV("build for GENERIC_AUDIO - using generic audio policy");
+#else
+    // if running in emulation - use the emulator driver
+    if (property_get("ro.kernel.qemu", value, 0)) {
+        LOGV("Running in emulation - using generic audio policy");
+        mpPolicyManager = new AudioPolicyManagerBase(this);
+    }
+    else {
+        LOGV("Using hardware specific audio policy");
+        mpPolicyManager = createAudioPolicyManager(this);
+    }
+#endif
+
+    // load properties
+    property_get("ro.camera.sound.forced", value, "0");
+    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+}
+
+AudioPolicyService::~AudioPolicyService()
+{
+    mTonePlaybackThread->exit();
+    mTonePlaybackThread.clear();
+    mAudioCommandThread->exit();
+    mAudioCommandThread.clear();
+
+    if (mpPolicyManager) {
+        delete mpPolicyManager;
+    }
+}
+
+
+status_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
+                                                  AudioSystem::device_connection_state state,
+                                                  const char *device_address)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
+        return BAD_VALUE;
+    }
+    if (state != AudioSystem::DEVICE_STATE_AVAILABLE && state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
+        return BAD_VALUE;
+    }
+
+    LOGV("setDeviceConnectionState() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
+}
+
+AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(AudioSystem::audio_devices device,
+                                                  const char *device_address)
+{
+    if (mpPolicyManager == NULL) {
+        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
+    }
+    if (!checkPermission()) {
+        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
+    }
+    return mpPolicyManager->getDeviceConnectionState(device, device_address);
+}
+
+status_t AudioPolicyService::setPhoneState(int state)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (state < 0 || state >= AudioSystem::NUM_MODES) {
+        return BAD_VALUE;
+    }
+
+    LOGV("setPhoneState() tid %d", gettid());
+
+    // TODO: check if it is more appropriate to do it in platform specific policy manager
+    AudioSystem::setMode(state);
+
+    Mutex::Autolock _l(mLock);
+    mpPolicyManager->setPhoneState(state);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+
+    mpPolicyManager->setRingerMode(mode, mask);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
+        return BAD_VALUE;
+    }
+    if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
+        return BAD_VALUE;
+    }
+    LOGV("setForceUse() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    mpPolicyManager->setForceUse(usage, config);
+    return NO_ERROR;
+}
+
+AudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
+{
+    if (mpPolicyManager == NULL) {
+        return AudioSystem::FORCE_NONE;
+    }
+    if (!checkPermission()) {
+        return AudioSystem::FORCE_NONE;
+    }
+    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
+        return AudioSystem::FORCE_NONE;
+    }
+    return mpPolicyManager->getForceUse(usage);
+}
+
+audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channels,
+                                    AudioSystem::output_flags flags)
+{
+    if (mpPolicyManager == NULL) {
+        return 0;
+    }
+    LOGV("getOutput() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
+}
+
+status_t AudioPolicyService::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    LOGV("startOutput() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->startOutput(output, stream);
+}
+
+status_t AudioPolicyService::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    LOGV("stopOutput() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->stopOutput(output, stream);
+}
+
+void AudioPolicyService::releaseOutput(audio_io_handle_t output)
+{
+    if (mpPolicyManager == NULL) {
+        return;
+    }
+    LOGV("releaseOutput() tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    mpPolicyManager->releaseOutput(output);
+}
+
+audio_io_handle_t AudioPolicyService::getInput(int inputSource,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channels,
+                                    AudioSystem::audio_in_acoustics acoustics)
+{
+    if (mpPolicyManager == NULL) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
+}
+
+status_t AudioPolicyService::startInput(audio_io_handle_t input)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->startInput(input);
+}
+
+status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpPolicyManager->stopInput(input);
+}
+
+void AudioPolicyService::releaseInput(audio_io_handle_t input)
+{
+    if (mpPolicyManager == NULL) {
+        return;
+    }
+    Mutex::Autolock _l(mLock);
+    mpPolicyManager->releaseInput(input);
+}
+
+status_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
+                                            int indexMin,
+                                            int indexMax)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+
+    return mpPolicyManager->setStreamVolumeIndex(stream, index);
+}
+
+status_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
+{
+    if (mpPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    if (!checkPermission()) {
+        return PERMISSION_DENIED;
+    }
+    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    return mpPolicyManager->getStreamVolumeIndex(stream, index);
+}
+
+void AudioPolicyService::binderDied(const wp<IBinder>& who) {
+    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+}
+
+static bool tryLock(Mutex& mutex)
+{
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+status_t AudioPolicyService::dumpInternals(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
+    result.append(buffer);
+
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
+{
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        dumpPermissionDenial(fd);
+    } else {
+        bool locked = tryLock(mLock);
+        if (!locked) {
+            String8 result(kDeadlockedString);
+            write(fd, result.string(), result.size());
+        }
+
+        dumpInternals(fd);
+        if (mAudioCommandThread != NULL) {
+            mAudioCommandThread->dump(fd);
+        }
+        if (mTonePlaybackThread != NULL) {
+            mTonePlaybackThread->dump(fd);
+        }
+
+        if (mpPolicyManager) {
+            mpPolicyManager->dump(fd);
+        }
+
+        if (locked) mLock.unlock();
+    }
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::dumpPermissionDenial(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "Permission Denial: "
+            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
+            IPCThreadState::self()->getCallingPid(),
+            IPCThreadState::self()->getCallingUid());
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioPolicyService::onTransact(code, data, reply, flags);
+}
+
+
+// ----------------------------------------------------------------------------
+void AudioPolicyService::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.audio_policy"), new AudioPolicyService());
+}
+
+
+// ----------------------------------------------------------------------------
+// AudioPolicyClientInterface implementation
+// ----------------------------------------------------------------------------
+
+
+audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
+                                uint32_t *pSamplingRate,
+                                uint32_t *pFormat,
+                                uint32_t *pChannels,
+                                uint32_t *pLatencyMs,
+                                AudioSystem::output_flags flags)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        LOGW("openOutput() could not get AudioFlinger");
+        return 0;
+    }
+
+    return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, pLatencyMs, flags);
+}
+
+audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        LOGW("openDuplicateOutput() could not get AudioFlinger");
+        return 0;
+    }
+    return af->openDuplicateOutput(output1, output2);
+}
+
+status_t AudioPolicyService::closeOutput(audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+
+    return af->closeOutput(output);
+}
+
+
+status_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        LOGW("suspendOutput() could not get AudioFlinger");
+        return PERMISSION_DENIED;
+    }
+
+    return af->suspendOutput(output);
+}
+
+status_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        LOGW("restoreOutput() could not get AudioFlinger");
+        return PERMISSION_DENIED;
+    }
+
+    return af->restoreOutput(output);
+}
+
+audio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
+                                uint32_t *pSamplingRate,
+                                uint32_t *pFormat,
+                                uint32_t *pChannels,
+                                uint32_t acoustics)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        LOGW("openInput() could not get AudioFlinger");
+        return 0;
+    }
+
+    return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
+}
+
+status_t AudioPolicyService::closeInput(audio_io_handle_t input)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+
+    return af->closeInput(input);
+}
+
+status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
+{
+    return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
+}
+
+status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+
+    return af->setStreamOutput(stream, output);
+}
+
+
+void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs)
+{
+    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
+}
+
+String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
+{
+    String8 result = AudioSystem::getParameters(ioHandle, keys);
+    return result;
+}
+
+status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream)
+{
+    mTonePlaybackThread->startToneCommand(tone, stream);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::stopTone()
+{
+    mTonePlaybackThread->stopToneCommand();
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
+{
+    return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
+}
+
+// -----------  AudioPolicyService::AudioCommandThread implementation ----------
+
+AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
+    : Thread(false), mName(name)
+{
+    mpToneGenerator = NULL;
+}
+
+
+AudioPolicyService::AudioCommandThread::~AudioCommandThread()
+{
+    if (mName != "" && !mAudioCommands.isEmpty()) {
+        release_wake_lock(mName.string());
+    }
+    mAudioCommands.clear();
+    if (mpToneGenerator != NULL) delete mpToneGenerator;
+}
+
+void AudioPolicyService::AudioCommandThread::onFirstRef()
+{
+    if (mName != "") {
+        run(mName.string(), ANDROID_PRIORITY_AUDIO);
+    } else {
+        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
+    }
+}
+
+bool AudioPolicyService::AudioCommandThread::threadLoop()
+{
+    nsecs_t waitTime = INT64_MAX;
+
+    mLock.lock();
+    while (!exitPending())
+    {
+        while(!mAudioCommands.isEmpty()) {
+            nsecs_t curTime = systemTime();
+            // commands are sorted by increasing time stamp: execute them from index 0 and up
+            if (mAudioCommands[0]->mTime <= curTime) {
+                AudioCommand *command = mAudioCommands[0];
+                mAudioCommands.removeAt(0);
+                mLastCommand = *command;
+
+                switch (command->mCommand) {
+                case START_TONE: {
+                    mLock.unlock();
+                    ToneData *data = (ToneData *)command->mParam;
+                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
+                            data->mType, data->mStream);
+                    if (mpToneGenerator != NULL)
+                        delete mpToneGenerator;
+                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
+                    mpToneGenerator->startTone(data->mType);
+                    delete data;
+                    mLock.lock();
+                    }break;
+                case STOP_TONE: {
+                    mLock.unlock();
+                    LOGV("AudioCommandThread() processing stop tone");
+                    if (mpToneGenerator != NULL) {
+                        mpToneGenerator->stopTone();
+                        delete mpToneGenerator;
+                        mpToneGenerator = NULL;
+                    }
+                    mLock.lock();
+                    }break;
+                case SET_VOLUME: {
+                    VolumeData *data = (VolumeData *)command->mParam;
+                    LOGV("AudioCommandThread() processing set volume stream %d, volume %f, output %d", data->mStream, data->mVolume, data->mIO);
+                    command->mStatus = AudioSystem::setStreamVolume(data->mStream, data->mVolume, data->mIO);
+                    if (command->mWaitStatus) {
+                        command->mCond.signal();
+                        mWaitWorkCV.wait(mLock);
+                    }
+                    delete data;
+                    }break;
+                case SET_PARAMETERS: {
+                     ParametersData *data = (ParametersData *)command->mParam;
+                     LOGV("AudioCommandThread() processing set parameters string %s, io %d", data->mKeyValuePairs.string(), data->mIO);
+                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
+                     if (command->mWaitStatus) {
+                         command->mCond.signal();
+                         mWaitWorkCV.wait(mLock);
+                     }
+                     delete data;
+                     }break;
+                case SET_VOICE_VOLUME: {
+                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
+                    LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
+                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
+                    if (command->mWaitStatus) {
+                        command->mCond.signal();
+                        mWaitWorkCV.wait(mLock);
+                    }
+                    delete data;
+                    }break;
+                default:
+                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
+                }
+                delete command;
+                waitTime = INT64_MAX;
+            } else {
+                waitTime = mAudioCommands[0]->mTime - curTime;
+                break;
+            }
+        }
+        // release delayed commands wake lock
+        if (mName != "" && mAudioCommands.isEmpty()) {
+            release_wake_lock(mName.string());
+        }
+        LOGV("AudioCommandThread() going to sleep");
+        mWaitWorkCV.waitRelative(mLock, waitTime);
+        LOGV("AudioCommandThread() waking up");
+    }
+    mLock.unlock();
+    return false;
+}
+
+status_t AudioPolicyService::AudioCommandThread::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+
+    bool locked = tryLock(mLock);
+    if (!locked) {
+        String8 result2(kCmdDeadlockedString);
+        write(fd, result2.string(), result2.size());
+    }
+
+    snprintf(buffer, SIZE, "- Commands:\n");
+    result = String8(buffer);
+    result.append("   Command Time        Wait pParam\n");
+    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
+        mAudioCommands[i]->dump(buffer, SIZE);
+        result.append(buffer);
+    }
+    result.append("  Last Command\n");
+    mLastCommand.dump(buffer, SIZE);
+    result.append(buffer);
+
+    write(fd, result.string(), result.size());
+
+    if (locked) mLock.unlock();
+
+    return NO_ERROR;
+}
+
+void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
+{
+    AudioCommand *command = new AudioCommand();
+    command->mCommand = START_TONE;
+    ToneData *data = new ToneData();
+    data->mType = type;
+    data->mStream = stream;
+    command->mParam = (void *)data;
+    command->mWaitStatus = false;
+    Mutex::Autolock _l(mLock);
+    insertCommand_l(command);
+    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
+    mWaitWorkCV.signal();
+}
+
+void AudioPolicyService::AudioCommandThread::stopToneCommand()
+{
+    AudioCommand *command = new AudioCommand();
+    command->mCommand = STOP_TONE;
+    command->mParam = NULL;
+    command->mWaitStatus = false;
+    Mutex::Autolock _l(mLock);
+    insertCommand_l(command);
+    LOGV("AudioCommandThread() adding tone stop");
+    mWaitWorkCV.signal();
+}
+
+status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
+{
+    status_t status = NO_ERROR;
+
+    AudioCommand *command = new AudioCommand();
+    command->mCommand = SET_VOLUME;
+    VolumeData *data = new VolumeData();
+    data->mStream = stream;
+    data->mVolume = volume;
+    data->mIO = output;
+    command->mParam = data;
+    if (delayMs == 0) {
+        command->mWaitStatus = true;
+    } else {
+        command->mWaitStatus = false;
+    }
+    Mutex::Autolock _l(mLock);
+    insertCommand_l(command, delayMs);
+    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
+    mWaitWorkCV.signal();
+    if (command->mWaitStatus) {
+        command->mCond.wait(mLock);
+        status =  command->mStatus;
+        mWaitWorkCV.signal();
+    }
+    return status;
+}
+
+status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs)
+{
+    status_t status = NO_ERROR;
+
+    AudioCommand *command = new AudioCommand();
+    command->mCommand = SET_PARAMETERS;
+    ParametersData *data = new ParametersData();
+    data->mIO = ioHandle;
+    data->mKeyValuePairs = keyValuePairs;
+    command->mParam = data;
+    if (delayMs == 0) {
+        command->mWaitStatus = true;
+    } else {
+        command->mWaitStatus = false;
+    }
+    Mutex::Autolock _l(mLock);
+    insertCommand_l(command, delayMs);
+    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
+    mWaitWorkCV.signal();
+    if (command->mWaitStatus) {
+        command->mCond.wait(mLock);
+        status =  command->mStatus;
+        mWaitWorkCV.signal();
+    }
+    return status;
+}
+
+status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
+{
+    status_t status = NO_ERROR;
+
+    AudioCommand *command = new AudioCommand();
+    command->mCommand = SET_VOICE_VOLUME;
+    VoiceVolumeData *data = new VoiceVolumeData();
+    data->mVolume = volume;
+    command->mParam = data;
+    if (delayMs == 0) {
+        command->mWaitStatus = true;
+    } else {
+        command->mWaitStatus = false;
+    }
+    Mutex::Autolock _l(mLock);
+    insertCommand_l(command, delayMs);
+    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
+    mWaitWorkCV.signal();
+    if (command->mWaitStatus) {
+        command->mCond.wait(mLock);
+        status =  command->mStatus;
+        mWaitWorkCV.signal();
+    }
+    return status;
+}
+
+// insertCommand_l() must be called with mLock held
+void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
+{
+    ssize_t i;
+    Vector <AudioCommand *> removedCommands;
+
+    command->mTime = systemTime() + milliseconds(delayMs);
+
+    // acquire wake lock to make sure delayed commands are processed
+    if (mName != "" && mAudioCommands.isEmpty()) {
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
+    }
+
+    // check same pending commands with later time stamps and eliminate them
+    for (i = mAudioCommands.size()-1; i >= 0; i--) {
+        AudioCommand *command2 = mAudioCommands[i];
+        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
+        if (command2->mTime <= command->mTime) break;
+        if (command2->mCommand != command->mCommand) continue;
+
+        switch (command->mCommand) {
+        case SET_PARAMETERS: {
+            ParametersData *data = (ParametersData *)command->mParam;
+            ParametersData *data2 = (ParametersData *)command2->mParam;
+            if (data->mIO != data2->mIO) break;
+            LOGV("Comparing parameter command %s to new command %s", data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
+            AudioParameter param = AudioParameter(data->mKeyValuePairs);
+            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
+            for (size_t j = 0; j < param.size(); j++) {
+               String8 key;
+               String8 value;
+               param.getAt(j, key, value);
+               for (size_t k = 0; k < param2.size(); k++) {
+                  String8 key2;
+                  String8 value2;
+                  param2.getAt(k, key2, value2);
+                  if (key2 == key) {
+                      param2.remove(key2);
+                      LOGV("Filtering out parameter %s", key2.string());
+                      break;
+                  }
+               }
+            }
+            // if all keys have been filtered out, remove the command.
+            // otherwise, update the key value pairs
+            if (param2.size() == 0) {
+                removedCommands.add(command2);
+            } else {
+                data2->mKeyValuePairs = param2.toString();
+            }
+        } break;
+
+        case SET_VOLUME: {
+            VolumeData *data = (VolumeData *)command->mParam;
+            VolumeData *data2 = (VolumeData *)command2->mParam;
+            if (data->mIO != data2->mIO) break;
+            if (data->mStream != data2->mStream) break;
+            LOGV("Filtering out volume command on output %d for stream %d", data->mIO, data->mStream);
+            removedCommands.add(command2);
+        } break;
+        case START_TONE:
+        case STOP_TONE:
+        default:
+            break;
+        }
+    }
+
+    // remove filtered commands
+    for (size_t j = 0; j < removedCommands.size(); j++) {
+        // removed commands always have time stamps greater than current command
+        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
+            if (mAudioCommands[k] == removedCommands[j]) {
+                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
+                mAudioCommands.removeAt(k);
+                break;
+            }
+        }
+    }
+    removedCommands.clear();
+
+    // insert command at the right place according to its time stamp
+    LOGV("inserting command: %d at index %d, num commands %d", command->mCommand, (int)i+1, mAudioCommands.size());
+    mAudioCommands.insertAt(command, i + 1);
+}
+
+void AudioPolicyService::AudioCommandThread::exit()
+{
+    LOGV("AudioCommandThread::exit");
+    {
+        AutoMutex _l(mLock);
+        requestExit();
+        mWaitWorkCV.signal();
+    }
+    requestExitAndWait();
+}
+
+void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
+            mCommand,
+            (int)ns2s(mTime),
+            (int)ns2ms(mTime)%1000,
+            mWaitStatus,
+            mParam);
+}
+
+}; // namespace android
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
new file mode 100644
index 0000000..a13d0bd
--- /dev/null
+++ b/services/audioflinger/AudioPolicyService.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOPOLICYSERVICE_H
+#define ANDROID_AUDIOPOLICYSERVICE_H
+
+#include <media/IAudioPolicyService.h>
+#include <hardware_legacy/AudioPolicyInterface.h>
+#include <media/ToneGenerator.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class String8;
+
+// ----------------------------------------------------------------------------
+
+class AudioPolicyService: public BnAudioPolicyService, public AudioPolicyClientInterface, public IBinder::DeathRecipient
+{
+
+public:
+    static  void        instantiate();
+
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    //
+    // BnAudioPolicyService (see AudioPolicyInterface for method descriptions)
+    //
+
+    virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
+                                              AudioSystem::device_connection_state state,
+                                              const char *device_address);
+    virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
+                                                                          const char *device_address);
+    virtual status_t setPhoneState(int state);
+    virtual status_t setRingerMode(uint32_t mode, uint32_t mask);
+    virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
+    virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
+    virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
+                                        uint32_t samplingRate = 0,
+                                        uint32_t format = AudioSystem::FORMAT_DEFAULT,
+                                        uint32_t channels = 0,
+                                        AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT);
+    virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
+    virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
+    virtual void releaseOutput(audio_io_handle_t output);
+    virtual audio_io_handle_t getInput(int inputSource,
+                                    uint32_t samplingRate = 0,
+                                    uint32_t format = AudioSystem::FORMAT_DEFAULT,
+                                    uint32_t channels = 0,
+                                    AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)0);
+    virtual status_t startInput(audio_io_handle_t input);
+    virtual status_t stopInput(audio_io_handle_t input);
+    virtual void releaseInput(audio_io_handle_t input);
+    virtual status_t initStreamVolume(AudioSystem::stream_type stream,
+                                      int indexMin,
+                                      int indexMax);
+    virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
+    virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
+
+    virtual     status_t    onTransact(
+                                uint32_t code,
+                                const Parcel& data,
+                                Parcel* reply,
+                                uint32_t flags);
+
+    // IBinder::DeathRecipient
+    virtual     void        binderDied(const wp<IBinder>& who);
+
+    //
+    // AudioPolicyClientInterface
+    //
+    virtual audio_io_handle_t openOutput(uint32_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    uint32_t *pFormat,
+                                    uint32_t *pChannels,
+                                    uint32_t *pLatencyMs,
+                                    AudioSystem::output_flags flags);
+    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2);
+    virtual status_t closeOutput(audio_io_handle_t output);
+    virtual status_t suspendOutput(audio_io_handle_t output);
+    virtual status_t restoreOutput(audio_io_handle_t output);
+    virtual audio_io_handle_t openInput(uint32_t *pDevices,
+                                    uint32_t *pSamplingRate,
+                                    uint32_t *pFormat,
+                                    uint32_t *pChannels,
+                                    uint32_t acoustics);
+    virtual status_t closeInput(audio_io_handle_t input);
+    virtual status_t setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs = 0);
+    virtual status_t setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output);
+    virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs = 0);
+    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
+    virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
+    virtual status_t stopTone();
+    virtual status_t setVoiceVolume(float volume, int delayMs = 0);
+
+private:
+                        AudioPolicyService();
+    virtual             ~AudioPolicyService();
+
+            status_t dumpInternals(int fd);
+
+    // Thread used for tone playback and to send audio config commands to audio flinger
+    // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
+    // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
+    // calls to AudioPolicyService and an attempt to lock mLock.
+    // For audio config commands, it is necessary because audio flinger requires that the calling process (user)
+    // has permission to modify audio settings.
+    class AudioCommandThread : public Thread {
+        class AudioCommand;
+    public:
+
+        // commands for tone AudioCommand
+        enum {
+            START_TONE,
+            STOP_TONE,
+            SET_VOLUME,
+            SET_PARAMETERS,
+            SET_VOICE_VOLUME
+        };
+
+        AudioCommandThread (String8 name);
+        virtual             ~AudioCommandThread();
+
+                    status_t    dump(int fd);
+
+        // Thread virtuals
+        virtual     void        onFirstRef();
+        virtual     bool        threadLoop();
+
+                    void        exit();
+                    void        startToneCommand(int type = 0, int stream = 0);
+                    void        stopToneCommand();
+                    status_t    volumeCommand(int stream, float volume, int output, int delayMs = 0);
+                    status_t    parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0);
+                    status_t    voiceVolumeCommand(float volume, int delayMs = 0);
+                    void        insertCommand_l(AudioCommand *command, int delayMs = 0);
+
+    private:
+        // descriptor for requested tone playback event
+        class AudioCommand {
+
+        public:
+            AudioCommand()
+            : mCommand(-1) {}
+
+            void dump(char* buffer, size_t size);
+
+            int mCommand;   // START_TONE, STOP_TONE ...
+            nsecs_t mTime;  // time stamp
+            Condition mCond; // condition for status return
+            status_t mStatus; // command status
+            bool mWaitStatus; // true if caller is waiting for status
+            void *mParam;     // command parameter (ToneData, VolumeData, ParametersData)
+        };
+
+        class ToneData {
+        public:
+            int mType;      // tone type (START_TONE only)
+            int mStream;    // stream type (START_TONE only)
+        };
+
+        class VolumeData {
+        public:
+            int mStream;
+            float mVolume;
+            int mIO;
+        };
+
+        class ParametersData {
+        public:
+            int mIO;
+            String8 mKeyValuePairs;
+        };
+
+        class VoiceVolumeData {
+        public:
+            float mVolume;
+        };
+
+        Mutex   mLock;
+        Condition mWaitWorkCV;
+        Vector <AudioCommand *> mAudioCommands; // list of pending commands
+        ToneGenerator *mpToneGenerator;     // the tone generator
+        AudioCommand mLastCommand;          // last processed command (used by dump)
+        String8 mName;                      // string used by wake lock fo delayed commands
+    };
+
+    // Internal dump utilities.
+    status_t dumpPermissionDenial(int fd);
+
+
+    Mutex   mLock;      // prevents concurrent access to AudioPolicy manager functions changing device
+                        // connection stated our routing
+    AudioPolicyInterface* mpPolicyManager;          // the platform specific policy manager
+    sp <AudioCommandThread> mAudioCommandThread;    // audio commands thread
+    sp <AudioCommandThread> mTonePlaybackThread;     // tone playback thread
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOPOLICYSERVICE_H
+
+
+
+
+
+
+
+
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
new file mode 100644
index 0000000..5dabacb
--- /dev/null
+++ b/services/audioflinger/AudioResampler.cpp
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioResampler"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "AudioResampler.h"
+#include "AudioResamplerSinc.h"
+#include "AudioResamplerCubic.h"
+
+namespace android {
+
+#ifdef __ARM_ARCH_5E__  // optimized asm option
+    #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
+#endif // __ARM_ARCH_5E__
+// ----------------------------------------------------------------------------
+
+class AudioResamplerOrder1 : public AudioResampler {
+public:
+    AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate), mX0L(0), mX0R(0) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 15 bits avoids overflow
+    static const int kNumInterpBits = 15;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+
+    void init() {}
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+    void AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+    void AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+#endif  // ASM_ARM_RESAMP1
+
+    static inline int32_t Interp(int32_t x0, int32_t x1, uint32_t f) {
+        return x0 + (((x1 - x0) * (int32_t)(f >> kPreInterpShift)) >> kNumInterpBits);
+    }
+    static inline void Advance(size_t* index, uint32_t* frac, uint32_t inc) {
+        *frac += inc;
+        *index += (size_t)(*frac >> kNumPhaseBits);
+        *frac &= kPhaseMask;
+    }
+    int mX0L;
+    int mX0R;
+};
+
+// ----------------------------------------------------------------------------
+AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
+        int32_t sampleRate, int quality) {
+
+    // can only create low quality resample now
+    AudioResampler* resampler;
+
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("af.resampler.quality", value, 0)) {
+        quality = atoi(value);
+        LOGD("forcing AudioResampler quality to %d", quality);
+    }
+
+    if (quality == DEFAULT)
+        quality = LOW_QUALITY;
+
+    switch (quality) {
+    default:
+    case LOW_QUALITY:
+        LOGV("Create linear Resampler");
+        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+        break;
+    case MED_QUALITY:
+        LOGV("Create cubic Resampler");
+        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+        break;
+    case HIGH_QUALITY:
+        LOGV("Create sinc Resampler");
+        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+        break;
+    }
+
+    // initialize resampler
+    resampler->init();
+    return resampler;
+}
+
+AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
+        int32_t sampleRate) :
+    mBitDepth(bitDepth), mChannelCount(inChannelCount),
+            mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
+            mPhaseFraction(0) {
+    // sanity check on format
+    if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
+        LOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
+                inChannelCount);
+        // LOG_ASSERT(0);
+    }
+
+    // initialize common members
+    mVolume[0] = mVolume[1] = 0;
+    mBuffer.frameCount = 0;
+
+    // save format for quick lookup
+    if (inChannelCount == 1) {
+        mFormat = MONO_16_BIT;
+    } else {
+        mFormat = STEREO_16_BIT;
+    }
+}
+
+AudioResampler::~AudioResampler() {
+}
+
+void AudioResampler::setSampleRate(int32_t inSampleRate) {
+    mInSampleRate = inSampleRate;
+    mPhaseIncrement = (uint32_t)((kPhaseMultiplier * inSampleRate) / mSampleRate);
+}
+
+void AudioResampler::setVolume(int16_t left, int16_t right) {
+    // TODO: Implement anti-zipper filter
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerOrder1::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+
+    while (outputIndex < outputSampleCount) {
+
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                goto resampleStereo16_exit;
+            }
+
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount > inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+             // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            out[outputIndex++] += vl * Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vr * Interp(mX0R, in[1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);   // 2 because 2 frames per loop
+            maxInIdx = mBuffer.frameCount - 2;
+            AsmStereo16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                    phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            out[outputIndex++] += vl * Interp(in[inputIndex*2-2],
+                    in[inputIndex*2], phaseFraction);
+            out[outputIndex++] += vr * Interp(in[inputIndex*2-1],
+                    in[inputIndex*2+1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleStereo16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerOrder1::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                mInputIndex = inputIndex;
+                mPhaseFraction = phaseFraction;
+                goto resampleMono16_exit;
+            }
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount >  inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+            // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            int32_t sample = Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);
+            maxInIdx = (int32_t)mBuffer.frameCount - 2;
+                AsmMono16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                        phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
+                    phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleMono16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+
+/*******************************************************************
+*
+*   AsmMono16Loop
+*   asm optimized monotonic loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define MO_PARAM5   "36"        // offset of parameter 5 (outputIndex)
+
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" MO_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" MO_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" MO_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, Out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12
+        // r13 sp
+        // r14
+
+        // the following loop works on 2 frames
+
+        ".Y4L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y4L02\n"
+
+#define MO_ONE_FRAME \
+    "   add r0, r1, r7, asl #1\n"       /* in + inputIndex */\
+    "   ldrsh r4, [r0]\n"               /* in[inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[inputIndex-1] */\
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+    "   sub r4, r4, r0\n"               /* in[inputIndex] - in[inputIndex-1] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r0, r0, r4\n"               /* x0 - (..) */\
+    "   mla r5, r0, r10, r5\n"          /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+    "   mla r4, r0, r11, r4\n"          /* vr*interp + out[] */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */
+
+        MO_ONE_FRAME    // frame 1
+        MO_ONE_FRAME    // frame 2
+
+        "   cmp r7, r3\n"                   // inputIndex - maxInIdx
+        "   bcc .Y4L01\n"
+        ".Y4L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"             // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
+    );
+}
+
+/*******************************************************************
+*
+*   AsmStereo16Loop
+*   asm optimized stereo loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define ST_PARAM5    "40"     // offset of parameter 5 (outputIndex)
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" ST_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" ST_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" ST_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12 temporary
+        // r13 sp
+        // r14
+
+        ".Y5L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y5L02\n"
+
+#define ST_ONE_FRAME \
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+\
+    "   add r0, r1, r7, asl #2\n"       /* in + 2*inputIndex */\
+\
+    "   ldrsh r4, [r0]\n"               /* in[2*inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r12, [r0, #-4]\n"         /* in[2*inputIndex-2] */\
+    "   sub r4, r4, r12\n"              /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r12, r12, r4\n"             /* x0 - (..) */\
+    "   mla r5, r12, r10, r5\n"         /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   ldrsh r12, [r0, #+2]\n"         /* in[2*inputIndex+1] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[2*inputIndex-1] */\
+    "   sub r12, r12, r0\n"             /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r12, r12, lsl #2\n"         /* <<2 */\
+    "   smulwt r12, r12, r6\n"          /* (x1-x0)*.. */\
+    "   add r12, r0, r12\n"             /* x0 - (..) */\
+    "   mla r4, r12, r11, r4\n"         /* vr*interp + out[] */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */
+
+    ST_ONE_FRAME    // frame 1
+    ST_ONE_FRAME    // frame 1
+
+        "   cmp r7, r3\n"                       // inputIndex - maxInIdx
+        "   bcc .Y5L01\n"
+        ".Y5L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"              // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}\n"
+    );
+}
+
+#endif  // ASM_ARM_RESAMP1
+
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
new file mode 100644
index 0000000..2dfac76
--- /dev/null
+++ b/services/audioflinger/AudioResampler.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_H
+#define ANDROID_AUDIO_RESAMPLER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResampler {
+public:
+    // Determines quality of SRC.
+    //  LOW_QUALITY: linear interpolator (1st order)
+    //  MED_QUALITY: cubic interpolator (3rd order)
+    //  HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
+    // NOTE: high quality SRC will only be supported for
+    // certain fixed rate conversions. Sample rate cannot be
+    // changed dynamically. 
+    enum src_quality {
+        DEFAULT=0,
+        LOW_QUALITY=1,
+        MED_QUALITY=2,
+        HIGH_QUALITY=3
+    };
+
+    static AudioResampler* create(int bitDepth, int inChannelCount,
+            int32_t sampleRate, int quality=DEFAULT);
+
+    virtual ~AudioResampler();
+
+    virtual void init() = 0;
+    virtual void setSampleRate(int32_t inSampleRate);
+    virtual void setVolume(int16_t left, int16_t right);
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider) = 0;
+
+protected:
+    // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
+    static const int kNumPhaseBits = 30;
+
+    // phase mask for fraction
+    static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
+
+    // multiplier to calculate fixed point phase increment
+    static const double kPhaseMultiplier = 1L << kNumPhaseBits;
+
+    enum format {MONO_16_BIT, STEREO_16_BIT};
+    AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    // prevent copying
+    AudioResampler(const AudioResampler&);
+    AudioResampler& operator=(const AudioResampler&);
+
+    int32_t mBitDepth;
+    int32_t mChannelCount;
+    int32_t mSampleRate;
+    int32_t mInSampleRate;
+    AudioBufferProvider::Buffer mBuffer;
+    union {
+        int16_t mVolume[2];
+        uint32_t mVolumeRL;
+    };
+    int16_t mTargetVolume[2];
+    format mFormat;
+    size_t mInputIndex;
+    int32_t mPhaseIncrement;
+    uint32_t mPhaseFraction;
+};
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
+#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp
new file mode 100644
index 0000000..1d247bd
--- /dev/null
+++ b/services/audioflinger/AudioResamplerCubic.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+#include "AudioResamplerCubic.h"
+
+#define LOG_TAG "AudioSRC"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+void AudioResamplerCubic::init() {
+    memset(&left, 0, sizeof(state));
+    memset(&right, 0, sizeof(state));
+}
+
+void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        out[outputIndex++] += vl * interp(&left, x);
+        out[outputIndex++] += vr * interp(&right, x);
+        // out[outputIndex++] += vr * in[inputIndex*2];
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                in = mBuffer.i16;
+                // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex*2]);
+            advance(&right, in[inputIndex*2+1]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        sample = interp(&left, x);
+        out[outputIndex++] += vl * sample;
+        out[outputIndex++] += vr * sample;
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+                in = mBuffer.i16;
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/services/audioflinger/AudioResamplerCubic.h b/services/audioflinger/AudioResamplerCubic.h
new file mode 100644
index 0000000..b72b62a
--- /dev/null
+++ b/services/audioflinger/AudioResamplerCubic.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_CUBIC_H
+#define ANDROID_AUDIO_RESAMPLER_CUBIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResamplerCubic : public AudioResampler {
+public:
+    AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 14 bits avoids overflow
+    static const int kNumInterpBits = 14;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+    typedef struct {
+        int32_t a, b, c, y0, y1, y2, y3;
+    } state;
+    void init();
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    static inline int32_t interp(state* p, int32_t x) {
+        return (((((p->a * x >> 14) + p->b) * x >> 14) + p->c) * x >> 14) + p->y1;
+    }
+    static inline void advance(state* p, int16_t in) {
+        p->y0 = p->y1;
+        p->y1 = p->y2;
+        p->y2 = p->y3;
+        p->y3 = in;
+        p->a = (3 * (p->y1 - p->y2) - p->y0 + p->y3) >> 1;            
+        p->b = (p->y2 << 1) + p->y0 - (((5 * p->y1 + p->y3)) >> 1);
+        p->c = (p->y2 - p->y0) >> 1;
+    }
+    state left, right;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
new file mode 100644
index 0000000..9e5e254
--- /dev/null
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "AudioResamplerSinc.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+
+/*
+ * These coeficients are computed with the "fir" utility found in
+ * tools/resampler_tools
+ * TODO: A good optimization would be to transpose this matrix, to take
+ * better advantage of the data-cache.
+ */
+const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
+        0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
+        0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
+        0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
+        0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
+        0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
+        0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
+        0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
+        0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+/*
+ * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
+ * It's possible to use the above coefficient for any down-sampling
+ * at the expense of a slower processing loop (we can interpolate
+ * these coefficient from the above by "Stretching" them in time).
+ */
+const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
+        0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
+        0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
+        0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
+        0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
+        0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
+        0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
+        0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
+        0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+// ----------------------------------------------------------------------------
+
+static inline
+int32_t mulRL(int left, int32_t in, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smultb %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(in>>16) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(in>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulAdd(int16_t in, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlawb %[out], %[v], %[in], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * (v>>16);
+    // improved precision
+    // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + (int16_t(inRL&0xFFFF) * (v>>16));
+        //improved precision
+        // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
+    } else {
+        return a + (int16_t(inRL>>16) * (v>>16));
+    }
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
+        int inChannelCount, int32_t sampleRate)
+    : AudioResampler(bitDepth, inChannelCount, sampleRate),
+    mState(0)
+{
+    /*
+     * Layout of the state buffer for 32 tap:
+     *
+     * "present" sample            beginning of 2nd buffer
+     *                 v                v
+     *  0              01               2              23              3
+     *  0              F0               0              F0              F
+     * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
+     *                 ^               ^ head
+     *
+     * p = past samples, convoluted with the (p)ositive side of sinc()
+     * n = future samples, convoluted with the (n)egative side of sinc()
+     * r = extra space for implementing the ring buffer
+     *
+     */
+
+    const size_t numCoefs = 2*halfNumCoefs;
+    const size_t stateSize = numCoefs * inChannelCount * 2;
+    mState = new int16_t[stateSize];
+    memset(mState, 0, sizeof(int16_t)*stateSize);
+    mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
+    mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
+}
+
+AudioResamplerSinc::~AudioResamplerSinc()
+{
+    delete [] mState;
+}
+
+void AudioResamplerSinc::init() {
+}
+
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider)
+{
+    mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resample<1>(out, outFrameCount, provider);
+        break;
+    case 2:
+        resample<2>(out, outFrameCount, provider);
+        break;
+    }
+}
+
+
+template<int CHANNELS>
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider)
+{
+    int16_t* impulse = mImpulse;
+    uint32_t vRL = mVolumeRL;
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    AudioBufferProvider::Buffer& buffer(mBuffer);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (buffer.frameCount == 0) {
+            buffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&buffer);
+            if (buffer.raw == NULL) {
+                goto resample_exit;
+            }
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                // read one frame
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+            } else if (phaseIndex == 2) {
+                // read 2 frames
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                inputIndex++;
+                if (inputIndex >= mBuffer.frameCount) {
+                    inputIndex -= mBuffer.frameCount;
+                    provider->releaseBuffer(&buffer);
+                } else {
+                    read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                }
+           }
+        }
+        int16_t *in = buffer.i16;
+        const size_t frameCount = buffer.frameCount;
+
+        // Always read-in the first samples from the input buffer
+        int16_t* head = impulse + halfNumCoefs*CHANNELS;
+        head[0] = in[inputIndex*CHANNELS + 0];
+        if (CHANNELS == 2)
+            head[1] = in[inputIndex*CHANNELS + 1];
+
+        // handle boundary case
+        int32_t l, r;
+        while (outputIndex < outputSampleCount) {
+            filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
+            out[outputIndex++] += 2 * mulRL(1, l, vRL);
+            out[outputIndex++] += 2 * mulRL(0, r, vRL);
+
+            phaseFraction += phaseIncrement;
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // need a new buffer
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            } else if(phaseIndex == 2) {    // maximum value
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 2 frames needed
+                // read first frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 1 frame needed
+                // read second frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            }
+        }
+
+        // if done with buffer, save samples
+        if (inputIndex >= frameCount) {
+            inputIndex -= frameCount;
+            provider->releaseBuffer(&buffer);
+        }
+    }
+
+resample_exit:
+    mImpulse = impulse;
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+template<int CHANNELS>
+/***
+* read()
+*
+* This function reads only one frame from input buffer and writes it in
+* state buffer
+*
+**/
+void AudioResamplerSinc::read(
+        int16_t*& impulse, uint32_t& phaseFraction,
+        int16_t const* in, size_t inputIndex)
+{
+    const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+    impulse += CHANNELS;
+    phaseFraction -= 1LU<<kNumPhaseBits;
+    if (impulse >= mRingFull) {
+        const size_t stateSize = (halfNumCoefs*2)*CHANNELS;
+        memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
+        impulse -= stateSize;
+    }
+    int16_t* head = impulse + halfNumCoefs*CHANNELS;
+    head[0] = in[inputIndex*CHANNELS + 0];
+    if (CHANNELS == 2)
+        head[1] = in[inputIndex*CHANNELS + 1];
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::filterCoefficient(
+        int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples)
+{
+    // compute the index of the coefficient on the positive side and
+    // negative side
+    uint32_t indexP = (phase & cMask) >> cShift;
+    uint16_t lerpP  = (phase & pMask) >> pShift;
+    uint32_t indexN = (-phase & cMask) >> cShift;
+    uint16_t lerpN  = (-phase & pMask) >> pShift;
+    if ((indexP == 0) && (lerpP == 0)) {
+        indexN = cMask >> cShift;
+        lerpN = pMask >> pShift;
+    }
+
+    l = 0;
+    r = 0;
+    int32_t const* coefs = mFirCoefs;
+    int16_t const *sP = samples;
+    int16_t const *sN = samples+CHANNELS;
+    for (unsigned int i=0 ; i<halfNumCoefs/4 ; i++) {
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+    }
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::interpolate(
+        int32_t& l, int32_t& r,
+        int32_t const* coefs, int16_t lerp, int16_t const* samples)
+{
+    int32_t c0 = coefs[0];
+    int32_t c1 = coefs[1];
+    int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
+    if (CHANNELS == 2) {
+        uint32_t rl = *reinterpret_cast<uint32_t const*>(samples);
+        l = mulAddRL(1, rl, sinc, l);
+        r = mulAddRL(0, rl, sinc, r);
+    } else {
+        r = l = mulAdd(samples[0], sinc, l);
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
new file mode 100644
index 0000000..e6cb90b
--- /dev/null
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_SINC_H
+#define ANDROID_AUDIO_RESAMPLER_SINC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioResamplerSinc : public AudioResampler {
+public:
+    AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    ~AudioResamplerSinc();
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    void init();
+
+    template<int CHANNELS>
+    void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+
+    template<int CHANNELS>
+    inline void filterCoefficient(
+            int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples);
+
+    template<int CHANNELS>
+    inline void interpolate(
+            int32_t& l, int32_t& r,
+            int32_t const* coefs, int16_t lerp, int16_t const* samples);
+
+    template<int CHANNELS>
+    inline void read(int16_t*& impulse, uint32_t& phaseFraction,
+            int16_t const* in, size_t inputIndex);
+
+    int16_t *mState;
+    int16_t *mImpulse;
+    int16_t *mRingFull;
+
+    int32_t const * mFirCoefs;
+    static const int32_t mFirCoefsDown[];
+    static const int32_t mFirCoefsUp[];
+
+    // ----------------------------------------------------------------------------
+    static const int32_t RESAMPLE_FIR_NUM_COEF       = 8;
+    static const int32_t RESAMPLE_FIR_LERP_INT_BITS  = 4;
+
+    // we have 16 coefs samples per zero-crossing
+    static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS;        // 4
+    static const int cShift = kNumPhaseBits - coefsBits;            // 26
+    static const uint32_t cMask  = ((1<<coefsBits)-1) << cShift;    // 0xf<<26 = 3c00 0000
+
+    // and we use 15 bits to interpolate between these samples
+    // this cannot change because the mul below rely on it.
+    static const int pLerpBits = 15;
+    static const int pShift = kNumPhaseBits - coefsBits - pLerpBits;    // 11
+    static const uint32_t pMask  = ((1<<pLerpBits)-1) << pShift;    // 0x7fff << 11
+
+    // number of zero-crossing on each side
+    static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
new file mode 100644
index 0000000..df5c166
--- /dev/null
+++ b/services/camera/libcameraservice/Android.mk
@@ -0,0 +1,71 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Set USE_CAMERA_STUB for non-emulator and non-simulator builds, if you want
+# the camera service to use the fake camera.  For emulator or simulator builds,
+# we always use the fake camera.
+
+ifeq ($(USE_CAMERA_STUB),)
+USE_CAMERA_STUB:=false
+ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
+USE_CAMERA_STUB:=true
+endif #libcamerastub
+endif
+
+ifeq ($(USE_CAMERA_STUB),true)
+#
+# libcamerastub
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    CameraHardwareStub.cpp      \
+    FakeCamera.cpp
+
+LOCAL_MODULE:= libcamerastub
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_CFLAGS += -DSINGLE_PROCESS
+endif
+
+LOCAL_SHARED_LIBRARIES:= libui
+
+include $(BUILD_STATIC_LIBRARY)
+endif # USE_CAMERA_STUB
+
+#
+# libcameraservice
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    CameraService.cpp
+
+LOCAL_SHARED_LIBRARIES:= \
+    libui \
+    libutils \
+    libbinder \
+    libcutils \
+    libmedia \
+    libcamera_client \
+    libsurfaceflinger_client
+
+LOCAL_MODULE:= libcameraservice
+
+LOCAL_CFLAGS += -DLOG_TAG=\"CameraService\"
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_CFLAGS += -DSINGLE_PROCESS
+endif
+
+ifeq ($(USE_CAMERA_STUB), true)
+LOCAL_STATIC_LIBRARIES += libcamerastub
+LOCAL_CFLAGS += -include CameraHardwareStub.h
+else
+LOCAL_SHARED_LIBRARIES += libcamera 
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/camera/libcameraservice/CameraHardwareStub.cpp b/services/camera/libcameraservice/CameraHardwareStub.cpp
new file mode 100644
index 0000000..8b66389
--- /dev/null
+++ b/services/camera/libcameraservice/CameraHardwareStub.cpp
@@ -0,0 +1,402 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "CameraHardwareStub"
+#include <utils/Log.h>
+
+#include "CameraHardwareStub.h"
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "CannedJpeg.h"
+
+namespace android {
+
+CameraHardwareStub::CameraHardwareStub()
+                  : mParameters(),
+                    mPreviewHeap(0),
+                    mRawHeap(0),
+                    mFakeCamera(0),
+                    mPreviewFrameSize(0),
+                    mNotifyCb(0),
+                    mDataCb(0),
+                    mDataCbTimestamp(0),
+                    mCallbackCookie(0),
+                    mMsgEnabled(0),
+                    mCurrentPreviewFrame(0)
+{
+    initDefaultParameters();
+}
+
+void CameraHardwareStub::initDefaultParameters()
+{
+    CameraParameters p;
+
+    p.set("preview-size-values","320x240");
+    p.setPreviewSize(320, 240);
+    p.setPreviewFrameRate(15);
+    p.setPreviewFormat("yuv422sp");
+
+    p.set("picture-size-values", "320x240");
+    p.setPictureSize(320, 240);
+    p.setPictureFormat("jpeg");
+
+    if (setParameters(p) != NO_ERROR) {
+        LOGE("Failed to set default parameters?!");
+    }
+}
+
+void CameraHardwareStub::initHeapLocked()
+{
+    // Create raw heap.
+    int picture_width, picture_height;
+    mParameters.getPictureSize(&picture_width, &picture_height);
+    mRawHeap = new MemoryHeapBase(picture_width * 2 * picture_height);
+
+    int preview_width, preview_height;
+    mParameters.getPreviewSize(&preview_width, &preview_height);
+    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);
+
+    // Note that we enforce yuv422 in setParameters().
+    int how_big = preview_width * preview_height * 2;
+
+    // If we are being reinitialized to the same size as before, no
+    // work needs to be done.
+    if (how_big == mPreviewFrameSize)
+        return;
+
+    mPreviewFrameSize = how_big;
+
+    // Make a new mmap'ed heap that can be shared across processes.
+    // use code below to test with pmem
+    mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
+    // Make an IMemory for each frame so that we can reuse them in callbacks.
+    for (int i = 0; i < kBufferCount; i++) {
+        mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
+    }
+
+    // Recreate the fake camera to reflect the current size.
+    delete mFakeCamera;
+    mFakeCamera = new FakeCamera(preview_width, preview_height);
+}
+
+CameraHardwareStub::~CameraHardwareStub()
+{
+    delete mFakeCamera;
+    mFakeCamera = 0; // paranoia
+    singleton.clear();
+}
+
+sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
+{
+    return mPreviewHeap;
+}
+
+sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const
+{
+    return mRawHeap;
+}
+
+void CameraHardwareStub::setCallbacks(notify_callback notify_cb,
+                                      data_callback data_cb,
+                                      data_callback_timestamp data_cb_timestamp,
+                                      void* user)
+{
+    Mutex::Autolock lock(mLock);
+    mNotifyCb = notify_cb;
+    mDataCb = data_cb;
+    mDataCbTimestamp = data_cb_timestamp;
+    mCallbackCookie = user;
+}
+
+void CameraHardwareStub::enableMsgType(int32_t msgType)
+{
+    Mutex::Autolock lock(mLock);
+    mMsgEnabled |= msgType;
+}
+
+void CameraHardwareStub::disableMsgType(int32_t msgType)
+{
+    Mutex::Autolock lock(mLock);
+    mMsgEnabled &= ~msgType;
+}
+
+bool CameraHardwareStub::msgTypeEnabled(int32_t msgType)
+{
+    Mutex::Autolock lock(mLock);
+    return (mMsgEnabled & msgType);
+}
+
+// ---------------------------------------------------------------------------
+
+int CameraHardwareStub::previewThread()
+{
+    mLock.lock();
+        // the attributes below can change under our feet...
+
+        int previewFrameRate = mParameters.getPreviewFrameRate();
+
+        // Find the offset within the heap of the current buffer.
+        ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize;
+
+        sp<MemoryHeapBase> heap = mPreviewHeap;
+
+        // this assumes the internal state of fake camera doesn't change
+        // (or is thread safe)
+        FakeCamera* fakeCamera = mFakeCamera;
+
+        sp<MemoryBase> buffer = mBuffers[mCurrentPreviewFrame];
+
+    mLock.unlock();
+
+    // TODO: here check all the conditions that could go wrong
+    if (buffer != 0) {
+        // Calculate how long to wait between frames.
+        int delay = (int)(1000000.0f / float(previewFrameRate));
+
+        // This is always valid, even if the client died -- the memory
+        // is still mapped in our process.
+        void *base = heap->base();
+
+        // Fill the current frame with the fake camera.
+        uint8_t *frame = ((uint8_t *)base) + offset;
+        fakeCamera->getNextFrameAsYuv422(frame);
+
+        //LOGV("previewThread: generated frame to buffer %d", mCurrentPreviewFrame);
+
+        // Notify the client of a new frame.
+        if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
+            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
+
+        // Advance the buffer pointer.
+        mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
+
+        // Wait for it...
+        usleep(delay);
+    }
+
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::startPreview()
+{
+    Mutex::Autolock lock(mLock);
+    if (mPreviewThread != 0) {
+        // already running
+        return INVALID_OPERATION;
+    }
+    mPreviewThread = new PreviewThread(this);
+    return NO_ERROR;
+}
+
+void CameraHardwareStub::stopPreview()
+{
+    sp<PreviewThread> previewThread;
+
+    { // scope for the lock
+        Mutex::Autolock lock(mLock);
+        previewThread = mPreviewThread;
+    }
+
+    // don't hold the lock while waiting for the thread to quit
+    if (previewThread != 0) {
+        previewThread->requestExitAndWait();
+    }
+
+    Mutex::Autolock lock(mLock);
+    mPreviewThread.clear();
+}
+
+bool CameraHardwareStub::previewEnabled() {
+    return mPreviewThread != 0;
+}
+
+status_t CameraHardwareStub::startRecording()
+{
+    return UNKNOWN_ERROR;
+}
+
+void CameraHardwareStub::stopRecording()
+{
+}
+
+bool CameraHardwareStub::recordingEnabled()
+{
+    return false;
+}
+
+void CameraHardwareStub::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+int CameraHardwareStub::beginAutoFocusThread(void *cookie)
+{
+    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
+    return c->autoFocusThread();
+}
+
+int CameraHardwareStub::autoFocusThread()
+{
+    if (mMsgEnabled & CAMERA_MSG_FOCUS)
+        mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::autoFocus()
+{
+    Mutex::Autolock lock(mLock);
+    if (createThread(beginAutoFocusThread, this) == false)
+        return UNKNOWN_ERROR;
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::cancelAutoFocus()
+{
+    return NO_ERROR;
+}
+
+/*static*/ int CameraHardwareStub::beginPictureThread(void *cookie)
+{
+    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
+    return c->pictureThread();
+}
+
+int CameraHardwareStub::pictureThread()
+{
+    if (mMsgEnabled & CAMERA_MSG_SHUTTER)
+        mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
+
+    if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
+        //FIXME: use a canned YUV image!
+        // In the meantime just make another fake camera picture.
+        int w, h;
+        mParameters.getPictureSize(&w, &h);
+        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h);
+        FakeCamera cam(w, h);
+        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());
+        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
+    }
+
+    if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
+        sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
+        sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
+        memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
+        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
+    }
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::takePicture()
+{
+    stopPreview();
+    if (createThread(beginPictureThread, this) == false)
+        return -1;
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::cancelPicture()
+{
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::dump(int fd, const Vector<String16>& args) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    AutoMutex lock(&mLock);
+    if (mFakeCamera != 0) {
+        mFakeCamera->dump(fd);
+        mParameters.dump(fd, args);
+        snprintf(buffer, 255, " preview frame(%d), size (%d), running(%s)\n", mCurrentPreviewFrame, mPreviewFrameSize, mPreviewRunning?"true": "false");
+        result.append(buffer);
+    } else {
+        result.append("No camera client yet.\n");
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::setParameters(const CameraParameters& params)
+{
+    Mutex::Autolock lock(mLock);
+    // XXX verify params
+
+    if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
+        LOGE("Only yuv422sp preview is supported");
+        return -1;
+    }
+
+    if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
+        LOGE("Only jpeg still pictures are supported");
+        return -1;
+    }
+
+    int w, h;
+    params.getPictureSize(&w, &h);
+    if (w != kCannedJpegWidth && h != kCannedJpegHeight) {
+        LOGE("Still picture size must be size of canned JPEG (%dx%d)",
+             kCannedJpegWidth, kCannedJpegHeight);
+        return -1;
+    }
+
+    mParameters = params;
+    initHeapLocked();
+
+    return NO_ERROR;
+}
+
+CameraParameters CameraHardwareStub::getParameters() const
+{
+    Mutex::Autolock lock(mLock);
+    return mParameters;
+}
+
+status_t CameraHardwareStub::sendCommand(int32_t command, int32_t arg1,
+                                         int32_t arg2)
+{
+    return BAD_VALUE;
+}
+
+void CameraHardwareStub::release()
+{
+}
+
+wp<CameraHardwareInterface> CameraHardwareStub::singleton;
+
+sp<CameraHardwareInterface> CameraHardwareStub::createInstance()
+{
+    if (singleton != 0) {
+        sp<CameraHardwareInterface> hardware = singleton.promote();
+        if (hardware != 0) {
+            return hardware;
+        }
+    }
+    sp<CameraHardwareInterface> hardware(new CameraHardwareStub());
+    singleton = hardware;
+    return hardware;
+}
+
+extern "C" sp<CameraHardwareInterface> openCameraHardware()
+{
+    return CameraHardwareStub::createInstance();
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/CameraHardwareStub.h b/services/camera/libcameraservice/CameraHardwareStub.h
new file mode 100644
index 0000000..957813a
--- /dev/null
+++ b/services/camera/libcameraservice/CameraHardwareStub.h
@@ -0,0 +1,135 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_STUB_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_STUB_H
+
+#include "FakeCamera.h"
+#include <utils/threads.h>
+#include <camera/CameraHardwareInterface.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class CameraHardwareStub : public CameraHardwareInterface {
+public:
+    virtual sp<IMemoryHeap> getPreviewHeap() const;
+    virtual sp<IMemoryHeap> getRawHeap() const;
+
+    virtual void        setCallbacks(notify_callback notify_cb,
+                                     data_callback data_cb,
+                                     data_callback_timestamp data_cb_timestamp,
+                                     void* user);
+
+    virtual void        enableMsgType(int32_t msgType);
+    virtual void        disableMsgType(int32_t msgType);
+    virtual bool        msgTypeEnabled(int32_t msgType);
+
+    virtual status_t    startPreview();
+    virtual void        stopPreview();
+    virtual bool        previewEnabled();
+
+    virtual status_t    startRecording();
+    virtual void        stopRecording();
+    virtual bool        recordingEnabled();
+    virtual void        releaseRecordingFrame(const sp<IMemory>& mem);
+
+    virtual status_t    autoFocus();
+    virtual status_t    cancelAutoFocus();
+    virtual status_t    takePicture();
+    virtual status_t    cancelPicture();
+    virtual status_t    dump(int fd, const Vector<String16>& args) const;
+    virtual status_t    setParameters(const CameraParameters& params);
+    virtual CameraParameters  getParameters() const;
+    virtual status_t    sendCommand(int32_t command, int32_t arg1,
+                                    int32_t arg2);
+    virtual void release();
+
+    static sp<CameraHardwareInterface> createInstance();
+
+private:
+                        CameraHardwareStub();
+    virtual             ~CameraHardwareStub();
+
+    static wp<CameraHardwareInterface> singleton;
+
+    static const int kBufferCount = 4;
+
+    class PreviewThread : public Thread {
+        CameraHardwareStub* mHardware;
+    public:
+        PreviewThread(CameraHardwareStub* hw) :
+#ifdef SINGLE_PROCESS
+            // In single process mode this thread needs to be a java thread,
+            // since we won't be calling through the binder.
+            Thread(true),
+#else
+            Thread(false),
+#endif
+              mHardware(hw) { }
+        virtual void onFirstRef() {
+            run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual bool threadLoop() {
+            mHardware->previewThread();
+            // loop until we need to quit
+            return true;
+        }
+    };
+
+    void initDefaultParameters();
+    void initHeapLocked();
+
+    int previewThread();
+
+    static int beginAutoFocusThread(void *cookie);
+    int autoFocusThread();
+
+    static int beginPictureThread(void *cookie);
+    int pictureThread();
+
+    mutable Mutex       mLock;
+
+    CameraParameters    mParameters;
+
+    sp<MemoryHeapBase>  mPreviewHeap;
+    sp<MemoryHeapBase>  mRawHeap;
+    sp<MemoryBase>      mBuffers[kBufferCount];
+
+    FakeCamera          *mFakeCamera;
+    bool                mPreviewRunning;
+    int                 mPreviewFrameSize;
+
+    // protected by mLock
+    sp<PreviewThread>   mPreviewThread;
+
+    notify_callback    mNotifyCb;
+    data_callback      mDataCb;
+    data_callback_timestamp mDataCbTimestamp;
+    void               *mCallbackCookie;
+
+    int32_t             mMsgEnabled;
+
+    // only used from PreviewThread
+    int                 mCurrentPreviewFrame;
+};
+
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
new file mode 100644
index 0000000..00bd54e
--- /dev/null
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -0,0 +1,1417 @@
+/*
+**
+** Copyright (C) 2008, The Android Open Source Project
+** Copyright (C) 2008 HTC Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "CameraService"
+#include <utils/Log.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/Errors.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <camera/ICameraService.h>
+#include <surfaceflinger/ISurface.h>
+#include <ui/Overlay.h>
+
+#include <hardware/hardware.h>
+
+#include <media/mediaplayer.h>
+#include <media/AudioSystem.h>
+#include "CameraService.h"
+
+#include <cutils/atomic.h>
+
+namespace android {
+
+extern "C" {
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <signal.h>
+}
+
+// When you enable this, as well as DEBUG_REFS=1 and
+// DEBUG_REFS_ENABLED_BY_DEFAULT=0 in libutils/RefBase.cpp, this will track all
+// references to the CameraService::Client in order to catch the case where the
+// client is being destroyed while a callback from the CameraHardwareInterface
+// is outstanding.  This is a serious bug because if we make another call into
+// CameraHardwreInterface that itself triggers a callback, we will deadlock.
+
+#define DEBUG_CLIENT_REFERENCES 0
+
+#define PICTURE_TIMEOUT seconds(5)
+
+#define DEBUG_DUMP_PREVIEW_FRAME_TO_FILE 0 /* n-th frame to write */
+#define DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE 0
+#define DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE 0
+#define DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE 0
+
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+static int debug_frame_cnt;
+#endif
+
+static int getCallingPid() {
+    return IPCThreadState::self()->getCallingPid();
+}
+
+// ----------------------------------------------------------------------------
+
+void CameraService::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.camera"), new CameraService());
+}
+
+// ----------------------------------------------------------------------------
+
+CameraService::CameraService() :
+    BnCameraService()
+{
+    LOGI("CameraService started: pid=%d", getpid());
+    mUsers = 0;
+}
+
+CameraService::~CameraService()
+{
+    if (mClient != 0) {
+        LOGE("mClient was still connected in destructor!");
+    }
+}
+
+sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
+{
+    int callingPid = getCallingPid();
+    LOGV("CameraService::connect E (pid %d, client %p)", callingPid,
+            cameraClient->asBinder().get());
+
+    Mutex::Autolock lock(mServiceLock);
+    sp<Client> client;
+    if (mClient != 0) {
+        sp<Client> currentClient = mClient.promote();
+        if (currentClient != 0) {
+            sp<ICameraClient> currentCameraClient(currentClient->getCameraClient());
+            if (cameraClient->asBinder() == currentCameraClient->asBinder()) {
+                // This is the same client reconnecting...
+                LOGV("CameraService::connect X (pid %d, same client %p) is reconnecting...",
+                    callingPid, cameraClient->asBinder().get());
+                return currentClient;
+            } else {
+                // It's another client... reject it
+                LOGV("CameraService::connect X (pid %d, new client %p) rejected. "
+                    "(old pid %d, old client %p)",
+                    callingPid, cameraClient->asBinder().get(),
+                    currentClient->mClientPid, currentCameraClient->asBinder().get());
+                if (kill(currentClient->mClientPid, 0) == -1 && errno == ESRCH) {
+                    LOGV("The old client is dead!");
+                }
+                return client;
+            }
+        } else {
+            // can't promote, the previous client has died...
+            LOGV("New client (pid %d) connecting, old reference was dangling...",
+                    callingPid);
+            mClient.clear();
+        }
+    }
+
+    if (mUsers > 0) {
+        LOGV("Still have client, rejected");
+        return client;
+    }
+
+    // create a new Client object
+    client = new Client(this, cameraClient, callingPid);
+    mClient = client;
+#if DEBUG_CLIENT_REFERENCES
+    // Enable tracking for this object, and track increments and decrements of
+    // the refcount.
+    client->trackMe(true, true);
+#endif
+    LOGV("CameraService::connect X");
+    return client;
+}
+
+void CameraService::removeClient(const sp<ICameraClient>& cameraClient)
+{
+    int callingPid = getCallingPid();
+
+    // Declare this outside the lock to make absolutely sure the
+    // destructor won't be called with the lock held.
+    sp<Client> client;
+
+    Mutex::Autolock lock(mServiceLock);
+
+    if (mClient == 0) {
+        // This happens when we have already disconnected.
+        LOGV("removeClient (pid %d): already disconnected", callingPid);
+        return;
+    }
+
+    // Promote mClient. It can fail if we are called from this path:
+    // Client::~Client() -> disconnect() -> removeClient().
+    client = mClient.promote();
+    if (client == 0) {
+        LOGV("removeClient (pid %d): no more strong reference", callingPid);
+        mClient.clear();
+        return;
+    }
+
+    if (cameraClient->asBinder() != client->getCameraClient()->asBinder()) {
+        // ugh! that's not our client!!
+        LOGW("removeClient (pid %d): mClient doesn't match!", callingPid);
+    } else {
+        // okay, good, forget about mClient
+        mClient.clear();
+    }
+
+    LOGV("removeClient (pid %d) done", callingPid);
+}
+
+// The reason we need this count is a new CameraService::connect() request may
+// come in while the previous Client's destructor has not been run or is still
+// running. If the last strong reference of the previous Client is gone but
+// destructor has not been run, we should not allow the new Client to be created
+// because we need to wait for the previous Client to tear down the hardware
+// first.
+void CameraService::incUsers() {
+    android_atomic_inc(&mUsers);
+}
+
+void CameraService::decUsers() {
+    android_atomic_dec(&mUsers);
+}
+
+static sp<MediaPlayer> newMediaPlayer(const char *file)
+{
+    sp<MediaPlayer> mp = new MediaPlayer();
+    if (mp->setDataSource(file, NULL /* headers */) == NO_ERROR) {
+        mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
+        mp->prepare();
+    } else {
+        mp.clear();
+        LOGE("Failed to load CameraService sounds.");
+    }
+    return mp;
+}
+
+CameraService::Client::Client(const sp<CameraService>& cameraService,
+        const sp<ICameraClient>& cameraClient, pid_t clientPid)
+{
+    int callingPid = getCallingPid();
+    LOGV("Client::Client E (pid %d)", callingPid);
+    mCameraService = cameraService;
+    mCameraClient = cameraClient;
+    mClientPid = clientPid;
+    mHardware = openCameraHardware();
+    mUseOverlay = mHardware->useOverlay();
+
+    mHardware->setCallbacks(notifyCallback,
+                            dataCallback,
+                            dataCallbackTimestamp,
+                            mCameraService.get());
+
+    // Enable zoom, error, and focus messages by default
+    mHardware->enableMsgType(CAMERA_MSG_ERROR |
+                             CAMERA_MSG_ZOOM |
+                             CAMERA_MSG_FOCUS);
+
+    mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
+    mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
+    mOverlayW = 0;
+    mOverlayH = 0;
+
+    // Callback is disabled by default
+    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    mOrientation = 0;
+    cameraService->incUsers();
+    LOGV("Client::Client X (pid %d)", callingPid);
+}
+
+status_t CameraService::Client::checkPid()
+{
+    int callingPid = getCallingPid();
+    if (mClientPid == callingPid) return NO_ERROR;
+    LOGW("Attempt to use locked camera (client %p) from different process "
+        " (old pid %d, new pid %d)",
+        getCameraClient()->asBinder().get(), mClientPid, callingPid);
+    return -EBUSY;
+}
+
+status_t CameraService::Client::lock()
+{
+    int callingPid = getCallingPid();
+    LOGV("lock from pid %d (mClientPid %d)", callingPid, mClientPid);
+    Mutex::Autolock _l(mLock);
+    // lock camera to this client if the the camera is unlocked
+    if (mClientPid == 0) {
+        mClientPid = callingPid;
+        return NO_ERROR;
+    }
+    // returns NO_ERROR if the client already owns the camera, -EBUSY otherwise
+    return checkPid();
+}
+
+status_t CameraService::Client::unlock()
+{
+    int callingPid = getCallingPid();
+    LOGV("unlock from pid %d (mClientPid %d)", callingPid, mClientPid);
+    Mutex::Autolock _l(mLock);
+    // allow anyone to use camera
+    status_t result = checkPid();
+    if (result == NO_ERROR) {
+        mClientPid = 0;
+        LOGV("clear mCameraClient (pid %d)", callingPid);
+        // we need to remove the reference so that when app goes
+        // away, the reference count goes to 0.
+        mCameraClient.clear();
+    }
+    return result;
+}
+
+status_t CameraService::Client::connect(const sp<ICameraClient>& client)
+{
+    int callingPid = getCallingPid();
+
+    // connect a new process to the camera
+    LOGV("Client::connect E (pid %d, client %p)", callingPid, client->asBinder().get());
+
+    // I hate this hack, but things get really ugly when the media recorder
+    // service is handing back the camera to the app. The ICameraClient
+    // destructor will be called during the same IPC, making it look like
+    // the remote client is trying to disconnect. This hack temporarily
+    // sets the mClientPid to an invalid pid to prevent the hardware from
+    // being torn down.
+    {
+
+        // hold a reference to the old client or we will deadlock if the client is
+        // in the same process and we hold the lock when we remove the reference
+        sp<ICameraClient> oldClient;
+        {
+            Mutex::Autolock _l(mLock);
+            if (mClientPid != 0 && checkPid() != NO_ERROR) {
+                LOGW("Tried to connect to locked camera (old pid %d, new pid %d)",
+                        mClientPid, callingPid);
+                return -EBUSY;
+            }
+            oldClient = mCameraClient;
+
+            // did the client actually change?
+            if ((mCameraClient != NULL) && (client->asBinder() == mCameraClient->asBinder())) {
+                LOGV("Connect to the same client");
+                return NO_ERROR;
+            }
+
+            mCameraClient = client;
+            mClientPid = -1;
+            mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+            LOGV("Connect to the new client (pid %d, client %p)",
+                callingPid, mCameraClient->asBinder().get());
+        }
+
+    }
+    // the old client destructor is called when oldClient goes out of scope
+    // now we set the new PID to lock the interface again
+    mClientPid = callingPid;
+
+    return NO_ERROR;
+}
+
+#if HAVE_ANDROID_OS
+static void *unregister_surface(void *arg)
+{
+    ISurface *surface = (ISurface *)arg;
+    surface->unregisterBuffers();
+    IPCThreadState::self()->flushCommands();
+    return NULL;
+}
+#endif
+
+CameraService::Client::~Client()
+{
+    int callingPid = getCallingPid();
+
+    // tear down client
+    LOGV("Client::~Client E (pid %d, client %p)",
+            callingPid, getCameraClient()->asBinder().get());
+    if (mSurface != 0 && !mUseOverlay) {
+#if HAVE_ANDROID_OS
+        pthread_t thr;
+        // We unregister the buffers in a different thread because binder does
+        // not let us make sychronous transactions in a binder destructor (that
+        // is, upon our reaching a refcount of zero.)
+        pthread_create(&thr, NULL,
+                       unregister_surface,
+                       mSurface.get());
+        pthread_join(thr, NULL);
+#else
+        mSurface->unregisterBuffers();
+#endif
+    }
+
+    if (mMediaPlayerBeep.get() != NULL) {
+        mMediaPlayerBeep->disconnect();
+        mMediaPlayerBeep.clear();
+    }
+    if (mMediaPlayerClick.get() != NULL) {
+        mMediaPlayerClick->disconnect();
+        mMediaPlayerClick.clear();
+    }
+
+    // make sure we tear down the hardware
+    mClientPid = callingPid;
+    disconnect();
+    LOGV("Client::~Client X (pid %d)", mClientPid);
+}
+
+void CameraService::Client::disconnect()
+{
+    int callingPid = getCallingPid();
+
+    LOGV("Client::disconnect() E (pid %d client %p)",
+            callingPid, getCameraClient()->asBinder().get());
+
+    Mutex::Autolock lock(mLock);
+    if (mClientPid <= 0) {
+        LOGV("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
+        return;
+    }
+    if (checkPid() != NO_ERROR) {
+        LOGV("Different client - don't disconnect");
+        return;
+    }
+
+    // Make sure disconnect() is done once and once only, whether it is called
+    // from the user directly, or called by the destructor.
+    if (mHardware == 0) return;
+
+    LOGV("hardware teardown");
+    // Before destroying mHardware, we must make sure it's in the
+    // idle state.
+    mHardware->stopPreview();
+    // Cancel all picture callbacks.
+    mHardware->disableMsgType(CAMERA_MSG_SHUTTER |
+                              CAMERA_MSG_POSTVIEW_FRAME |
+                              CAMERA_MSG_RAW_IMAGE |
+                              CAMERA_MSG_COMPRESSED_IMAGE);
+    mHardware->cancelPicture();
+    // Turn off remaining messages.
+    mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
+    // Release the hardware resources.
+    mHardware->release();
+    // Release the held overlay resources.
+    if (mUseOverlay)
+    {
+        mOverlayRef = 0;
+    }
+    mHardware.clear();
+
+    mCameraService->removeClient(mCameraClient);
+    mCameraService->decUsers();
+
+    LOGV("Client::disconnect() X (pid %d)", callingPid);
+}
+
+// pass the buffered ISurface to the camera service
+status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
+{
+    LOGV("setPreviewDisplay(%p) (pid %d)",
+         ((surface == NULL) ? NULL : surface.get()), getCallingPid());
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    Mutex::Autolock surfaceLock(mSurfaceLock);
+    result = NO_ERROR;
+    // asBinder() is safe on NULL (returns NULL)
+    if (surface->asBinder() != mSurface->asBinder()) {
+        if (mSurface != 0) {
+            LOGV("clearing old preview surface %p", mSurface.get());
+            if ( !mUseOverlay)
+            {
+                mSurface->unregisterBuffers();
+            }
+            else
+            {
+                // Force the destruction of any previous overlay
+                sp<Overlay> dummy;
+                mHardware->setOverlay( dummy );
+            }
+        }
+        mSurface = surface;
+        mOverlayRef = 0;
+        // If preview has been already started, set overlay or register preview
+        // buffers now.
+        if (mHardware->previewEnabled()) {
+            if (mUseOverlay) {
+                result = setOverlay();
+            } else if (mSurface != 0) {
+                result = registerPreviewBuffers();
+            }
+        }
+    }
+    return result;
+}
+
+// set the preview callback flag to affect how the received frames from
+// preview are handled.
+void CameraService::Client::setPreviewCallbackFlag(int callback_flag)
+{
+    LOGV("setPreviewCallbackFlag (pid %d)", getCallingPid());
+    Mutex::Autolock lock(mLock);
+    if (checkPid() != NO_ERROR) return;
+    mPreviewCallbackFlag = callback_flag;
+
+    if(mUseOverlay) {
+        if(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)
+            mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+        else
+            mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+    }
+}
+
+// start preview mode
+status_t CameraService::Client::startCameraMode(camera_mode mode)
+{
+    int callingPid = getCallingPid();
+
+    LOGV("startCameraMode(%d) (pid %d)", mode, callingPid);
+
+    /* we cannot call into mHardware with mLock held because
+     * mHardware has callbacks onto us which acquire this lock
+     */
+
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    switch(mode) {
+    case CAMERA_RECORDING_MODE:
+        if (mSurface == 0) {
+            LOGE("setPreviewDisplay must be called before startRecordingMode.");
+            return INVALID_OPERATION;
+        }
+        return startRecordingMode();
+
+    default: // CAMERA_PREVIEW_MODE
+        if (mSurface == 0) {
+            LOGV("mSurface is not set yet.");
+        }
+        return startPreviewMode();
+    }
+}
+
+status_t CameraService::Client::startRecordingMode()
+{
+    LOGV("startRecordingMode (pid %d)", getCallingPid());
+
+    status_t ret = UNKNOWN_ERROR;
+
+    // if preview has not been started, start preview first
+    if (!mHardware->previewEnabled()) {
+        ret = startPreviewMode();
+        if (ret != NO_ERROR) {
+            return ret;
+        }
+    }
+
+    // if recording has been enabled, nothing needs to be done
+    if (mHardware->recordingEnabled()) {
+        return NO_ERROR;
+    }
+
+    // start recording mode
+    ret = mHardware->startRecording();
+    if (ret != NO_ERROR) {
+        LOGE("mHardware->startRecording() failed with status %d", ret);
+    }
+    return ret;
+}
+
+status_t CameraService::Client::setOverlay()
+{
+    LOGV("setOverlay");
+    int w, h;
+    CameraParameters params(mHardware->getParameters());
+    params.getPreviewSize(&w, &h);
+
+    if ( w != mOverlayW || h != mOverlayH )
+    {
+        // Force the destruction of any previous overlay
+        sp<Overlay> dummy;
+        mHardware->setOverlay( dummy );
+        mOverlayRef = 0;
+    }
+
+    status_t ret = NO_ERROR;
+    if (mSurface != 0) {
+        if (mOverlayRef.get() == NULL) {
+
+            // FIXME:
+            // Surfaceflinger may hold onto the previous overlay reference for some
+            // time after we try to destroy it. retry a few times. In the future, we
+            // should make the destroy call block, or possibly specify that we can
+            // wait in the createOverlay call if the previous overlay is in the 
+            // process of being destroyed.
+            for (int retry = 0; retry < 50; ++retry) {
+                mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT,
+                                                      mOrientation);
+                if (mOverlayRef != NULL) break;
+                LOGW("Overlay create failed - retrying");
+                usleep(20000);
+            }
+            if ( mOverlayRef.get() == NULL )
+            {
+                LOGE("Overlay Creation Failed!");
+                return -EINVAL;
+            }
+            ret = mHardware->setOverlay(new Overlay(mOverlayRef));
+        }
+    } else {
+        ret = mHardware->setOverlay(NULL);
+    }
+    if (ret != NO_ERROR) {
+        LOGE("mHardware->setOverlay() failed with status %d\n", ret);
+    }
+
+    mOverlayW = w;
+    mOverlayH = h;
+
+    return ret;
+}
+
+status_t CameraService::Client::registerPreviewBuffers()
+{
+    int w, h;
+    CameraParameters params(mHardware->getParameters());
+    params.getPreviewSize(&w, &h);
+
+    // don't use a hardcoded format here
+    ISurface::BufferHeap buffers(w, h, w, h,
+                                 HAL_PIXEL_FORMAT_YCrCb_420_SP,
+                                 mOrientation,
+                                 0,
+                                 mHardware->getPreviewHeap());
+
+    status_t ret = mSurface->registerBuffers(buffers);
+    if (ret != NO_ERROR) {
+        LOGE("registerBuffers failed with status %d", ret);
+    }
+    return ret;
+}
+
+status_t CameraService::Client::startPreviewMode()
+{
+    LOGV("startPreviewMode (pid %d)", getCallingPid());
+
+    // if preview has been enabled, nothing needs to be done
+    if (mHardware->previewEnabled()) {
+        return NO_ERROR;
+    }
+
+    // start preview mode
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+    debug_frame_cnt = 0;
+#endif
+    status_t ret = NO_ERROR;
+
+    if (mUseOverlay) {
+        // If preview display has been set, set overlay now.
+        if (mSurface != 0) {
+            ret = setOverlay();
+        }
+        if (ret != NO_ERROR) return ret;
+        ret = mHardware->startPreview();
+    } else {
+        mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+        ret = mHardware->startPreview();
+        if (ret != NO_ERROR) return ret;
+        // If preview display has been set, register preview buffers now.
+        if (mSurface != 0) {
+           // Unregister here because the surface registered with raw heap.
+           mSurface->unregisterBuffers();
+           ret = registerPreviewBuffers();
+        }
+    }
+    return ret;
+}
+
+status_t CameraService::Client::startPreview()
+{
+    LOGV("startPreview (pid %d)", getCallingPid());
+
+    return startCameraMode(CAMERA_PREVIEW_MODE);
+}
+
+status_t CameraService::Client::startRecording()
+{
+    LOGV("startRecording (pid %d)", getCallingPid());
+
+    if (mMediaPlayerBeep.get() != NULL) {
+        // do not play record jingle if stream volume is 0
+        // (typically because ringer mode is silent).
+        int index;
+        AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+        if (index != 0) {
+            mMediaPlayerBeep->seekTo(0);
+            mMediaPlayerBeep->start();
+        }
+    }
+
+    mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
+
+    return startCameraMode(CAMERA_RECORDING_MODE);
+}
+
+// stop preview mode
+void CameraService::Client::stopPreview()
+{
+    LOGV("stopPreview (pid %d)", getCallingPid());
+
+    // hold main lock during state transition
+    {
+        Mutex::Autolock lock(mLock);
+        if (checkPid() != NO_ERROR) return;
+
+        if (mHardware == 0) {
+            LOGE("mHardware is NULL, returning.");
+            return;
+        }
+
+        mHardware->stopPreview();
+        mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+        LOGV("stopPreview(), hardware stopped OK");
+
+        if (mSurface != 0 && !mUseOverlay) {
+            mSurface->unregisterBuffers();
+        }
+    }
+
+    // hold preview buffer lock
+    {
+        Mutex::Autolock lock(mPreviewLock);
+        mPreviewBuffer.clear();
+    }
+}
+
+// stop recording mode
+void CameraService::Client::stopRecording()
+{
+    LOGV("stopRecording (pid %d)", getCallingPid());
+
+    // hold main lock during state transition
+    {
+        Mutex::Autolock lock(mLock);
+        if (checkPid() != NO_ERROR) return;
+
+        if (mHardware == 0) {
+            LOGE("mHardware is NULL, returning.");
+            return;
+        }
+
+        if (mMediaPlayerBeep.get() != NULL) {
+            mMediaPlayerBeep->seekTo(0);
+            mMediaPlayerBeep->start();
+        }
+
+        mHardware->stopRecording();
+        mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
+        LOGV("stopRecording(), hardware stopped OK");
+    }
+
+    // hold preview buffer lock
+    {
+        Mutex::Autolock lock(mPreviewLock);
+        mPreviewBuffer.clear();
+    }
+}
+
+// release a recording frame
+void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+    Mutex::Autolock lock(mLock);
+    if (checkPid() != NO_ERROR) return;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return;
+    }
+
+    mHardware->releaseRecordingFrame(mem);
+}
+
+bool CameraService::Client::previewEnabled()
+{
+    Mutex::Autolock lock(mLock);
+    if (mHardware == 0) return false;
+    return mHardware->previewEnabled();
+}
+
+bool CameraService::Client::recordingEnabled()
+{
+    Mutex::Autolock lock(mLock);
+    if (mHardware == 0) return false;
+    return mHardware->recordingEnabled();
+}
+
+// Safely retrieves a strong pointer to the client during a hardware callback.
+sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user)
+{
+    sp<Client> client = 0;
+    CameraService *service = static_cast<CameraService*>(user);
+    if (service != NULL) {
+        Mutex::Autolock ourLock(service->mServiceLock);
+        if (service->mClient != 0) {
+            client = service->mClient.promote();
+            if (client == 0) {
+                LOGE("getClientFromCookie: client appears to have died");
+                service->mClient.clear();
+            }
+        } else {
+            LOGE("getClientFromCookie: got callback but client was NULL");
+        }
+    }
+    return client;
+}
+
+
+#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE || \
+    DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE || \
+    DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+static void dump_to_file(const char *fname,
+                         uint8_t *buf, uint32_t size)
+{
+    int nw, cnt = 0;
+    uint32_t written = 0;
+
+    LOGV("opening file [%s]\n", fname);
+    int fd = open(fname, O_RDWR | O_CREAT);
+    if (fd < 0) {
+        LOGE("failed to create file [%s]: %s", fname, strerror(errno));
+        return;
+    }
+
+    LOGV("writing %d bytes to file [%s]\n", size, fname);
+    while (written < size) {
+        nw = ::write(fd,
+                     buf + written,
+                     size - written);
+        if (nw < 0) {
+            LOGE("failed to write to file [%s]: %s",
+                 fname, strerror(errno));
+            break;
+        }
+        written += nw;
+        cnt++;
+    }
+    LOGV("done writing %d bytes to file [%s] in %d passes\n",
+         size, fname, cnt);
+    ::close(fd);
+}
+#endif
+
+status_t CameraService::Client::autoFocus()
+{
+    LOGV("autoFocus (pid %d)", getCallingPid());
+
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    return mHardware->autoFocus();
+}
+
+status_t CameraService::Client::cancelAutoFocus()
+{
+    LOGV("cancelAutoFocus (pid %d)", getCallingPid());
+
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    return mHardware->cancelAutoFocus();
+}
+
+// take a picture - image is returned in callback
+status_t CameraService::Client::takePicture()
+{
+    LOGV("takePicture (pid %d)", getCallingPid());
+
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    mHardware->enableMsgType(CAMERA_MSG_SHUTTER |
+                             CAMERA_MSG_POSTVIEW_FRAME |
+                             CAMERA_MSG_RAW_IMAGE |
+                             CAMERA_MSG_COMPRESSED_IMAGE);
+
+    return mHardware->takePicture();
+}
+
+// snapshot taken
+void CameraService::Client::handleShutter(
+    image_rect_type *size // The width and height of yuv picture for
+                          // registerBuffer. If this is NULL, use the picture
+                          // size from parameters.
+)
+{
+    // Play shutter sound.
+    if (mMediaPlayerClick.get() != NULL) {
+        // do not play shutter sound if stream volume is 0
+        // (typically because ringer mode is silent).
+        int index;
+        AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+        if (index != 0) {
+            mMediaPlayerClick->seekTo(0);
+            mMediaPlayerClick->start();
+        }
+    }
+
+    // Screen goes black after the buffer is unregistered.
+    if (mSurface != 0 && !mUseOverlay) {
+        mSurface->unregisterBuffers();
+    }
+
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
+    }
+    mHardware->disableMsgType(CAMERA_MSG_SHUTTER);
+
+    // It takes some time before yuvPicture callback to be called.
+    // Register the buffer for raw image here to reduce latency.
+    if (mSurface != 0 && !mUseOverlay) {
+        int w, h;
+        CameraParameters params(mHardware->getParameters());
+        if (size == NULL) {
+            params.getPictureSize(&w, &h);
+        } else {
+            w = size->width;
+            h = size->height;
+            w &= ~1;
+            h &= ~1;
+            LOGV("Snapshot image width=%d, height=%d", w, h);
+        }
+        // FIXME: don't use hardcoded format constants here
+        ISurface::BufferHeap buffers(w, h, w, h,
+            HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0,
+            mHardware->getRawHeap());
+
+        mSurface->registerBuffers(buffers);
+    }
+}
+
+// preview callback - frame buffer update
+void CameraService::Client::handlePreviewData(const sp<IMemory>& mem)
+{
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+
+#if DEBUG_HEAP_LEAKS && 0 // debugging
+    if (gWeakHeap == NULL) {
+        if (gWeakHeap != heap) {
+            LOGV("SETTING PREVIEW HEAP");
+            heap->trackMe(true, true);
+            gWeakHeap = heap;
+        }
+    }
+#endif
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+    {
+        if (debug_frame_cnt++ == DEBUG_DUMP_PREVIEW_FRAME_TO_FILE) {
+            dump_to_file("/data/preview.yuv",
+                         (uint8_t *)heap->base() + offset, size);
+        }
+    }
+#endif
+
+    if (!mUseOverlay)
+    {
+        Mutex::Autolock surfaceLock(mSurfaceLock);
+        if (mSurface != NULL) {
+            mSurface->postBuffer(offset);
+        }
+    }
+
+    // local copy of the callback flags
+    int flags = mPreviewCallbackFlag;
+
+    // is callback enabled?
+    if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
+        // If the enable bit is off, the copy-out and one-shot bits are ignored
+        LOGV("frame callback is diabled");
+        return;
+    }
+
+    // hold a strong pointer to the client
+    sp<ICameraClient> c = mCameraClient;
+
+    // clear callback flags if no client or one-shot mode
+    if ((c == NULL) || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
+        LOGV("Disable preview callback");
+        mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
+                                FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
+                                FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        // TODO: Shouldn't we use this API for non-overlay hardware as well?
+        if (mUseOverlay)
+            mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+    }
+
+    // Is the received frame copied out or not?
+    if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
+        LOGV("frame is copied");
+        copyFrameAndPostCopiedFrame(c, heap, offset, size);
+    } else {
+        LOGV("frame is forwarded");
+        c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+    }
+}
+
+// picture callback - postview image ready
+void CameraService::Client::handlePostview(const sp<IMemory>& mem)
+{
+#if DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE // for testing pursposes only
+    {
+        ssize_t offset;
+        size_t size;
+        sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+        dump_to_file("/data/postview.yuv",
+                     (uint8_t *)heap->base() + offset, size);
+    }
+#endif
+
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+    }
+    mHardware->disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
+}
+
+// picture callback - raw image ready
+void CameraService::Client::handleRawPicture(const sp<IMemory>& mem)
+{
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+#if DEBUG_HEAP_LEAKS && 0 // debugging
+    gWeakHeap = heap; // debugging
+#endif
+
+    //LOGV("handleRawPicture(%d, %d)", offset, size);
+#if DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE // for testing pursposes only
+    dump_to_file("/data/photo.yuv",
+                 (uint8_t *)heap->base() + offset, size);
+#endif
+
+    // Put the YUV version of the snapshot in the preview display.
+    if (mSurface != 0 && !mUseOverlay) {
+        mSurface->postBuffer(offset);
+    }
+
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+    }
+    mHardware->disableMsgType(CAMERA_MSG_RAW_IMAGE);
+}
+
+// picture callback - compressed picture ready
+void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem)
+{
+#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE // for testing pursposes only
+    {
+        ssize_t offset;
+        size_t size;
+        sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+        dump_to_file("/data/photo.jpg",
+                     (uint8_t *)heap->base() + offset, size);
+    }
+#endif
+
+    sp<ICameraClient> c = mCameraClient;
+    if (c != NULL) {
+        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+    }
+    mHardware->disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+}
+
+void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user)
+{
+    LOGV("notifyCallback(%d)", msgType);
+
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+
+    switch (msgType) {
+        case CAMERA_MSG_SHUTTER:
+            // ext1 is the dimension of the yuv picture.
+            client->handleShutter((image_rect_type *)ext1);
+            break;
+        default:
+            sp<ICameraClient> c = client->mCameraClient;
+            if (c != NULL) {
+                c->notifyCallback(msgType, ext1, ext2);
+            }
+            break;
+    }
+
+#if DEBUG_CLIENT_REFERENCES
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (NOTIFY CALLBACK) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user)
+{
+    LOGV("dataCallback(%d)", msgType);
+
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+
+    sp<ICameraClient> c = client->mCameraClient;
+    if (dataPtr == NULL) {
+        LOGE("Null data returned in data callback");
+        if (c != NULL) {
+            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
+            c->dataCallback(msgType, NULL);
+        }
+        return;
+    }
+
+    switch (msgType) {
+        case CAMERA_MSG_PREVIEW_FRAME:
+            client->handlePreviewData(dataPtr);
+            break;
+        case CAMERA_MSG_POSTVIEW_FRAME:
+            client->handlePostview(dataPtr);
+            break;
+        case CAMERA_MSG_RAW_IMAGE:
+            client->handleRawPicture(dataPtr);
+            break;
+        case CAMERA_MSG_COMPRESSED_IMAGE:
+            client->handleCompressedPicture(dataPtr);
+            break;
+        default:
+            if (c != NULL) {
+                c->dataCallback(msgType, dataPtr);
+            }
+            break;
+    }
+
+#if DEBUG_CLIENT_REFERENCES
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (DATA CALLBACK) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
+                                                  const sp<IMemory>& dataPtr, void* user)
+{
+    LOGV("dataCallbackTimestamp(%d)", msgType);
+
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+    sp<ICameraClient> c = client->mCameraClient;
+
+    if (dataPtr == NULL) {
+        LOGE("Null data returned in data with timestamp callback");
+        if (c != NULL) {
+            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
+            c->dataCallbackTimestamp(0, msgType, NULL);
+        }
+        return;
+    }
+
+    if (c != NULL) {
+        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+    }
+
+#if DEBUG_CLIENT_REFERENCES
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (DATA CALLBACK TIMESTAMP) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+// set preview/capture parameters - key/value pairs
+status_t CameraService::Client::setParameters(const String8& params)
+{
+    LOGV("setParameters(%s)", params.string());
+
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    CameraParameters p(params);
+
+    return mHardware->setParameters(p);
+}
+
+// get preview/capture parameters - key/value pairs
+String8 CameraService::Client::getParameters() const
+{
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return String8();
+    }
+
+    String8 params(mHardware->getParameters().flatten());
+    LOGV("getParameters(%s)", params.string());
+    return params;
+}
+
+status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+{
+    LOGV("sendCommand (pid %d)", getCallingPid());
+    Mutex::Autolock lock(mLock);
+    status_t result = checkPid();
+    if (result != NO_ERROR) return result;
+
+    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
+        // The orientation cannot be set during preview.
+        if (mHardware->previewEnabled()) {
+            return INVALID_OPERATION;
+        }
+        switch (arg1) {
+            case 0:
+                mOrientation = ISurface::BufferHeap::ROT_0;
+                break;
+            case 90:
+                mOrientation = ISurface::BufferHeap::ROT_90;
+                break;
+            case 180:
+                mOrientation = ISurface::BufferHeap::ROT_180;
+                break;
+            case 270:
+                mOrientation = ISurface::BufferHeap::ROT_270;
+                break;
+            default:
+                return BAD_VALUE;
+        }
+        return OK;
+    }
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    return mHardware->sendCommand(cmd, arg1, arg2);
+}
+
+void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
+        const sp<IMemoryHeap>& heap, size_t offset, size_t size)
+{
+    LOGV("copyFrameAndPostCopiedFrame");
+    // It is necessary to copy out of pmem before sending this to
+    // the callback. For efficiency, reuse the same MemoryHeapBase
+    // provided it's big enough. Don't allocate the memory or
+    // perform the copy if there's no callback.
+
+    // hold the preview lock while we grab a reference to the preview buffer
+    sp<MemoryHeapBase> previewBuffer;
+    {
+        Mutex::Autolock lock(mPreviewLock);
+        if (mPreviewBuffer == 0) {
+            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+        } else if (size > mPreviewBuffer->virtualSize()) {
+            mPreviewBuffer.clear();
+            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+        }
+        if (mPreviewBuffer == 0) {
+            LOGE("failed to allocate space for preview buffer");
+            return;
+        }
+        previewBuffer = mPreviewBuffer;
+    }
+    memcpy(previewBuffer->base(),
+           (uint8_t *)heap->base() + offset, size);
+
+    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
+    if (frame == 0) {
+        LOGE("failed to allocate space for frame callback");
+        return;
+    }
+    client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+}
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 60000;
+
+static bool tryLock(Mutex& mutex)
+{
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+status_t CameraService::dump(int fd, const Vector<String16>& args)
+{
+    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
+
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        snprintf(buffer, SIZE, "Permission Denial: "
+                "can't dump CameraService from pid=%d, uid=%d\n",
+                getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+        write(fd, result.string(), result.size());
+    } else {
+        bool locked = tryLock(mServiceLock);
+        // failed to lock - CameraService is probably deadlocked
+        if (!locked) {
+            String8 result(kDeadlockedString);
+            write(fd, result.string(), result.size());
+        }
+
+        if (mClient != 0) {
+            sp<Client> currentClient = mClient.promote();
+            sprintf(buffer, "Client (%p) PID: %d\n",
+                    currentClient->getCameraClient()->asBinder().get(),
+                    currentClient->mClientPid);
+            result.append(buffer);
+            write(fd, result.string(), result.size());
+            currentClient->mHardware->dump(fd, args);
+        } else {
+            result.append("No camera client yet.\n");
+            write(fd, result.string(), result.size());
+        }
+
+        if (locked) mServiceLock.unlock();
+    }
+    return NO_ERROR;
+}
+
+
+status_t CameraService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // permission checks...
+    switch (code) {
+        case BnCameraService::CONNECT:
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (pid != self_pid) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.CAMERA")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't use the camera pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+            break;
+    }
+
+    status_t err = BnCameraService::onTransact(code, data, reply, flags);
+
+#if DEBUG_HEAP_LEAKS
+    LOGV("+++ onTransact err %d code %d", err, code);
+
+    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
+        // the 'service' command interrogates this binder for its name, and then supplies it
+        // even for the debugging commands.  that means we need to check for it here, using
+        // ISurfaceComposer (since we delegated the INTERFACE_TRANSACTION handling to
+        // BnSurfaceComposer before falling through to this code).
+
+        LOGV("+++ onTransact code %d", code);
+
+        CHECK_INTERFACE(ICameraService, data, reply);
+
+        switch(code) {
+        case 1000:
+        {
+            if (gWeakHeap != 0) {
+                sp<IMemoryHeap> h = gWeakHeap.promote();
+                IMemoryHeap *p = gWeakHeap.unsafe_get();
+                LOGV("CHECKING WEAK REFERENCE %p (%p)", h.get(), p);
+                if (h != 0)
+                    h->printRefs();
+                bool attempt_to_delete = data.readInt32() == 1;
+                if (attempt_to_delete) {
+                    // NOT SAFE!
+                    LOGV("DELETING WEAK REFERENCE %p (%p)", h.get(), p);
+                    if (p) delete p;
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+        default:
+            break;
+        }
+    }
+#endif // DEBUG_HEAP_LEAKS
+
+    return err;
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
new file mode 100644
index 0000000..bc49b1d
--- /dev/null
+++ b/services/camera/libcameraservice/CameraService.h
@@ -0,0 +1,227 @@
+/*
+**
+** Copyright (C) 2008, The Android Open Source Project
+** Copyright (C) 2008 HTC Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
+#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
+
+#include <camera/ICameraService.h>
+#include <camera/CameraHardwareInterface.h>
+#include <camera/Camera.h>
+
+namespace android {
+
+class MemoryHeapBase;
+class MediaPlayer;
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// When enabled, this feature allows you to send an event to the CameraService
+// so that you can cause all references to the heap object gWeakHeap, defined
+// below, to be printed. You will also need to set DEBUG_REFS=1 and
+// DEBUG_REFS_ENABLED_BY_DEFAULT=0 in libutils/RefBase.cpp. You just have to
+// set gWeakHeap to the appropriate heap you want to track.
+
+#define DEBUG_HEAP_LEAKS 0
+
+// ----------------------------------------------------------------------------
+
+class CameraService : public BnCameraService
+{
+    class Client;
+
+public:
+    static void instantiate();
+
+    // ICameraService interface
+    virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient);
+
+    virtual status_t        dump(int fd, const Vector<String16>& args);
+
+            void            removeClient(const sp<ICameraClient>& cameraClient);
+
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
+private:
+
+// ----------------------------------------------------------------------------
+
+    class Client : public BnCamera {
+
+    public:
+        virtual void            disconnect();
+
+        // connect new client with existing camera remote
+        virtual status_t        connect(const sp<ICameraClient>& client);
+
+        // prevent other processes from using this ICamera interface
+        virtual status_t        lock();
+
+        // allow other processes to use this ICamera interface
+        virtual status_t        unlock();
+
+        // pass the buffered ISurface to the camera service
+        virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);
+
+        // set the preview callback flag to affect how the received frames from
+        // preview are handled.
+        virtual void            setPreviewCallbackFlag(int callback_flag);
+
+        // start preview mode, must call setPreviewDisplay first
+        virtual status_t        startPreview();
+
+        // stop preview mode
+        virtual void            stopPreview();
+
+        // get preview state
+        virtual bool            previewEnabled();
+
+        // start recording mode
+        virtual status_t        startRecording();
+
+        // stop recording mode
+        virtual void            stopRecording();
+
+        // get recording state
+        virtual bool            recordingEnabled();
+
+        // release a recording frame
+        virtual void            releaseRecordingFrame(const sp<IMemory>& mem);
+
+        // auto focus
+        virtual status_t        autoFocus();
+
+        // cancel auto focus
+        virtual status_t        cancelAutoFocus();
+
+        // take a picture - returns an IMemory (ref-counted mmap)
+        virtual status_t        takePicture();
+
+        // set preview/capture parameters - key/value pairs
+        virtual status_t        setParameters(const String8& params);
+
+        // get preview/capture parameters - key/value pairs
+        virtual String8         getParameters() const;
+
+        // send command to camera driver
+        virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+
+        // our client...
+        const sp<ICameraClient>&    getCameraClient() const { return mCameraClient; }
+
+    private:
+        friend class CameraService;
+                                Client(const sp<CameraService>& cameraService,
+                                        const sp<ICameraClient>& cameraClient,
+                                        pid_t clientPid);
+                                Client();
+        virtual                 ~Client();
+
+                    status_t    checkPid();
+
+        static      void        notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
+        static      void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
+        static      void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
+                                                      const sp<IMemory>& dataPtr, void* user);
+
+        static      sp<Client>  getClientFromCookie(void* user);
+
+                    void        handlePreviewData(const sp<IMemory>&);
+                    void        handleShutter(image_rect_type *image);
+                    void        handlePostview(const sp<IMemory>&);
+                    void        handleRawPicture(const sp<IMemory>&);
+                    void        handleCompressedPicture(const sp<IMemory>&);
+
+                    void        copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
+                                    const sp<IMemoryHeap>& heap, size_t offset, size_t size);
+
+        // camera operation mode
+        enum camera_mode {
+            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
+            CAMERA_RECORDING_MODE = 1,  // frame has to be explicitly released by releaseRecordingFrame()
+        };
+        status_t                startCameraMode(camera_mode mode);
+        status_t                startPreviewMode();
+        status_t                startRecordingMode();
+        status_t                setOverlay();
+        status_t                registerPreviewBuffers();
+
+        // Ensures atomicity among the public methods
+        mutable     Mutex                       mLock;
+
+        // mSurfaceLock synchronizes access to mSurface between
+        // setPreviewSurface() and postPreviewFrame().  Note that among
+        // the public methods, all accesses to mSurface are
+        // syncrhonized by mLock.  However, postPreviewFrame() is called
+        // by the CameraHardwareInterface callback, and needs to
+        // access mSurface.  It cannot hold mLock, however, because
+        // stopPreview() may be holding that lock while attempting
+        // to stop preview, and stopPreview itself will block waiting
+        // for a callback from CameraHardwareInterface.  If this
+        // happens, it will cause a deadlock.
+        mutable     Mutex                       mSurfaceLock;
+        mutable     Condition                   mReady;
+                    sp<CameraService>           mCameraService;
+                    sp<ISurface>                mSurface;
+                    int                         mPreviewCallbackFlag;
+                    int                         mOrientation;
+
+                    sp<MediaPlayer>             mMediaPlayerClick;
+                    sp<MediaPlayer>             mMediaPlayerBeep;
+
+                    // these are immutable once the object is created,
+                    // they don't need to be protected by a lock
+                    sp<ICameraClient>           mCameraClient;
+                    sp<CameraHardwareInterface> mHardware;
+                    pid_t                       mClientPid;
+                    bool                        mUseOverlay;
+
+                    sp<OverlayRef>              mOverlayRef;
+                    int                         mOverlayW;
+                    int                         mOverlayH;
+
+        mutable     Mutex                       mPreviewLock;
+                    sp<MemoryHeapBase>          mPreviewBuffer;
+    };
+
+// ----------------------------------------------------------------------------
+
+                            CameraService();
+    virtual                 ~CameraService();
+
+    // We use a count for number of clients (shoule only be 0 or 1).
+    volatile    int32_t                     mUsers;
+    virtual     void                        incUsers();
+    virtual     void                        decUsers();
+
+    mutable     Mutex                       mServiceLock;
+                wp<Client>                  mClient;
+
+#if DEBUG_HEAP_LEAKS
+                wp<IMemoryHeap>             gWeakHeap;
+#endif
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/CannedJpeg.h b/services/camera/libcameraservice/CannedJpeg.h
new file mode 100644
index 0000000..b6266fb
--- /dev/null
+++ b/services/camera/libcameraservice/CannedJpeg.h
@@ -0,0 +1,734 @@
+const int kCannedJpegWidth = 320;
+const int kCannedJpegHeight = 240;
+const int kCannedJpegSize = 8733;
+
+const char kCannedJpeg[] = {
+  0xff,  0xd8,  0xff,  0xe0,  0x00,  0x10,  0x4a,  0x46,  0x49,  0x46,  0x00,  0x01,
+  0x01,  0x01,  0x00,  0x60,  0x00,  0x60,  0x00,  0x00,  0xff,  0xe1,  0x00,  0x66,
+  0x45,  0x78,  0x69,  0x66,  0x00,  0x00,  0x49,  0x49,  0x2a,  0x00,  0x08,  0x00,
+  0x00,  0x00,  0x04,  0x00,  0x1a,  0x01,  0x05,  0x00,  0x01,  0x00,  0x00,  0x00,
+  0x3e,  0x00,  0x00,  0x00,  0x1b,  0x01,  0x05,  0x00,  0x01,  0x00,  0x00,  0x00,
+  0x46,  0x00,  0x00,  0x00,  0x28,  0x01,  0x03,  0x00,  0x01,  0x00,  0x00,  0x00,
+  0x02,  0x00,  0x00,  0x00,  0x31,  0x01,  0x02,  0x00,  0x10,  0x00,  0x00,  0x00,
+  0x4e,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60,  0x00,  0x00,  0x00,
+  0x01,  0x00,  0x00,  0x00,  0x60,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x00,
+  0x50,  0x61,  0x69,  0x6e,  0x74,  0x2e,  0x4e,  0x45,  0x54,  0x20,  0x76,  0x33,
+  0x2e,  0x33,  0x36,  0x00,  0xff,  0xdb,  0x00,  0x43,  0x00,  0x03,  0x02,  0x02,
+  0x03,  0x02,  0x02,  0x03,  0x03,  0x03,  0x03,  0x04,  0x03,  0x03,  0x04,  0x05,
+  0x08,  0x05,  0x05,  0x04,  0x04,  0x05,  0x0a,  0x07,  0x07,  0x06,  0x08,  0x0c,
+  0x0a,  0x0c,  0x0c,  0x0b,  0x0a,  0x0b,  0x0b,  0x0d,  0x0e,  0x12,  0x10,  0x0d,
+  0x0e,  0x11,  0x0e,  0x0b,  0x0b,  0x10,  0x16,  0x10,  0x11,  0x13,  0x14,  0x15,
+  0x15,  0x15,  0x0c,  0x0f,  0x17,  0x18,  0x16,  0x14,  0x18,  0x12,  0x14,  0x15,
+  0x14,  0xff,  0xdb,  0x00,  0x43,  0x01,  0x03,  0x04,  0x04,  0x05,  0x04,  0x05,
+  0x09,  0x05,  0x05,  0x09,  0x14,  0x0d,  0x0b,  0x0d,  0x14,  0x14,  0x14,  0x14,
+  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
+  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
+  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
+  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0xff,  0xc0,
+  0x00,  0x11,  0x08,  0x00,  0xf0,  0x01,  0x40,  0x03,  0x01,  0x22,  0x00,  0x02,
+  0x11,  0x01,  0x03,  0x11,  0x01,  0xff,  0xc4,  0x00,  0x1f,  0x00,  0x00,  0x01,
+  0x05,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,  0x08,  0x09,
+  0x0a,  0x0b,  0xff,  0xc4,  0x00,  0xb5,  0x10,  0x00,  0x02,  0x01,  0x03,  0x03,
+  0x02,  0x04,  0x03,  0x05,  0x05,  0x04,  0x04,  0x00,  0x00,  0x01,  0x7d,  0x01,
+  0x02,  0x03,  0x00,  0x04,  0x11,  0x05,  0x12,  0x21,  0x31,  0x41,  0x06,  0x13,
+  0x51,  0x61,  0x07,  0x22,  0x71,  0x14,  0x32,  0x81,  0x91,  0xa1,  0x08,  0x23,
+  0x42,  0xb1,  0xc1,  0x15,  0x52,  0xd1,  0xf0,  0x24,  0x33,  0x62,  0x72,  0x82,
+  0x09,  0x0a,  0x16,  0x17,  0x18,  0x19,  0x1a,  0x25,  0x26,  0x27,  0x28,  0x29,
+  0x2a,  0x34,  0x35,  0x36,  0x37,  0x38,  0x39,  0x3a,  0x43,  0x44,  0x45,  0x46,
+  0x47,  0x48,  0x49,  0x4a,  0x53,  0x54,  0x55,  0x56,  0x57,  0x58,  0x59,  0x5a,
+  0x63,  0x64,  0x65,  0x66,  0x67,  0x68,  0x69,  0x6a,  0x73,  0x74,  0x75,  0x76,
+  0x77,  0x78,  0x79,  0x7a,  0x83,  0x84,  0x85,  0x86,  0x87,  0x88,  0x89,  0x8a,
+  0x92,  0x93,  0x94,  0x95,  0x96,  0x97,  0x98,  0x99,  0x9a,  0xa2,  0xa3,  0xa4,
+  0xa5,  0xa6,  0xa7,  0xa8,  0xa9,  0xaa,  0xb2,  0xb3,  0xb4,  0xb5,  0xb6,  0xb7,
+  0xb8,  0xb9,  0xba,  0xc2,  0xc3,  0xc4,  0xc5,  0xc6,  0xc7,  0xc8,  0xc9,  0xca,
+  0xd2,  0xd3,  0xd4,  0xd5,  0xd6,  0xd7,  0xd8,  0xd9,  0xda,  0xe1,  0xe2,  0xe3,
+  0xe4,  0xe5,  0xe6,  0xe7,  0xe8,  0xe9,  0xea,  0xf1,  0xf2,  0xf3,  0xf4,  0xf5,
+  0xf6,  0xf7,  0xf8,  0xf9,  0xfa,  0xff,  0xc4,  0x00,  0x1f,  0x01,  0x00,  0x03,
+  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,  0x08,  0x09,
+  0x0a,  0x0b,  0xff,  0xc4,  0x00,  0xb5,  0x11,  0x00,  0x02,  0x01,  0x02,  0x04,
+  0x04,  0x03,  0x04,  0x07,  0x05,  0x04,  0x04,  0x00,  0x01,  0x02,  0x77,  0x00,
+  0x01,  0x02,  0x03,  0x11,  0x04,  0x05,  0x21,  0x31,  0x06,  0x12,  0x41,  0x51,
+  0x07,  0x61,  0x71,  0x13,  0x22,  0x32,  0x81,  0x08,  0x14,  0x42,  0x91,  0xa1,
+  0xb1,  0xc1,  0x09,  0x23,  0x33,  0x52,  0xf0,  0x15,  0x62,  0x72,  0xd1,  0x0a,
+  0x16,  0x24,  0x34,  0xe1,  0x25,  0xf1,  0x17,  0x18,  0x19,  0x1a,  0x26,  0x27,
+  0x28,  0x29,  0x2a,  0x35,  0x36,  0x37,  0x38,  0x39,  0x3a,  0x43,  0x44,  0x45,
+  0x46,  0x47,  0x48,  0x49,  0x4a,  0x53,  0x54,  0x55,  0x56,  0x57,  0x58,  0x59,
+  0x5a,  0x63,  0x64,  0x65,  0x66,  0x67,  0x68,  0x69,  0x6a,  0x73,  0x74,  0x75,
+  0x76,  0x77,  0x78,  0x79,  0x7a,  0x82,  0x83,  0x84,  0x85,  0x86,  0x87,  0x88,
+  0x89,  0x8a,  0x92,  0x93,  0x94,  0x95,  0x96,  0x97,  0x98,  0x99,  0x9a,  0xa2,
+  0xa3,  0xa4,  0xa5,  0xa6,  0xa7,  0xa8,  0xa9,  0xaa,  0xb2,  0xb3,  0xb4,  0xb5,
+  0xb6,  0xb7,  0xb8,  0xb9,  0xba,  0xc2,  0xc3,  0xc4,  0xc5,  0xc6,  0xc7,  0xc8,
+  0xc9,  0xca,  0xd2,  0xd3,  0xd4,  0xd5,  0xd6,  0xd7,  0xd8,  0xd9,  0xda,  0xe2,
+  0xe3,  0xe4,  0xe5,  0xe6,  0xe7,  0xe8,  0xe9,  0xea,  0xf2,  0xf3,  0xf4,  0xf5,
+  0xf6,  0xf7,  0xf8,  0xf9,  0xfa,  0xff,  0xda,  0x00,  0x0c,  0x03,  0x01,  0x00,
+  0x02,  0x11,  0x03,  0x11,  0x00,  0x3f,  0x00,  0xf9,  0xd2,  0xa3,  0x95,  0xbb,
+  0x54,  0x84,  0xe0,  0x66,  0xa0,  0x27,  0x27,  0x35,  0xed,  0x9e,  0x50,  0x95,
+  0x2c,  0x4b,  0xc6,  0x6a,  0x35,  0x1b,  0x8e,  0x2a,  0x70,  0x30,  0x28,  0x00,
+  0xa8,  0xe5,  0x6e,  0x71,  0x52,  0x31,  0xda,  0x33,  0x50,  0x13,  0x93,  0x40,
+  0x09,  0x52,  0xc6,  0xb8,  0x19,  0xf5,  0xa6,  0x2a,  0xee,  0x6c,  0x54,  0xd4,
+  0x00,  0x54,  0x52,  0x36,  0x5b,  0x1e,  0x95,  0x23,  0xb6,  0xd5,  0xcd,  0x41,
+  0x40,  0x05,  0x4c,  0x8b,  0xb5,  0x7d,  0xea,  0x34,  0x5d,  0xcd,  0xed,  0x53,
+  0x50,  0x01,  0x50,  0xbb,  0x6e,  0x6f,  0x6a,  0x91,  0xdb,  0x6a,  0xfb,  0xd4,
+  0x34,  0x00,  0x54,  0xe8,  0xbb,  0x57,  0x15,  0x1c,  0x6b,  0x96,  0xcf,  0xa5,
+  0x4b,  0x40,  0x05,  0x42,  0xcd,  0xb9,  0xb3,  0x4f,  0x91,  0xb0,  0x31,  0xeb,
+  0x51,  0x50,  0x02,  0x81,  0x93,  0x53,  0xa8,  0xda,  0x31,  0x51,  0xc4,  0xbc,
+  0xe6,  0xa4,  0xa0,  0x00,  0x9c,  0x0a,  0x81,  0x8e,  0xe3,  0x9a,  0x92,  0x56,
+  0xe3,  0x15,  0x15,  0x00,  0x28,  0x19,  0x38,  0xa9,  0xc0,  0xc0,  0xc5,  0x47,
+  0x12,  0xf7,  0xa9,  0x28,  0x00,  0x27,  0x00,  0x9a,  0x80,  0x9c,  0x9c,  0xd3,
+  0xe5,  0x6e,  0xd5,  0x1d,  0x00,  0x2a,  0x8d,  0xc7,  0x15,  0x3d,  0x32,  0x35,
+  0xc0,  0xcf,  0xad,  0x3e,  0x80,  0x11,  0x8e,  0xd1,  0x9a,  0x82,  0x9f,  0x23,
+  0x64,  0xe3,  0xd2,  0x99,  0x40,  0x0e,  0x45,  0xdc,  0xde,  0xd5,  0x35,  0x36,
+  0x35,  0xc2,  0xfb,  0x9a,  0x75,  0x00,  0x35,  0xdb,  0x6a,  0xfb,  0xd4,  0x34,
+  0xe9,  0x1b,  0x73,  0x7b,  0x0a,  0x6d,  0x00,  0x3e,  0x35,  0xcb,  0x7b,  0x0a,
+  0x96,  0x91,  0x17,  0x6a,  0xd2,  0xd0,  0x03,  0x64,  0x6c,  0x2f,  0xb9,  0xa8,
+  0x69,  0xce,  0xdb,  0x9a,  0x9b,  0xd6,  0x80,  0x1f,  0x12,  0xe4,  0xe7,  0xd2,
+  0xa5,  0xa4,  0x51,  0xb4,  0x62,  0x97,  0xa5,  0x00,  0x67,  0xc9,  0xad,  0xd8,
+  0x91,  0x81,  0x72,  0x9f,  0x9d,  0x47,  0xfd,  0xb3,  0x65,  0xff,  0x00,  0x3f,
+  0x29,  0x5f,  0xa0,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,
+  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,
+  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd7,  0x3f,  0xb7,  0x87,  0x73,  0x6f,
+  0x63,  0x33,  0xe0,  0x28,  0xf5,  0x9b,  0x11,  0xc9,  0xb9,  0x4c,  0xfd,  0x69,
+  0xff,  0x00,  0xdb,  0x96,  0x1f,  0xf3,  0xf5,  0x1f,  0xe7,  0x5f,  0x7d,  0x7f,
+  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,
+  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,  0x0f,  0xba,  0xd7,
+  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x87,  0x70,  0xf6,  0x33,  0x3e,  0x02,  0x93,
+  0x5b,  0xb1,  0x3c,  0x0b,  0x94,  0xc7,  0xd6,  0x99,  0xfd,  0xb3,  0x65,  0xff,
+  0x00,  0x3f,  0x29,  0xf9,  0xd7,  0xe8,  0x07,  0xfc,  0x3a,  0x5b,  0xc2,  0x5f,
+  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,
+  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0xbd,  0xbc,  0x03,  0xd8,
+  0xcc,  0xf8,  0x0e,  0x3d,  0x6a,  0xc1,  0x47,  0x37,  0x29,  0x9f,  0xad,  0x3b,
+  0xfb,  0x72,  0xc3,  0xfe,  0x7e,  0xa3,  0xfc,  0xeb,  0xef,  0xaf,  0xf8,  0x74,
+  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,  0x3f,  0xe1,
+  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,  0x48,
+  0x69,  0xfb,  0x78,  0x77,  0x0f,  0x63,  0x33,  0xe0,  0x19,  0x35,  0xbb,  0x26,
+  0x3c,  0x5c,  0xa6,  0x3e,  0xb4,  0xdf,  0xed,  0x9b,  0x2f,  0xf9,  0xf9,  0x4a,
+  0xfd,  0x00,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
+  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,
+  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x97,  0xb7,  0x80,  0x7b,  0x19,  0x9f,  0x01,
+  0xa6,  0xb5,  0x60,  0xab,  0xff,  0x00,  0x1f,  0x51,  0xe7,  0xeb,  0x4e,  0xfe,
+  0xdc,  0xb0,  0xff,  0x00,  0x9f,  0xa8,  0xff,  0x00,  0x3a,  0xfb,  0xeb,  0xfe,
+  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,
+  0xf8,  0x74,  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,
+  0x3d,  0xbc,  0x03,  0xd8,  0xcc,  0xf8,  0x05,  0xf5,  0xab,  0x26,  0x6f,  0xf8,
+  0xf9,  0x4c,  0x7d,  0x69,  0xbf,  0xdb,  0x36,  0x5f,  0xf3,  0xf2,  0x9f,  0x9d,
+  0x7e,  0x80,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,
+  0xff,  0x00,  0x80,  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,
+  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x80,  0x7b,  0x19,  0x9f,
+  0x02,  0x26,  0xb5,  0x60,  0xab,  0x8f,  0xb5,  0x47,  0xf9,  0xd2,  0xff,  0x00,
+  0x6e,  0x58,  0x7f,  0xcf,  0xd4,  0x7f,  0x9d,  0x7d,  0xf5,  0xff,  0x00,  0x0e,
+  0x96,  0xf0,  0x97,  0xfd,  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xfc,
+  0x3a,  0x5b,  0xc2,  0x5f,  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1e,
+  0xde,  0x01,  0xec,  0x66,  0x7c,  0x00,  0xda,  0xd5,  0x93,  0x1c,  0xfd,  0xa5,
+  0x3f,  0x3a,  0x4f,  0xed,  0x8b,  0x2f,  0xf9,  0xf9,  0x4f,  0xce,  0xbf,  0x40,
+  0x3f,  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,
+  0xc0,  0x48,  0x68,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,
+  0x6b,  0xff,  0x00,  0x01,  0x21,  0xa7,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,
+  0x81,  0x57,  0x5a,  0xb0,  0x51,  0x8f,  0xb5,  0x47,  0xf9,  0xd1,  0xfd,  0xb9,
+  0x61,  0xff,  0x00,  0x3f,  0x49,  0xf9,  0xd7,  0xdf,  0x5f,  0xf0,  0xe9,  0x6f,
+  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,
+  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd2,
+  0xf6,  0xf0,  0x0f,  0x63,  0x33,  0xe0,  0x06,  0xd6,  0xac,  0x98,  0xe7,  0xed,
+  0x29,  0xf9,  0xd2,  0x0d,  0x62,  0xcb,  0xfe,  0x7e,  0x53,  0xf3,  0xaf,  0xd0,
+  0x0f,  0xf8,  0x74,  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,
+  0x1a,  0x3f,  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,
+  0x00,  0xc0,  0x48,  0x69,  0xfb,  0x78,  0x77,  0x0f,  0x63,  0x33,  0xe0,  0x51,
+  0xad,  0xd8,  0x01,  0x8f,  0xb5,  0x47,  0xf9,  0xd0,  0x75,  0xcb,  0x0c,  0x7f,
+  0xc7,  0xca,  0x7e,  0x75,  0xf7,  0xd7,  0xfc,  0x3a,  0x5b,  0xc2,  0x5f,  0xf4,
+  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,
+  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7b,  0x78,  0x77,  0x0f,  0x63,
+  0x33,  0xf3,  0xfc,  0xeb,  0x36,  0x44,  0xff,  0x00,  0xc7,  0xca,  0x7e,  0x74,
+  0xa3,  0x58,  0xb1,  0x24,  0x66,  0xe5,  0x31,  0xf5,  0xaf,  0xbf,  0xff,  0x00,
+  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,
+  0x48,  0x68,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
+  0xff,  0x00,  0x01,  0x21,  0xa3,  0xdb,  0xc3,  0xb8,  0x7b,  0x19,  0x9f,  0x02,
+  0xff,  0x00,  0x6d,  0xd8,  0x7f,  0xcf,  0xd4,  0x7f,  0x9d,  0x07,  0x5c,  0xb1,
+  0x03,  0x8b,  0x94,  0xcf,  0xd6,  0xbe,  0xfa,  0xff,  0x00,  0x87,  0x4b,  0x78,
+  0x4b,  0xfe,  0x87,  0xdd,  0x6b,  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,
+  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,  0x6f,
+  0x0e,  0xe1,  0xec,  0x66,  0x7e,  0x7f,  0xff,  0x00,  0x6c,  0xd9,  0x7f,  0xcf,
+  0xca,  0x7e,  0x74,  0xab,  0xac,  0x58,  0xe7,  0x9b,  0x94,  0xc7,  0xd6,  0xbe,
+  0xff,  0x00,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
+  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,
+  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,  0x6f,  0x0e,  0xe1,  0xec,  0x66,  0x7c,
+  0x0b,  0xfd,  0xb9,  0x61,  0xff,  0x00,  0x3f,  0x51,  0xfe,  0x74,  0x8d,  0xae,
+  0x58,  0xed,  0x38,  0xb9,  0x4c,  0xfd,  0x6b,  0xef,  0xbf,  0xf8,  0x74,  0xb7,
+  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,  0x3f,  0xe1,  0xd2,
+  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,  0x48,  0x68,
+  0xf6,  0xf0,  0xee,  0x1e,  0xc6,  0x67,  0xe7,  0xff,  0x00,  0xf6,  0xc5,  0x97,
+  0xfc,  0xfc,  0xa7,  0xe7,  0x4e,  0x4d,  0x62,  0xc7,  0x77,  0x37,  0x29,  0xf9,
+  0xd7,  0xdf,  0xdf,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,
+  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,
+  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd1,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,
+  0x81,  0x7f,  0xb7,  0x2c,  0x3f,  0xe7,  0xea,  0x3f,  0xce,  0x91,  0xf5,  0xcb,
+  0x1c,  0x71,  0x72,  0x9f,  0x9d,  0x7d,  0xf7,  0xff,  0x00,  0x0e,  0x96,  0xf0,
+  0x97,  0xfd,  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xfc,  0x3a,  0x5b,
+  0xc2,  0x5f,  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1e,  0xde,  0x1d,
+  0xc3,  0xd8,  0xcc,  0xfc,  0xff,  0x00,  0xfe,  0xd9,  0xb2,  0xff,  0x00,  0x9f,
+  0x94,  0xfc,  0xe9,  0xd1,  0xeb,  0x36,  0x20,  0xe4,  0xdc,  0xa7,  0xe7,  0x5f,
+  0x7f,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,
+  0x00,  0x80,  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,  0x0f,
+  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x87,  0x70,  0xf6,  0x33,  0x3e,
+  0x05,  0xfe,  0xdc,  0xb0,  0xff,  0x00,  0x9f,  0xa8,  0xff,  0x00,  0x3a,  0x6c,
+  0x9a,  0xdd,  0x89,  0x18,  0x17,  0x29,  0xf9,  0xd7,  0xdf,  0x9f,  0xf0,  0xe9,
+  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,
+  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,
+  0xd1,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,  0xbc,  0xa8,  0xa2,  0x8a,  0xf3,
+  0x0e,  0xf0,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
+  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
+  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0xa0,  0xbb,  0xbd,  0xb7,  0xb0,
+  0x88,  0x49,  0x73,  0x3c,  0x56,  0xf1,  0x96,  0x0a,  0x1e,  0x57,  0x0a,  0x09,
+  0x3d,  0x06,  0x4f,  0x7a,  0x9e,  0x95,  0xd3,  0x76,  0xea,  0x01,  0x45,  0x14,
+  0x53,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x82,  0xda,  0xf6,  0xde,
+  0xf0,  0xca,  0x2d,  0xe7,  0x8a,  0x73,  0x13,  0x98,  0xe4,  0xf2,  0xdc,  0x36,
+  0xc6,  0x1d,  0x54,  0xe3,  0xa1,  0xf6,  0xa4,  0xda,  0x4e,  0xcc,  0x09,  0xe8,
+  0xa2,  0x8a,  0x60,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,
+  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,
+  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x02,  0xb8,
+  0x51,  0x45,  0x14,  0x05,  0xc2,  0x8a,  0x28,  0xa0,  0x2e,  0x14,  0x51,  0x45,
+  0x01,  0x70,  0xa2,  0x8a,  0x28,  0x18,  0x51,  0x45,  0x14,  0x0a,  0xe1,  0x45,
+  0x14,  0x50,  0x17,  0x0a,  0x28,  0xa2,  0x80,  0xb9,  0xca,  0xfc,  0x4a,  0xf0,
+  0x52,  0x78,  0xef,  0xc2,  0xb7,  0x1a,  0x76,  0xef,  0x2e,  0xe5,  0x4f,  0x9d,
+  0x6c,  0xe4,  0xe0,  0x09,  0x00,  0x38,  0xcf,  0xb1,  0xc9,  0x1f,  0x8e,  0x7b,
+  0x57,  0x3d,  0xf0,  0x5b,  0xc7,  0x53,  0x6b,  0xba,  0x6c,  0xda,  0x16,  0xaa,
+  0x5a,  0x3d,  0x73,  0x4a,  0xfd,  0xd4,  0x8b,  0x2f,  0xdf,  0x91,  0x01,  0xc0,
+  0x27,  0xdc,  0x1e,  0x0f,  0xe0,  0x7b,  0xd7,  0xa3,  0x5c,  0xdc,  0xc5,  0x67,
+  0x04,  0x93,  0xcf,  0x2a,  0x43,  0x0c,  0x60,  0xb3,  0xc9,  0x23,  0x05,  0x55,
+  0x1e,  0xa4,  0x9e,  0x95,  0xf3,  0x47,  0xc4,  0x8f,  0x1f,  0xe9,  0x36,  0xdf,
+  0x10,  0xed,  0x3c,  0x41,  0xe1,  0x39,  0x99,  0xaf,  0xa1,  0xe2,  0xea,  0x42,
+  0x98,  0x82,  0x72,  0x38,  0xe3,  0x90,  0x4e,  0x46,  0x41,  0xe9,  0x9c,  0x0c,
+  0x7a,  0xd7,  0xc4,  0x67,  0x98,  0x9a,  0x59,  0x3e,  0x26,  0x9e,  0x64,  0xa6,
+  0x93,  0x7e,  0xec,  0xe3,  0x7d,  0x65,  0x1e,  0xe9,  0x77,  0x8b,  0xd7,  0xd3,
+  0x4b,  0x99,  0x4d,  0xa8,  0xbe,  0x63,  0xe9,  0xca,  0x2b,  0xe4,  0x3d,  0x73,
+  0xe3,  0x3f,  0x8b,  0xb5,  0xc6,  0x6d,  0xfa,  0xb4,  0x96,  0x71,  0x9e,  0x91,
+  0x59,  0x0f,  0x28,  0x0f,  0xc4,  0x7c,  0xdf,  0x99,  0xae,  0x56,  0xe7,  0x5a,
+  0xd4,  0x6f,  0x18,  0xb5,  0xc5,  0xfd,  0xd4,  0xec,  0x7b,  0xc9,  0x33,  0x31,
+  0xfd,  0x4d,  0x78,  0x75,  0xf8,  0xfb,  0x0b,  0x07,  0x6a,  0x14,  0x65,  0x25,
+  0xe6,  0xd2,  0xff,  0x00,  0x32,  0x1d,  0x75,  0xd1,  0x1f,  0x73,  0x51,  0x5f,
+  0x0b,  0xdb,  0xea,  0xf7,  0xf6,  0xad,  0xba,  0x0b,  0xdb,  0x88,  0x58,  0x77,
+  0x8e,  0x56,  0x53,  0xfa,  0x1a,  0xe9,  0xf4,  0x5f,  0x8b,  0xfe,  0x2e,  0xd0,
+  0xd9,  0x7c,  0xad,  0x66,  0x7b,  0x84,  0x1f,  0xf2,  0xce,  0xec,  0xf9,  0xc0,
+  0xff,  0x00,  0xdf,  0x59,  0x23,  0xf0,  0x34,  0xa8,  0x71,  0xf6,  0x1a,  0x4e,
+  0xd5,  0xa8,  0x4a,  0x2b,  0xc9,  0xa7,  0xfe,  0x40,  0xab,  0xae,  0xa8,  0xfa,
+  0x13,  0xe2,  0xff,  0x00,  0x8f,  0xcf,  0x82,  0xfc,  0x3e,  0x21,  0xb3,  0x6d,
+  0xda,  0xcd,  0xfe,  0x62,  0xb5,  0x45,  0xe5,  0x97,  0xb1,  0x7c,  0x7b,  0x67,
+  0x8f,  0x72,  0x3d,  0xea,  0x5f,  0x84,  0x7e,  0x05,  0x6f,  0x04,  0x78,  0x60,
+  0x2d,  0xd1,  0x2d,  0xa9,  0xde,  0xb0,  0x9e,  0xe8,  0x93,  0x9d,  0xad,  0x8e,
+  0x17,  0xf0,  0x1d,  0x4f,  0xa9,  0x35,  0xe2,  0x5e,  0x13,  0xf8,  0x89,  0x61,
+  0xac,  0xfc,  0x49,  0x8f,  0xc4,  0x3e,  0x30,  0x76,  0xcc,  0x68,  0x16,  0xd8,
+  0x43,  0x19,  0x68,  0x61,  0x61,  0xd0,  0x91,  0x92,  0x40,  0x1c,  0x9e,  0x33,
+  0xc9,  0xcd,  0x7d,  0x3b,  0x63,  0x7f,  0x6d,  0xaa,  0x5a,  0x45,  0x75,  0x69,
+  0x3c,  0x77,  0x36,  0xd2,  0x8d,  0xc9,  0x2c,  0x4c,  0x19,  0x58,  0x7b,  0x11,
+  0x5e,  0xde,  0x4d,  0x8b,  0xa3,  0x9d,  0xe3,  0x2a,  0x66,  0x1c,  0xe9,  0xf2,
+  0x5e,  0x30,  0x8f,  0x58,  0xae,  0xb2,  0x6b,  0xbc,  0xbf,  0x05,  0xa1,  0x50,
+  0x6a,  0x6f,  0x98,  0xb1,  0x45,  0x14,  0x57,  0xdc,  0x9b,  0x5c,  0x28,  0xa2,
+  0x8a,  0x02,  0xe1,  0x45,  0x14,  0x50,  0x17,  0x0a,  0x28,  0xa2,  0x80,  0xb8,
+  0x51,  0x45,  0x14,  0x05,  0xc2,  0x8a,  0x28,  0xa0,  0x2e,  0x14,  0x51,  0x45,
+  0x01,  0x70,  0xa2,  0x8a,  0x28,  0x0b,  0x8d,  0xcd,  0x19,  0xa6,  0xe4,  0x51,
+  0x91,  0x55,  0x62,  0x47,  0x66,  0x8c,  0xd3,  0x72,  0x28,  0xc8,  0xa2,  0xc0,
+  0x3b,  0x34,  0x66,  0x9b,  0x91,  0x46,  0x45,  0x16,  0x01,  0xd9,  0xa3,  0x34,
+  0xdc,  0x8a,  0x32,  0x28,  0xb0,  0x0e,  0xcd,  0x19,  0xa6,  0xe4,  0x52,  0xe4,
+  0x51,  0x60,  0xb8,  0xb9,  0xa3,  0x34,  0xdc,  0x8a,  0x32,  0x28,  0xb0,  0x0e,
+  0xdd,  0x46,  0x69,  0xb9,  0x14,  0x64,  0x51,  0x60,  0x1d,  0x9a,  0xa7,  0xac,
+  0x6b,  0x16,  0x9a,  0x0e,  0x9b,  0x71,  0xa8,  0x5f,  0x4c,  0x20,  0xb5,  0x81,
+  0x37,  0xbb,  0x9e,  0xc3,  0xd0,  0x7a,  0x93,  0xd0,  0x0a,  0xb5,  0x91,  0x5f,
+  0x39,  0xfe,  0xd1,  0x1e,  0x37,  0x7d,  0x4b,  0x5a,  0x4f,  0x0f,  0x5b,  0x48,
+  0x45,  0xa5,  0x96,  0x1e,  0x70,  0xa7,  0xef,  0xca,  0x46,  0x40,  0x3f,  0xee,
+  0x83,  0xf9,  0x93,  0xe9,  0x5e,  0x06,  0x79,  0x9a,  0xc3,  0x27,  0xc1,  0x4b,
+  0x12,  0xd5,  0xe5,  0xb4,  0x57,  0x76,  0xff,  0x00,  0xab,  0xbf,  0x24,  0x44,
+  0xe5,  0xca,  0xae,  0x72,  0xbf,  0x12,  0xbe,  0x2a,  0xea,  0x3e,  0x3e,  0xbd,
+  0x78,  0xd5,  0x9e,  0xd3,  0x48,  0x46,  0xfd,  0xd5,  0xa2,  0x9f,  0xbd,  0xe8,
+  0xcf,  0xea,  0x7f,  0x41,  0xdb,  0xd4,  0xc3,  0xe0,  0x5f,  0x85,  0x1a,  0xd7,
+  0x8f,  0xed,  0xe6,  0xb9,  0xb1,  0xf2,  0x2d,  0xed,  0x22,  0x6d,  0x86,  0x7b,
+  0x96,  0x21,  0x59,  0xb1,  0x9c,  0x0c,  0x02,  0x4f,  0x51,  0xf9,  0xd7,  0x19,
+  0x5e,  0xcd,  0xf0,  0x73,  0xe3,  0x16,  0x97,  0xe1,  0x0d,  0x06,  0x4d,  0x23,
+  0x57,  0x49,  0x63,  0x44,  0x95,  0xa5,  0x86,  0x78,  0x53,  0x78,  0x21,  0xba,
+  0xab,  0x0e,  0xb9,  0xcf,  0x7f,  0x7f,  0x6a,  0xfc,  0x1b,  0x2e,  0xa9,  0x87,
+  0xcd,  0xb3,  0x2f,  0x69,  0x9c,  0xd5,  0x6a,  0x2e,  0xfa,  0xde,  0xda,  0xf4,
+  0x57,  0xe8,  0xbf,  0xe1,  0x8e,  0x48,  0xda,  0x52,  0xf7,  0x8f,  0x30,  0xf1,
+  0x57,  0x85,  0x75,  0x0f,  0x06,  0xeb,  0x12,  0x69,  0xba,  0x94,  0x42,  0x3b,
+  0x84,  0x01,  0x83,  0x21,  0xca,  0xba,  0x9e,  0x8c,  0xa7,  0xb8,  0xac,  0x8a,
+  0xed,  0x3e,  0x2c,  0xf8,  0xee,  0x1f,  0x1f,  0xf8,  0x9c,  0x5e,  0xda,  0xc2,
+  0xf0,  0xda,  0x41,  0x08,  0x82,  0x2f,  0x33,  0x01,  0xd8,  0x02,  0x49,  0x63,
+  0xe9,  0xc9,  0x3c,  0x57,  0x17,  0x5e,  0x26,  0x3e,  0x9e,  0x1e,  0x96,  0x2a,
+  0xa4,  0x30,  0xb2,  0xe6,  0xa6,  0x9b,  0xb3,  0xee,  0x88,  0x76,  0xbe,  0x81,
+  0x5a,  0x1a,  0x06,  0x83,  0x7b,  0xe2,  0x7d,  0x5e,  0xdf,  0x4d,  0xd3,  0xe2,
+  0xf3,  0xae,  0xa7,  0x38,  0x55,  0xce,  0x00,  0x00,  0x64,  0x92,  0x7b,  0x00,
+  0x39,  0xac,  0xfa,  0xea,  0x3e,  0x1b,  0x78,  0xc1,  0x7c,  0x0d,  0xe2,  0xcb,
+  0x5d,  0x52,  0x58,  0x4c,  0xf6,  0xe1,  0x5a,  0x39,  0x51,  0x3e,  0xf6,  0xd6,
+  0x18,  0x24,  0x7b,  0x8e,  0x0d,  0x67,  0x83,  0x85,  0x1a,  0x98,  0x8a,  0x70,
+  0xc4,  0x4b,  0x96,  0x0d,  0xae,  0x67,  0xd9,  0x5f,  0x50,  0x56,  0xbe,  0xa6,
+  0x97,  0x8d,  0x7e,  0x0e,  0xeb,  0xde,  0x06,  0xd3,  0x17,  0x50,  0xbb,  0x36,
+  0xf7,  0x56,  0x99,  0x0b,  0x24,  0x96,  0xae,  0x4f,  0x96,  0x4f,  0x4d,  0xc0,
+  0x81,  0xc1,  0x3c,  0x66,  0xa9,  0xfc,  0x3e,  0xf8,  0x93,  0xaa,  0x78,  0x03,
+  0x50,  0x0f,  0x6c,  0xe6,  0x7b,  0x07,  0x6f,  0xdf,  0xd9,  0x3b,  0x7c,  0x8e,
+  0x3d,  0x47,  0xa3,  0x7b,  0xfe,  0x79,  0xaf,  0x45,  0xf8,  0xad,  0xf1,  0xb3,
+  0x47,  0xf1,  0x27,  0x85,  0x26,  0xd2,  0x34,  0x84,  0x9a,  0x67,  0xbb,  0x2b,
+  0xe6,  0xcb,  0x34,  0x7b,  0x04,  0x6a,  0x18,  0x36,  0x07,  0xa9,  0xc8,  0x1e,
+  0xd5,  0xe1,  0x95,  0xf4,  0x39,  0xab,  0xc2,  0x65,  0x79,  0x84,  0x67,  0x93,
+  0x55,  0x6d,  0x24,  0x9d,  0xd3,  0xbd,  0x9f,  0x55,  0x7e,  0xaa,  0xd6,  0xbe,
+  0xfb,  0xd8,  0xb9,  0x5a,  0x32,  0xf7,  0x59,  0xf6,  0xef,  0x86,  0xbc,  0x49,
+  0x63,  0xe2,  0xbd,  0x1a,  0xdf,  0x53,  0xd3,  0xe5,  0xf3,  0x2d,  0xe6,  0x1d,
+  0xfe,  0xf2,  0x1e,  0xea,  0xc3,  0xb1,  0x15,  0xa9,  0x9a,  0xf9,  0x7b,  0xe0,
+  0x27,  0x8d,  0xe4,  0xf0,  0xef,  0x8a,  0x53,  0x4a,  0x9e,  0x43,  0xfd,  0x9f,
+  0xa9,  0x30,  0x8f,  0x69,  0x3c,  0x24,  0xdf,  0xc0,  0xc3,  0xeb,  0xf7,  0x7f,
+  0x11,  0xe9,  0x5f,  0x4f,  0xe4,  0x57,  0xee,  0x3c,  0x3f,  0x9b,  0xc7,  0x39,
+  0xc1,  0x2a,  0xed,  0x5a,  0x6b,  0x49,  0x2f,  0x3f,  0xf2,  0x7b,  0xfe,  0x1d,
+  0x0e,  0xb8,  0x4f,  0x99,  0x5c,  0x76,  0x4d,  0x19,  0xa6,  0xe4,  0x51,  0x91,
+  0x5f,  0x4b,  0x62,  0xc7,  0x64,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,
+  0x2e,  0x3b,  0x34,  0x66,  0x9b,  0x91,  0x46,  0x45,  0x16,  0x0b,  0x8e,  0xcd,
+  0x19,  0xa6,  0xe4,  0x51,  0x91,  0x45,  0x80,  0x76,  0x68,  0xcd,  0x37,  0x34,
+  0x64,  0x51,  0x60,  0xb8,  0xec,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,
+  0x07,  0x64,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,  0x06,  0x6e,  0xa3,
+  0x75,  0x37,  0x34,  0x66,  0xae,  0xc4,  0x5c,  0x76,  0xea,  0x37,  0x53,  0x73,
+  0x46,  0x68,  0xb0,  0x5c,  0x76,  0xea,  0x37,  0x53,  0x73,  0x46,  0x68,  0xb0,
+  0x5c,  0x76,  0xea,  0x37,  0x53,  0x72,  0x28,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,
+  0x46,  0xea,  0x6e,  0x68,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,  0x46,  0xea,  0x6e,
+  0x68,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,  0x46,  0xea,  0xc4,  0xf1,  0x57,  0x8c,
+  0x34,  0xaf,  0x06,  0x69,  0xff,  0x00,  0x6b,  0xd5,  0x2e,  0x44,  0x28,  0xc7,
+  0x08,  0x8a,  0x37,  0x3c,  0x87,  0xd1,  0x47,  0x7f,  0xe5,  0x5c,  0x0d,  0x9f,
+  0xed,  0x1f,  0xe1,  0xcb,  0x8b,  0xc1,  0x14,  0xd6,  0x97,  0xf6,  0xb0,  0x93,
+  0x81,  0x3b,  0xa2,  0xb0,  0x1e,  0xe4,  0x06,  0x27,  0xf2,  0xcd,  0x78,  0xf8,
+  0xac,  0xdf,  0x2f,  0xc0,  0xd4,  0x54,  0x71,  0x35,  0xa3,  0x19,  0x3e,  0x8d,
+  0xfe,  0x7d,  0xbe,  0x64,  0xb9,  0x25,  0xb9,  0xeb,  0x05,  0xf6,  0x82,  0x4f,
+  0x41,  0x5f,  0x10,  0xeb,  0x7a,  0x93,  0xeb,  0x3a,  0xcd,  0xf5,  0xfc,  0x84,
+  0x97,  0xb9,  0x9d,  0xe6,  0x39,  0xff,  0x00,  0x69,  0x89,  0xfe,  0xb5,  0xf6,
+  0xad,  0x8e,  0xa1,  0x6b,  0xab,  0x58,  0xc5,  0x75,  0x69,  0x34,  0x77,  0x36,
+  0xb3,  0x2e,  0xe4,  0x91,  0x0e,  0x55,  0x85,  0x78,  0x5f,  0xfc,  0x2d,  0x5f,
+  0x87,  0x3f,  0xf4,  0x25,  0x27,  0xfe,  0x00,  0xdb,  0xff,  0x00,  0x8d,  0x7c,
+  0x67,  0x18,  0xe1,  0xa8,  0x63,  0x61,  0x87,  0x55,  0x31,  0x31,  0xa7,  0x1f,
+  0x79,  0xab,  0xdd,  0xf3,  0x7c,  0x3a,  0xab,  0x76,  0xfd,  0x4c,  0xea,  0x59,
+  0xdb,  0x53,  0xc4,  0x68,  0xaf,  0x6e,  0xff,  0x00,  0x85,  0xab,  0xf0,  0xe7,
+  0xfe,  0x84,  0xa4,  0xff,  0x00,  0xc0,  0x1b,  0x7f,  0xf1,  0xa3,  0xfe,  0x16,
+  0xaf,  0xc3,  0x9f,  0xfa,  0x12,  0x93,  0xff,  0x00,  0x00,  0x6d,  0xff,  0x00,
+  0xc6,  0xbf,  0x33,  0xfe,  0xc5,  0xc0,  0xff,  0x00,  0xd0,  0x7c,  0x3e,  0xe9,
+  0x7f,  0x91,  0x8f,  0x2a,  0xee,  0x78,  0x8d,  0x15,  0xed,  0xdf,  0xf0,  0xb5,
+  0x7e,  0x1c,  0xff,  0x00,  0xd0,  0x94,  0x9f,  0xf8,  0x03,  0x6f,  0xfe,  0x34,
+  0x7f,  0xc2,  0xd5,  0xf8,  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,
+  0xbf,  0xf8,  0xd1,  0xfd,  0x8b,  0x81,  0xff,  0x00,  0xa0,  0xf8,  0x7d,  0xd2,
+  0xff,  0x00,  0x20,  0xe5,  0x5d,  0xcf,  0x11,  0xa2,  0xbd,  0xbb,  0xfe,  0x16,
+  0xaf,  0xc3,  0x9f,  0xfa,  0x12,  0x93,  0xff,  0x00,  0x00,  0x6d,  0xff,  0x00,
+  0xc6,  0x8f,  0xf8,  0x5a,  0xbf,  0x0e,  0x7f,  0xe8,  0x4a,  0x4f,  0xfc,  0x01,
+  0xb7,  0xff,  0x00,  0x1a,  0x3f,  0xb1,  0x70,  0x3f,  0xf4,  0x1f,  0x0f,  0xba,
+  0x5f,  0xe4,  0x1c,  0xab,  0xb9,  0xe2,  0x34,  0x57,  0xb7,  0x7f,  0xc2,  0xd5,
+  0xf8,  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,  0xbf,  0xf8,  0xd1,
+  0xff,  0x00,  0x0b,  0x57,  0xe1,  0xcf,  0xfd,  0x09,  0x49,  0xff,  0x00,  0x80,
+  0x36,  0xff,  0x00,  0xe3,  0x47,  0xf6,  0x2e,  0x07,  0xfe,  0x83,  0xe1,  0xf7,
+  0x4b,  0xfc,  0x83,  0x95,  0x77,  0x3c,  0x52,  0x09,  0xde,  0xda,  0x78,  0xe6,
+  0x89,  0x8a,  0x49,  0x1b,  0x07,  0x56,  0x1d,  0x41,  0x07,  0x20,  0xd7,  0xdb,
+  0xfa,  0x5d,  0xf0,  0xd4,  0x74,  0xdb,  0x4b,  0xb0,  0x30,  0x27,  0x85,  0x25,
+  0x03,  0xfd,  0xe5,  0x07,  0xfa,  0xd7,  0x85,  0xff,  0x00,  0xc2,  0xd5,  0xf8,
+  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,  0xbf,  0xf8,  0xd7,  0xb6,
+  0x69,  0x1a,  0x95,  0xa5,  0xc7,  0x87,  0xec,  0xaf,  0xe1,  0x55,  0xb3,  0xb1,
+  0x7b,  0x54,  0x99,  0x11,  0xf0,  0x82,  0x28,  0xca,  0x02,  0x01,  0xec,  0x30,
+  0x3f,  0x0e,  0x2b,  0xf4,  0x7e,  0x0e,  0xc2,  0xd0,  0xc1,  0xce,  0xbc,  0x69,
+  0x62,  0x63,  0x51,  0x34,  0x9b,  0x4a,  0xfa,  0x5a,  0xfa,  0xeb,  0xea,  0x6d,
+  0x4e,  0xca,  0xfa,  0x9a,  0x5b,  0xa8,  0xdd,  0x5e,  0x57,  0xab,  0xfe,  0xd1,
+  0x3e,  0x1b,  0xd3,  0xaf,  0x1a,  0x0b,  0x68,  0x6e,  0xf5,  0x15,  0x53,  0x83,
+  0x34,  0x28,  0xaa,  0x87,  0xe9,  0xb8,  0x82,  0x7f,  0x2a,  0xeb,  0xbc,  0x1b,
+  0xf1,  0x07,  0x45,  0xf1,  0xcd,  0xbb,  0xbe,  0x99,  0x70,  0x7c,  0xe8,  0xc6,
+  0x64,  0xb6,  0x98,  0x6d,  0x91,  0x07,  0xa9,  0x1d,  0xc7,  0xb8,  0xc8,  0xaf,
+  0xb7,  0xc3,  0xe7,  0x19,  0x76,  0x2a,  0xb7,  0xd5,  0xe8,  0x56,  0x8c,  0xa7,
+  0xd9,  0x3f,  0xcb,  0xbf,  0xc8,  0xd1,  0x49,  0x3d,  0x2e,  0x74,  0xdb,  0xa8,
+  0xcd,  0x37,  0x34,  0x64,  0x57,  0xb2,  0x55,  0xc7,  0x6e,  0xa3,  0x75,  0x37,
+  0x34,  0x66,  0x8b,  0x05,  0xc7,  0x6e,  0xa3,  0x75,  0x37,  0x34,  0x66,  0x8b,
+  0x05,  0xc7,  0x6e,  0xa3,  0x75,  0x37,  0x34,  0x66,  0x8b,  0x05,  0xc7,  0x6e,
+  0xa3,  0x75,  0x37,  0x34,  0x64,  0x51,  0x60,  0xb8,  0xed,  0xd4,  0x6e,  0xa6,
+  0xe4,  0x51,  0x9a,  0x2c,  0x17,  0x1b,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,
+  0x55,  0x88,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8d,  0xd4,  0x58,  0x2e,
+  0x49,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,  0x16,  0x15,  0xc9,  0x32,  0x28,
+  0xa8,  0xf7,  0x51,  0xba,  0x8b,  0x0e,  0xe4,  0x99,  0xa3,  0x35,  0x1e,  0xea,
+  0x37,  0x51,  0x60,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8c,  0xd3,  0xb0,
+  0x5c,  0xf9,  0x7b,  0xe3,  0xb6,  0xaf,  0x3e,  0xa5,  0xf1,  0x0e,  0xf2,  0xde,
+  0x47,  0x26,  0x1b,  0x24,  0x48,  0x62,  0x4e,  0xc0,  0x15,  0x0c,  0x4f,  0xe2,
+  0x58,  0xfe,  0x95,  0xe7,  0x95,  0xda,  0x7c,  0x64,  0xff,  0x00,  0x92,  0x97,
+  0xad,  0xff,  0x00,  0xbf,  0x1f,  0xfe,  0x8a,  0x4a,  0xe2,  0xeb,  0xf9,  0x47,
+  0x3a,  0x9c,  0xaa,  0x66,  0x78,  0x99,  0x49,  0xdd,  0xf3,  0xcb,  0xf0,  0x6d,
+  0x23,  0x92,  0x5b,  0x9e,  0xf7,  0xfb,  0x34,  0xeb,  0x13,  0xcd,  0x67,  0xac,
+  0xe9,  0xb2,  0x39,  0x6b,  0x78,  0x1a,  0x39,  0xa2,  0x04,  0xfd,  0xd2,  0xdb,
+  0x83,  0x0f,  0xc7,  0x68,  0xfd,  0x6b,  0xc1,  0x2b,  0xda,  0xff,  0x00,  0x66,
+  0x73,  0x8b,  0xed,  0x7f,  0xfe,  0xb9,  0xc3,  0xfc,  0xde,  0xbc,  0x52,  0xbd,
+  0x8c,  0xd2,  0x72,  0x9e,  0x4b,  0x97,  0x39,  0x3b,  0xdb,  0xda,  0xaf,  0x92,
+  0x92,  0xb1,  0x4f,  0xe1,  0x41,  0x45,  0x14,  0x57,  0xc6,  0x90,  0x14,  0x51,
+  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x15,  0xef,
+  0x7f,  0x13,  0xf5,  0x89,  0xf4,  0xef,  0x82,  0xbe,  0x19,  0xb6,  0x81,  0xca,
+  0x0b,  0xc8,  0x2d,  0x62,  0x94,  0x83,  0xd5,  0x04,  0x3b,  0x88,  0xfc,  0x48,
+  0x15,  0xe0,  0x95,  0xed,  0x7f,  0x17,  0x0f,  0xfc,  0x5a,  0x5f,  0x05,  0xff,
+  0x00,  0xd7,  0x38,  0x3f,  0xf4,  0x45,  0x7d,  0x96,  0x47,  0x39,  0x43,  0x03,
+  0x98,  0x4a,  0x2e,  0xcf,  0x91,  0x7e,  0x32,  0xb3,  0xfc,  0x0a,  0x8e,  0xcc,
+  0xf1,  0x4a,  0xe9,  0xbe,  0x1a,  0x6a,  0xf3,  0xe8,  0xbe,  0x3a,  0xd1,  0x67,
+  0x81,  0xca,  0x99,  0x2e,  0x52,  0x07,  0x00,  0xfd,  0xe4,  0x76,  0x0a,  0xc0,
+  0xfe,  0x07,  0xf4,  0xae,  0x66,  0xb6,  0x3c,  0x1b,  0xff,  0x00,  0x23,  0x7e,
+  0x87,  0xff,  0x00,  0x5f,  0xd0,  0x7f,  0xe8,  0xc5,  0xaf,  0x9b,  0xc0,  0xce,
+  0x54,  0xf1,  0x54,  0xa7,  0x07,  0x66,  0xa4,  0xbf,  0x31,  0x2d,  0xcf,  0xb4,
+  0x33,  0x46,  0x6a,  0x3d,  0xd4,  0x6e,  0xaf,  0xeb,  0x9b,  0x1d,  0x57,  0x24,
+  0xcd,  0x19,  0xa8,  0xf7,  0x51,  0xba,  0x8b,  0x0e,  0xe4,  0x99,  0xa3,  0x35,
+  0x1e,  0xea,  0x37,  0x51,  0x60,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8d,
+  0xd4,  0x58,  0x2e,  0x49,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,  0x16,  0x15,
+  0xc9,  0x33,  0x46,  0x6a,  0x3d,  0xd4,  0x6e,  0xa2,  0xc3,  0xb8,  0xdd,  0xd4,
+  0x9b,  0xa9,  0xbb,  0xa8,  0xdd,  0x5a,  0x19,  0xdc,  0x7e,  0xea,  0x4d,  0xd4,
+  0xdd,  0xd4,  0x6e,  0xa0,  0x57,  0x1f,  0xba,  0x8d,  0xd4,  0xcd,  0xd4,  0x6e,
+  0xa0,  0x77,  0x1f,  0xba,  0x8d,  0xd4,  0xcd,  0xd4,  0x6e,  0xa4,  0x2b,  0x8f,
+  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,  0xd4,  0xc2,  0xe3,  0xb7,  0x52,  0xee,
+  0xa6,  0x6e,  0xa3,  0x75,  0x20,  0xb9,  0xf2,  0x9f,  0xc6,  0x3f,  0xf9,  0x29,
+  0x5a,  0xdf,  0xfb,  0xf1,  0xff,  0x00,  0xe8,  0xb4,  0xae,  0x32,  0xbb,  0x2f,
+  0x8c,  0x5c,  0xfc,  0x49,  0xd6,  0xff,  0x00,  0xdf,  0x8f,  0xff,  0x00,  0x45,
+  0xa5,  0x71,  0xb5,  0xfc,  0x99,  0x9c,  0x7f,  0xc8,  0xcb,  0x13,  0xfe,  0x39,
+  0xff,  0x00,  0xe9,  0x4c,  0xc1,  0xee,  0x7b,  0x57,  0xec,  0xd2,  0x71,  0x7d,
+  0xaf,  0x7f,  0xd7,  0x38,  0x7f,  0x9b,  0xd7,  0x8a,  0xd7,  0xb4,  0x7e,  0xcd,
+  0x67,  0x17,  0xda,  0xf7,  0xfd,  0x73,  0x87,  0xf9,  0xbd,  0x78,  0xbd,  0x7b,
+  0x19,  0x97,  0xfc,  0x89,  0x32,  0xef,  0xfb,  0x8b,  0xff,  0x00,  0xa5,  0x21,
+  0xbd,  0x90,  0x51,  0x45,  0x15,  0xf2,  0x02,  0x0a,  0x28,  0xa2,  0x80,  0x0a,
+  0x28,  0xa2,  0x80,  0x0a,  0x28,  0xa2,  0x80,  0x0a,  0xf6,  0xaf,  0x8b,  0x47,
+  0x3f,  0x09,  0x7c,  0x17,  0xff,  0x00,  0x5c,  0xe0,  0xff,  0x00,  0xd1,  0x15,
+  0xe2,  0xb5,  0xed,  0x1f,  0x16,  0x4f,  0xfc,  0x5a,  0x6f,  0x06,  0x7f,  0xd7,
+  0x38,  0x3f,  0xf4,  0x45,  0x7d,  0x7e,  0x4d,  0xff,  0x00,  0x22,  0xfc,  0xc3,
+  0xfc,  0x11,  0xff,  0x00,  0xd2,  0x90,  0xd6,  0xcc,  0xf1,  0x7a,  0xd8,  0xf0,
+  0x67,  0xfc,  0x8e,  0x1a,  0x17,  0xfd,  0x7f,  0xc1,  0xff,  0x00,  0xa3,  0x16,
+  0xb1,  0xeb,  0x63,  0xc1,  0xdf,  0xf2,  0x37,  0x68,  0x7f,  0xf5,  0xfd,  0x07,
+  0xfe,  0x8c,  0x5a,  0xf9,  0xbc,  0x27,  0xfb,  0xcd,  0x3f,  0xf1,  0x2f,  0xcc,
+  0x48,  0xfb,  0x2b,  0x75,  0x1b,  0xa9,  0x9b,  0xa8,  0xdd,  0x5f,  0xd8,  0x16,
+  0x37,  0xb8,  0xfd,  0xd4,  0x6e,  0xa6,  0x6e,  0xa3,  0x75,  0x20,  0xb8,  0xed,
+  0xd4,  0xbb,  0xa9,  0x9b,  0xa8,  0xdd,  0x4c,  0x2e,  0x3f,  0x75,  0x26,  0xea,
+  0x6e,  0xea,  0x37,  0x52,  0x0b,  0x8f,  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,
+  0xd4,  0xec,  0x3b,  0x8f,  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,  0xd4,  0x0a,
+  0xe4,  0x74,  0x53,  0x33,  0x4b,  0x93,  0x57,  0x63,  0x3b,  0x8e,  0xa2,  0x9b,
+  0x9a,  0x4c,  0xd1,  0x60,  0xb8,  0xfa,  0x29,  0x99,  0xa3,  0x34,  0x58,  0x2e,
+  0x3f,  0x34,  0x53,  0x33,  0x4b,  0x93,  0x45,  0x82,  0xe3,  0xa8,  0xcd,  0x33,
+  0x34,  0x66,  0x8b,  0x05,  0xc7,  0xd1,  0x4d,  0xc9,  0xa3,  0x26,  0x8b,  0x05,
+  0xcf,  0x96,  0x3e,  0x30,  0x7f,  0xc9,  0x48,  0xd6,  0xbf,  0xdf,  0x8f,  0xff,
+  0x00,  0x45,  0xa5,  0x71,  0xb5,  0xdd,  0xfc,  0x6c,  0xd3,  0xa6,  0xb1,  0xf8,
+  0x85,  0x7f,  0x2c,  0x8a,  0x44,  0x77,  0x4b,  0x1c,  0xd1,  0xb7,  0x66,  0x1b,
+  0x02,  0x9f,  0xd5,  0x4d,  0x70,  0x95,  0xfc,  0x97,  0x9d,  0x42,  0x50,  0xcc,
+  0xf1,  0x31,  0x92,  0xb7,  0xbf,  0x2f,  0xfd,  0x29,  0x90,  0x7b,  0x3f,  0xec,
+  0xdb,  0xff,  0x00,  0x1f,  0xba,  0xef,  0xfd,  0x73,  0x87,  0xf9,  0xbd,  0x78,
+  0xc5,  0x7b,  0x87,  0xec,  0xe3,  0xa7,  0x4d,  0x1c,  0x3a,  0xd5,  0xf3,  0x29,
+  0x58,  0x24,  0x31,  0xc2,  0x8d,  0xfd,  0xe2,  0x37,  0x16,  0xfc,  0xb2,  0x3f,
+  0x3a,  0xf0,  0xfa,  0xf6,  0x73,  0x58,  0x4a,  0x19,  0x26,  0x5b,  0xcc,  0xad,
+  0x7f,  0x6a,  0xff,  0x00,  0xf2,  0x64,  0x01,  0x45,  0x14,  0x57,  0xc6,  0x00,
+  0x51,  0x45,  0x14,  0x00,  0x51,  0x45,  0x14,  0x00,  0x51,  0x45,  0x14,  0x00,
+  0x57,  0xb3,  0xfc,  0x57,  0xff,  0x00,  0x92,  0x51,  0xe0,  0xdf,  0xfa,  0xe7,
+  0x07,  0xfe,  0x88,  0xaf,  0x18,  0xaf,  0x70,  0xf8,  0x9b,  0xa7,  0x4d,  0x79,
+  0xf0,  0x77,  0xc3,  0x37,  0x11,  0x29,  0x74,  0xb5,  0x8a,  0xd9,  0xe4,  0xc7,
+  0x65,  0x30,  0xed,  0xcf,  0xe6,  0x40,  0xfc,  0x6b,  0xec,  0xf2,  0x38,  0x4a,
+  0x78,  0x0c,  0xc1,  0x45,  0x5f,  0xdc,  0x5f,  0x84,  0xae,  0xc0,  0xf0,  0xfa,
+  0xd8,  0xf0,  0x6f,  0xfc,  0x8d,  0xfa,  0x1f,  0xfd,  0x7f,  0x41,  0xff,  0x00,
+  0xa3,  0x16,  0xb1,  0xeb,  0xa2,  0xf8,  0x79,  0xa7,  0x4d,  0xaa,  0x78,  0xdf,
+  0x45,  0x86,  0x15,  0x2c,  0xcb,  0x75,  0x1c,  0xad,  0x8e,  0xca,  0x8c,  0x18,
+  0x9f,  0xc8,  0x57,  0xcd,  0x60,  0x61,  0x29,  0xe2,  0xe9,  0x46,  0x2a,  0xed,
+  0xca,  0x3f,  0x9a,  0x03,  0xeb,  0x9c,  0xd1,  0x4c,  0xcd,  0x2e,  0x4d,  0x7f,
+  0x60,  0x58,  0xbb,  0x8e,  0xa2,  0x99,  0x9a,  0x33,  0x45,  0x82,  0xe3,  0xe8,
+  0xa6,  0x66,  0x8c,  0xd1,  0x60,  0xb8,  0xfa,  0x29,  0x99,  0xa5,  0xc9,  0xa2,
+  0xc1,  0x71,  0xd9,  0xa2,  0x9b,  0x93,  0x49,  0x9a,  0x2c,  0x17,  0x1f,  0x45,
+  0x33,  0x34,  0x66,  0x8b,  0x05,  0xc6,  0x6e,  0xa3,  0x75,  0x30,  0x90,  0x3a,
+  0x9c,  0x51,  0x9a,  0xd2,  0xc6,  0x57,  0x1f,  0xba,  0x8d,  0xd4,  0xda,  0x4c,
+  0xd1,  0x60,  0xb8,  0xfd,  0xd4,  0x6e,  0xa6,  0x02,  0x0f,  0x43,  0x9a,  0x37,
+  0x01,  0xdf,  0x14,  0x58,  0x2e,  0x3f,  0x75,  0x1b,  0xa9,  0xb4,  0x94,  0x58,
+  0x2e,  0x3f,  0x75,  0x1b,  0xa9,  0xb4,  0x80,  0x83,  0xd0,  0xe6,  0x8b,  0x05,
+  0xc7,  0xee,  0xa3,  0x75,  0x30,  0x90,  0x3a,  0x9c,  0x51,  0x9a,  0x2c,  0x17,
+  0x31,  0x3c,  0x5d,  0xe0,  0xcd,  0x2f,  0xc6,  0xb6,  0x2b,  0x6f,  0xa8,  0xc4,
+  0x4b,  0x26,  0x4c,  0x53,  0xc6,  0x71,  0x24,  0x64,  0xf5,  0xc1,  0xfe,  0x87,
+  0x8a,  0xe0,  0x6d,  0x3f,  0x67,  0x7d,  0x32,  0x2b,  0xb0,  0xf7,  0x1a,  0xad,
+  0xcc,  0xf6,  0xe0,  0xe7,  0xca,  0x58,  0xd5,  0x09,  0x1e,  0x85,  0xb2,  0x7f,
+  0x95,  0x7a,  0xd5,  0x25,  0x78,  0x38,  0xcc,  0x87,  0x2c,  0xcc,  0x2b,  0x2a,
+  0xf8,  0x9a,  0x2a,  0x52,  0xef,  0xaa,  0xfb,  0xec,  0xd5,  0xfe,  0x77,  0x0b,
+  0x95,  0xf4,  0xad,  0x32,  0xd3,  0x44,  0xb0,  0x86,  0xca,  0xc6,  0x05,  0xb7,
+  0xb6,  0x88,  0x61,  0x23,  0x4e,  0x83,  0xfc,  0x4f,  0xbd,  0x7c,  0x6b,  0x5f,
+  0x69,  0x57,  0xc5,  0xb5,  0xf9,  0x8f,  0x88,  0xb0,  0x8d,  0x38,  0xe0,  0xe1,
+  0x05,  0x64,  0xb9,  0xec,  0x97,  0xfd,  0xb8,  0x34,  0x14,  0x51,  0x45,  0x7e,
+  0x32,  0x30,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
+  0x28,  0x00,  0xaf,  0xad,  0xfc,  0x2b,  0x04,  0x57,  0x9e,  0x06,  0xd1,  0xad,
+  0xe7,  0x8d,  0x66,  0x86,  0x4d,  0x3a,  0x04,  0x78,  0xdc,  0x65,  0x58,  0x18,
+  0xd7,  0x20,  0x8a,  0xf9,  0x22,  0xbe,  0xba,  0xf0,  0x67,  0xfc,  0x89,  0xfa,
+  0x17,  0xfd,  0x78,  0x41,  0xff,  0x00,  0xa2,  0xd6,  0xbf,  0x5c,  0xf0,  0xee,
+  0x2a,  0x58,  0x9c,  0x42,  0x7b,  0x72,  0xaf,  0xcc,  0x47,  0x05,  0xab,  0x7e,
+  0xcf,  0x7a,  0x4d,  0xdd,  0xdb,  0x4b,  0x65,  0xa8,  0x4f,  0x63,  0x13,  0x1c,
+  0xf9,  0x25,  0x04,  0x80,  0x7b,  0x02,  0x48,  0x3f,  0x9e,  0x6b,  0xaf,  0xf0,
+  0x57,  0xc3,  0xcd,  0x27,  0xc0,  0xd1,  0xb9,  0xb3,  0x47,  0x9a,  0xee,  0x41,
+  0xb6,  0x4b,  0xa9,  0xb0,  0x5c,  0x8f,  0x41,  0xe8,  0x3d,  0x87,  0xe3,  0x5d,
+  0x36,  0x69,  0x6b,  0xf5,  0x7c,  0x37,  0x0f,  0xe5,  0x78,  0x3a,  0xff,  0x00,
+  0x59,  0xa1,  0x41,  0x46,  0x7d,  0xf5,  0xd3,  0xd1,  0x6c,  0xbe,  0x49,  0x0a,
+  0xe3,  0xb7,  0x51,  0xba,  0x99,  0x9a,  0x03,  0x03,  0xde,  0xbd,  0xfb,  0x05,
+  0xc7,  0xee,  0xa3,  0x75,  0x30,  0x90,  0x06,  0x4f,  0x14,  0x51,  0x60,  0xb8,
+  0xfd,  0xd4,  0x6e,  0xa6,  0xd1,  0x45,  0x82,  0xe3,  0xb7,  0x51,  0xba,  0x98,
+  0x08,  0x3d,  0x0e,  0x68,  0x24,  0x0e,  0xf4,  0x58,  0x2e,  0x3f,  0x75,  0x1b,
+  0xa9,  0x94,  0xb4,  0x58,  0x2e,  0x3b,  0x75,  0x1b,  0xa9,  0x99,  0xa0,  0x10,
+  0x7a,  0x1a,  0x2c,  0x17,  0x31,  0x62,  0xbd,  0x91,  0x46,  0xf7,  0x90,  0x3e,
+  0xd3,  0xf7,  0x1b,  0xa9,  0xad,  0x58,  0xa5,  0x13,  0x46,  0xae,  0xbd,  0x08,
+  0xac,  0x3f,  0x38,  0xff,  0x00,  0x71,  0x3f,  0xef,  0x91,  0x56,  0x52,  0xf1,
+  0xe3,  0x48,  0x55,  0x42,  0x80,  0x7a,  0x80,  0x3d,  0xeb,  0xb2,  0x70,  0xbe,
+  0xc7,  0x9d,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xcd,  0x36,  0x59,  0x44,  0x31,
+  0xb3,  0xb7,  0x41,  0x49,  0xba,  0xb3,  0x1e,  0xf2,  0x49,  0x12,  0x65,  0x60,
+  0x08,  0x1d,  0x01,  0x1e,  0xf5,  0x84,  0x61,  0xcc,  0x75,  0x4e,  0xa7,  0x22,
+  0x1b,  0x2d,  0xec,  0x8c,  0x0b,  0xa4,  0x81,  0x37,  0x1f,  0xb8,  0xbd,  0x7e,
+  0xb4,  0xb1,  0x5e,  0xc8,  0xa0,  0x3b,  0xb8,  0x7d,  0xa7,  0xee,  0x37,  0x5f,
+  0xad,  0x57,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,  0x14,  0x79,  0xc7,  0xfb,
+  0x89,  0xff,  0x00,  0x7c,  0x8a,  0xeb,  0xe5,  0x56,  0xb5,  0x8e,  0x0e,  0x77,
+  0x7b,  0xdc,  0xdd,  0x8e,  0x41,  0x2a,  0x2b,  0xaf,  0x42,  0x33,  0x4e,  0xac,
+  0xa8,  0xef,  0x1d,  0x3c,  0x85,  0x00,  0x05,  0x3d,  0x40,  0x1e,  0xe6,  0xb4,
+  0x77,  0x57,  0x24,  0xa3,  0xca,  0x77,  0xc2,  0x7c,  0xe8,  0x74,  0x92,  0x08,
+  0xd1,  0x99,  0x8f,  0x00,  0x66,  0xb2,  0xa5,  0xbd,  0x91,  0x81,  0x74,  0x70,
+  0x99,  0x38,  0xd8,  0x3a,  0xfd,  0x69,  0xd2,  0x5e,  0x3b,  0xf9,  0xea,  0x40,
+  0x2a,  0x3a,  0x02,  0x3d,  0xc5,  0x55,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,
+  0x15,  0xbc,  0x21,  0x6d,  0xce,  0x6a,  0x95,  0x6f,  0xa2,  0x64,  0xf1,  0x5e,
+  0x48,  0xa3,  0x7b,  0x48,  0x1f,  0x69,  0xfb,  0x8d,  0xd4,  0xd6,  0xac,  0x52,
+  0x89,  0xa3,  0x57,  0x5e,  0x86,  0xb0,  0xfc,  0xe3,  0xfd,  0xc4,  0xff,  0x00,
+  0xbe,  0x45,  0x59,  0x4b,  0xc7,  0x8d,  0x61,  0x0a,  0x14,  0x03,  0xd4,  0x01,
+  0xef,  0x44,  0xe1,  0x7d,  0x85,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xcd,  0x15,
+  0x1e,  0xea,  0x5d,  0xd5,  0xcd,  0x63,  0xba,  0xe3,  0xeb,  0xc0,  0xbc,  0x71,
+  0xf0,  0x57,  0x55,  0x83,  0x57,  0x9e,  0xe7,  0x44,  0x85,  0x6f,  0x6c,  0xa6,
+  0x72,  0xe2,  0x25,  0x70,  0xaf,  0x16,  0x4e,  0x76,  0xe0,  0x91,  0x91,  0xe9,
+  0x8a,  0xf7,  0xad,  0xd4,  0x66,  0xbe,  0x7f,  0x39,  0xc8,  0xf0,  0x99,  0xe5,
+  0x18,  0xd2,  0xc4,  0xdd,  0x72,  0xbb,  0xa6,  0xb7,  0x5d,  0xfb,  0xef,  0xe8,
+  0x17,  0xb1,  0xf2,  0xc5,  0xff,  0x00,  0xc3,  0x5f,  0x12,  0xe9,  0x96,  0x53,
+  0x5d,  0xdd,  0x69,  0x52,  0x43,  0x6f,  0x0a,  0x97,  0x92,  0x42,  0xe8,  0x42,
+  0x81,  0xd4,  0xf0,  0x6b,  0x99,  0xaf,  0xaa,  0xfe,  0x21,  0x9c,  0xf8,  0x1f,
+  0x5c,  0xff,  0x00,  0xaf,  0x47,  0xfe,  0x55,  0xf2,  0xa5,  0x7e,  0x01,  0xc5,
+  0x59,  0x1e,  0x1f,  0x22,  0xc4,  0x53,  0xa3,  0x87,  0x93,  0x92,  0x94,  0x6f,
+  0xef,  0x5b,  0xbd,  0xba,  0x24,  0x5a,  0x77,  0x0a,  0xe9,  0xec,  0xbe,  0x19,
+  0xf8,  0x9b,  0x51,  0xb3,  0x86,  0xea,  0xdb,  0x49,  0x92,  0x5b,  0x79,  0x90,
+  0x49,  0x1b,  0x87,  0x40,  0x19,  0x48,  0xc8,  0x3d,  0x6b,  0x98,  0xaf,  0xac,
+  0x3c,  0x08,  0x71,  0xe0,  0xad,  0x0b,  0xfe,  0xbc,  0xa1,  0xff,  0x00,  0xd0,
+  0x05,  0x57,  0x0a,  0xe4,  0x58,  0x7c,  0xf6,  0xbd,  0x5a,  0x58,  0x89,  0x4a,
+  0x2a,  0x2a,  0xfe,  0xed,  0xbb,  0xdb,  0xaa,  0x60,  0xdd,  0x8f,  0x9e,  0xdb,
+  0xe1,  0x4f,  0x8a,  0xd1,  0x4b,  0x1d,  0x1a,  0x50,  0x00,  0xc9,  0x3e,  0x62,
+  0x7f,  0xf1,  0x55,  0xc9,  0xd7,  0xd9,  0x17,  0x4d,  0xfe,  0x8d,  0x37,  0xfb,
+  0x87,  0xf9,  0x57,  0xc6,  0xf5,  0xd1,  0xc5,  0x9c,  0x3d,  0x86,  0xc8,  0x5d,
+  0x05,  0x87,  0x9c,  0xa5,  0xcf,  0xcd,  0x7e,  0x6b,  0x74,  0xb6,  0xd6,  0x4b,
+  0xb8,  0x27,  0x70,  0xae,  0x87,  0x47,  0xf0,  0x07,  0x88,  0x35,  0xfb,  0x04,
+  0xbd,  0xb0,  0xd3,  0x64,  0xb9,  0xb5,  0x72,  0x42,  0xc8,  0xae,  0xa0,  0x12,
+  0x0e,  0x0f,  0x53,  0xeb,  0x5c,  0xf5,  0x7d,  0x27,  0xf0,  0x54,  0xe3,  0xe1,
+  0xed,  0x8f,  0xfd,  0x74,  0x97,  0xff,  0x00,  0x43,  0x35,  0xe7,  0x70,  0xbe,
+  0x4f,  0x43,  0x3c,  0xc6,  0xcb,  0x0d,  0x5e,  0x4d,  0x25,  0x16,  0xf4,  0xb5,
+  0xee,  0x9a,  0x5d,  0x53,  0xee,  0x0d,  0xd8,  0xf3,  0x1f,  0x0d,  0x7c,  0x12,
+  0xd7,  0xb5,  0x3d,  0x42,  0x31,  0xa9,  0x40,  0x34,  0xdb,  0x20,  0xc0,  0xc8,
+  0xee,  0xea,  0xce,  0x47,  0x70,  0xa0,  0x13,  0xcf,  0xb9,  0xe2,  0xbe,  0x87,
+  0xb7,  0x82,  0x3b,  0x4b,  0x78,  0xa0,  0x89,  0x42,  0x45,  0x12,  0x84,  0x45,
+  0x1d,  0x80,  0x18,  0x02,  0x97,  0x34,  0x9b,  0xab,  0xfa,  0x07,  0x25,  0xe1,
+  0xfc,  0x1e,  0x45,  0x09,  0x47,  0x0d,  0x76,  0xe5,  0xbb,  0x7a,  0xbd,  0x36,
+  0x5a,  0x24,  0xad,  0xf2,  0x22,  0xf7,  0x24,  0xcd,  0x19,  0xa8,  0xf7,  0x51,
+  0xba,  0xbe,  0x96,  0xc1,  0x71,  0xd2,  0x48,  0x22,  0x46,  0x76,  0xe0,  0x0e,
+  0x6b,  0x2a,  0x5b,  0xd9,  0x18,  0x17,  0x47,  0x11,  0xe4,  0xe3,  0x60,  0xeb,
+  0xf5,  0xa7,  0x49,  0x78,  0xef,  0xe7,  0xa9,  0x00,  0xa8,  0xe8,  0x08,  0xf7,
+  0x02,  0xaa,  0xf9,  0xc7,  0xfb,  0x89,  0xff,  0x00,  0x7c,  0x8a,  0xe9,  0x84,
+  0x2d,  0xb9,  0xc5,  0x56,  0xaf,  0x36,  0x89,  0x93,  0xc5,  0x7b,  0x22,  0x8d,
+  0xef,  0x20,  0x7d,  0xa7,  0xee,  0x37,  0x53,  0x5a,  0xd1,  0x4a,  0x26,  0x8d,
+  0x5d,  0x7a,  0x1a,  0xc2,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,  0x15,  0x65,
+  0x2f,  0x1e,  0x34,  0x84,  0x28,  0x50,  0x09,  0xe4,  0x01,  0xef,  0x44,  0xe1,
+  0x7d,  0x85,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xa6,  0xcb,  0x28,  0x86,  0x36,
+  0x76,  0xe8,  0x29,  0x37,  0x56,  0x63,  0xde,  0x3c,  0x89,  0x30,  0x60,  0xa4,
+  0x0e,  0x80,  0x8f,  0x7a,  0xc2,  0x30,  0xe6,  0x3a,  0xa7,  0x53,  0x91,  0x0d,
+  0x96,  0xf6,  0x46,  0x05,  0xd2,  0x40,  0x9b,  0x8f,  0xdc,  0x5e,  0xa3,  0xde,
+  0x96,  0x2b,  0xd9,  0x14,  0x07,  0x77,  0x0f,  0xb4,  0xfd,  0xc6,  0xeb,  0xf5,
+  0xaa,  0xfe,  0x71,  0xfe,  0xe2,  0x7f,  0xdf,  0x22,  0x8f,  0x38,  0xff,  0x00,
+  0x71,  0x3f,  0xef,  0x91,  0x5d,  0x7c,  0xaa,  0xd6,  0xb1,  0xc1,  0xce,  0xef,
+  0x7b,  0x9b,  0xb1,  0xc8,  0x25,  0x45,  0x75,  0xe8,  0x46,  0x69,  0xd5,  0x95,
+  0x1d,  0xe3,  0xa0,  0x81,  0x46,  0x02,  0x9e,  0xa0,  0x0f,  0x72,  0x2b,  0x4b,
+  0x35,  0xc9,  0x28,  0xf2,  0x9d,  0xf0,  0xa9,  0xce,  0x85,  0x92,  0x41,  0x1a,
+  0x33,  0xb7,  0x40,  0x32,  0x6b,  0x2a,  0x5b,  0xd9,  0x1c,  0x17,  0x47,  0x09,
+  0x93,  0x8d,  0x83,  0xaf,  0xd6,  0x9d,  0x25,  0xe3,  0xbf,  0x9e,  0xa4,  0x02,
+  0xa3,  0xa0,  0x23,  0xdc,  0x55,  0x5f,  0x38,  0xff,  0x00,  0x71,  0x3f,  0xef,
+  0x91,  0x5b,  0xc2,  0x16,  0xdc,  0xe6,  0xa9,  0x57,  0x9b,  0x44,  0xc8,  0xea,
+  0x70,  0xa4,  0x88,  0x30,  0x09,  0xff,  0x00,  0xf5,  0xd3,  0x4d,  0xbb,  0x09,
+  0x84,  0x59,  0x1b,  0xbd,  0x7b,  0x56,  0x95,  0xb4,  0x66,  0x18,  0x42,  0x13,
+  0x92,  0x3d,  0x2a,  0xe5,  0x2b,  0x23,  0x2a,  0x70,  0x72,  0x6d,  0x32,  0x7a,
+  0xc8,  0x2a,  0x40,  0x9f,  0x20,  0x8f,  0xff,  0x00,  0x5d,  0x6a,  0xe6,  0xa3,
+  0xb9,  0x8c,  0xcf,  0x09,  0x40,  0x40,  0x27,  0xd6,  0xb1,  0x83,  0xe5,  0x3a,
+  0x6a,  0x47,  0x99,  0x5c,  0xc7,  0xa2,  0xa5,  0x5b,  0x76,  0x69,  0x8c,  0x59,
+  0x1b,  0xbf,  0x4a,  0x3e,  0xce,  0xde,  0x7f,  0x95,  0x91,  0xbb,  0xd7,  0xb5,
+  0x74,  0xdd,  0x1c,  0x3c,  0xac,  0x7a,  0xa9,  0x2d,  0x6f,  0x80,  0x7f,  0xcb,
+  0x1a,  0xd6,  0xa8,  0x6d,  0xe3,  0x30,  0xc2,  0xa8,  0x48,  0x24,  0x77,  0x15,
+  0x26,  0x6b,  0x9a,  0x6f,  0x99,  0x9d,  0xf4,  0xe3,  0xca,  0x8c,  0xb6,  0x52,
+  0x1a,  0xe3,  0x20,  0xff,  0x00,  0x96,  0x15,  0x5e,  0xb6,  0x2e,  0x23,  0x33,
+  0x44,  0xc8,  0x08,  0x04,  0xd6,  0x67,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,
+  0x7a,  0xf6,  0xad,  0xa1,  0x24,  0xd1,  0xcb,  0x52,  0x0e,  0x2d,  0x58,  0x8a,
+  0xa7,  0x0a,  0x48,  0x83,  0x00,  0x9f,  0xff,  0x00,  0x5d,  0x34,  0xdb,  0xb2,
+  0xcc,  0x22,  0xc8,  0xdd,  0xeb,  0xda,  0xb4,  0xad,  0xa3,  0x30,  0xc2,  0xaa,
+  0x4e,  0x48,  0xf4,  0xa2,  0x52,  0xb2,  0x0a,  0x70,  0x72,  0x6d,  0x32,  0x7a,
+  0x29,  0xa4,  0xd1,  0x9a,  0xe5,  0xb1,  0xde,  0x3a,  0x8a,  0x6e,  0x73,  0x41,
+  0x34,  0x58,  0x0e,  0x7f,  0xe2,  0x1f,  0xfc,  0x88,  0xfa,  0xe7,  0xfd,  0x7a,
+  0xbf,  0xf2,  0xaf,  0x95,  0xab,  0xeb,  0x2f,  0x18,  0x58,  0x4b,  0xaa,  0xf8,
+  0x57,  0x56,  0xb4,  0x80,  0x6e,  0x9a,  0x6b,  0x69,  0x15,  0x17,  0xd5,  0xb6,
+  0x9c,  0x0f,  0xce,  0xbe,  0x4e,  0x65,  0x2a,  0x48,  0x20,  0x82,  0x38,  0x20,
+  0xf6,  0xaf,  0xc1,  0x7c,  0x46,  0x84,  0x96,  0x32,  0x84,  0xed,  0xa3,  0x8b,
+  0x5f,  0x73,  0xff,  0x00,  0x82,  0x8d,  0x20,  0x25,  0x7d,  0x5d,  0xe0,  0x5f,
+  0xf9,  0x12,  0xf4,  0x2f,  0xfa,  0xf2,  0x87,  0xff,  0x00,  0x40,  0x15,  0xf2,
+  0x9a,  0x23,  0x48,  0xea,  0x88,  0xa5,  0x9d,  0x8e,  0x02,  0x81,  0x92,  0x4d,
+  0x7d,  0x69,  0xe1,  0x8b,  0x19,  0x34,  0xbf,  0x0d,  0xe9,  0x76,  0x73,  0x71,
+  0x2c,  0x16,  0xd1,  0xc6,  0xe3,  0xd0,  0x85,  0x00,  0xd5,  0x78,  0x73,  0x09,
+  0x3c,  0x56,  0x22,  0x76,  0xd1,  0x45,  0x2f,  0xc7,  0xfe,  0x00,  0x4c,  0xd0,
+  0xba,  0xff,  0x00,  0x8f,  0x69,  0xbf,  0xdc,  0x3f,  0xca,  0xbe,  0x39,  0xaf,
+  0xb1,  0xe5,  0x5f,  0x32,  0x27,  0x4c,  0xe3,  0x72,  0x91,  0x9a,  0xf9,  0x03,
+  0x50,  0xb1,  0x9b,  0x4c,  0xbe,  0xb8,  0xb4,  0x9d,  0x0a,  0x4d,  0x04,  0x86,
+  0x37,  0x53,  0xd8,  0x83,  0x8a,  0xed,  0xf1,  0x22,  0x12,  0xff,  0x00,  0x65,
+  0x9d,  0xb4,  0xf7,  0xd7,  0xfe,  0x92,  0x10,  0x2b,  0xd7,  0xd2,  0x5f,  0x05,
+  0xbf,  0xe4,  0x9f,  0x58,  0xff,  0x00,  0xd7,  0x49,  0x7f,  0xf4,  0x33,  0x5f,
+  0x36,  0xd7,  0xd3,  0x9f,  0x0a,  0x74,  0xe9,  0xb4,  0xbf,  0x01,  0xe9,  0x91,
+  0x4e,  0xa5,  0x24,  0x75,  0x69,  0x76,  0x9e,  0xa0,  0x33,  0x12,  0x3f,  0x42,
+  0x2b,  0xc3,  0xf0,  0xf6,  0x12,  0x96,  0x69,  0x52,  0x49,  0x68,  0xa0,  0xff,
+  0x00,  0x19,  0x44,  0x72,  0xd8,  0xeb,  0xe8,  0xa6,  0xe6,  0x8c,  0xd7,  0xf4,
+  0x3d,  0x8c,  0x87,  0x51,  0x4d,  0xcd,  0x19,  0xa2,  0xc0,  0x65,  0xb2,  0x90,
+  0xd7,  0x19,  0x04,  0x7f,  0xfb,  0x42,  0xab,  0xd6,  0xc5,  0xc4,  0x66,  0x68,
+  0x59,  0x07,  0x04,  0xfa,  0xd6,  0x67,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,
+  0x7a,  0xf6,  0xae,  0xa8,  0x4a,  0xe8,  0xe0,  0xa9,  0x07,  0x16,  0xac,  0x45,
+  0x53,  0x85,  0x24,  0x41,  0x80,  0x4f,  0xff,  0x00,  0xae,  0x9a,  0x6d,  0xd9,
+  0x66,  0x11,  0x64,  0x6e,  0xf5,  0xed,  0x5a,  0x76,  0xd1,  0x98,  0x21,  0x0a,
+  0x48,  0x27,  0xda,  0x89,  0x4a,  0xc8,  0x29,  0xc1,  0xc9,  0xb4,  0xc9,  0xab,
+  0x20,  0xa9,  0x02,  0x7c,  0x82,  0x3f,  0xfd,  0x75,  0xab,  0x9a,  0x8a,  0xe6,
+  0x33,  0x34,  0x45,  0x41,  0xc1,  0xf7,  0xac,  0x60,  0xf9,  0x4e,  0x9a,  0x91,
+  0xe6,  0x46,  0x45,  0x15,  0x28,  0xb7,  0x66,  0x98,  0xc5,  0x91,  0xb8,  0x77,
+  0xed,  0x47,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,  0x7a,  0xf6,  0xae,  0x9b,
+  0xa3,  0x87,  0x95,  0x8f,  0x55,  0x25,  0xad,  0xf0,  0x0f,  0xf9,  0x63,  0x5a,
+  0xd5,  0x0d,  0xba,  0x18,  0x61,  0x54,  0x24,  0x12,  0x3d,  0x2a,  0x4c,  0xd7,
+  0x34,  0xdf,  0x33,  0x3b,  0xe9,  0xc7,  0x95,  0x19,  0x6c,  0xa4,  0x35,  0xc6,
+  0x41,  0xff,  0x00,  0x2c,  0x2a,  0xbd,  0x6c,  0x5c,  0x46,  0x66,  0x85,  0x90,
+  0x1c,  0x13,  0xeb,  0x59,  0x9f,  0x67,  0x6f,  0x3f,  0xca,  0xc8,  0xdd,  0xfa,
+  0x56,  0xd0,  0x92,  0x68,  0xe5,  0xa9,  0x06,  0x9a,  0xb1,  0xa0,  0xd6,  0xc1,
+  0xae,  0x04,  0xb9,  0x39,  0x1d,  0xaa,  0x6a,  0x28,  0xae,  0x76,  0xdb,  0x3a,
+  0xd2,  0xb6,  0xc1,  0x45,  0x14,  0x52,  0x19,  0x0a,  0xdb,  0x05,  0xb8,  0x32,
+  0xe4,  0xe4,  0xf6,  0xa3,  0xec,  0xc3,  0xed,  0x1e,  0x6e,  0x4e,  0x7d,  0x2a,
+  0x6a,  0x2a,  0xb9,  0x99,  0x3c,  0xa8,  0x28,  0xa2,  0x8a,  0x92,  0x82,  0xa1,
+  0xfb,  0x30,  0xfb,  0x47,  0x9b,  0x93,  0x9f,  0x4a,  0x9a,  0x8a,  0x69,  0xd8,
+  0x4d,  0x5f,  0x72,  0x16,  0xb6,  0x0d,  0x70,  0x25,  0xc9,  0xc8,  0xed,  0x53,
+  0x51,  0x45,  0x0d,  0xb6,  0x09,  0x5b,  0x60,  0xa2,  0x8a,  0x29,  0x0c,  0x28,
+  0xa2,  0x8a,  0x00,  0x2b,  0x83,  0xf1,  0x57,  0xc1,  0xdd,  0x1b,  0xc4,  0xb7,
+  0xaf,  0x79,  0x1b,  0xcb,  0xa7,  0x5d,  0x48,  0x73,  0x21,  0x80,  0x02,  0x8e,
+  0x7d,  0x4a,  0x9e,  0xff,  0x00,  0x42,  0x2b,  0xbc,  0xa2,  0xbc,  0xfc,  0x76,
+  0x5f,  0x85,  0xcc,  0xa9,  0xfb,  0x1c,  0x5d,  0x35,  0x38,  0xf9,  0xfe,  0x8f,
+  0x75,  0xf2,  0x1a,  0x6d,  0x1c,  0x3f,  0x84,  0xbe,  0x11,  0xe8,  0xde,  0x16,
+  0xbb,  0x4b,  0xc2,  0xd2,  0x5f,  0xde,  0x27,  0x29,  0x24,  0xf8,  0xda,  0x87,
+  0xd5,  0x54,  0x77,  0xf7,  0x39,  0xae,  0xe2,  0x8a,  0x29,  0xe0,  0xb0,  0x18,
+  0x5c,  0xba,  0x97,  0xb1,  0xc2,  0x53,  0x50,  0x8f,  0x97,  0xeb,  0xd5,  0xfc,
+  0xc2,  0xed,  0x85,  0x71,  0xfe,  0x31,  0xf8,  0x5f,  0xa4,  0x78,  0xc6,  0x6f,
+  0xb4,  0xcd,  0xe6,  0x5a,  0x5e,  0xe3,  0x06,  0xe2,  0x0c,  0x65,  0xc7,  0x6d,
+  0xc0,  0xf5,  0xfe,  0x7e,  0xf5,  0xd8,  0x51,  0x55,  0x8c,  0xc1,  0x61,  0xf1,
+  0xf4,  0x9d,  0x0c,  0x54,  0x14,  0xe2,  0xfa,  0x3f,  0xeb,  0x46,  0x17,  0x68,
+  0xf3,  0xbf,  0x0f,  0x7c,  0x11,  0xd1,  0x74,  0x6b,  0xc4,  0xb9,  0xb9,  0x96,
+  0x5d,  0x49,  0xd0,  0xe5,  0x63,  0x94,  0x05,  0x8f,  0x3e,  0xa5,  0x47,  0x5f,
+  0xc4,  0xe3,  0xda,  0xbd,  0x13,  0xa5,  0x14,  0x56,  0x38,  0x1c,  0xb7,  0x07,
+  0x96,  0x41,  0xd3,  0xc1,  0xd3,  0x50,  0x4f,  0x7b,  0x75,  0xf5,  0x7b,  0xb0,
+  0x6d,  0xb0,  0xa2,  0x8a,  0x2b,  0xd3,  0x10,  0x51,  0x45,  0x14,  0x00,  0x54,
+  0x3f,  0x66,  0x1f,  0x68,  0xf3,  0x72,  0x73,  0xe9,  0x53,  0x51,  0x4d,  0x3b,
+  0x09,  0xab,  0xee,  0x42,  0xd6,  0xc1,  0xae,  0x04,  0xb9,  0x39,  0x1d,  0xaa,
+  0x6a,  0x28,  0xa1,  0xb6,  0xc1,  0x2b,  0x6c,  0x14,  0x51,  0x45,  0x21,  0x90,
+  0xad,  0xb0,  0x5b,  0x83,  0x2e,  0x4e,  0x4f,  0x6a,  0x3e,  0xcc,  0x3e,  0xd1,
+  0xe6,  0xe4,  0xe7,  0xd2,  0xa6,  0xa2,  0xab,  0x99,  0x93,  0xca,  0x82,  0x8a,
+  0x28,  0xa9,  0x28,  0x2a,  0x1f,  0xb3,  0x0f,  0xb4,  0x79,  0xb9,  0x39,  0xf4,
+  0xa9,  0xa8,  0xa6,  0x9d,  0x84,  0xd5,  0xf7,  0x3e,  0x20,  0xff,  0x00,  0x87,
+  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,
+  0xfe,  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,
+  0xbe,  0x17,  0xfe,  0xc6,  0xb2,  0xff,  0x00,  0x9f,  0x64,  0xa7,  0x47,  0xa2,
+  0x59,  0x31,  0xe6,  0xd9,  0x31,  0x45,  0x8e,  0x9e,  0x44,  0x7d,  0xcd,  0xff,
+  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,  0x05,  0x45,
+  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,
+  0x15,  0x7c,  0x3b,  0xfd,  0x87,  0x61,  0xff,  0x00,  0x3e,  0xb1,  0xfe,  0x54,
+  0xd9,  0x34,  0x6b,  0x05,  0x1c,  0x5b,  0x47,  0x9f,  0xa5,  0x16,  0x0e,  0x44,
+  0x7d,  0xc9,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,
+  0xfe,  0x05,  0x45,  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,
+  0x1f,  0xf8,  0x15,  0x15,  0x7c,  0x2f,  0xfd,  0x8d,  0x65,  0xff,  0x00,  0x3e,
+  0xc9,  0xf9,  0x53,  0xe3,  0xd1,  0x2c,  0x4f,  0x26,  0xd9,  0x31,  0xf4,  0xa2,
+  0xc1,  0xc8,  0x8f,  0xb9,  0x7f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,  0x00,  0xa1,
+  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xa8,  0xff,  0x00,  0x87,  0xa6,  0xf8,
+  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xaf,  0x87,  0x7f,
+  0xb0,  0xec,  0x3f,  0xe7,  0xd6,  0x3f,  0xca,  0x99,  0x26,  0x8d,  0x62,  0x38,
+  0x16,  0xc9,  0x9a,  0x2c,  0x1c,  0x88,  0xfb,  0x97,  0xfe,  0x1e,  0x9b,  0xe1,
+  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0x8f,  0xf8,  0x7a,  0x6f,
+  0x85,  0xbf,  0xe8,  0x47,  0xd6,  0x3f,  0xf0,  0x2a,  0x2a,  0xf8,  0x5f,  0xfb,
+  0x1a,  0xcb,  0xfe,  0x7d,  0x93,  0xf2,  0xa9,  0x23,  0xd1,  0x2c,  0x48,  0xc9,
+  0xb6,  0x4f,  0xca,  0x8b,  0x07,  0x22,  0x3e,  0xe4,  0xff,  0x00,  0x87,  0xa6,
+  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,
+  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,
+  0x1d,  0xfe,  0xc3,  0xb0,  0xff,  0x00,  0x9f,  0x58,  0xff,  0x00,  0x2a,  0x64,
+  0x9a,  0x35,  0x88,  0x38,  0x16,  0xc9,  0xf9,  0x51,  0x60,  0xe4,  0x47,  0xdc,
+  0xbf,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,
+  0x54,  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,
+  0x00,  0x81,  0x51,  0x57,  0xc2,  0xff,  0x00,  0xd8,  0xd6,  0x5f,  0xf3,  0xec,
+  0x9f,  0x95,  0x48,  0x9a,  0x1d,  0x89,  0x19,  0x36,  0xc9,  0xf9,  0x51,  0x60,
+  0xe4,  0x47,  0xdc,  0x9f,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,
+  0x7f,  0xe0,  0x54,  0x54,  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,
+  0x3e,  0xb1,  0xff,  0x00,  0x81,  0x51,  0x57,  0xc3,  0xbf,  0xd8,  0x76,  0x1f,
+  0xf3,  0xeb,  0x1f,  0xe5,  0x51,  0xbe,  0x8d,  0x63,  0x9c,  0x0b,  0x64,  0xfc,
+  0xa8,  0xb0,  0x72,  0x23,  0xee,  0x6f,  0xf8,  0x7a,  0x6f,  0x85,  0xbf,  0xe8,
+  0x47,  0xd6,  0x3f,  0xf0,  0x2a,  0x2a,  0x3f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,
+  0x00,  0xa1,  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xab,  0xe1,  0x7f,  0xec,
+  0x7b,  0x2f,  0xf9,  0xf6,  0x4f,  0xca,  0x9b,  0x2e,  0x9d,  0xa7,  0xdb,  0xed,
+  0x53,  0x67,  0xe6,  0xc8,  0xc0,  0x90,  0xb1,  0xae,  0x4e,  0x3d,  0x68,  0xb0,
+  0x72,  0x23,  0xee,  0xaf,  0xf8,  0x7a,  0x6f,  0x85,  0xbf,  0xe8,  0x47,  0xd6,
+  0x3f,  0xf0,  0x2a,  0x2a,  0x3f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,  0x00,  0xa1,
+  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xab,  0xe1,  0x1f,  0x23,  0x4b,  0xd8,
+  0x1b,  0xec,  0x44,  0x8d,  0xbb,  0x9b,  0x09,  0xf7,  0x06,  0x48,  0xc9,  0xe7,
+  0xd8,  0xfe,  0x54,  0x3d,  0x9e,  0x9e,  0x2e,  0x04,  0x66,  0xcb,  0x60,  0x27,
+  0x68,  0x72,  0xbf,  0x29,  0x3f,  0x5c,  0xd1,  0x60,  0xe4,  0x47,  0xdd,  0xdf,
+  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,  0x54,
+  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,  0x00,
+  0x81,  0x51,  0x57,  0xc1,  0x82,  0xdf,  0x4e,  0x1b,  0xb7,  0xd9,  0x98,  0x88,
+  0x19,  0xda,  0xeb,  0xc9,  0xe7,  0x1c,  0x73,  0xea,  0x45,  0x4d,  0x1d,  0x9e,
+  0x9a,  0x46,  0x0d,  0x91,  0x12,  0x02,  0x41,  0x8c,  0xaf,  0xcd,  0x9c,  0x67,
+  0xd7,  0xd2,  0x8b,  0x07,  0x22,  0x3e,  0xed,  0xff,  0x00,  0x87,  0xa6,  0xf8,
+  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,  0x1e,
+  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,  0x16,
+  0xb7,  0xd3,  0xf4,  0xeb,  0x86,  0x65,  0xfb,  0x1f,  0x96,  0xea,  0x01,  0x2b,
+  0x22,  0xe0,  0xe0,  0xf7,  0xa7,  0x36,  0x8f,  0x62,  0x49,  0xc5,  0xb2,  0x62,
+  0x8b,  0x07,  0x22,  0x3e,  0xe7,  0xff,  0x00,  0x87,  0xa6,  0xf8,  0x5b,  0xfe,
+  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,  0x1e,  0x9b,  0xe1,
+  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,  0x17,  0xfe,  0xc6,
+  0xb2,  0x3f,  0xf2,  0xec,  0x95,  0x30,  0xd0,  0xec,  0x40,  0xff,  0x00,  0x8f,
+  0x64,  0xa2,  0xc1,  0xc8,  0x8f,  0xb8,  0xbf,  0xe1,  0xe9,  0xbe,  0x16,  0xff,
+  0x00,  0xa1,  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xa8,  0xff,  0x00,  0x87,
+  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xaf,
+  0x87,  0x7f,  0xb1,  0x2c,  0x07,  0xfc,  0xba,  0xc7,  0xf9,  0x54,  0x27,  0x47,
+  0xb2,  0x27,  0xfe,  0x3d,  0x92,  0x8b,  0x07,  0x22,  0x3e,  0xe8,  0xff,  0x00,
+  0x87,  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,
+  0xa3,  0xfe,  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,
+  0x8a,  0xbe,  0x17,  0x1a,  0x2d,  0x91,  0x38,  0xfb,  0x32,  0x54,  0xdf,  0xd8,
+  0x76,  0x1f,  0xf3,  0xea,  0x9f,  0x95,  0x16,  0x0e,  0x44,  0x7d,  0xc5,  0xff,
+  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,  0x05,  0x45,
+  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,
+  0x15,  0x7c,  0x3a,  0x74,  0x4b,  0x00,  0x33,  0xf6,  0x58,  0xff,  0x00,  0x2a,
+  0x84,  0xe8,  0xd6,  0x5f,  0xf3,  0xec,  0x94,  0x58,  0x39,  0x11,  0xf7,  0x47,
+  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,  0x15,
+  0x1f,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,
+  0x55,  0xf0,  0xc2,  0xe8,  0xb6,  0x4c,  0x40,  0xfb,  0x32,  0x54,  0xbf,  0xd8,
+  0x76,  0x1f,  0xf3,  0xea,  0x94,  0x58,  0x39,  0x11,  0xf7,  0x17,  0xfc,  0x3d,
+  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,  0x15,  0x1f,  0xf0,
+  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,  0x55,  0xf0,
+  0xe3,  0x68,  0xb6,  0x0a,  0x09,  0xfb,  0x2c,  0x7f,  0x95,  0x45,  0xfd,  0x8d,
+  0x65,  0xff,  0x00,  0x3e,  0xc9,  0x45,  0x83,  0x91,  0x1f,  0x74,  0x7f,  0xc3,
+  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,  0x00,  0x81,  0x51,
+  0x51,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,
+  0x05,  0x45,  0x5f,  0x0c,  0x26,  0x89,  0x64,  0xcd,  0xff,  0x00,  0x1e,  0xc9,
+  0x52,  0xff,  0x00,  0x61,  0xd8,  0x7f,  0xcf,  0xac,  0x7f,  0x95,  0x16,  0x0e,
+  0x44,  0x7d,  0xc5,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,
+  0xc7,  0xfe,  0x05,  0x45,  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,
+  0xeb,  0x1f,  0xf8,  0x15,  0x15,  0x7c,  0x38,  0xfa,  0x2d,  0x82,  0xaf,  0xfc,
+  0x7a,  0xc7,  0xf9,  0x54,  0x5f,  0xd8,  0xd6,  0x5f,  0xf3,  0xec,  0x94,  0x58,
+  0x39,  0x11,  0x72,  0xa7,  0x45,  0xda,  0xb8,  0xa8,  0xe3,  0x5c,  0xb6,  0x7d,
+  0x2a,  0x5a,  0xa2,  0xc2,  0xa1,  0x66,  0xdc,  0xd9,  0xa7,  0xc8,  0xd8,  0x18,
+  0xf5,  0xa8,  0xa8,  0x01,  0x40,  0xc9,  0xa9,  0xd4,  0x6d,  0x18,  0xa8,  0xe2,
+  0x5e,  0x73,  0x52,  0x50,  0x00,  0x4e,  0x05,  0x40,  0xc7,  0x71,  0xcd,  0x49,
+  0x2b,  0x71,  0x8a,  0x8a,  0x80,  0x14,  0x0c,  0x9c,  0x54,  0xe0,  0x60,  0x62,
+  0xa3,  0x89,  0x7b,  0xd4,  0x94,  0x00,  0x13,  0x80,  0x4d,  0x40,  0x4e,  0x4e,
+  0x69,  0xf2,  0xb7,  0x6a,  0x8e,  0x80,  0x15,  0x46,  0xe3,  0x8a,  0x9e,  0x99,
+  0x1a,  0xe0,  0x67,  0xd6,  0x9f,  0x40,  0x08,  0xc7,  0x68,  0xcd,  0x41,  0x4f,
+  0x91,  0xb2,  0x71,  0xe9,  0x4c,  0xa0,  0x07,  0x22,  0xee,  0x6f,  0x6a,  0x27,
+  0xb5,  0x59,  0xa4,  0x49,  0x37,  0xbc,  0x6e,  0xbc,  0x06,  0x43,  0x8c,  0x8f,
+  0x43,  0xed,  0x52,  0x46,  0xb8,  0x5f,  0x73,  0x4e,  0xa0,  0x0a,  0xa6,  0xca,
+  0x38,  0xa2,  0x95,  0x41,  0x6f,  0xde,  0x2e,  0xc3,  0xcf,  0x6c,  0x93,  0xff,
+  0x00,  0xb3,  0x1a,  0x87,  0xec,  0x60,  0xca,  0xae,  0xd2,  0x48,  0xe1,  0x4e,
+  0x42,  0x12,  0x36,  0x83,  0xf9,  0x55,  0xa9,  0x1b,  0x73,  0x7b,  0x0a,  0x6d,
+  0x00,  0x57,  0x8b,  0x49,  0xb7,  0x0c,  0xfb,  0x53,  0xcb,  0x0c,  0x00,  0x21,
+  0x38,  0xe8,  0x72,  0x0f,  0xd6,  0xa6,  0x5d,  0x39,  0x17,  0x90,  0xf2,  0x79,
+  0x99,  0x2c,  0x64,  0x27,  0x2c,  0x4e,  0xdc,  0x7e,  0x82,  0xac,  0xa2,  0xed,
+  0x5a,  0x5a,  0x00,  0xad,  0x1d,  0xaa,  0xdb,  0x16,  0x6f,  0x31,  0xe5,  0x91,
+  0xc0,  0x05,  0xe4,  0x39,  0x38,  0x1d,  0xbf,  0x5a,  0x5a,  0x73,  0xb6,  0xe6,
+  0xa6,  0xf5,  0xa0,  0x07,  0xc4,  0xb9,  0x39,  0xf4,  0xa9,  0x69,  0x14,  0x6d,
+  0x18,  0xa5,  0xe9,  0x40,  0x0c,  0x95,  0xb0,  0x31,  0x51,  0x52,  0xb1,  0xdc,
+  0x49,  0xa0,  0x0c,  0x9c,  0x50,  0x03,  0xe2,  0x5e,  0xf5,  0x25,  0x00,  0x60,
+  0x62,  0x82,  0x70,  0x33,  0x40,  0x11,  0xca,  0xdd,  0xaa,  0x3a,  0x52,  0x72,
+  0x73,  0x42,  0x8d,  0xc4,  0x0a,  0x00,  0x92,  0x25,  0xc0,  0xcd,  0x3e,  0x8e,
+  0x94,  0x8c,  0x76,  0x82,  0x68,  0x02,  0x39,  0x5b,  0x27,  0x1e,  0x94,  0xca,
+  0x3a,  0xd3,  0x91,  0x77,  0x35,  0x00,  0x49,  0x1a,  0xe1,  0x7d,  0xcd,  0x3a,
+  0x8a,  0x47,  0x6d,  0xab,  0x40,  0x11,  0xc8,  0xd9,  0x6f,  0x61,  0x4c,  0xa2,
+  0x9d,  0x1a,  0xee,  0x6f,  0x61,  0x40,  0x1f,  0xff,  0xd9
+};
diff --git a/services/camera/libcameraservice/FakeCamera.cpp b/services/camera/libcameraservice/FakeCamera.cpp
new file mode 100644
index 0000000..6749899
--- /dev/null
+++ b/services/camera/libcameraservice/FakeCamera.cpp
@@ -0,0 +1,430 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#define LOG_TAG "FakeCamera"
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <utils/String8.h>
+
+#include "FakeCamera.h"
+
+
+namespace android {
+
+// TODO: All this rgb to yuv should probably be in a util class.
+
+// TODO: I think something is wrong in this class because the shadow is kBlue
+// and the square color should alternate between kRed and kGreen. However on the
+// emulator screen these are all shades of gray. Y seems ok but the U and V are
+// probably not.
+
+static int tables_initialized = 0;
+uint8_t *gYTable, *gCbTable, *gCrTable;
+
+static int
+clamp(int  x)
+{
+    if (x > 255) return 255;
+    if (x < 0)   return 0;
+    return x;
+}
+
+/* the equation used by the video code to translate YUV to RGB looks like this
+ *
+ *    Y  = (Y0 - 16)*k0
+ *    Cb = Cb0 - 128
+ *    Cr = Cr0 - 128
+ *
+ *    G = ( Y - k1*Cr - k2*Cb )
+ *    R = ( Y + k3*Cr )
+ *    B = ( Y + k4*Cb )
+ *
+ */
+
+static const double  k0 = 1.164;
+static const double  k1 = 0.813;
+static const double  k2 = 0.391;
+static const double  k3 = 1.596;
+static const double  k4 = 2.018;
+
+/* let's try to extract the value of Y
+ *
+ *   G + k1/k3*R + k2/k4*B = Y*( 1 + k1/k3 + k2/k4 )
+ *
+ *   Y  = ( G + k1/k3*R + k2/k4*B ) / (1 + k1/k3 + k2/k4)
+ *   Y0 = ( G0 + k1/k3*R0 + k2/k4*B0 ) / ((1 + k1/k3 + k2/k4)*k0) + 16
+ *
+ * let define:
+ *   kYr = k1/k3
+ *   kYb = k2/k4
+ *   kYy = k0 * ( 1 + kYr + kYb )
+ *
+ * we have:
+ *    Y  = ( G + kYr*R + kYb*B )
+ *    Y0 = clamp[ Y/kYy + 16 ]
+ */
+
+static const double kYr = k1/k3;
+static const double kYb = k2/k4;
+static const double kYy = k0*( 1. + kYr + kYb );
+
+static void
+initYtab( void )
+{
+    const  int imax = (int)( (kYr + kYb)*(31 << 2) + (61 << 3) + 0.1 );
+    int    i;
+
+    gYTable = (uint8_t *)malloc(imax);
+
+    for(i=0; i<imax; i++) {
+        int  x = (int)(i/kYy + 16.5);
+        if (x < 16) x = 16;
+        else if (x > 235) x = 235;
+        gYTable[i] = (uint8_t) x;
+    }
+}
+
+/*
+ *   the source is RGB565, so adjust for 8-bit range of input values:
+ *
+ *   G = (pixels >> 3) & 0xFC;
+ *   R = (pixels >> 8) & 0xF8;
+ *   B = (pixels & 0x1f) << 3;
+ *
+ *   R2 = (pixels >> 11)      R = R2*8
+ *   B2 = (pixels & 0x1f)     B = B2*8
+ *
+ *   kYr*R = kYr2*R2 =>  kYr2 = kYr*8
+ *   kYb*B = kYb2*B2 =>  kYb2 = kYb*8
+ *
+ *   we want to use integer multiplications:
+ *
+ *   SHIFT1 = 9
+ *
+ *   (ALPHA*R2) >> SHIFT1 == R*kYr  =>  ALPHA = kYr*8*(1 << SHIFT1)
+ *
+ *   ALPHA = kYr*(1 << (SHIFT1+3))
+ *   BETA  = kYb*(1 << (SHIFT1+3))
+ */
+
+static const int  SHIFT1  = 9;
+static const int  ALPHA   = (int)( kYr*(1 << (SHIFT1+3)) + 0.5 );
+static const int  BETA    = (int)( kYb*(1 << (SHIFT1+3)) + 0.5 );
+
+/*
+ *  now let's try to get the values of Cb and Cr
+ *
+ *  R-B = (k3*Cr - k4*Cb)
+ *
+ *    k3*Cr = k4*Cb + (R-B)
+ *    k4*Cb = k3*Cr - (R-B)
+ *
+ *  R-G = (k1+k3)*Cr + k2*Cb
+ *      = (k1+k3)*Cr + k2/k4*(k3*Cr - (R-B)/k0)
+ *      = (k1 + k3 + k2*k3/k4)*Cr - k2/k4*(R-B)
+ *
+ *  kRr*Cr = (R-G) + kYb*(R-B)
+ *
+ *  Cr  = ((R-G) + kYb*(R-B))/kRr
+ *  Cr0 = clamp(Cr + 128)
+ */
+
+static const double  kRr = (k1 + k3 + k2*k3/k4);
+
+static void
+initCrtab( void )
+{
+    uint8_t *pTable;
+    int i;
+
+    gCrTable = (uint8_t *)malloc(768*2);
+
+    pTable = gCrTable + 384;
+    for(i=-384; i<384; i++)
+        pTable[i] = (uint8_t) clamp( i/kRr + 128.5 );
+}
+
+/*
+ *  B-G = (k2 + k4)*Cb + k1*Cr
+ *      = (k2 + k4)*Cb + k1/k3*(k4*Cb + (R-B))
+ *      = (k2 + k4 + k1*k4/k3)*Cb + k1/k3*(R-B)
+ *
+ *  kBb*Cb = (B-G) - kYr*(R-B)
+ *
+ *  Cb   = ((B-G) - kYr*(R-B))/kBb
+ *  Cb0  = clamp(Cb + 128)
+ *
+ */
+
+static const double  kBb = (k2 + k4 + k1*k4/k3);
+
+static void
+initCbtab( void )
+{
+    uint8_t *pTable;
+    int i;
+
+    gCbTable = (uint8_t *)malloc(768*2);
+
+    pTable = gCbTable + 384;
+    for(i=-384; i<384; i++)
+        pTable[i] = (uint8_t) clamp( i/kBb + 128.5 );
+}
+
+/*
+ *   SHIFT2 = 16
+ *
+ *   DELTA = kYb*(1 << SHIFT2)
+ *   GAMMA = kYr*(1 << SHIFT2)
+ */
+
+static const int  SHIFT2 = 16;
+static const int  DELTA  = kYb*(1 << SHIFT2);
+static const int  GAMMA  = kYr*(1 << SHIFT2);
+
+int32_t ccrgb16toyuv_wo_colorkey(uint8_t *rgb16,uint8_t *yuv422,uint32_t *param,uint8_t *table[])
+{
+    uint16_t *inputRGB = (uint16_t*)rgb16;
+    uint8_t *outYUV =  yuv422;
+    int32_t width_dst = param[0];
+    int32_t height_dst = param[1];
+    int32_t pitch_dst = param[2];
+    int32_t mheight_dst = param[3];
+    int32_t pitch_src = param[4];
+    uint8_t *y_tab = table[0];
+    uint8_t *cb_tab = table[1];
+    uint8_t *cr_tab = table[2];
+
+    int32_t size16 = pitch_dst*mheight_dst;
+    int32_t i,j,count;
+    int32_t ilimit,jlimit;
+    uint8_t *tempY,*tempU,*tempV;
+    uint16_t pixels;
+    int   tmp;
+uint32_t temp;
+
+    tempY = outYUV;
+    tempU = outYUV + (height_dst * pitch_dst);
+    tempV = tempU + 1;
+
+    jlimit = height_dst;
+    ilimit = width_dst;
+
+    for(j=0; j<jlimit; j+=1)
+    {
+        for (i=0; i<ilimit; i+=2)
+        {
+            int32_t   G_ds = 0, B_ds = 0, R_ds = 0;
+            uint8_t   y0, y1, u, v;
+
+            pixels =  inputRGB[i];
+            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
+            y0   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
+
+            G_ds    += (pixels>>1) & 0x03E0;
+            B_ds    += (pixels<<5) & 0x03E0;
+            R_ds    += (pixels>>6) & 0x03E0;
+
+            pixels =  inputRGB[i+1];
+            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
+            y1   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
+
+            G_ds    += (pixels>>1) & 0x03E0;
+            B_ds    += (pixels<<5) & 0x03E0;
+            R_ds    += (pixels>>6) & 0x03E0;
+
+            R_ds >>= 1;
+            B_ds >>= 1;
+            G_ds >>= 1;
+
+            tmp = R_ds - B_ds;
+
+            u = cb_tab[(((B_ds-G_ds)<<SHIFT2) - GAMMA*tmp)>>(SHIFT2+2)];
+            v = cr_tab[(((R_ds-G_ds)<<SHIFT2) + DELTA*tmp)>>(SHIFT2+2)];
+
+            tempY[0] = y0;
+            tempY[1] = y1;
+            tempU[0] = u;
+            tempV[0] = v;
+
+            tempY += 2;
+            tempU += 2;
+            tempV += 2;
+        }
+
+        inputRGB += pitch_src;
+    }
+
+    return 1;
+}
+
+#define min(a,b) ((a)<(b)?(a):(b))
+#define max(a,b) ((a)>(b)?(a):(b))
+
+static void convert_rgb16_to_yuv422(uint8_t *rgb, uint8_t *yuv, int width, int height)
+{
+    if (!tables_initialized) {
+        initYtab();
+        initCrtab();
+        initCbtab();
+        tables_initialized = 1;
+    }
+
+    uint32_t param[6];
+    param[0] = (uint32_t) width;
+    param[1] = (uint32_t) height;
+    param[2] = (uint32_t) width;
+    param[3] = (uint32_t) height;
+    param[4] = (uint32_t) width;
+    param[5] = (uint32_t) 0;
+
+    uint8_t *table[3];
+    table[0] = gYTable;
+    table[1] = gCbTable + 384;
+    table[2] = gCrTable + 384;
+
+    ccrgb16toyuv_wo_colorkey(rgb, yuv, param, table);
+}
+
+const int FakeCamera::kRed;
+const int FakeCamera::kGreen;
+const int FakeCamera::kBlue;
+
+FakeCamera::FakeCamera(int width, int height)
+          : mTmpRgb16Buffer(0)
+{
+    setSize(width, height);
+}
+
+FakeCamera::~FakeCamera()
+{
+    delete[] mTmpRgb16Buffer;
+}
+
+void FakeCamera::setSize(int width, int height)
+{
+    mWidth = width;
+    mHeight = height;
+    mCounter = 0;
+    mCheckX = 0;
+    mCheckY = 0;
+
+    // This will cause it to be reallocated on the next call
+    // to getNextFrameAsYuv422().
+    delete[] mTmpRgb16Buffer;
+    mTmpRgb16Buffer = 0;
+}
+
+void FakeCamera::getNextFrameAsRgb565(uint16_t *buffer)
+{
+    int size = mWidth / 10;
+
+    drawCheckerboard(buffer, size);
+
+    int x = ((mCounter*3)&255);
+    if(x>128) x = 255 - x;
+    int y = ((mCounter*5)&255);
+    if(y>128) y = 255 - y;
+
+    drawSquare(buffer, x*size/32, y*size/32, (size*5)>>1, (mCounter&0x100)?kRed:kGreen, kBlue);
+
+    mCounter++;
+}
+
+void FakeCamera::getNextFrameAsYuv422(uint8_t *buffer)
+{
+    if (mTmpRgb16Buffer == 0)
+        mTmpRgb16Buffer = new uint16_t[mWidth * mHeight];
+
+    getNextFrameAsRgb565(mTmpRgb16Buffer);
+    convert_rgb16_to_yuv422((uint8_t*)mTmpRgb16Buffer, buffer, mWidth, mHeight);
+}
+
+void FakeCamera::drawSquare(uint16_t *dst, int x, int y, int size, int color, int shadow)
+{
+    int square_xstop, square_ystop, shadow_xstop, shadow_ystop;
+
+    square_xstop = min(mWidth, x+size);
+    square_ystop = min(mHeight, y+size);
+    shadow_xstop = min(mWidth, x+size+(size/4));
+    shadow_ystop = min(mHeight, y+size+(size/4));
+
+    // Do the shadow.
+    uint16_t *sh = &dst[(y+(size/4))*mWidth];
+    for (int j = y + (size/4); j < shadow_ystop; j++) {
+        for (int i = x + (size/4); i < shadow_xstop; i++) {
+            sh[i] &= shadow;
+        }
+        sh += mWidth;
+    }
+
+    // Draw the square.
+    uint16_t *sq = &dst[y*mWidth];
+    for (int j = y; j < square_ystop; j++) {
+        for (int i = x; i < square_xstop; i++) {
+            sq[i] = color;
+        }
+        sq += mWidth;
+    }
+}
+
+void FakeCamera::drawCheckerboard(uint16_t *dst, int size)
+{
+    bool black = true;
+
+    if((mCheckX/size)&1)
+        black = false;
+    if((mCheckY/size)&1)
+        black = !black;
+
+    int county = mCheckY%size;
+    int checkxremainder = mCheckX%size;
+
+    for(int y=0;y<mHeight;y++) {
+        int countx = checkxremainder;
+        bool current = black;
+        for(int x=0;x<mWidth;x++) {
+            dst[y*mWidth+x] = current?0:0xffff;
+            if(countx++ >= size) {
+                countx=0;
+                current = !current;
+            }
+        }
+        if(county++ >= size) {
+            county=0;
+            black = !black;
+        }
+    }
+    mCheckX += 3;
+    mCheckY++;
+}
+
+
+void FakeCamera::dump(int fd) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, " width x height (%d x %d), counter (%d), check x-y coordinate(%d, %d)\n", mWidth, mHeight, mCounter, mCheckX, mCheckY);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+}
+
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/FakeCamera.h b/services/camera/libcameraservice/FakeCamera.h
new file mode 100644
index 0000000..f7f8803
--- /dev/null
+++ b/services/camera/libcameraservice/FakeCamera.h
@@ -0,0 +1,67 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#ifndef ANDROID_HARDWARE_FAKECAMERA_H
+#define ANDROID_HARDWARE_FAKECAMERA_H
+
+#include <sys/types.h>
+#include <stdint.h>
+
+namespace android {
+
+/*
+ * FakeCamera is used in the CameraHardwareStub to provide a fake video feed
+ * when the system does not have a camera in hardware.
+ * The fake video is a moving black and white checkerboard background with a
+ * bouncing gray square in the foreground.
+ * This class is not thread-safe.
+ *
+ * TODO: Since the major methods provides a raw/uncompressed video feed, rename
+ * this class to RawVideoSource.
+ */
+
+class FakeCamera {
+public:
+    FakeCamera(int width, int height);
+    ~FakeCamera();
+
+    void setSize(int width, int height);
+    void getNextFrameAsYuv422(uint8_t *buffer);
+    // Write to the fd a string representing the current state.
+    void dump(int fd) const;
+
+private:
+    // TODO: remove the uint16_t buffer param everywhere since it is a field of
+    // this class.
+    void getNextFrameAsRgb565(uint16_t *buffer);
+
+    void drawSquare(uint16_t *buffer, int x, int y, int size, int color, int shadow);
+    void drawCheckerboard(uint16_t *buffer, int size);
+
+    static const int kRed = 0xf800;
+    static const int kGreen = 0x07c0;
+    static const int kBlue = 0x003e;
+
+    int         mWidth, mHeight;
+    int         mCounter;
+    int         mCheckX, mCheckY;
+    uint16_t    *mTmpRgb16Buffer;
+};
+
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_FAKECAMERA_H
diff --git a/services/camera/tests/CameraServiceTest/Android.mk b/services/camera/tests/CameraServiceTest/Android.mk
new file mode 100644
index 0000000..9bb190a
--- /dev/null
+++ b/services/camera/tests/CameraServiceTest/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= CameraServiceTest.cpp
+
+LOCAL_MODULE:= CameraServiceTest
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += \
+                frameworks/base/libs
+
+LOCAL_CFLAGS :=
+
+LOCAL_SHARED_LIBRARIES += \
+		libbinder \
+                libcutils \
+                libutils \
+                libui \
+                libcamera_client \
+                libsurfaceflinger_client
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
new file mode 100644
index 0000000..9fc795b
--- /dev/null
+++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -0,0 +1,849 @@
+#define LOG_TAG "CameraServiceTest"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <surfaceflinger/ISurface.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
+#include <ui/GraphicBuffer.h>
+#include <camera/ICamera.h>
+#include <camera/ICameraClient.h>
+#include <camera/ICameraService.h>
+#include <ui/Overlay.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+using namespace android;
+
+//
+//  Assertion and Logging utilities
+//
+#define INFO(...) \
+    do { \
+        printf(__VA_ARGS__); \
+        printf("\n"); \
+        LOGD(__VA_ARGS__); \
+    } while(0)
+
+void assert_fail(const char *file, int line, const char *func, const char *expr) {
+    INFO("assertion failed at file %s, line %d, function %s:",
+            file, line, func);
+    INFO("%s", expr);
+    exit(1);
+}
+
+void assert_eq_fail(const char *file, int line, const char *func,
+        const char *expr, int actual) {
+    INFO("assertion failed at file %s, line %d, function %s:",
+            file, line, func);
+    INFO("(expected) %s != (actual) %d", expr, actual);
+    exit(1);
+}
+
+#define ASSERT(e) \
+    do { \
+        if (!(e)) \
+            assert_fail(__FILE__, __LINE__, __func__, #e); \
+    } while(0)
+
+#define ASSERT_EQ(expected, actual) \
+    do { \
+        int _x = (actual); \
+        if (_x != (expected)) \
+            assert_eq_fail(__FILE__, __LINE__, __func__, #expected, _x); \
+    } while(0)
+
+//
+//  Holder service for pass objects between processes.
+//
+class IHolder : public IInterface {
+protected:
+    enum {
+        HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION,
+        HOLDER_GET,
+        HOLDER_CLEAR
+    };
+public:
+    DECLARE_META_INTERFACE(Holder);
+
+    virtual void put(sp<IBinder> obj) = 0;
+    virtual sp<IBinder> get() = 0;
+    virtual void clear() = 0;
+};
+
+class BnHolder : public BnInterface<IHolder> {
+    virtual status_t onTransact(uint32_t code,
+                                const Parcel& data,
+                                Parcel* reply,
+                                uint32_t flags = 0);
+};
+
+class BpHolder : public BpInterface<IHolder> {
+public:
+    BpHolder(const sp<IBinder>& impl)
+        : BpInterface<IHolder>(impl) {
+    }
+
+    virtual void put(sp<IBinder> obj) {
+        Parcel data, reply;
+        data.writeStrongBinder(obj);
+        remote()->transact(HOLDER_PUT, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    virtual sp<IBinder> get() {
+        Parcel data, reply;
+        remote()->transact(HOLDER_GET, data, &reply);
+        return reply.readStrongBinder();
+    }
+
+    virtual void clear() {
+        Parcel data, reply;
+        remote()->transact(HOLDER_CLEAR, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder");
+
+status_t BnHolder::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    switch(code) {
+        case HOLDER_PUT: {
+            put(data.readStrongBinder());
+            return NO_ERROR;
+        } break;
+        case HOLDER_GET: {
+            reply->writeStrongBinder(get());
+            return NO_ERROR;
+        } break;
+        case HOLDER_CLEAR: {
+            clear();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+class HolderService : public BnHolder {
+    virtual void put(sp<IBinder> obj) {
+        mObj = obj;
+    }
+    virtual sp<IBinder> get() {
+        return mObj;
+    }
+    virtual void clear() {
+        mObj.clear();
+    }
+private:
+    sp<IBinder> mObj;
+};
+
+//
+//  A mock CameraClient
+//
+class MCameraClient : public BnCameraClient {
+public:
+    virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2);
+    virtual void dataCallback(int32_t msgType, const sp<IMemory>& data);
+    virtual void dataCallbackTimestamp(nsecs_t timestamp,
+            int32_t msgType, const sp<IMemory>& data) {}
+
+    // new functions
+    void clearStat();
+    enum OP { EQ, GE, LE, GT, LT };
+    void assertNotify(int32_t msgType, OP op, int count);
+    void assertData(int32_t msgType, OP op, int count);
+    void waitNotify(int32_t msgType, OP op, int count);
+    void waitData(int32_t msgType, OP op, int count);
+    void assertDataSize(int32_t msgType, OP op, int dataSize);
+
+    void setReleaser(ICamera *releaser) {
+        mReleaser = releaser;
+    }
+private:
+    Mutex mLock;
+    Condition mCond;
+    DefaultKeyedVector<int32_t, int> mNotifyCount;
+    DefaultKeyedVector<int32_t, int> mDataCount;
+    DefaultKeyedVector<int32_t, int> mDataSize;
+    bool test(OP op, int v1, int v2);
+
+    ICamera *mReleaser;
+};
+
+void MCameraClient::clearStat() {
+    Mutex::Autolock _l(mLock);
+    mNotifyCount.clear();
+    mDataCount.clear();
+    mDataSize.clear();
+}
+
+bool MCameraClient::test(OP op, int v1, int v2) {
+    switch (op) {
+        case EQ: return v1 == v2;
+        case GT: return v1 > v2;
+        case LT: return v1 < v2;
+        case GE: return v1 >= v2;
+        case LE: return v1 <= v2;
+        default: ASSERT(0); break;
+    }
+    return false;
+}
+
+void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
+    Mutex::Autolock _l(mLock);
+    int v = mNotifyCount.valueFor(msgType);
+    ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertData(int32_t msgType, OP op, int count) {
+    Mutex::Autolock _l(mLock);
+    int v = mDataCount.valueFor(msgType);
+    ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
+    Mutex::Autolock _l(mLock);
+    int v = mDataSize.valueFor(msgType);
+    ASSERT(test(op, v, dataSize));
+}
+
+void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
+    INFO(__func__);
+    Mutex::Autolock _l(mLock);
+    ssize_t i = mNotifyCount.indexOfKey(msgType);
+    if (i < 0) {
+        mNotifyCount.add(msgType, 1);
+    } else {
+        ++mNotifyCount.editValueAt(i);
+    }
+    mCond.signal();
+}
+
+void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) {
+    INFO(__func__);
+    int dataSize = data->size();
+    INFO("data type = %d, size = %d", msgType, dataSize);
+    Mutex::Autolock _l(mLock);
+    ssize_t i = mDataCount.indexOfKey(msgType);
+    if (i < 0) {
+        mDataCount.add(msgType, 1);
+        mDataSize.add(msgType, dataSize);
+    } else {
+        ++mDataCount.editValueAt(i);
+        mDataSize.editValueAt(i) = dataSize;
+    }
+    mCond.signal();
+
+    if (msgType == CAMERA_MSG_VIDEO_FRAME) {
+        ASSERT(mReleaser != NULL);
+        mReleaser->releaseRecordingFrame(data);
+    }
+}
+
+void MCameraClient::waitNotify(int32_t msgType, OP op, int count) {
+    INFO("waitNotify: %d, %d, %d", msgType, op, count);
+    Mutex::Autolock _l(mLock);
+    while (true) {
+        int v = mNotifyCount.valueFor(msgType);
+        if (test(op, v, count)) {
+            break;
+        }
+        mCond.wait(mLock);
+    }
+}
+
+void MCameraClient::waitData(int32_t msgType, OP op, int count) {
+    INFO("waitData: %d, %d, %d", msgType, op, count);
+    Mutex::Autolock _l(mLock);
+    while (true) {
+        int v = mDataCount.valueFor(msgType);
+        if (test(op, v, count)) {
+            break;
+        }
+        mCond.wait(mLock);
+    }
+}
+
+//
+//  A mock Surface
+//
+class MSurface : public BnSurface {
+public:
+    virtual status_t registerBuffers(const BufferHeap& buffers);
+    virtual void postBuffer(ssize_t offset);
+    virtual void unregisterBuffers();
+    virtual sp<OverlayRef> createOverlay(
+            uint32_t w, uint32_t h, int32_t format, int32_t orientation);
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
+
+    // new functions
+    void clearStat();
+    void waitUntil(int c0, int c1, int c2);
+
+private:
+    // check callback count
+    Condition mCond;
+    Mutex mLock;
+    int registerBuffersCount;
+    int postBufferCount;
+    int unregisterBuffersCount;
+};
+
+status_t MSurface::registerBuffers(const BufferHeap& buffers) {
+    INFO(__func__);
+    Mutex::Autolock _l(mLock);
+    ++registerBuffersCount;
+    mCond.signal();
+    return NO_ERROR;
+}
+
+void MSurface::postBuffer(ssize_t offset) {
+    // INFO(__func__);
+    Mutex::Autolock _l(mLock);
+    ++postBufferCount;
+    mCond.signal();
+}
+
+void MSurface::unregisterBuffers() {
+    INFO(__func__);
+    Mutex::Autolock _l(mLock);
+    ++unregisterBuffersCount;
+    mCond.signal();
+}
+
+sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
+    INFO(__func__);
+    return NULL;
+}
+
+void MSurface::clearStat() {
+    Mutex::Autolock _l(mLock);
+    registerBuffersCount = 0;
+    postBufferCount = 0;
+    unregisterBuffersCount = 0;
+}
+
+void MSurface::waitUntil(int c0, int c1, int c2) {
+    INFO("waitUntil: %d %d %d", c0, c1, c2);
+    Mutex::Autolock _l(mLock);
+    while (true) {
+        if (registerBuffersCount >= c0 &&
+            postBufferCount >= c1 &&
+            unregisterBuffersCount >= c2) {
+            break;
+        }
+        mCond.wait(mLock);
+    }
+}
+
+sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format,
+        int32_t orientation) {
+    // We don't expect this to be called in current hardware.
+    ASSERT(0);
+    sp<OverlayRef> dummy;
+    return dummy;
+}
+
+//
+//  Utilities to use the Holder service
+//
+sp<IHolder> getHolder() {
+    sp<IServiceManager> sm = defaultServiceManager();
+    ASSERT(sm != 0);
+    sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
+    ASSERT(binder != 0);
+    sp<IHolder> holder = interface_cast<IHolder>(binder);
+    ASSERT(holder != 0);
+    return holder;
+}
+
+void putTempObject(sp<IBinder> obj) {
+    INFO(__func__);
+    getHolder()->put(obj);
+}
+
+sp<IBinder> getTempObject() {
+    INFO(__func__);
+    return getHolder()->get();
+}
+
+void clearTempObject() {
+    INFO(__func__);
+    getHolder()->clear();
+}
+
+//
+//  Get a Camera Service
+//
+sp<ICameraService> getCameraService() {
+    sp<IServiceManager> sm = defaultServiceManager();
+    ASSERT(sm != 0);
+    sp<IBinder> binder = sm->getService(String16("media.camera"));
+    ASSERT(binder != 0);
+    sp<ICameraService> cs = interface_cast<ICameraService>(binder);
+    ASSERT(cs != 0);
+    return cs;
+}
+
+//
+// Various Connect Tests
+//
+void testConnect() {
+    INFO(__func__);
+    sp<ICameraService> cs = getCameraService();
+    sp<MCameraClient> cc = new MCameraClient();
+    sp<ICamera> c = cs->connect(cc);
+    ASSERT(c != 0);
+    c->disconnect();
+}
+
+void testAllowConnectOnceOnly() {
+    INFO(__func__);
+    sp<ICameraService> cs = getCameraService();
+    // Connect the first client.
+    sp<MCameraClient> cc = new MCameraClient();
+    sp<ICamera> c = cs->connect(cc);
+    ASSERT(c != 0);
+    // Same client -- ok.
+    ASSERT(cs->connect(cc) != 0);
+    // Different client -- not ok.
+    sp<MCameraClient> cc2 = new MCameraClient();
+    ASSERT(cs->connect(cc2) == 0);
+    c->disconnect();
+}
+
+void testReconnectFailed() {
+    INFO(__func__);
+    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+    sp<MCameraClient> cc2 = new MCameraClient();
+    ASSERT(c->connect(cc2) != NO_ERROR);
+}
+
+void testReconnectSuccess() {
+    INFO(__func__);
+    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+    sp<MCameraClient> cc = new MCameraClient();
+    ASSERT(c->connect(cc) == NO_ERROR);
+}
+
+void testLockFailed() {
+    INFO(__func__);
+    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+    ASSERT(c->lock() != NO_ERROR);
+}
+
+void testLockUnlockSuccess() {
+    INFO(__func__);
+    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+    ASSERT(c->lock() == NO_ERROR);
+    ASSERT(c->unlock() == NO_ERROR);
+}
+
+void testLockSuccess() {
+    INFO(__func__);
+    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+    ASSERT(c->lock() == NO_ERROR);
+}
+
+//
+// Run the connect tests in another process.
+//
+const char *gExecutable;
+
+struct FunctionTableEntry {
+    const char *name;
+    void (*func)();
+};
+
+FunctionTableEntry function_table[] = {
+#define ENTRY(x) {#x, &x}
+    ENTRY(testReconnectFailed),
+    ENTRY(testReconnectSuccess),
+    ENTRY(testLockUnlockSuccess),
+    ENTRY(testLockFailed),
+    ENTRY(testLockSuccess),
+#undef ENTRY
+};
+
+void runFunction(const char *tag) {
+    INFO("runFunction: %s", tag);
+    int entries = sizeof(function_table) / sizeof(function_table[0]);
+    for (int i = 0; i < entries; i++) {
+        if (strcmp(function_table[i].name, tag) == 0) {
+            (*function_table[i].func)();
+            return;
+        }
+    }
+    ASSERT(0);
+}
+
+void runInAnotherProcess(const char *tag) {
+    pid_t pid = fork();
+    if (pid == 0) {
+        execlp(gExecutable, gExecutable, tag, NULL);
+        ASSERT(0);
+    } else {
+        int status;
+        ASSERT_EQ(pid, wait(&status));
+        ASSERT_EQ(0, status);
+    }
+}
+
+void testReconnect() {
+    INFO(__func__);
+    sp<ICameraService> cs = getCameraService();
+    sp<MCameraClient> cc = new MCameraClient();
+    sp<ICamera> c = cs->connect(cc);
+    ASSERT(c != 0);
+    // Reconnect to the same client -- ok.
+    ASSERT(c->connect(cc) == NO_ERROR);
+    // Reconnect to a different client (but the same pid) -- ok.
+    sp<MCameraClient> cc2 = new MCameraClient();
+    ASSERT(c->connect(cc2) == NO_ERROR);
+    c->disconnect();
+    cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+}
+
+void testLockUnlock() {
+    sp<ICameraService> cs = getCameraService();
+    sp<MCameraClient> cc = new MCameraClient();
+    sp<ICamera> c = cs->connect(cc);
+    ASSERT(c != 0);
+    // We can lock as many times as we want.
+    ASSERT(c->lock() == NO_ERROR);
+    ASSERT(c->lock() == NO_ERROR);
+    // Lock from a different process -- not ok.
+    putTempObject(c->asBinder());
+    runInAnotherProcess("testLockFailed");
+    // Unlock then lock from a different process -- ok.
+    ASSERT(c->unlock() == NO_ERROR);
+    runInAnotherProcess("testLockUnlockSuccess");
+    // Unlock then lock from a different process -- ok.
+    runInAnotherProcess("testLockSuccess");
+    c->disconnect();
+    clearTempObject();
+}
+
+void testReconnectFromAnotherProcess() {
+    INFO(__func__);
+
+    sp<ICameraService> cs = getCameraService();
+    sp<MCameraClient> cc = new MCameraClient();
+    sp<ICamera> c = cs->connect(cc);
+    ASSERT(c != 0);
+    // Reconnect from a different process -- not ok.
+    putTempObject(c->asBinder());
+    runInAnotherProcess("testReconnectFailed");
+    // Unlock then reconnect from a different process -- ok.
+    ASSERT(c->unlock() == NO_ERROR);
+    runInAnotherProcess("testReconnectSuccess");
+    c->disconnect();
+    clearTempObject();
+}
+
+// We need to flush the command buffer after the reference
+// to ICamera is gone. The sleep is for the server to run
+// the destructor for it.
+static void flushCommands() {
+    IPCThreadState::self()->flushCommands();
+    usleep(200000);  // 200ms
+}
+
+// Run a test case
+#define RUN(class_name) do { \
+    { \
+        INFO(#class_name); \
+        class_name instance; \
+        instance.run(); \
+    } \
+    flushCommands(); \
+} while(0)
+
+// Base test case after the the camera is connected.
+class AfterConnect {
+protected:
+    sp<ICameraService> cs;
+    sp<MCameraClient> cc;
+    sp<ICamera> c;
+
+    AfterConnect() {
+        cs = getCameraService();
+        cc = new MCameraClient();
+        c = cs->connect(cc);
+        ASSERT(c != 0);
+    }
+
+    ~AfterConnect() {
+        c.clear();
+        cc.clear();
+        cs.clear();
+    }
+};
+
+class TestSetPreviewDisplay : public AfterConnect {
+public:
+    void run() {
+        sp<MSurface> surface = new MSurface();
+        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestStartPreview : public AfterConnect {
+public:
+    void run() {
+        sp<MSurface> surface = new MSurface();
+        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+        ASSERT(c->startPreview() == NO_ERROR);
+        ASSERT(c->previewEnabled() == true);
+
+        surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
+        surface->clearStat();
+
+        c->disconnect();
+        // TODO: CameraService crashes for this. Fix it.
+#if 0
+        sp<MSurface> another_surface = new MSurface();
+        c->setPreviewDisplay(another_surface);  // just to make sure unregisterBuffers
+                                                // is called.
+        surface->waitUntil(0, 0, 1);  // needs unregisterBuffers
+#endif
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestStartPreviewWithoutDisplay : AfterConnect {
+public:
+    void run() {
+        ASSERT(c->startPreview() == NO_ERROR);
+        ASSERT(c->previewEnabled() == true);
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+// Base test case after the the camera is connected and the preview is started.
+class AfterStartPreview : public AfterConnect {
+protected:
+    sp<MSurface> surface;
+
+    AfterStartPreview() {
+        surface = new MSurface();
+        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+        ASSERT(c->startPreview() == NO_ERROR);
+    }
+
+    ~AfterStartPreview() {
+        surface.clear();
+    }
+};
+
+class TestAutoFocus : public AfterStartPreview {
+public:
+    void run() {
+        cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
+        c->autoFocus();
+        cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestStopPreview : public AfterStartPreview {
+public:
+    void run() {
+        ASSERT(c->previewEnabled() == true);
+        c->stopPreview();
+        ASSERT(c->previewEnabled() == false);
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestTakePicture: public AfterStartPreview {
+public:
+    void run() {
+        ASSERT(c->takePicture() == NO_ERROR);
+        cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+        cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+        cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+        c->stopPreview();
+#if 1  // TODO: It crashes if we don't have this. Fix it.
+        usleep(100000);
+#endif
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestTakeMultiplePictures: public AfterStartPreview {
+public:
+    void run() {
+        for (int i = 0; i < 10; i++) {
+            cc->clearStat();
+            ASSERT(c->takePicture() == NO_ERROR);
+            cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+            cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+            cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+            usleep(100000);  // 100ms
+        }
+        c->disconnect();
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+    }
+};
+
+class TestGetParameters: public AfterStartPreview {
+public:
+    void run() {
+        String8 param_str = c->getParameters();
+        INFO(param_str);
+    }
+};
+
+class TestPictureSize : public AfterStartPreview {
+public:
+    void checkOnePicture(int w, int h) {
+        const float rate = 0.5;  // byte per pixel limit
+        int pixels = w * h;
+
+        CameraParameters param(c->getParameters());
+        param.setPictureSize(w, h);
+        c->setParameters(param.flatten());
+
+        cc->clearStat();
+        ASSERT(c->takePicture() == NO_ERROR);
+        cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+        cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
+        cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+        cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
+                int(pixels * rate));
+        cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
+        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+        usleep(100000);  // 100ms
+    }
+
+    void run() {
+        checkOnePicture(2048, 1536);
+        checkOnePicture(1600, 1200);
+        checkOnePicture(1024, 768);
+    }
+};
+
+class TestPreviewCallbackFlag : public AfterConnect {
+public:
+    void run() {
+        sp<MSurface> surface = new MSurface();
+        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+        // Try all flag combinations.
+        for (int v = 0; v < 8; v++) {
+            cc->clearStat();
+            c->setPreviewCallbackFlag(v);
+            ASSERT(c->previewEnabled() == false);
+            ASSERT(c->startPreview() == NO_ERROR);
+            ASSERT(c->previewEnabled() == true);
+            sleep(2);
+            c->stopPreview();
+            if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
+                cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
+            } else {
+                if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
+                    cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
+                } else {
+                    cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
+                }
+            }
+        }
+    }
+};
+
+class TestRecording : public AfterConnect {
+public:
+    void run() {
+        ASSERT(c->recordingEnabled() == false);
+        sp<MSurface> surface = new MSurface();
+        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        cc->setReleaser(c.get());
+        c->startRecording();
+        ASSERT(c->recordingEnabled() == true);
+        sleep(2);
+        c->stopRecording();
+        cc->setReleaser(NULL);
+        cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
+    }
+};
+
+class TestPreviewSize : public AfterStartPreview {
+public:
+    void checkOnePicture(int w, int h) {
+        int size = w*h*3/2;  // should read from parameters
+
+        c->stopPreview();
+
+        CameraParameters param(c->getParameters());
+        param.setPreviewSize(w, h);
+        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        c->setParameters(param.flatten());
+
+        c->startPreview();
+
+        cc->clearStat();
+        cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
+        cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
+    }
+
+    void run() {
+        checkOnePicture(480, 320);
+        checkOnePicture(352, 288);
+        checkOnePicture(176, 144);
+    }
+};
+
+void runHolderService() {
+    defaultServiceManager()->addService(
+            String16("CameraServiceTest.Holder"), new HolderService());
+    ProcessState::self()->startThreadPool();
+}
+
+int main(int argc, char **argv)
+{
+    if (argc != 1) {
+        runFunction(argv[1]);
+        return 0;
+    }
+    INFO("CameraServiceTest start");
+    gExecutable = argv[0];
+    runHolderService();
+
+    testConnect();                              flushCommands();
+    testAllowConnectOnceOnly();                 flushCommands();
+    testReconnect();                            flushCommands();
+    testLockUnlock();                           flushCommands();
+    testReconnectFromAnotherProcess();          flushCommands();
+
+    RUN(TestSetPreviewDisplay);
+    RUN(TestStartPreview);
+    RUN(TestStartPreviewWithoutDisplay);
+    RUN(TestAutoFocus);
+    RUN(TestStopPreview);
+    RUN(TestTakePicture);
+    RUN(TestTakeMultiplePictures);
+    RUN(TestGetParameters);
+    RUN(TestPictureSize);
+    RUN(TestPreviewCallbackFlag);
+    RUN(TestRecording);
+    RUN(TestPreviewSize);
+}
