diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
deleted file mode 100644
index 87975af..0000000
--- a/camera/libcameraservice/Android.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Set USE_CAMERA_STUB if you don't want to use the hardware camera.
-
-# force these builds to use camera stub only
-ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
-  USE_CAMERA_STUB:=true
-endif
-
-ifeq ($(USE_CAMERA_STUB),)
-  USE_CAMERA_STUB:=false
-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
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-ifeq ($(USE_CAMERA_STUB), true)
-LOCAL_STATIC_LIBRARIES += libcamerastub
-else
-LOCAL_SHARED_LIBRARIES += libcamera 
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
deleted file mode 100644
index b3e0ee6..0000000
--- a/camera/libcameraservice/CameraHardwareStub.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
-**
-** 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(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240");
-    p.setPreviewSize(320, 240);
-    p.setPreviewFrameRate(15);
-    p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
-
-    p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, "320x240");
-    p.setPictureSize(320, 240);
-    p.setPictureFormat(CameraParameters::PIXEL_FORMAT_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 * picture_height * 3 / 2);
-
-    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 yuv420sp in setParameters().
-    int how_big = preview_width * preview_height * 3 / 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
-}
-
-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->getNextFrameAsYuv420(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 * h * 3 / 2);
-        FakeCamera cam(w, h);
-        cam.getNextFrameAsYuv420((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 UNKNOWN_ERROR;
-    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(),
-        CameraParameters::PIXEL_FORMAT_YUV420SP) != 0) {
-        LOGE("Only yuv420sp preview is supported");
-        return -1;
-    }
-
-    if (strcmp(params.getPictureFormat(),
-        CameraParameters::PIXEL_FORMAT_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()
-{
-}
-
-sp<CameraHardwareInterface> CameraHardwareStub::createInstance()
-{
-    return new CameraHardwareStub();
-}
-
-static CameraInfo sCameraInfo[] = {
-    {
-        CAMERA_FACING_BACK,
-        90,  /* orientation */
-    }
-};
-
-extern "C" int HAL_getNumberOfCameras()
-{
-    return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
-}
-
-extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
-{
-    memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
-}
-
-extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
-{
-    return CameraHardwareStub::createInstance();
-}
-
-}; // namespace android
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
deleted file mode 100644
index d3427ba..0000000
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-**
-** 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 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/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
deleted file mode 100644
index 10668a4..0000000
--- a/camera/libcameraservice/CameraService.cpp
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
-**
-** 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 <stdio.h>
-#include <sys/types.h>
-#include <pthread.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <cutils/atomic.h>
-#include <hardware/hardware.h>
-#include <media/AudioSystem.h>
-#include <media/mediaplayer.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/Overlay.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
-
-#include "CameraService.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-// Logging support -- this is for debugging only
-// Use "adb shell dumpsys media.camera -v 1" to change it.
-static volatile int32_t gLogLevel = 0;
-
-#define LOG1(...) LOGD_IF(gLogLevel >= 1, __VA_ARGS__);
-#define LOG2(...) LOGD_IF(gLogLevel >= 2, __VA_ARGS__);
-
-static void setLogLevel(int level) {
-    android_atomic_write(level, &gLogLevel);
-}
-
-// ----------------------------------------------------------------------------
-
-static int getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
-static int getCallingUid() {
-    return IPCThreadState::self()->getCallingUid();
-}
-
-// ----------------------------------------------------------------------------
-
-// This is ugly and only safe if we never re-create the CameraService, but
-// should be ok for now.
-static CameraService *gCameraService;
-
-CameraService::CameraService()
-:mSoundRef(0)
-{
-    LOGI("CameraService started (pid=%d)", getpid());
-
-    mNumberOfCameras = HAL_getNumberOfCameras();
-    if (mNumberOfCameras > MAX_CAMERAS) {
-        LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
-             mNumberOfCameras, MAX_CAMERAS);
-        mNumberOfCameras = MAX_CAMERAS;
-    }
-
-    for (int i = 0; i < mNumberOfCameras; i++) {
-        setCameraFree(i);
-    }
-
-    gCameraService = this;
-}
-
-CameraService::~CameraService() {
-    for (int i = 0; i < mNumberOfCameras; i++) {
-        if (mBusy[i]) {
-            LOGE("camera %d is still in use in destructor!", i);
-        }
-    }
-
-    gCameraService = NULL;
-}
-
-int32_t CameraService::getNumberOfCameras() {
-    return mNumberOfCameras;
-}
-
-status_t CameraService::getCameraInfo(int cameraId,
-                                      struct CameraInfo* cameraInfo) {
-    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
-        return BAD_VALUE;
-    }
-
-    HAL_getCameraInfo(cameraId, cameraInfo);
-    return OK;
-}
-
-sp<ICamera> CameraService::connect(
-        const sp<ICameraClient>& cameraClient, int cameraId) {
-    int callingPid = getCallingPid();
-    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
-
-    sp<Client> client;
-    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
-        LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
-            callingPid, cameraId);
-        return NULL;
-    }
-
-    Mutex::Autolock lock(mServiceLock);
-    if (mClient[cameraId] != 0) {
-        client = mClient[cameraId].promote();
-        if (client != 0) {
-            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
-                LOG1("CameraService::connect X (pid %d) (the same client)",
-                    callingPid);
-                return client;
-            } else {
-                LOGW("CameraService::connect X (pid %d) rejected (existing client).",
-                    callingPid);
-                return NULL;
-            }
-        }
-        mClient[cameraId].clear();
-    }
-
-    if (mBusy[cameraId]) {
-        LOGW("CameraService::connect X (pid %d) rejected"
-             " (camera %d is still busy).", callingPid, cameraId);
-        return NULL;
-    }
-
-    client = new Client(this, cameraClient, cameraId, callingPid);
-    mClient[cameraId] = client;
-    LOG1("CameraService::connect X");
-    return client;
-}
-
-void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
-    int callingPid = getCallingPid();
-    LOG1("CameraService::removeClient E (pid %d)", callingPid);
-
-    for (int i = 0; i < mNumberOfCameras; i++) {
-        // Declare this before the lock to make absolutely sure the
-        // destructor won't be called with the lock held.
-        sp<Client> client;
-
-        Mutex::Autolock lock(mServiceLock);
-
-        // This happens when we have already disconnected (or this is
-        // just another unused camera).
-        if (mClient[i] == 0) continue;
-
-        // Promote mClient. It can fail if we are called from this path:
-        // Client::~Client() -> disconnect() -> removeClient().
-        client = mClient[i].promote();
-
-        if (client == 0) {
-            mClient[i].clear();
-            continue;
-        }
-
-        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
-            // Found our camera, clear and leave.
-            LOG1("removeClient: clear camera %d", i);
-            mClient[i].clear();
-            break;
-        }
-    }
-
-    LOG1("CameraService::removeClient X (pid %d)", callingPid);
-}
-
-sp<CameraService::Client> CameraService::getClientById(int cameraId) {
-    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
-    return mClient[cameraId].promote();
-}
-
-void CameraService::instantiate() {
-    defaultServiceManager()->addService(String16("media.camera"),
-        new CameraService());
-}
-
-status_t CameraService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
-    // Permission checks
-    switch (code) {
-        case BnCameraService::CONNECT:
-            const int pid = 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 = getCallingUid();
-                    LOGE("Permission Denial: "
-                         "can't use the camera pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-            break;
-    }
-
-    return BnCameraService::onTransact(code, data, reply, flags);
-}
-
-// The reason we need this busy bit 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 the destructor has not been finished, 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::setCameraBusy(int cameraId) {
-    android_atomic_write(1, &mBusy[cameraId]);
-}
-
-void CameraService::setCameraFree(int cameraId) {
-    android_atomic_write(0, &mBusy[cameraId]);
-}
-
-// We share the media players for shutter and recording sound for all clients.
-// A reference count is kept to determine when we will actually release the
-// media players.
-
-static MediaPlayer* newMediaPlayer(const char *file) {
-    MediaPlayer* mp = new MediaPlayer();
-    if (mp->setDataSource(file, NULL) == NO_ERROR) {
-        mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
-        mp->prepare();
-    } else {
-        LOGE("Failed to load CameraService sounds: %s", file);
-        return NULL;
-    }
-    return mp;
-}
-
-void CameraService::loadSound() {
-    Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::loadSound ref=%d", mSoundRef);
-    if (mSoundRef++) return;
-
-    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
-    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
-}
-
-void CameraService::releaseSound() {
-    Mutex::Autolock lock(mSoundLock);
-    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
-    if (--mSoundRef) return;
-
-    for (int i = 0; i < NUM_SOUNDS; i++) {
-        if (mSoundPlayer[i] != 0) {
-            mSoundPlayer[i]->disconnect();
-            mSoundPlayer[i].clear();
-        }
-    }
-}
-
-void CameraService::playSound(sound_kind kind) {
-    LOG1("playSound(%d)", kind);
-    Mutex::Autolock lock(mSoundLock);
-    sp<MediaPlayer> player = mSoundPlayer[kind];
-    if (player != 0) {
-        // do not play the sound if stream volume is 0
-        // (typically because ringer mode is silent).
-        int index;
-        AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
-        if (index != 0) {
-            player->seekTo(0);
-            player->start();
-        }
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-CameraService::Client::Client(const sp<CameraService>& cameraService,
-        const sp<ICameraClient>& cameraClient, int cameraId, int clientPid) {
-    int callingPid = getCallingPid();
-    LOG1("Client::Client E (pid %d)", callingPid);
-
-    mCameraService = cameraService;
-    mCameraClient = cameraClient;
-    mCameraId = cameraId;
-    mClientPid = clientPid;
-
-    mHardware = HAL_openCameraHardware(cameraId);
-    mUseOverlay = mHardware->useOverlay();
-    mMsgEnabled = 0;
-
-    mHardware->setCallbacks(notifyCallback,
-                            dataCallback,
-                            dataCallbackTimestamp,
-                            (void *)cameraId);
-
-    // Enable zoom, error, and focus messages by default
-    enableMsgType(CAMERA_MSG_ERROR |
-                  CAMERA_MSG_ZOOM |
-                  CAMERA_MSG_FOCUS);
-    mOverlayW = 0;
-    mOverlayH = 0;
-
-    // Callback is disabled by default
-    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
-    mOrientation = 0;
-    cameraService->setCameraBusy(cameraId);
-    cameraService->loadSound();
-    LOG1("Client::Client X (pid %d)", callingPid);
-}
-
-static void *unregister_surface(void *arg) {
-    ISurface *surface = (ISurface *)arg;
-    surface->unregisterBuffers();
-    IPCThreadState::self()->flushCommands();
-    return NULL;
-}
-
-// tear down the client
-CameraService::Client::~Client() {
-    int callingPid = getCallingPid();
-    LOG1("Client::~Client E (pid %d, this %p)", callingPid, this);
-
-    if (mSurface != 0 && !mUseOverlay) {
-        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,  // attr
-                       unregister_surface,
-                       mSurface.get());
-        pthread_join(thr, NULL);
-    }
-
-    // set mClientPid to let disconnet() tear down the hardware
-    mClientPid = callingPid;
-    disconnect();
-    mCameraService->releaseSound();
-    LOG1("Client::~Client X (pid %d, this %p)", callingPid, this);
-}
-
-// ----------------------------------------------------------------------------
-
-status_t CameraService::Client::checkPid() const {
-    int callingPid = getCallingPid();
-    if (callingPid == mClientPid) return NO_ERROR;
-
-    LOGW("attempt to use a locked camera from a different process"
-         " (old pid %d, new pid %d)", mClientPid, callingPid);
-    return EBUSY;
-}
-
-status_t CameraService::Client::checkPidAndHardware() const {
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-    if (mHardware == 0) {
-        LOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
-        return INVALID_OPERATION;
-    }
-    return NO_ERROR;
-}
-
-status_t CameraService::Client::lock() {
-    int callingPid = getCallingPid();
-    LOG1("lock (pid %d)", callingPid);
-    Mutex::Autolock lock(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();
-    LOG1("unlock (pid %d)", callingPid);
-    Mutex::Autolock lock(mLock);
-
-    // allow anyone to use camera (after they lock the camera)
-    status_t result = checkPid();
-    if (result == NO_ERROR) {
-        mClientPid = 0;
-        LOG1("clear mCameraClient (pid %d)", callingPid);
-        // we need to remove the reference to ICameraClient so that when the app
-        // goes away, the reference count goes to 0.
-        mCameraClient.clear();
-    }
-    return result;
-}
-
-// connect a new client to the camera
-status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
-    int callingPid = getCallingPid();
-    LOG1("connect E (pid %d)", callingPid);
-    Mutex::Autolock lock(mLock);
-
-    if (mClientPid != 0 && checkPid() != NO_ERROR) {
-        LOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
-                mClientPid, callingPid);
-        return EBUSY;
-    }
-
-    if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) {
-        LOG1("Connect to the same client");
-        return NO_ERROR;
-    }
-
-    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
-    mClientPid = callingPid;
-    mCameraClient = client;
-
-    LOG1("connect X (pid %d)", callingPid);
-    return NO_ERROR;
-}
-
-void CameraService::Client::disconnect() {
-    int callingPid = getCallingPid();
-    LOG1("disconnect E (pid %d)", callingPid);
-    Mutex::Autolock lock(mLock);
-
-    if (checkPid() != NO_ERROR) {
-        LOGW("different client - don't disconnect");
-        return;
-    }
-
-    if (mClientPid <= 0) {
-        LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
-        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;
-
-    LOG1("hardware teardown");
-    // Before destroying mHardware, we must make sure it's in the
-    // idle state.
-    // Turn off all messages.
-    disableMsgType(CAMERA_MSG_ALL_MSGS);
-    mHardware->stopPreview();
-    mHardware->cancelPicture();
-    // Release the hardware resources.
-    mHardware->release();
-    // Release the held overlay resources.
-    if (mUseOverlay) {
-        mOverlayRef = 0;
-    }
-    mHardware.clear();
-
-    mCameraService->removeClient(mCameraClient);
-    mCameraService->setCameraFree(mCameraId);
-
-    LOG1("disconnect X (pid %d)", callingPid);
-}
-
-// ----------------------------------------------------------------------------
-
-// set the ISurface that the preview will use
-status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) {
-    LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    result = NO_ERROR;
-
-    // return if no change in surface.
-    // asBinder() is safe on NULL (returns NULL)
-    if (surface->asBinder() == mSurface->asBinder()) {
-        return result;
-    }
-
-    if (mSurface != 0) {
-        LOG1("clearing old preview surface %p", mSurface.get());
-        if (mUseOverlay) {
-            // Force the destruction of any previous overlay
-            sp<Overlay> dummy;
-            mHardware->setOverlay(dummy);
-        } else {
-            mSurface->unregisterBuffers();
-        }
-    }
-    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;
-}
-
-status_t CameraService::Client::registerPreviewBuffers() {
-    int w, h;
-    CameraParameters params(mHardware->getParameters());
-    params.getPreviewSize(&w, &h);
-
-    // FIXME: 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 result = mSurface->registerBuffers(buffers);
-    if (result != NO_ERROR) {
-        LOGE("registerBuffers failed with status %d", result);
-    }
-    return result;
-}
-
-status_t CameraService::Client::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 result = NO_ERROR;
-    if (mSurface == 0) {
-        result = mHardware->setOverlay(NULL);
-    } else {
-        if (mOverlayRef == 0) {
-            // 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 != 0) break;
-                LOGW("Overlay create failed - retrying");
-                usleep(20000);
-            }
-            if (mOverlayRef == 0) {
-                LOGE("Overlay Creation Failed!");
-                return -EINVAL;
-            }
-            result = mHardware->setOverlay(new Overlay(mOverlayRef));
-        }
-    }
-    if (result != NO_ERROR) {
-        LOGE("mHardware->setOverlay() failed with status %d\n", result);
-        return result;
-    }
-
-    mOverlayW = w;
-    mOverlayH = h;
-
-    return result;
-}
-
-// set the preview callback flag to affect how the received frames from
-// preview are handled.
-void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
-    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return;
-
-    mPreviewCallbackFlag = callback_flag;
-
-    // If we don't use overlay, we always need the preview frame for display.
-    // If we do use overlay, we only need the preview frame if the user
-    // wants the data.
-    if (mUseOverlay) {
-        if(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) {
-            enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        } else {
-            disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        }
-    }
-}
-
-// start preview mode
-status_t CameraService::Client::startPreview() {
-    LOG1("startPreview (pid %d)", getCallingPid());
-    return startCameraMode(CAMERA_PREVIEW_MODE);
-}
-
-// start recording mode
-status_t CameraService::Client::startRecording() {
-    LOG1("startRecording (pid %d)", getCallingPid());
-    return startCameraMode(CAMERA_RECORDING_MODE);
-}
-
-// start preview or recording
-status_t CameraService::Client::startCameraMode(camera_mode mode) {
-    LOG1("startCameraMode(%d)", mode);
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    switch(mode) {
-        case CAMERA_PREVIEW_MODE:
-            if (mSurface == 0) {
-                LOG1("mSurface is not set yet.");
-                // still able to start preview in this case.
-            }
-            return startPreviewMode();
-        case CAMERA_RECORDING_MODE:
-            if (mSurface == 0) {
-                LOGE("mSurface must be set before startRecordingMode.");
-                return INVALID_OPERATION;
-            }
-            return startRecordingMode();
-        default:
-            return UNKNOWN_ERROR;
-    }
-}
-
-status_t CameraService::Client::startPreviewMode() {
-    LOG1("startPreviewMode");
-    status_t result = NO_ERROR;
-
-    // if preview has been enabled, nothing needs to be done
-    if (mHardware->previewEnabled()) {
-        return NO_ERROR;
-    }
-
-    if (mUseOverlay) {
-        // If preview display has been set, set overlay now.
-        if (mSurface != 0) {
-            result = setOverlay();
-        }
-        if (result != NO_ERROR) return result;
-        result = mHardware->startPreview();
-    } else {
-        enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        result = mHardware->startPreview();
-        if (result != NO_ERROR) return result;
-        // If preview display has been set, register preview buffers now.
-        if (mSurface != 0) {
-           // Unregister here because the surface may be previously registered
-           // with the raw (snapshot) heap.
-           mSurface->unregisterBuffers();
-           result = registerPreviewBuffers();
-        }
-    }
-    return result;
-}
-
-status_t CameraService::Client::startRecordingMode() {
-    LOG1("startRecordingMode");
-    status_t result = NO_ERROR;
-
-    // if recording has been enabled, nothing needs to be done
-    if (mHardware->recordingEnabled()) {
-        return NO_ERROR;
-    }
-
-    // if preview has not been started, start preview first
-    if (!mHardware->previewEnabled()) {
-        result = startPreviewMode();
-        if (result != NO_ERROR) {
-            return result;
-        }
-    }
-
-    // start recording mode
-    enableMsgType(CAMERA_MSG_VIDEO_FRAME);
-    mCameraService->playSound(SOUND_RECORDING);
-    result = mHardware->startRecording();
-    if (result != NO_ERROR) {
-        LOGE("mHardware->startRecording() failed with status %d", result);
-    }
-    return result;
-}
-
-// stop preview mode
-void CameraService::Client::stopPreview() {
-    LOG1("stopPreview (pid %d)", getCallingPid());
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return;
-
-    disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-    mHardware->stopPreview();
-
-    if (mSurface != 0 && !mUseOverlay) {
-        mSurface->unregisterBuffers();
-    }
-
-    mPreviewBuffer.clear();
-}
-
-// stop recording mode
-void CameraService::Client::stopRecording() {
-    LOG1("stopRecording (pid %d)", getCallingPid());
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return;
-
-    mCameraService->playSound(SOUND_RECORDING);
-    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
-    mHardware->stopRecording();
-
-    mPreviewBuffer.clear();
-}
-
-// release a recording frame
-void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return;
-    mHardware->releaseRecordingFrame(mem);
-}
-
-bool CameraService::Client::previewEnabled() {
-    LOG1("previewEnabled (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return false;
-    return mHardware->previewEnabled();
-}
-
-bool CameraService::Client::recordingEnabled() {
-    LOG1("recordingEnabled (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return false;
-    return mHardware->recordingEnabled();
-}
-
-status_t CameraService::Client::autoFocus() {
-    LOG1("autoFocus (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    return mHardware->autoFocus();
-}
-
-status_t CameraService::Client::cancelAutoFocus() {
-    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    return mHardware->cancelAutoFocus();
-}
-
-// take a picture - image is returned in callback
-status_t CameraService::Client::takePicture() {
-    LOG1("takePicture (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    enableMsgType(CAMERA_MSG_SHUTTER |
-                  CAMERA_MSG_POSTVIEW_FRAME |
-                  CAMERA_MSG_RAW_IMAGE |
-                  CAMERA_MSG_COMPRESSED_IMAGE);
-
-    return mHardware->takePicture();
-}
-
-// set preview/capture parameters - key/value pairs
-status_t CameraService::Client::setParameters(const String8& params) {
-    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
-
-    CameraParameters p(params);
-    return mHardware->setParameters(p);
-}
-
-// get preview/capture parameters - key/value pairs
-String8 CameraService::Client::getParameters() const {
-    Mutex::Autolock lock(mLock);
-    if (checkPidAndHardware() != NO_ERROR) return String8();
-
-    String8 params(mHardware->getParameters().flatten());
-    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
-    return params;
-}
-
-status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
-    LOG1("sendCommand (pid %d)", getCallingPid());
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    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;
-    }
-
-    return mHardware->sendCommand(cmd, arg1, arg2);
-}
-
-// ----------------------------------------------------------------------------
-
-void CameraService::Client::enableMsgType(int32_t msgType) {
-    android_atomic_or(msgType, &mMsgEnabled);
-    mHardware->enableMsgType(msgType);
-}
-
-void CameraService::Client::disableMsgType(int32_t msgType) {
-    android_atomic_and(~msgType, &mMsgEnabled);
-    mHardware->disableMsgType(msgType);
-}
-
-#define CHECK_MESSAGE_INTERVAL 10 // 10ms
-bool CameraService::Client::lockIfMessageWanted(int32_t msgType) {
-    int sleepCount = 0;
-    while (mMsgEnabled & msgType) {
-        if (mLock.tryLock() == NO_ERROR) {
-            if (sleepCount > 0) {
-                LOG1("lockIfMessageWanted(%d): waited for %d ms",
-                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
-            }
-            return true;
-        }
-        if (sleepCount++ == 0) {
-            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
-        }
-        usleep(CHECK_MESSAGE_INTERVAL * 1000);
-    }
-    LOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
-    return false;
-}
-
-// ----------------------------------------------------------------------------
-
-// Converts from a raw pointer to the client to a strong pointer during a
-// hardware callback. This requires the callbacks only happen when the client
-// is still alive.
-sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
-    sp<Client> client = gCameraService->getClientById((int) user);
-
-    // This could happen if the Client is in the process of shutting down (the
-    // last strong reference is gone, but the destructor hasn't finished
-    // stopping the hardware).
-    if (client == 0) return NULL;
-
-    // The checks below are not necessary and are for debugging only.
-    if (client->mCameraService.get() != gCameraService) {
-        LOGE("mismatch service!");
-        return NULL;
-    }
-
-    if (client->mHardware == 0) {
-        LOGE("mHardware == 0: callback after disconnect()?");
-        return NULL;
-    }
-
-    return client;
-}
-
-// Callback messages can be dispatched to internal handlers or pass to our
-// client's callback functions, depending on the message type.
-//
-// notifyCallback:
-//      CAMERA_MSG_SHUTTER              handleShutter
-//      (others)                        c->notifyCallback
-// dataCallback:
-//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
-//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
-//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
-//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
-//      (others)                        c->dataCallback
-// dataCallbackTimestamp
-//      (others)                        c->dataCallbackTimestamp
-//
-// NOTE: the *Callback functions grab mLock of the client before passing
-// control to handle* functions. So the handle* functions must release the
-// lock before calling the ICameraClient's callbacks, so those callbacks can
-// invoke methods in the Client class again (For example, the preview frame
-// callback may want to releaseRecordingFrame). The handle* functions must
-// release the lock after all accesses to member variables, so it must be
-// handled very carefully.
-
-void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1,
-        int32_t ext2, void* user) {
-    LOG2("notifyCallback(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) return;
-    if (!client->lockIfMessageWanted(msgType)) return;
-
-    switch (msgType) {
-        case CAMERA_MSG_SHUTTER:
-            // ext1 is the dimension of the yuv picture.
-            client->handleShutter((image_rect_type *)ext1);
-            break;
-        default:
-            client->handleGenericNotify(msgType, ext1, ext2);
-            break;
-    }
-}
-
-void CameraService::Client::dataCallback(int32_t msgType,
-        const sp<IMemory>& dataPtr, void* user) {
-    LOG2("dataCallback(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) return;
-    if (!client->lockIfMessageWanted(msgType)) return;
-
-    if (dataPtr == 0) {
-        LOGE("Null data returned in data callback");
-        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-        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:
-            client->handleGenericData(msgType, dataPtr);
-            break;
-    }
-}
-
-void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
-        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
-    LOG2("dataCallbackTimestamp(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) return;
-    if (!client->lockIfMessageWanted(msgType)) return;
-
-    if (dataPtr == 0) {
-        LOGE("Null data returned in data with timestamp callback");
-        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-        return;
-    }
-
-    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
-}
-
-// snapshot taken callback
-// "size" is the width and height of yuv picture for registerBuffer.
-// If it is NULL, use the picture size from parameters.
-void CameraService::Client::handleShutter(image_rect_type *size) {
-    mCameraService->playSound(SOUND_SHUTTER);
-
-    // Screen goes black after the buffer is unregistered.
-    if (mSurface != 0 && !mUseOverlay) {
-        mSurface->unregisterBuffers();
-    }
-
-    sp<ICameraClient> c = mCameraClient;
-    if (c != 0) {
-        mLock.unlock();
-        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
-        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
-    }
-    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;
-            LOG1("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);
-        IPCThreadState::self()->flushCommands();
-    }
-
-    mLock.unlock();
-}
-
-// 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 (!mUseOverlay) {
-        if (mSurface != 0) {
-            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
-        LOG2("frame callback is disabled");
-        mLock.unlock();
-        return;
-    }
-
-    // hold a strong pointer to the client
-    sp<ICameraClient> c = mCameraClient;
-
-    // clear callback flags if no client or one-shot mode
-    if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
-        LOG2("Disable preview callback");
-        mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
-                                  FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
-                                  FRAME_CALLBACK_FLAG_ENABLE_MASK);
-        if (mUseOverlay) {
-            disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        }
-    }
-
-    if (c != 0) {
-        // Is the received frame copied out or not?
-        if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
-            LOG2("frame is copied");
-            copyFrameAndPostCopiedFrame(c, heap, offset, size);
-        } else {
-            LOG2("frame is forwarded");
-            mLock.unlock();
-            c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
-        }
-    } else {
-        mLock.unlock();
-    }
-}
-
-// picture callback - postview image ready
-void CameraService::Client::handlePostview(const sp<IMemory>& mem) {
-    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
-
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
-    }
-}
-
-// picture callback - raw image ready
-void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) {
-    disableMsgType(CAMERA_MSG_RAW_IMAGE);
-
-    ssize_t offset;
-    size_t size;
-    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-
-    // Put the YUV version of the snapshot in the preview display.
-    if (mSurface != 0 && !mUseOverlay) {
-        mSurface->postBuffer(offset);
-    }
-
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
-    }
-}
-
-// picture callback - compressed picture ready
-void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
-    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
-
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
-    }
-}
-
-
-void CameraService::Client::handleGenericNotify(int32_t msgType,
-    int32_t ext1, int32_t ext2) {
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->notifyCallback(msgType, ext1, ext2);
-    }
-}
-
-void CameraService::Client::handleGenericData(int32_t msgType,
-    const sp<IMemory>& dataPtr) {
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->dataCallback(msgType, dataPtr);
-    }
-}
-
-void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
-    int32_t msgType, const sp<IMemory>& dataPtr) {
-    sp<ICameraClient> c = mCameraClient;
-    mLock.unlock();
-    if (c != 0) {
-        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
-    }
-}
-
-void CameraService::Client::copyFrameAndPostCopiedFrame(
-        const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
-        size_t offset, size_t size) {
-    LOG2("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;
-
-    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");
-        mLock.unlock();
-        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");
-        mLock.unlock();
-        return;
-    }
-
-    mLock.unlock();
-    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(),
-                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());
-        }
-
-        bool hasClient = false;
-        for (int i = 0; i < mNumberOfCameras; i++) {
-            sp<Client> client = mClient[i].promote();
-            if (client == 0) continue;
-            hasClient = true;
-            sprintf(buffer, "Client[%d] (%p) PID: %d\n",
-                    i,
-                    client->getCameraClient()->asBinder().get(),
-                    client->mClientPid);
-            result.append(buffer);
-            write(fd, result.string(), result.size());
-            client->mHardware->dump(fd, args);
-        }
-        if (!hasClient) {
-            result.append("No camera client yet.\n");
-            write(fd, result.string(), result.size());
-        }
-
-        if (locked) mServiceLock.unlock();
-
-        // change logging level
-        int n = args.size();
-        for (int i = 0; i + 1 < n; i++) {
-            if (args[i] == String16("-v")) {
-                String8 levelStr(args[i+1]);
-                int level = atoi(levelStr.string());
-                sprintf(buffer, "Set Log Level to %d", level);
-                result.append(buffer);
-                setLogLevel(level);
-            }
-        }
-    }
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
deleted file mode 100644
index 8193e77..0000000
--- a/camera/libcameraservice/CameraService.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-**
-** 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>
-
-/* This needs to be increased if we can have more cameras */
-#define MAX_CAMERAS 2
-
-namespace android {
-
-class MemoryHeapBase;
-class MediaPlayer;
-
-class CameraService: public BnCameraService
-{
-    class Client;
-public:
-    static void         instantiate();
-
-                        CameraService();
-    virtual             ~CameraService();
-
-    virtual int32_t     getNumberOfCameras();
-    virtual status_t    getCameraInfo(int cameraId,
-                                      struct CameraInfo* cameraInfo);
-    virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId);
-    virtual void        removeClient(const sp<ICameraClient>& cameraClient);
-    virtual sp<Client>  getClientById(int cameraId);
-
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    virtual status_t    onTransact(uint32_t code, const Parcel& data,
-                                   Parcel* reply, uint32_t flags);
-
-    enum sound_kind {
-        SOUND_SHUTTER = 0,
-        SOUND_RECORDING = 1,
-        NUM_SOUNDS
-    };
-
-    void                loadSound();
-    void                playSound(sound_kind kind);
-    void                releaseSound();
-
-private:
-    Mutex               mServiceLock;
-    wp<Client>          mClient[MAX_CAMERAS];  // protected by mServiceLock
-    int                 mNumberOfCameras;
-
-    // atomics to record whether the hardware is allocated to some client.
-    volatile int32_t    mBusy[MAX_CAMERAS];
-    void                setCameraBusy(int cameraId);
-    void                setCameraFree(int cameraId);
-
-    // sounds
-    Mutex               mSoundLock;
-    sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS];
-    int                 mSoundRef;  // reference count (release all MediaPlayer when 0)
-
-    class Client : public BnCamera
-    {
-    public:
-        // ICamera interface (see ICamera for details)
-        virtual void            disconnect();
-        virtual status_t        connect(const sp<ICameraClient>& client);
-        virtual status_t        lock();
-        virtual status_t        unlock();
-        virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);
-        virtual void            setPreviewCallbackFlag(int flag);
-        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        setParameters(const String8& params);
-        virtual String8         getParameters() const;
-        virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
-    private:
-        friend class CameraService;
-                                Client(const sp<CameraService>& cameraService,
-                                       const sp<ICameraClient>& cameraClient,
-                                       int cameraId,
-                                       int clientPid);
-                                ~Client();
-
-        // return our camera client
-        const sp<ICameraClient>&    getCameraClient() { return mCameraClient; }
-
-        // check whether the calling process matches mClientPid.
-        status_t                checkPid() const;
-        status_t                checkPidAndHardware() const;  // also check mHardware != 0
-
-        // these are internal functions used to set up preview buffers
-        status_t                registerPreviewBuffers();
-        status_t                setOverlay();
-
-        // 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()
-        };
-        // these are internal functions used for preview/recording
-        status_t                startCameraMode(camera_mode mode);
-        status_t                startPreviewMode();
-        status_t                startRecordingMode();
-
-        // these are static callback functions
-        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);
-        // convert client from cookie
-        static sp<Client>       getClientFromCookie(void* user);
-        // handlers for messages
-        void                    handleShutter(image_rect_type *size);
-        void                    handlePreviewData(const sp<IMemory>& mem);
-        void                    handlePostview(const sp<IMemory>& mem);
-        void                    handleRawPicture(const sp<IMemory>& mem);
-        void                    handleCompressedPicture(const sp<IMemory>& mem);
-        void                    handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
-        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
-        void                    handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
-
-        void                    copyFrameAndPostCopiedFrame(
-                                    const sp<ICameraClient>& client,
-                                    const sp<IMemoryHeap>& heap,
-                                    size_t offset, size_t size);
-
-        // these are initialized in the constructor.
-        sp<CameraService>               mCameraService;  // immutable after constructor
-        sp<ICameraClient>               mCameraClient;
-        int                             mCameraId;       // immutable after constructor
-        pid_t                           mClientPid;
-        sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()
-        bool                            mUseOverlay;     // immutable after constructor
-        sp<OverlayRef>                  mOverlayRef;
-        int                             mOverlayW;
-        int                             mOverlayH;
-        int                             mPreviewCallbackFlag;
-        int                             mOrientation;
-
-        // Ensures atomicity among the public methods
-        mutable Mutex                   mLock;
-        sp<ISurface>                    mSurface;
-
-        // If the user want us to return a copy of the preview frame (instead
-        // of the original one), we allocate mPreviewBuffer and reuse it if possible.
-        sp<MemoryHeapBase>              mPreviewBuffer;
-
-        // We need to avoid the deadlock when the incoming command thread and
-        // the CameraHardwareInterface callback thread both want to grab mLock.
-        // An extra flag is used to tell the callback thread that it should stop
-        // trying to deliver the callback messages if the client is not
-        // interested in it anymore. For example, if the client is calling
-        // stopPreview(), the preview frame messages do not need to be delivered
-        // anymore.
-
-        // This function takes the same parameter as the enableMsgType() and
-        // disableMsgType() functions in CameraHardwareInterface.
-        void                    enableMsgType(int32_t msgType);
-        void                    disableMsgType(int32_t msgType);
-        volatile int32_t        mMsgEnabled;
-
-        // This function keeps trying to grab mLock, or give up if the message
-        // is found to be disabled. It returns true if mLock is grabbed.
-        bool                    lockIfMessageWanted(int32_t msgType);
-    };
-};
-
-} // namespace android
-
-#endif
diff --git a/camera/libcameraservice/CannedJpeg.h b/camera/libcameraservice/CannedJpeg.h
deleted file mode 100644
index b6266fb..0000000
--- a/camera/libcameraservice/CannedJpeg.h
+++ /dev/null
@@ -1,734 +0,0 @@
-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/camera/libcameraservice/FakeCamera.cpp b/camera/libcameraservice/FakeCamera.cpp
deleted file mode 100644
index f3a6a67..0000000
--- a/camera/libcameraservice/FakeCamera.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
-**
-** 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 *yuv420,
-        uint32_t *param, uint8_t *table[])
-{
-    uint16_t *inputRGB = (uint16_t*)rgb16;
-    uint8_t *outYUV = yuv420;
-    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;
-            tempY += 2;
-
-            if ((j&1) == 0) {
-                tempU[0] = u;
-                tempV[0] = v;
-                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_yuv420(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 getNextFrameAsYuv420().
-    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::getNextFrameAsYuv420(uint8_t *buffer)
-{
-    if (mTmpRgb16Buffer == 0)
-        mTmpRgb16Buffer = new uint16_t[mWidth * mHeight];
-
-    getNextFrameAsRgb565(mTmpRgb16Buffer);
-    convert_rgb16_to_yuv420((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/camera/libcameraservice/FakeCamera.h b/camera/libcameraservice/FakeCamera.h
deleted file mode 100644
index 724de20..0000000
--- a/camera/libcameraservice/FakeCamera.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-**
-** 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 getNextFrameAsYuv420(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/camera/tests/CameraServiceTest/Android.mk b/camera/tests/CameraServiceTest/Android.mk
deleted file mode 100644
index cf4e42f..0000000
--- a/camera/tests/CameraServiceTest/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-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
-
-# Disable it because the ISurface interface may change, and before we have a
-# chance to fix this test, we don't want to break normal builds.
-#include $(BUILD_EXECUTABLE)
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
deleted file mode 100644
index 3c8d553..0000000
--- a/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ /dev/null
@@ -1,919 +0,0 @@
-#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);
-    abort();
-}
-
-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);
-    abort();
-}
-
-#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);
-    void assertTest(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::assertTest(OP op, int v1, int v2) {
-    if (!test(op, v1, v2)) {
-        LOGE("assertTest failed: op=%d, v1=%d, v2=%d", op, v1, v2);
-        ASSERT(0);
-    }
-}
-
-void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
-    Mutex::Autolock _l(mLock);
-    int v = mNotifyCount.valueFor(msgType);
-    assertTest(op, v, count);
-}
-
-void MCameraClient::assertData(int32_t msgType, OP op, int count) {
-    Mutex::Autolock _l(mLock);
-    int v = mDataCount.valueFor(msgType);
-    assertTest(op, v, count);
-}
-
-void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
-    Mutex::Autolock _l(mLock);
-    int v = mDataSize.valueFor(msgType);
-    assertTest(op, v, dataSize);
-}
-
-void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
-    INFO("%s", __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("%s", __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::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
-        const sp<IMemory>& data) {
-    dataCallback(msgType, 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);
-    virtual status_t setBufferCount(int bufferCount);
-
-    // 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("%s", __func__);
-    Mutex::Autolock _l(mLock);
-    ++registerBuffersCount;
-    mCond.signal();
-    return NO_ERROR;
-}
-
-void MSurface::postBuffer(ssize_t offset) {
-    // INFO("%s", __func__);
-    Mutex::Autolock _l(mLock);
-    ++postBufferCount;
-    mCond.signal();
-}
-
-void MSurface::unregisterBuffers() {
-    INFO("%s", __func__);
-    Mutex::Autolock _l(mLock);
-    ++unregisterBuffersCount;
-    mCond.signal();
-}
-
-sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
-    INFO("%s", __func__);
-    return NULL;
-}
-
-status_t MSurface::setBufferCount(int bufferCount) {
-    INFO("%s", __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) {
-    // Not implemented.
-    ASSERT(0);
-    return NULL;
-}
-
-//
-//  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("%s", __func__);
-    getHolder()->put(obj);
-}
-
-sp<IBinder> getTempObject() {
-    INFO("%s", __func__);
-    return getHolder()->get();
-}
-
-void clearTempObject() {
-    INFO("%s", __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;
-}
-
-int getNumberOfCameras() {
-    sp<ICameraService> cs = getCameraService();
-    return cs->getNumberOfCameras();
-}
-
-//
-// Various Connect Tests
-//
-void testConnect(int cameraId) {
-    INFO("%s", __func__);
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc, cameraId);
-    ASSERT(c != 0);
-    c->disconnect();
-}
-
-void testAllowConnectOnceOnly(int cameraId) {
-    INFO("%s", __func__);
-    sp<ICameraService> cs = getCameraService();
-    // Connect the first client.
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc, cameraId);
-    ASSERT(c != 0);
-    // Same client -- ok.
-    ASSERT(cs->connect(cc, cameraId) != 0);
-    // Different client -- not ok.
-    sp<MCameraClient> cc2 = new MCameraClient();
-    ASSERT(cs->connect(cc2, cameraId) == 0);
-    c->disconnect();
-}
-
-void testReconnectFailed() {
-    INFO("%s", __func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    sp<MCameraClient> cc = new MCameraClient();
-    ASSERT(c->connect(cc) != NO_ERROR);
-}
-
-void testReconnectSuccess() {
-    INFO("%s", __func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    sp<MCameraClient> cc = new MCameraClient();
-    ASSERT(c->connect(cc) == NO_ERROR);
-    c->disconnect();
-}
-
-void testLockFailed() {
-    INFO("%s", __func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() != NO_ERROR);
-}
-
-void testLockUnlockSuccess() {
-    INFO("%s", __func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() == NO_ERROR);
-    ASSERT(c->unlock() == NO_ERROR);
-}
-
-void testLockSuccess() {
-    INFO("%s", __func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() == NO_ERROR);
-    c->disconnect();
-}
-
-//
-// 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(int cameraId) {
-    INFO("%s", __func__);
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc, cameraId);
-    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(int cameraId) {
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc, cameraId);
-    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");
-    clearTempObject();
-}
-
-void testReconnectFromAnotherProcess(int cameraId) {
-    INFO("%s", __func__);
-
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc, cameraId);
-    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");
-    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, cameraId) do { \
-    { \
-        INFO(#class_name); \
-        class_name instance; \
-        instance.init(cameraId); \
-        instance.run(); \
-    } \
-    flushCommands(); \
-} while(0)
-
-// Base test case after the the camera is connected.
-class AfterConnect {
-public:
-    void init(int cameraId) {
-        cs = getCameraService();
-        cc = new MCameraClient();
-        c = cs->connect(cc, cameraId);
-        ASSERT(c != 0);
-    }
-
-protected:
-    sp<ICameraService> cs;
-    sp<MCameraClient> cc;
-    sp<ICamera> c;
-
-    ~AfterConnect() {
-        c->disconnect();
-        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();
-
-        sp<MSurface> another_surface = new MSurface();
-        c->setPreviewDisplay(another_surface);  // just to make sure unregisterBuffers
-                                                // is called.
-        surface->waitUntil(0, 0, 1);  // needs unregisterBuffers
-
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestStartPreviewWithoutDisplay : public 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 {
-public:
-    void init(int cameraId) {
-        AfterConnect::init(cameraId);
-        surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-        ASSERT(c->startPreview() == NO_ERROR);
-    }
-
-protected:
-    sp<MSurface> surface;
-
-    ~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();
-        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);
-        }
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestGetParameters: public AfterStartPreview {
-public:
-    void run() {
-        String8 param_str = c->getParameters();
-        INFO("%s", static_cast<const char*>(param_str));
-    }
-};
-
-static bool getNextSize(const char **ptrS, int *w, int *h) {
-    const char *s = *ptrS;
-
-    // skip over ','
-    if (*s == ',') s++;
-
-    // remember start position in p
-    const char *p = s;
-    while (*s != '\0' && *s != 'x') {
-        s++;
-    }
-    if (*s == '\0') return false;
-
-    // get the width
-    *w = atoi(p);
-
-    // skip over 'x'
-    ASSERT(*s == 'x');
-    p = s + 1;
-    while (*s != '\0' && *s != ',') {
-        s++;
-    }
-
-    // get the height
-    *h = atoi(p);
-    *ptrS = s;
-    return true;
-}
-
-class TestPictureSize : public AfterStartPreview {
-public:
-    void checkOnePicture(int w, int h) {
-        const float rate = 0.9;  // byte per pixel limit
-        int pixels = w * h;
-
-        CameraParameters param(c->getParameters());
-        param.setPictureSize(w, h);
-        // disable thumbnail to get more accurate size.
-        param.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, 0);
-        param.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, 0);
-        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);
-    }
-
-    void run() {
-        CameraParameters param(c->getParameters());
-        int w, h;
-        const char *s = param.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES);
-        while (getNextSize(&s, &w, &h)) {
-            LOGD("checking picture size %dx%d", w, h);
-            checkOnePicture(w, h);
-        }
-    }
-};
-
-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++) {
-            LOGD("TestPreviewCallbackFlag: flag=%d", v);
-            usleep(100000); // sleep a while to clear the in-flight callbacks.
-            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();
-        usleep(100000); // sleep a while to clear the in-flight callbacks.
-        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() {
-        CameraParameters param(c->getParameters());
-        int w, h;
-        const char *s = param.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
-        while (getNextSize(&s, &w, &h)) {
-            LOGD("checking preview size %dx%d", w, h);
-            checkOnePicture(w, h);
-        }
-    }
-};
-
-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();
-    int n = getNumberOfCameras();
-    INFO("%d Cameras available", n);
-
-    for (int id = 0; id < n; id++) {
-        INFO("Testing camera %d", id);
-        testConnect(id);                              flushCommands();
-        testAllowConnectOnceOnly(id);                 flushCommands();
-        testReconnect(id);                            flushCommands();
-        testLockUnlock(id);                           flushCommands();
-        testReconnectFromAnotherProcess(id);          flushCommands();
-
-        RUN(TestSetPreviewDisplay, id);
-        RUN(TestStartPreview, id);
-        RUN(TestStartPreviewWithoutDisplay, id);
-        RUN(TestAutoFocus, id);
-        RUN(TestStopPreview, id);
-        RUN(TestTakePicture, id);
-        RUN(TestTakeMultiplePictures, id);
-        RUN(TestGetParameters, id);
-        RUN(TestPictureSize, id);
-        RUN(TestPreviewCallbackFlag, id);
-        RUN(TestRecording, id);
-        RUN(TestPreviewSize, id);
-    }
-
-    INFO("CameraServiceTest finished");
-}
diff --git a/cmds/surfaceflinger/Android.mk b/cmds/surfaceflinger/Android.mk
index bfa58a1..1df32bb 100644
--- a/cmds/surfaceflinger/Android.mk
+++ b/cmds/surfaceflinger/Android.mk
@@ -10,7 +10,7 @@
 	libutils
 
 LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/../../libs/surfaceflinger
+	$(LOCAL_PATH)/../../services/surfaceflinger
 
 LOCAL_MODULE:= surfaceflinger
 
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
deleted file mode 100644
index 995e31c..0000000
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * 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/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
deleted file mode 100644
index 48154f9..0000000
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
deleted file mode 100644
index 22ecc54..0000000
--- a/libs/audioflinger/Android.mk
+++ /dev/null
@@ -1,131 +0,0 @@
-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 \
-    libeffects
-
-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/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
deleted file mode 100644
index 81c5c39..0000000
--- a/libs/audioflinger/AudioBufferProvider.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
deleted file mode 100644
index 6c11114..0000000
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ /dev/null
@@ -1,573 +0,0 @@
-/* //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)
-    : 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]);
-    }
-
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        closeInputStream((AudioStreamIn *)mInputs[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;
-
-
-    outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
-    if (outFinal != 0) {
-        lFormat = outFinal->format();
-        lChannels = outFinal->channels();
-        lRate = outFinal->sampleRate();
-    } else {
-        if (format != 0) {
-            if (*format != 0) {
-                lFormat = *format;
-            } else {
-                *format = lFormat;
-            }
-        }
-        if (channels != 0) {
-            if (*channels != 0) {
-                lChannels = *channels;
-            } else {
-                *channels = lChannels;
-            }
-        }
-        if (sampleRate != 0) {
-            if (*sampleRate != 0) {
-                lRate = *sampleRate;
-            } else {
-                *sampleRate = lRate;
-            }
-        }
-        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());
-    }
-
-    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;
-
-    inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
-    if (inFinal != 0) {
-        lFormat = inFinal->format();
-        lChannels = inFinal->channels();
-        lRate = inFinal->sampleRate();
-    } else {
-        if (format != 0) {
-            if (*format != 0) {
-                lFormat = *format;
-            } else {
-                *format = lFormat;
-            }
-        }
-        if (channels != 0) {
-            if (*channels != 0) {
-                lChannels = *channels;
-            } else {
-                *channels = lChannels;
-            }
-        }
-        if (sampleRate != 0) {
-            if (*sampleRate != 0) {
-                lRate = *sampleRate;
-            } else {
-                *sampleRate = lRate;
-            }
-        }
-        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;
-}
-
-status_t AudioDumpInterface::setMode(int mode)
-{
-    return mFinalInterface->setMode(mode);
-}
-
-size_t AudioDumpInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
-    return mFinalInterface->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-// ----------------------------------------------------------------------------
-
-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), mFile(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 * 1000) / frameSize()) / sampleRate()) * 1000);
-        ret = bytes;
-    }
-    if(!mFile) {
-        if (mInterface->fileName() != "") {
-            char name[255];
-            sprintf(name, "%s_out_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
-            mFile = fopen(name, "wb");
-            LOGV("Opening dump file %s, fh %p", name, mFile);
-        }
-    }
-    if (mFile) {
-        fwrite(buffer, bytes, 1, mFile);
-    }
-    return ret;
-}
-
-status_t AudioStreamOutDump::standby()
-{
-    LOGV("AudioStreamOutDump standby(), mFile %p, mFinalStream %p", mFile, 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 (mFile == 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 (mFile == 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(mFile) {
-        fclose(mFile);
-        mFile = 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), mFile(0), mFileCount(0)
-{
-    LOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
-}
-
-
-AudioStreamInDump::~AudioStreamInDump()
-{
-    Close();
-}
-
-ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
-{
-    ssize_t ret;
-
-    if (mFinalStream) {
-        ret = mFinalStream->read(buffer, bytes);
-        if(!mFile) {
-            if (mInterface->fileName() != "") {
-                char name[255];
-                sprintf(name, "%s_in_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
-                mFile = fopen(name, "wb");
-                LOGV("Opening input dump file %s, fh %p", name, mFile);
-            }
-        }
-        if (mFile) {
-            fwrite(buffer, bytes, 1, mFile);
-        }
-    } else {
-        usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
-        ret = bytes;
-        if(!mFile) {
-            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");
-            mFile = fopen(name, "rb");
-            LOGV("Opening input read file %s, fh %p", name, mFile);
-            if (mFile) {
-                fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
-            }
-        }
-        if (mFile) {
-            ssize_t bytesRead = fread(buffer, bytes, 1, mFile);
-            if (bytesRead >=0 && bytesRead < bytes) {
-                fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
-                fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mFile);
-            }
-        }
-    }
-
-    return ret;
-}
-
-status_t AudioStreamInDump::standby()
-{
-    LOGV("AudioStreamInDump standby(), mFile %p, mFinalStream %p", mFile, 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(mFile) {
-        fclose(mFile);
-        mFile = 0;
-    }
-}
-}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
deleted file mode 100644
index 814ce5f..0000000
--- a/libs/audioflinger/AudioDumpInterface.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* //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                *mFile;      // 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                *mFile;      // output file
-    int                 mFileCount;
-};
-
-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);}
-
-    virtual status_t    setMode(int mode);
-
-    // 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 size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-
-    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;
-    SortedVector<AudioStreamInDump *>    mInputs;
-    Mutex                           mLock;
-    String8                         mPolicyCommands;
-    String8                         mFileName;
-};
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
deleted file mode 100644
index 97eb6c0..0000000
--- a/libs/audioflinger/AudioFlinger.cpp
+++ /dev/null
@@ -1,6078 +0,0 @@
-/* //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 <private/media/AudioEffectShared.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
-
-#include <media/EffectsFactoryApi.h>
-#include <media/EffectVisualizerApi.h>
-
-// ----------------------------------------------------------------------------
-// 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;
-static const float MAX_GAIN_INT = 0x1000;
-
-// 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), mNextUniqueId(1),
-        mTotalEffectsCpuLoad(0), mTotalEffectsMemory(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
-        mMode = AudioSystem::MODE_NORMAL;
-        setMode(mMode);
-
-        setMasterVolume(1.0f);
-        setMasterMute(false);
-    } else {
-        LOGE("Couldn't even initialize the stubbed audio hardware!");
-    }
-#ifdef LVMX
-    LifeVibes::init();
-    mLifeVibesClientPid = -1;
-#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,
-        int *sessionId,
-        status_t *status)
-{
-    sp<PlaybackThread::Track> track;
-    sp<TrackHandle> trackHandle;
-    sp<Client> client;
-    wp<Client> wclient;
-    status_t lStatus;
-    int lSessionId;
-
-    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);
-        }
-
-        // If no audio session id is provided, create one here
-        // TODO: enforce same stream type for all tracks in same audio session?
-        // TODO: prevent same audio session on different output threads
-        LOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
-        if (sessionId != NULL && *sessionId != 0) {
-            lSessionId = *sessionId;
-        } else {
-            lSessionId = nextUniqueId();
-            if (sessionId != NULL) {
-                *sessionId = lSessionId;
-            }
-        }
-        LOGV("createTrack() lSessionId: %d", lSessionId);
-
-        track = thread->createTrack_l(client, streamType, sampleRate, format,
-                channelCount, frameCount, sharedBuffer, lSessionId, &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)
-{
-    status_t ret;
-
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
-        LOGW("Illegal value: setMode(%d)", mode);
-        return BAD_VALUE;
-    }
-
-    { // scope for the lock
-        AutoMutex lock(mHardwareLock);
-        mHardwareStatus = AUDIO_HW_SET_MODE;
-        ret = mAudioHardware->setMode(mode);
-        mHardwareStatus = AUDIO_HW_IDLE;
-    }
-
-    if (NO_ERROR == ret) {
-        Mutex::Autolock _l(mLock);
-        mMode = mode;
-        for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
-           mPlaybackThreads.valueAt(i)->setMode(mode);
-#ifdef LVMX
-        LifeVibes::setMode(mode);
-#endif
-    }
-
-    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) {
-            mLifeVibesClientPid = IPCThreadState::self()->getCallingPid();
-            musicEnabled = 1;
-        } else if (value == LifevibesDisable) {
-            mLifeVibesClientPid = -1;
-            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 (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)
-{
-
-    Mutex::Autolock _l(mLock);
-
-    int pid = IPCThreadState::self()->getCallingPid();
-    if (mNotificationClients.indexOfKey(pid) < 0) {
-        sp<NotificationClient> notificationClient = new NotificationClient(this,
-                                                                            client,
-                                                                            pid);
-        LOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
-
-        mNotificationClients.add(pid, notificationClient);
-
-        sp<IBinder> binder = client->asBinder();
-        binder->linkToDeath(notificationClient);
-
-        // 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::removeNotificationClient(pid_t pid)
-{
-    Mutex::Autolock _l(mLock);
-
-    int index = mNotificationClients.indexOfKey(pid);
-    if (index >= 0) {
-        sp <NotificationClient> client = mNotificationClients.valueFor(pid);
-        LOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
-#ifdef LVMX
-        if (pid == mLifeVibesClientPid) {
-            LOGV("Disabling lifevibes");
-            LifeVibes::enableMusic(false);
-            mLifeVibesClientPid = -1;
-        }
-#endif
-        mNotificationClients.removeItem(pid);
-    }
-}
-
-// 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++) {
-        mNotificationClients.valueAt(i)->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),
-        mFrameSize(1), mFormat(0), 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 (int)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 before locking AudioFlinger mLock: lock order is always
-        // AudioFlinger then ThreadBase to avoid cross deadlock
-        mLock.unlock();
-        mAudioFlinger->mLock.lock();
-        audioConfigChanged_l(configEvent->mEvent, configEvent->mParam);
-        mAudioFlinger->mLock.unlock();
-        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, uint32_t device)
-    :   ThreadBase(audioFlinger, id),
-        mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
-        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
-        mDevice(device)
-{
-    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);
-    }
-}
-
-AudioFlinger::PlaybackThread::~PlaybackThread()
-{
-    delete [] mMixBuffer;
-}
-
-status_t AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
-{
-    dumpInternals(fd, args);
-    dumpTracks(fd, args);
-    dumpEffectChains(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 Session Buf  S M F SRate LeftV RighV  Serv       User       Main buf   Aux Buf\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 Session Buf  S M F SRate LeftV RighV  Serv       User       Main buf   Aux Buf\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::dumpEffectChains(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
-    write(fd, buffer, strlen(buffer));
-
-    for (size_t i = 0; i < mEffectChains.size(); ++i) {
-        sp<EffectChain> chain = mEffectChains[i];
-        if (chain != 0) {
-            chain->dump(fd, args);
-        }
-    }
-    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);
-    snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
-    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,
-        int sessionId,
-        status_t *status)
-{
-    sp<Track> track;
-    status_t lStatus;
-
-    if (mType == DIRECT) {
-        if (sampleRate != mSampleRate || format != mFormat || channelCount != (int)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, sessionId);
-        if (track->getCblk() == NULL || track->name() < 0) {
-            lStatus = NO_MEMORY;
-            goto Exit;
-        }
-        mTracks.add(track);
-
-        sp<EffectChain> chain = getEffectChain_l(sessionId);
-        if (chain != 0) {
-            LOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
-            track->setMainBuffer(chain->inBuffer());
-        }
-    }
-    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);
-        if (track->mainBuffer() != mMixBuffer) {
-            sp<EffectChain> chain = getEffectChain_l(track->sessionId());
-            if (chain != 0) {
-                LOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId());
-                chain->startTrack();
-            }
-        }
-
-        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);
-}
-
-// destroyTrack_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
-    AudioSystem::OutputDescriptor desc;
-    void *param2 = 0;
-
-    LOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event, param);
-
-    switch (event) {
-    case AudioSystem::OUTPUT_OPENED:
-    case AudioSystem::OUTPUT_CONFIG_CHANGED:
-        desc.channels = mChannels;
-        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;
-    }
-    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
-}
-
-void AudioFlinger::PlaybackThread::readOutputParameters()
-{
-    mSampleRate = mOutput->sampleRate();
-    mChannels = mOutput->channels();
-    mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
-    mFormat = mOutput->format();
-    mFrameSize = (uint16_t)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));
-
-    //TODO handle effects reconfig
-}
-
-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);
-}
-
-bool AudioFlinger::PlaybackThread::hasAudioSession(int sessionId)
-{
-    Mutex::Autolock _l(mLock);
-    if (getEffectChain_l(sessionId) != 0) {
-        return true;
-    }
-
-    for (size_t i = 0; i < mTracks.size(); ++i) {
-        sp<Track> track = mTracks[i];
-        if (sessionId == track->sessionId()) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain(int sessionId)
-{
-    Mutex::Autolock _l(mLock);
-    return getEffectChain_l(sessionId);
-}
-
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain_l(int sessionId)
-{
-    sp<EffectChain> chain;
-
-    size_t size = mEffectChains.size();
-    for (size_t i = 0; i < size; i++) {
-        if (mEffectChains[i]->sessionId() == sessionId) {
-            chain = mEffectChains[i];
-            break;
-        }
-    }
-    return chain;
-}
-
-void AudioFlinger::PlaybackThread::setMode(uint32_t mode)
-{
-    Mutex::Autolock _l(mLock);
-    size_t size = mEffectChains.size();
-    for (size_t i = 0; i < size; i++) {
-        mEffectChains[i]->setMode(mode);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
-    :   PlaybackThread(audioFlinger, output, id, device),
-        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()
-{
-    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;
-    Vector< sp<EffectChain> > effectChains;
-
-    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);
-
-            // prevent any changes in effect chain list and in each effect chain
-            // during mixing and effect process as the audio buffers could be deleted
-            // or modified if an effect is created or deleted
-            effectChains = mEffectChains;
-            lockEffectChains_l();
-       }
-
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
-            // mix buffers...
-            mAudioMixer->process();
-            sleepTime = 0;
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
-            //TODO: delay standby when effects have a tail
-        } 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 (mMixBuffer, 0, mixBufferSize);
-                sleepTime = 0;
-                LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
-            }
-            // TODO add standby time extension fct of effect tail
-        }
-
-        if (mSuspended) {
-            sleepTime = idleSleepTime;
-        }
-        // sleepTime == 0 means we must write to audio hardware
-        if (sleepTime == 0) {
-             for (size_t i = 0; i < effectChains.size(); i ++) {
-                 effectChains[i]->process_l();
-             }
-             // enable changes in effect chain
-             unlockEffectChains();
-#ifdef LVMX
-            int audioOutputType = LifeVibes::getMixerType(mId, mType);
-            if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-               LifeVibes::process(audioOutputType, mMixBuffer, mixBufferSize);
-            }
-#endif
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            mBytesWritten += mixBufferSize;
-
-            int bytesWritten = (int)mOutput->write(mMixBuffer, 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 {
-            // enable changes in effect chain
-            unlockEffectChains();
-            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();
-
-        // Effect chains will be actually deleted here if they were removed from
-        // mEffectChains list during mixing or effects processing
-        effectChains.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();
-    size_t mixedTracks = 0;
-    size_t tracksWithEffect = 0;
-
-    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
-    // Delegate master volume control to effect in output mix effect chain if needed
-    sp<EffectChain> chain = getEffectChain_l(0);
-    if (chain != 0) {
-        uint32_t v = (uint32_t)(masterVolume * (1 << 24));
-        chain->setVolume(&v, &v);
-        masterVolume = (float)((v + (1 << 23)) >> 24);
-        chain.clear();
-    }
-
-    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);
-
-            mixedTracks++;
-
-            // track->mainBuffer() != mMixBuffer means there is an effect chain
-            // connected to the track
-            chain.clear();
-            if (track->mainBuffer() != mMixBuffer) {
-                chain = getEffectChain_l(track->sessionId());
-                // Delegate volume control to effect in track effect chain if needed
-                if (chain != 0) {
-                    tracksWithEffect++;
-                } else {
-                    LOGW("prepareTracks_l(): track %08x attached to effect but no chain found on session %d",
-                            track->name(), track->sessionId());
-                }
-            }
-
-
-            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;
-            }
-
-            // compute volume for this track
-            int16_t left, right, aux;
-            if (track->isMuted() || masterMute || track->isPausing() ||
-                mStreamTypes[track->type()].mute) {
-                left = right = aux = 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;
-                uint32_t vl = (uint32_t)(v * cblk->volume[0]) << 12;
-                uint32_t vr = (uint32_t)(v * cblk->volume[1]) << 12;
-
-                // Delegate volume control to effect in track effect chain if needed
-                if (chain != 0 && chain->setVolume(&vl, &vr)) {
-                    // Do not ramp volume is volume is controlled by effect
-                    param = AudioMixer::VOLUME;
-                }
-
-                // Convert volumes from 8.24 to 4.12 format
-                uint32_t v_clamped = (vl + (1 << 11)) >> 12;
-                if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
-                left = int16_t(v_clamped);
-                v_clamped = (vr + (1 << 11)) >> 12;
-                if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
-                right = int16_t(v_clamped);
-
-                v_clamped = (uint32_t)(v * cblk->sendLevel);
-                if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
-                aux = int16_t(v_clamped);
-            }
-
-#ifdef LVMX
-            if ( tracksConnectedChanged || stateChanged )
-            {
-                 // only do the ramp when the volume is changed by the user / application
-                 param = AudioMixer::VOLUME;
-            }
-#endif
-
-            // XXX: these things DON'T need to be done each time
-            mAudioMixer->setBufferProvider(track);
-            mAudioMixer->enable(AudioMixer::MIXING);
-
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
-            mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::FORMAT, (void *)track->format());
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::CHANNEL_COUNT, (void *)track->channelCount());
-            mAudioMixer->setParameter(
-                AudioMixer::RESAMPLE,
-                AudioMixer::SAMPLE_RATE,
-                (void *)(cblk->sampleRate));
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
-
-            // 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);
-            } 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->mainBuffer() != mMixBuffer) {
-                chain = getEffectChain_l(track->sessionId());
-                if (chain != 0) {
-                    LOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId());
-                    chain->stopTrack();
-                }
-            }
-            if (track->isTerminated()) {
-                mTracks.remove(track);
-                deleteTrackName_l(track->mName);
-            }
-        }
-    }
-
-    // mix buffer must be cleared if all tracks are connected to an
-    // effect chain as in this case the mixer will not write to
-    // mix buffer and track effects will accumulate into it
-    if (mixedTracks != 0 && mixedTracks == tracksWithEffect) {
-        memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
-    }
-
-    return mixerStatus;
-}
-
-void AudioFlinger::MixerThread::invalidateTracks(int streamType)
-{
-    LOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d", this,  streamType, mTracks.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) {
-            t->mCblk->lock.lock();
-            t->mCblk->flags |= CBLK_INVALID_ON;
-            t->mCblk->cv.signal();
-            t->mCblk->lock.unlock();
-        }
-    }
-}
-
-
-// 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 (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
-            // forward device change to effects that have requested to be
-            // aware of attached audio device.
-            mDevice = (uint32_t)value;
-            for (size_t i = 0; i < mEffectChains.size(); i++) {
-                mEffectChains[i]->setDevice(mDevice);
-            }
-        }
-
-        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, uint32_t device)
-    :   PlaybackThread(audioFlinger, output, id, device)
-{
-    mType = PlaybackThread::DIRECT;
-}
-
-AudioFlinger::DirectOutputThread::~DirectOutputThread()
-{
-}
-
-
-static inline int16_t clamp16(int32_t sample)
-{
-    if ((sample>>15) ^ (sample>>31))
-        sample = 0x7FFF ^ (sample>>31);
-    return sample;
-}
-
-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
-}
-
-void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t rightVol, bool ramp)
-{
-    // Do not apply volume on compressed audio
-    if (!AudioSystem::isLinearPCM(mFormat)) {
-        return;
-    }
-
-    // convert to signed 16 bit before volume calculation
-    if (mFormat == AudioSystem::PCM_8_BIT) {
-        size_t count = mFrameCount * mChannelCount;
-        uint8_t *src = (uint8_t *)mMixBuffer + count-1;
-        int16_t *dst = mMixBuffer + count-1;
-        while(count--) {
-            *dst-- = (int16_t)(*src--^0x80) << 8;
-        }
-    }
-
-    size_t frameCount = mFrameCount;
-    int16_t *out = mMixBuffer;
-    if (ramp) {
-        if (mChannelCount == 1) {
-            int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
-            int32_t vlInc = d / (int32_t)frameCount;
-            int32_t vl = ((int32_t)mLeftVolShort << 16);
-            do {
-                out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
-                out++;
-                vl += vlInc;
-            } while (--frameCount);
-
-        } else {
-            int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
-            int32_t vlInc = d / (int32_t)frameCount;
-            d = ((int32_t)rightVol - (int32_t)mRightVolShort) << 16;
-            int32_t vrInc = d / (int32_t)frameCount;
-            int32_t vl = ((int32_t)mLeftVolShort << 16);
-            int32_t vr = ((int32_t)mRightVolShort << 16);
-            do {
-                out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
-                out[1] = clamp16(mul(out[1], vr >> 16) >> 12);
-                out += 2;
-                vl += vlInc;
-                vr += vrInc;
-            } while (--frameCount);
-        }
-    } else {
-        if (mChannelCount == 1) {
-            do {
-                out[0] = clamp16(mul(out[0], leftVol) >> 12);
-                out++;
-            } while (--frameCount);
-        } else {
-            do {
-                out[0] = clamp16(mul(out[0], leftVol) >> 12);
-                out[1] = clamp16(mul(out[1], rightVol) >> 12);
-                out += 2;
-            } while (--frameCount);
-        }
-    }
-
-    // convert back to unsigned 8 bit after volume calculation
-    if (mFormat == AudioSystem::PCM_8_BIT) {
-        size_t count = mFrameCount * mChannelCount;
-        int16_t *src = mMixBuffer;
-        uint8_t *dst = (uint8_t *)mMixBuffer;
-        while(count--) {
-            *dst++ = (uint8_t)(((int32_t)*src++ + (1<<7)) >> 8)^0x80;
-        }
-    }
-
-    mLeftVolShort = leftVol;
-    mRightVolShort = rightVol;
-}
-
-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())
-    {
-        bool rampVolume;
-        uint16_t leftVol;
-        uint16_t rightVol;
-        Vector< sp<EffectChain> > effectChains;
-
-        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;
-                }
-            }
-
-            effectChains = mEffectChains;
-
-            // 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);
-
-                    if (track->mFillingUpStatus == Track::FS_FILLED) {
-                        track->mFillingUpStatus = Track::FS_ACTIVE;
-                        mLeftVolFloat = mRightVolFloat = 0;
-                        mLeftVolShort = mRightVolShort = 0;
-                        if (track->mState == TrackBase::RESUMING) {
-                            track->mState = TrackBase::ACTIVE;
-                            rampVolume = true;
-                        }
-                    } else if (cblk->server != 0) {
-                        // If the track is stopped before the first frame was mixed,
-                        // do not apply ramp
-                        rampVolume = true;
-                    }
-                    // 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 != mLeftVolFloat || right != mRightVolFloat) {
-                        mLeftVolFloat = left;
-                        mRightVolFloat = right;
-
-                        // If audio HAL implements volume control,
-                        // force software volume to nominal value
-                        if (mOutput->setVolume(left, right) == NO_ERROR) {
-                            left = 1.0f;
-                            right = 1.0f;
-                        }
-
-                        // Convert volumes from float to 8.24
-                        uint32_t vl = (uint32_t)(left * (1 << 24));
-                        uint32_t vr = (uint32_t)(right * (1 << 24));
-
-                        // Delegate volume control to effect in track effect chain if needed
-                        // only one effect chain can be present on DirectOutputThread, so if
-                        // there is one, the track is connected to it
-                        if (!effectChains.isEmpty()) {
-                            // Do not ramp volume is volume is controlled by effect
-                            if(effectChains[0]->setVolume(&vl, &vr)) {
-                                rampVolume = false;
-                            }
-                        }
-
-                        // Convert volumes from 8.24 to 4.12 format
-                        uint32_t v_clamped = (vl + (1 << 11)) >> 12;
-                        if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
-                        leftVol = (uint16_t)v_clamped;
-                        v_clamped = (vr + (1 << 11)) >> 12;
-                        if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
-                        rightVol = (uint16_t)v_clamped;
-                    } else {
-                        leftVol = mLeftVolShort;
-                        rightVol = mRightVolShort;
-                        rampVolume = false;
-                    }
-
-                    // 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 (!effectChains.isEmpty()) {
-                    LOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(), trackToRemove->sessionId());
-                    effectChains[0]->stopTrack();
-                }
-                if (trackToRemove->isTerminated()) {
-                    mTracks.remove(trackToRemove);
-                    deleteTrackName_l(trackToRemove->mName);
-                }
-            }
-
-            lockEffectChains_l();
-       }
-
-        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) {
-            if (mixerStatus == MIXER_TRACKS_READY) {
-                applyVolume(leftVol, rightVol, rampVolume);
-            }
-            for (size_t i = 0; i < effectChains.size(); i ++) {
-                effectChains[i]->process_l();
-            }
-            unlockEffectChains();
-
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            mBytesWritten += mixBufferSize;
-            int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
-            if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
-            mNumWrites++;
-            mInWrite = false;
-            mStandby = false;
-        } else {
-            unlockEffectChains();
-            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();
-
-        // Effect chains will be actually deleted here if they were removed from
-        // mEffectChains list during mixing or effects processing
-        effectChains.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, mainThread->device()), 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()
-{
-    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;
-    Vector< sp<EffectChain> > effectChains;
-
-    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);
-
-            // prevent any changes in effect chain list and in each effect chain
-            // during mixing and effect process as the audio buffers could be deleted
-            // or modified if an effect is created or deleted
-            effectChains = mEffectChains;
-            lockEffectChains_l();
-        }
-
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
-            // mix buffers...
-            if (outputsReady(outputTracks)) {
-                mAudioMixer->process();
-            } else {
-                memset(mMixBuffer, 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;
-                        memset(mMixBuffer, 0, mixBufferSize);
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (mSuspended) {
-            sleepTime = idleSleepTime;
-        }
-        // sleepTime == 0 means we must write to audio hardware
-        if (sleepTime == 0) {
-            for (size_t i = 0; i < effectChains.size(); i ++) {
-                effectChains[i]->process_l();
-            }
-            // enable changes in effect chain
-            unlockEffectChains();
-
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
-            for (size_t i = 0; i < outputTracks.size(); i++) {
-                outputTracks[i]->write(mMixBuffer, writeFrames);
-            }
-            mStandby = false;
-            mBytesWritten += mixBufferSize;
-        } else {
-            // enable changes in effect chain
-            unlockEffectChains();
-            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();
-
-        // Effect chains will be actually deleted here if they were removed from
-        // mEffectChains list during mixing or effects processing
-        effectChains.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,
-            int sessionId)
-    :   RefBase(),
-        mThread(thread),
-        mClient(client),
-        mCblk(0),
-        mFrameCount(0),
-        mState(IDLE),
-        mClientTid(-1),
-        mFormat(format),
-        mFlags(flags & ~SYSTEM_FLAGS_MASK),
-        mSessionId(sessionId)
-{
-    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->channelCount = (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->flags = CBLK_UNDERRUN_ON;
-                } 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->channelCount = (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->flags = CBLK_UNDERRUN_ON;
-           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->channelCount;
-}
-
-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, channelCount %d",
-                bufferStart, bufferEnd, mBuffer, mBufferEnd,
-                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channelCount);
-        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,
-            int sessionId)
-    :   TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId),
-    mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL), mAuxEffectId(0)
-{
-    if (mCblk != NULL) {
-        sp<ThreadBase> baseThread = thread.promote();
-        if (baseThread != 0) {
-            PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
-            mName = playbackThread->getTrackName_l();
-            mMainBuffer = playbackThread->mixBuffer();
-        }
-        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, "   %05d %05d %03u %03u %03u %05u   %04u %1d %1d %1d %05u %05u %05u  0x%08x 0x%08x 0x%08x 0x%08x\n",
-            mName - AudioMixer::TRACK0,
-            (mClient == NULL) ? getpid() : mClient->pid(),
-            mStreamType,
-            mFormat,
-            mCblk->channelCount,
-            mSessionId,
-            mFrameCount,
-            mState,
-            mMute,
-            mFillingUpStatus,
-            mCblk->sampleRate,
-            mCblk->volume[0],
-            mCblk->volume[1],
-            mCblk->server,
-            mCblk->user,
-            (int)mMainBuffer,
-            (int)mAuxBuffer);
-}
-
-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->flags & CBLK_FORCEREADY_MSK)) {
-        mFillingUpStatus = FS_FILLED;
-        mCblk->flags &= ~CBLK_FORCEREADY_MSK;
-        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->flags |= CBLK_UNDERRUN_ON;
-        mCblk->flags &= ~CBLK_FORCEREADY_MSK;
-        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;
-}
-
-status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
-{
-    status_t status = DEAD_OBJECT;
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-       PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-       status = playbackThread->attachAuxEffect(this, EffectId);
-    }
-    return status;
-}
-
-void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
-{
-    mAuxEffectId = EffectId;
-    mAuxBuffer = buffer;
-}
-
-// ----------------------------------------------------------------------------
-
-// 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,
-            int sessionId)
-    :   TrackBase(thread, client, sampleRate, format,
-                  channelCount, frameCount, flags, 0, sessionId),
-        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->flags |= CBLK_UNDERRUN_ON;
-    }
-}
-
-void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
-{
-    snprintf(buffer, size, "   %05d %03u %03u %05d   %04u %01d %05u  %08x %08x\n",
-            (mClient == NULL) ? getpid() : mClient->pid(),
-            mFormat,
-            mCblk->channelCount,
-            mSessionId,
-            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, 0),
-    mActive(false), mSourceThread(sourceThread)
-{
-
-    PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
-    if (mCblk != NULL) {
-        mCblk->flags |= CBLK_DIRECTION_OUT;
-        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->channelCount %d mBufferEnd %p",
-                mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channelCount, 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 channelCount = mCblk->channelCount;
-    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 * channelCount];
-                    pInBuffer->frameCount = startFrames;
-                    pInBuffer->i16 = pInBuffer->mBuffer;
-                    memset(pInBuffer->raw, 0, startFrames * channelCount * 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 * channelCount * sizeof(int16_t));
-        mCblk->stepUser(outFrames);
-        pInBuffer->frameCount -= outFrames;
-        pInBuffer->i16 += outFrames * channelCount;
-        mOutBuffer.frameCount -= outFrames;
-        mOutBuffer.i16 += outFrames * channelCount;
-
-        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 * channelCount];
-                pInBuffer->frameCount = inBuffer.frameCount;
-                pInBuffer->i16 = pInBuffer->mBuffer;
-                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount * 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 * channelCount];
-            pInBuffer->frameCount = frames;
-            pInBuffer->i16 = pInBuffer->mBuffer;
-            memset(pInBuffer->raw, 0, frames * channelCount * 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::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
-                                                     const sp<IAudioFlingerClient>& client,
-                                                     pid_t pid)
-    : mAudioFlinger(audioFlinger), mPid(pid), mClient(client)
-{
-}
-
-AudioFlinger::NotificationClient::~NotificationClient()
-{
-    mClient.clear();
-}
-
-void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
-{
-    sp<NotificationClient> keep(this);
-    {
-        mAudioFlinger->removeNotificationClient(mPid);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-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::attachAuxEffect(int EffectId)
-{
-    return mTrack->attachAuxEffect(EffectId);
-}
-
-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,
-        int *sessionId,
-        status_t *status)
-{
-    sp<RecordThread::RecordTrack> recordTrack;
-    sp<RecordHandle> recordHandle;
-    sp<Client> client;
-    wp<Client> wclient;
-    status_t lStatus;
-    RecordThread *thread;
-    size_t inFrameCount;
-    int lSessionId;
-
-    // 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);
-        }
-
-        // If no audio session id is provided, create one here
-        if (sessionId != NULL && *sessionId != 0) {
-            lSessionId = *sessionId;
-        } else {
-            lSessionId = nextUniqueId();
-            if (sessionId != NULL) {
-                *sessionId = lSessionId;
-            }
-        }
-        // 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, lSessionId);
-    }
-    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();
-}
-
-
-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 ((int)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 &&
-                                ((int)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 Session 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_l(int event, int param) {
-    AudioSystem::OutputDescriptor desc;
-    void *param2 = 0;
-
-    switch (event) {
-    case AudioSystem::INPUT_OPENED:
-    case AudioSystem::INPUT_CONFIG_CHANGED:
-        desc.channels = mChannels;
-        desc.samplingRate = mSampleRate;
-        desc.format = mFormat;
-        desc.frameCount = mFrameCount;
-        desc.latency = 0;
-        param2 = &desc;
-        break;
-
-    case AudioSystem::INPUT_CLOSED:
-    default:
-        break;
-    }
-    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();
-    mChannels = mInput->channels();
-    mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
-    mFormat = mInput->format();
-    mFrameSize = (uint16_t)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) {
-        int id = nextUniqueId();
-        if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
-            (format != AudioSystem::PCM_16_BIT) ||
-            (channels != AudioSystem::CHANNEL_OUT_STEREO)) {
-            thread = new DirectOutputThread(this, output, id, *pDevices);
-            LOGV("openOutput() created direct output: ID %d thread %p", id, thread);
-        } else {
-            thread = new MixerThread(this, output, id, *pDevices);
-            LOGV("openOutput() created mixer output: ID %d thread %p", id, 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(id, thread);
-
-        if (pSamplingRate) *pSamplingRate = samplingRate;
-        if (pFormat) *pFormat = format;
-        if (pChannels) *pChannels = channels;
-        if (pLatencyMs) *pLatencyMs = thread->latency();
-
-        // notify client processes of the new output creation
-        thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
-        return id;
-    }
-
-    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;
-    }
-
-    int id = nextUniqueId();
-    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
-    thread->addOutputTrack(thread2);
-    mPlaybackThreads.add(id, thread);
-    // notify client processes of the new output creation
-    thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
-    return id;
-}
-
-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) {
-        int id = nextUniqueId();
-         // Start record thread
-        thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id);
-        mRecordThreads.add(id, thread);
-        LOGV("openInput() created record thread: ID %d thread %p", id, thread);
-        if (pSamplingRate) *pSamplingRate = reqSamplingRate;
-        if (pFormat) *pFormat = format;
-        if (pChannels) *pChannels = reqChannels;
-
-        input->standby();
-
-        // notify client processes of the new input creation
-        thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
-        return id;
-    }
-
-    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);
-    audioConfigChanged_l(AudioSystem::STREAM_CONFIG_CHANGED, output, &stream);
-
-    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;
-            srcThread->invalidateTracks(stream);
-            }
-        }
-
-    return NO_ERROR;
-}
-
-
-int AudioFlinger::newAudioSessionId()
-{
-    return nextUniqueId();
-}
-
-// 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;
-}
-
-int AudioFlinger::nextUniqueId()
-{
-    return android_atomic_inc(&mNextUniqueId);
-}
-
-// ----------------------------------------------------------------------------
-//  Effect management
-// ----------------------------------------------------------------------------
-
-
-status_t AudioFlinger::loadEffectLibrary(const char *libPath, int *handle)
-{
-    Mutex::Autolock _l(mLock);
-    return EffectLoadLibrary(libPath, handle);
-}
-
-status_t AudioFlinger::unloadEffectLibrary(int handle)
-{
-    Mutex::Autolock _l(mLock);
-    return EffectUnloadLibrary(handle);
-}
-
-status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects)
-{
-    Mutex::Autolock _l(mLock);
-    return EffectQueryNumberEffects(numEffects);
-}
-
-status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
-{
-    Mutex::Autolock _l(mLock);
-    return EffectQueryEffect(index, descriptor);
-}
-
-status_t AudioFlinger::getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor)
-{
-    Mutex::Autolock _l(mLock);
-    return EffectGetDescriptor(pUuid, descriptor);
-}
-
-
-// this UUID must match the one defined in media/libeffects/EffectVisualizer.cpp
-static const effect_uuid_t VISUALIZATION_UUID_ =
-    {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-sp<IEffect> AudioFlinger::createEffect(pid_t pid,
-        effect_descriptor_t *pDesc,
-        const sp<IEffectClient>& effectClient,
-        int32_t priority,
-        int output,
-        int sessionId,
-        status_t *status,
-        int *id,
-        int *enabled)
-{
-    status_t lStatus = NO_ERROR;
-    sp<EffectHandle> handle;
-    effect_interface_t itfe;
-    effect_descriptor_t desc;
-    sp<Client> client;
-    wp<Client> wclient;
-
-    LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, output %d", pid, effectClient.get(), priority, sessionId, output);
-
-    if (pDesc == NULL) {
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
-    {
-        Mutex::Autolock _l(mLock);
-
-        // check recording permission for visualizer
-        if (memcmp(&pDesc->type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0 ||
-            memcmp(&pDesc->uuid, &VISUALIZATION_UUID_, sizeof(effect_uuid_t)) == 0) {
-            if (!recordingAllowed()) {
-                lStatus = PERMISSION_DENIED;
-                goto Exit;
-            }
-        }
-
-        if (!EffectIsNullUuid(&pDesc->uuid)) {
-            // if uuid is specified, request effect descriptor
-            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
-            if (lStatus < 0) {
-                LOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
-                goto Exit;
-            }
-        } else {
-            // if uuid is not specified, look for an available implementation
-            // of the required type in effect factory
-            if (EffectIsNullUuid(&pDesc->type)) {
-                LOGW("createEffect() no effect type");
-                lStatus = BAD_VALUE;
-                goto Exit;
-            }
-            uint32_t numEffects = 0;
-            effect_descriptor_t d;
-            bool found = false;
-
-            lStatus = EffectQueryNumberEffects(&numEffects);
-            if (lStatus < 0) {
-                LOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
-                goto Exit;
-            }
-            for (uint32_t i = 0; i < numEffects; i++) {
-                lStatus = EffectQueryEffect(i, &desc);
-                if (lStatus < 0) {
-                    LOGW("createEffect() error %d from EffectQueryEffect", lStatus);
-                    continue;
-                }
-                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
-                    // If matching type found save effect descriptor. If the session is
-                    // 0 and the effect is not auxiliary, continue enumeration in case
-                    // an auxiliary version of this effect type is available
-                    found = true;
-                    memcpy(&d, &desc, sizeof(effect_descriptor_t));
-                    if (sessionId != 0 ||
-                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-                        break;
-                    }
-                }
-            }
-            if (!found) {
-                lStatus = BAD_VALUE;
-                LOGW("createEffect() effect not found");
-                goto Exit;
-            }
-            // For same effect type, chose auxiliary version over insert version if
-            // connect to output mix (Compliance to OpenSL ES)
-            if (sessionId == 0 &&
-                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
-                memcpy(&desc, &d, sizeof(effect_descriptor_t));
-            }
-        }
-
-        // Do not allow auxiliary effects on a session different from 0 (output mix)
-        if (sessionId != 0 &&
-             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-            lStatus = INVALID_OPERATION;
-            goto Exit;
-        }
-
-        // Session -1 is reserved for output stage effects that can only be created
-        // by audio policy manager (running in same process)
-        if (sessionId == -1 && getpid() != IPCThreadState::self()->getCallingPid()) {
-            lStatus = INVALID_OPERATION;
-            goto Exit;
-        }
-
-        // return effect descriptor
-        memcpy(pDesc, &desc, sizeof(effect_descriptor_t));
-
-        // If output is not specified try to find a matching audio session ID in one of the
-        // output threads.
-        // TODO: allow attachment of effect to inputs
-        if (output == 0) {
-            if (sessionId <= 0) {
-                // default to first output
-                // TODO: define criteria to choose output when not specified. Or
-                // receive output from audio policy manager
-                if (mPlaybackThreads.size() != 0) {
-                    output = mPlaybackThreads.keyAt(0);
-                }
-            } else {
-                 // look for the thread where the specified audio session is present
-                for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-                    if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId)) {
-                        output = mPlaybackThreads.keyAt(i);
-                        break;
-                    }
-                }
-            }
-        }
-        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);
-        }
-
-        // create effect on selected output trhead
-        handle = thread->createEffect_l(client, effectClient, priority, sessionId, &desc, enabled, &lStatus);
-        if (handle != 0 && id != NULL) {
-            *id = handle->id();
-        }
-    }
-
-Exit:
-    if(status) {
-        *status = lStatus;
-    }
-    return handle;
-}
-
-status_t AudioFlinger::registerEffectResource_l(effect_descriptor_t *desc) {
-    if (mTotalEffectsCpuLoad + desc->cpuLoad > MAX_EFFECTS_CPU_LOAD) {
-        LOGW("registerEffectResource() CPU Load limit exceeded for Fx %s, CPU %f MIPS",
-                desc->name, (float)desc->cpuLoad/10);
-        return INVALID_OPERATION;
-    }
-    if (mTotalEffectsMemory + desc->memoryUsage > MAX_EFFECTS_MEMORY) {
-        LOGW("registerEffectResource() memory limit exceeded for Fx %s, Memory %d KB",
-                desc->name, desc->memoryUsage);
-        return INVALID_OPERATION;
-    }
-    mTotalEffectsCpuLoad += desc->cpuLoad;
-    mTotalEffectsMemory += desc->memoryUsage;
-    LOGV("registerEffectResource_l() effect %s, CPU %d, memory %d",
-            desc->name, desc->cpuLoad, desc->memoryUsage);
-    LOGV("  total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
-    return NO_ERROR;
-}
-
-void AudioFlinger::unregisterEffectResource_l(effect_descriptor_t *desc) {
-    mTotalEffectsCpuLoad -= desc->cpuLoad;
-    mTotalEffectsMemory -= desc->memoryUsage;
-    LOGV("unregisterEffectResource_l() effect %s, CPU %d, memory %d",
-            desc->name, desc->cpuLoad, desc->memoryUsage);
-    LOGV("  total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
-}
-
-// PlaybackThread::createEffect_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
-        const sp<AudioFlinger::Client>& client,
-        const sp<IEffectClient>& effectClient,
-        int32_t priority,
-        int sessionId,
-        effect_descriptor_t *desc,
-        int *enabled,
-        status_t *status
-        )
-{
-    sp<EffectModule> effect;
-    sp<EffectHandle> handle;
-    status_t lStatus;
-    sp<Track> track;
-    sp<EffectChain> chain;
-    bool effectCreated = false;
-    bool effectRegistered = false;
-
-    if (mOutput == 0) {
-        LOGW("createEffect_l() Audio driver not initialized.");
-        lStatus = NO_INIT;
-        goto Exit;
-    }
-
-    // Do not allow auxiliary effect on session other than 0
-    if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY &&
-        sessionId != 0) {
-        LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d", desc->name, sessionId);
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
-    // Do not allow effects with session ID 0 on direct output or duplicating threads
-    // TODO: add rule for hw accelerated effects on direct outputs with non PCM format
-    if (sessionId == 0 && mType != MIXER) {
-        LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d", desc->name, sessionId);
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
-    LOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
-
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
-
-        // check for existing effect chain with the requested audio session
-        chain = getEffectChain_l(sessionId);
-        if (chain == 0) {
-            // create a new chain for this session
-            LOGV("createEffect_l() new effect chain for session %d", sessionId);
-            chain = new EffectChain(this, sessionId);
-            addEffectChain_l(chain);
-        } else {
-            effect = chain->getEffectFromDesc(desc);
-        }
-
-        LOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get());
-
-        if (effect == 0) {
-            // Check CPU and memory usage
-            lStatus = mAudioFlinger->registerEffectResource_l(desc);
-            if (lStatus != NO_ERROR) {
-                goto Exit;
-            }
-            effectRegistered = true;
-            // create a new effect module if none present in the chain
-            effect = new EffectModule(this, chain, desc, mAudioFlinger->nextUniqueId(), sessionId);
-            lStatus = effect->status();
-            if (lStatus != NO_ERROR) {
-                goto Exit;
-            }
-            lStatus = chain->addEffect(effect);
-            if (lStatus != NO_ERROR) {
-                goto Exit;
-            }
-            effectCreated = true;
-
-            effect->setDevice(mDevice);
-            effect->setMode(mAudioFlinger->getMode());
-        }
-        // create effect handle and connect it to effect module
-        handle = new EffectHandle(effect, client, effectClient, priority);
-        lStatus = effect->addHandle(handle);
-        if (enabled) {
-            *enabled = (int)effect->isEnabled();
-        }
-    }
-
-Exit:
-    if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
-        if (effectCreated) {
-            if (chain->removeEffect(effect) == 0) {
-                removeEffectChain_l(chain);
-            }
-        }
-        if (effectRegistered) {
-            mAudioFlinger->unregisterEffectResource_l(desc);
-        }
-        handle.clear();
-    }
-
-    if(status) {
-        *status = lStatus;
-    }
-    return handle;
-}
-
-void AudioFlinger::PlaybackThread::disconnectEffect(const sp< EffectModule>& effect,
-                                                    const wp<EffectHandle>& handle) {
-    effect_descriptor_t desc = effect->desc();
-    Mutex::Autolock _l(mLock);
-    // delete the effect module if removing last handle on it
-    if (effect->removeHandle(handle) == 0) {
-        if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-            detachAuxEffect_l(effect->id());
-        }
-        sp<EffectChain> chain = effect->chain().promote();
-        if (chain != 0) {
-            // remove effect chain if remove last effect
-            if (chain->removeEffect(effect) == 0) {
-                removeEffectChain_l(chain);
-            }
-        }
-        mLock.unlock();
-        mAudioFlinger->mLock.lock();
-        mAudioFlinger->unregisterEffectResource_l(&desc);
-        mAudioFlinger->mLock.unlock();
-    }
-}
-
-status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
-{
-    int session = chain->sessionId();
-    int16_t *buffer = mMixBuffer;
-    bool ownsBuffer = false;
-
-    LOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
-    if (session > 0) {
-        // Only one effect chain can be present in direct output thread and it uses
-        // the mix buffer as input
-        if (mType != DIRECT) {
-            size_t numSamples = mFrameCount * mChannelCount;
-            buffer = new int16_t[numSamples];
-            memset(buffer, 0, numSamples * sizeof(int16_t));
-            LOGV("addEffectChain_l() creating new input buffer %p session %d", buffer, session);
-            ownsBuffer = true;
-        }
-
-        // Attach all tracks with same session ID to this chain.
-        for (size_t i = 0; i < mTracks.size(); ++i) {
-            sp<Track> track = mTracks[i];
-            if (session == track->sessionId()) {
-                LOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer);
-                track->setMainBuffer(buffer);
-            }
-        }
-
-        // indicate all active tracks in the chain
-        for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
-            sp<Track> track = mActiveTracks[i].promote();
-            if (track == 0) continue;
-            if (session == track->sessionId()) {
-                LOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
-                chain->startTrack();
-            }
-        }
-    }
-
-    chain->setInBuffer(buffer, ownsBuffer);
-    chain->setOutBuffer(mMixBuffer);
-    // Effect chain for session -1 is inserted at end of effect chains list
-    // in order to be processed last as it contains output stage effects
-    // Effect chain for session 0 is inserted before session -1 to be processed
-    // after track specific effects and before output stage
-    // Effect chain for session other than 0 is inserted at beginning of effect
-    // chains list to be processed before output mix effects. Relative order between
-    // sessions other than 0 is not important
-    size_t size = mEffectChains.size();
-    size_t i = 0;
-    for (i = 0; i < size; i++) {
-        if (mEffectChains[i]->sessionId() < session) break;
-    }
-    mEffectChains.insertAt(chain, i);
-
-    return NO_ERROR;
-}
-
-size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain)
-{
-    int session = chain->sessionId();
-
-    LOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session);
-
-    for (size_t i = 0; i < mEffectChains.size(); i++) {
-        if (chain == mEffectChains[i]) {
-            mEffectChains.removeAt(i);
-            // detach all tracks with same session ID from this chain
-            for (size_t i = 0; i < mTracks.size(); ++i) {
-                sp<Track> track = mTracks[i];
-                if (session == track->sessionId()) {
-                    track->setMainBuffer(mMixBuffer);
-                }
-            }
-        }
-    }
-    return mEffectChains.size();
-}
-
-void AudioFlinger::PlaybackThread::lockEffectChains_l()
-{
-    for (size_t i = 0; i < mEffectChains.size(); i++) {
-        mEffectChains[i]->lock();
-    }
-}
-
-void AudioFlinger::PlaybackThread::unlockEffectChains()
-{
-    Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i < mEffectChains.size(); i++) {
-        mEffectChains[i]->unlock();
-    }
-}
-
-sp<AudioFlinger::EffectModule> AudioFlinger::PlaybackThread::getEffect_l(int sessionId, int effectId)
-{
-    sp<EffectModule> effect;
-
-    sp<EffectChain> chain = getEffectChain_l(sessionId);
-    if (chain != 0) {
-        effect = chain->getEffectFromId(effectId);
-    }
-    return effect;
-}
-
-status_t AudioFlinger::PlaybackThread::attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
-{
-    Mutex::Autolock _l(mLock);
-    return attachAuxEffect_l(track, EffectId);
-}
-
-status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
-{
-    status_t status = NO_ERROR;
-
-    if (EffectId == 0) {
-        track->setAuxBuffer(0, NULL);
-    } else {
-        // Auxiliary effects are always in audio session 0
-        sp<EffectModule> effect = getEffect_l(0, EffectId);
-        if (effect != 0) {
-            if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-                track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());
-            } else {
-                status = INVALID_OPERATION;
-            }
-        } else {
-            status = BAD_VALUE;
-        }
-    }
-    return status;
-}
-
-void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
-{
-     for (size_t i = 0; i < mTracks.size(); ++i) {
-        sp<Track> track = mTracks[i];
-        if (track->auxEffectId() == effectId) {
-            attachAuxEffect_l(track, 0);
-        }
-    }
-}
-
-// ----------------------------------------------------------------------------
-//  EffectModule implementation
-// ----------------------------------------------------------------------------
-
-#undef LOG_TAG
-#define LOG_TAG "AudioFlinger::EffectModule"
-
-AudioFlinger::EffectModule::EffectModule(const wp<ThreadBase>& wThread,
-                                        const wp<AudioFlinger::EffectChain>& chain,
-                                        effect_descriptor_t *desc,
-                                        int id,
-                                        int sessionId)
-    : mThread(wThread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
-      mStatus(NO_INIT), mState(IDLE)
-{
-    LOGV("Constructor %p", this);
-    int lStatus;
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread == 0) {
-        return;
-    }
-    PlaybackThread *p = (PlaybackThread *)thread.get();
-
-    memcpy(&mDescriptor, desc, sizeof(effect_descriptor_t));
-
-    // create effect engine from effect factory
-    mStatus = EffectCreate(&desc->uuid, sessionId, p->id(), &mEffectInterface);
-
-    if (mStatus != NO_ERROR) {
-        return;
-    }
-    lStatus = init();
-    if (lStatus < 0) {
-        mStatus = lStatus;
-        goto Error;
-    }
-
-    LOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
-    return;
-Error:
-    EffectRelease(mEffectInterface);
-    mEffectInterface = NULL;
-    LOGV("Constructor Error %d", mStatus);
-}
-
-AudioFlinger::EffectModule::~EffectModule()
-{
-    LOGV("Destructor %p", this);
-    if (mEffectInterface != NULL) {
-        // release effect engine
-        EffectRelease(mEffectInterface);
-    }
-}
-
-status_t AudioFlinger::EffectModule::addHandle(sp<EffectHandle>& handle)
-{
-    status_t status;
-
-    Mutex::Autolock _l(mLock);
-    // First handle in mHandles has highest priority and controls the effect module
-    int priority = handle->priority();
-    size_t size = mHandles.size();
-    sp<EffectHandle> h;
-    size_t i;
-    for (i = 0; i < size; i++) {
-        h = mHandles[i].promote();
-        if (h == 0) continue;
-        if (h->priority() <= priority) break;
-    }
-    // if inserted in first place, move effect control from previous owner to this handle
-    if (i == 0) {
-        if (h != 0) {
-            h->setControl(false, true);
-        }
-        handle->setControl(true, false);
-        status = NO_ERROR;
-    } else {
-        status = ALREADY_EXISTS;
-    }
-    mHandles.insertAt(handle, i);
-    return status;
-}
-
-size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
-{
-    Mutex::Autolock _l(mLock);
-    size_t size = mHandles.size();
-    size_t i;
-    for (i = 0; i < size; i++) {
-        if (mHandles[i] == handle) break;
-    }
-    if (i == size) {
-        return size;
-    }
-    mHandles.removeAt(i);
-    size = mHandles.size();
-    // if removed from first place, move effect control from this handle to next in line
-    if (i == 0 && size != 0) {
-        sp<EffectHandle> h = mHandles[0].promote();
-        if (h != 0) {
-            h->setControl(true, true);
-        }
-    }
-
-    return size;
-}
-
-void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
-{
-    // keep a strong reference on this EffectModule to avoid calling the
-    // destructor before we exit
-    sp<EffectModule> keep(this);
-    {
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread != 0) {
-            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-            playbackThread->disconnectEffect(keep, handle);
-        }
-    }
-}
-
-void AudioFlinger::EffectModule::updateState() {
-    Mutex::Autolock _l(mLock);
-
-    switch (mState) {
-    case RESTART:
-        reset_l();
-        // FALL THROUGH
-
-    case STARTING:
-        // clear auxiliary effect input buffer for next accumulation
-        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-            memset(mConfig.inputCfg.buffer.raw,
-                   0,
-                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
-        }
-        start_l();
-        mState = ACTIVE;
-        break;
-    case STOPPING:
-        stop_l();
-        mDisableWaitCnt = mMaxDisableWaitCnt;
-        mState = STOPPED;
-        break;
-    case STOPPED:
-        // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
-        // turn off sequence.
-        if (--mDisableWaitCnt == 0) {
-            reset_l();
-            mState = IDLE;
-        }
-        break;
-    default: //IDLE , ACTIVE
-        break;
-    }
-}
-
-void AudioFlinger::EffectModule::process()
-{
-    Mutex::Autolock _l(mLock);
-
-    if (mEffectInterface == NULL ||
-            mConfig.inputCfg.buffer.raw == NULL ||
-            mConfig.outputCfg.buffer.raw == NULL) {
-        return;
-    }
-
-    if (mState == ACTIVE || mState == STOPPING || mState == STOPPED) {
-        // do 32 bit to 16 bit conversion for auxiliary effect input buffer
-        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-            AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
-                                        mConfig.inputCfg.buffer.s32,
-                                        mConfig.inputCfg.buffer.frameCount);
-        }
-
-        // do the actual processing in the effect engine
-        int ret = (*mEffectInterface)->process(mEffectInterface,
-                                               &mConfig.inputCfg.buffer,
-                                               &mConfig.outputCfg.buffer);
-
-        // force transition to IDLE state when engine is ready
-        if (mState == STOPPED && ret == -ENODATA) {
-            mDisableWaitCnt = 1;
-        }
-
-        // clear auxiliary effect input buffer for next accumulation
-        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-            memset(mConfig.inputCfg.buffer.raw, 0, mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
-        }
-    } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
-                mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw){
-        // If an insert effect is idle and input buffer is different from output buffer, copy input to
-        // output
-        sp<EffectChain> chain = mChain.promote();
-        if (chain != 0 && chain->activeTracks() != 0) {
-            size_t size = mConfig.inputCfg.buffer.frameCount * sizeof(int16_t);
-            if (mConfig.inputCfg.channels == CHANNEL_STEREO) {
-                size *= 2;
-            }
-            memcpy(mConfig.outputCfg.buffer.raw, mConfig.inputCfg.buffer.raw, size);
-        }
-    }
-}
-
-void AudioFlinger::EffectModule::reset_l()
-{
-    if (mEffectInterface == NULL) {
-        return;
-    }
-    (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL);
-}
-
-status_t AudioFlinger::EffectModule::configure()
-{
-    uint32_t channels;
-    if (mEffectInterface == NULL) {
-        return NO_INIT;
-    }
-
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread == 0) {
-        return DEAD_OBJECT;
-    }
-
-    // TODO: handle configuration of effects replacing track process
-    if (thread->channelCount() == 1) {
-        channels = CHANNEL_MONO;
-    } else {
-        channels = CHANNEL_STEREO;
-    }
-
-    if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-        mConfig.inputCfg.channels = CHANNEL_MONO;
-    } else {
-        mConfig.inputCfg.channels = channels;
-    }
-    mConfig.outputCfg.channels = channels;
-    mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
-    mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
-    mConfig.inputCfg.samplingRate = thread->sampleRate();
-    mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
-    mConfig.inputCfg.bufferProvider.cookie = NULL;
-    mConfig.inputCfg.bufferProvider.getBuffer = NULL;
-    mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
-    mConfig.outputCfg.bufferProvider.cookie = NULL;
-    mConfig.outputCfg.bufferProvider.getBuffer = NULL;
-    mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
-    mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
-    // Insert effect:
-    // - in session 0 or -1, always overwrites output buffer: input buffer == output buffer
-    // - in other sessions:
-    //      last effect in the chain accumulates in output buffer: input buffer != output buffer
-    //      other effect: overwrites output buffer: input buffer == output buffer
-    // Auxiliary effect:
-    //      accumulates in output buffer: input buffer != output buffer
-    // Therefore: accumulate <=> input buffer != output buffer
-    if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
-        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    } else {
-        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
-    }
-    mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
-    mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
-    mConfig.inputCfg.buffer.frameCount = thread->frameCount();
-    mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
-
-    status_t cmdStatus;
-    int size = sizeof(int);
-    status_t status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_CONFIGURE, sizeof(effect_config_t), &mConfig, &size, &cmdStatus);
-    if (status == 0) {
-        status = cmdStatus;
-    }
-
-    mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
-            (1000 * mConfig.outputCfg.buffer.frameCount);
-
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::init()
-{
-    Mutex::Autolock _l(mLock);
-    if (mEffectInterface == NULL) {
-        return NO_INIT;
-    }
-    status_t cmdStatus;
-    int size = sizeof(status_t);
-    status_t status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_INIT, 0, NULL, &size, &cmdStatus);
-    if (status == 0) {
-        status = cmdStatus;
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::start_l()
-{
-    if (mEffectInterface == NULL) {
-        return NO_INIT;
-    }
-    status_t cmdStatus;
-    int size = sizeof(status_t);
-    status_t status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_ENABLE, 0, NULL, &size, &cmdStatus);
-    if (status == 0) {
-        status = cmdStatus;
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::stop_l()
-{
-    if (mEffectInterface == NULL) {
-        return NO_INIT;
-    }
-    status_t cmdStatus;
-    int size = sizeof(status_t);
-    status_t status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_DISABLE, 0, NULL, &size, &cmdStatus);
-    if (status == 0) {
-        status = cmdStatus;
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::command(int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData)
-{
-    Mutex::Autolock _l(mLock);
-//    LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
-
-    if (mEffectInterface == NULL) {
-        return NO_INIT;
-    }
-    status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
-    if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
-        int size = (replySize == NULL) ? 0 : *replySize;
-        for (size_t i = 1; i < mHandles.size(); i++) {
-            sp<EffectHandle> h = mHandles[i].promote();
-            if (h != 0) {
-                h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
-            }
-        }
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
-{
-    Mutex::Autolock _l(mLock);
-    LOGV("setEnabled %p enabled %d", this, enabled);
-
-    if (enabled != isEnabled()) {
-        switch (mState) {
-        // going from disabled to enabled
-        case IDLE:
-            mState = STARTING;
-            break;
-        case STOPPED:
-            mState = RESTART;
-            break;
-        case STOPPING:
-            mState = ACTIVE;
-            break;
-
-        // going from enabled to disabled
-        case RESTART:
-        case STARTING:
-            mState = IDLE;
-            break;
-        case ACTIVE:
-            mState = STOPPING;
-            break;
-        }
-        for (size_t i = 1; i < mHandles.size(); i++) {
-            sp<EffectHandle> h = mHandles[i].promote();
-            if (h != 0) {
-                h->setEnabled(enabled);
-            }
-        }
-    }
-    return NO_ERROR;
-}
-
-bool AudioFlinger::EffectModule::isEnabled()
-{
-    switch (mState) {
-    case RESTART:
-    case STARTING:
-    case ACTIVE:
-        return true;
-    case IDLE:
-    case STOPPING:
-    case STOPPED:
-    default:
-        return false;
-    }
-}
-
-status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
-{
-    Mutex::Autolock _l(mLock);
-    status_t status = NO_ERROR;
-
-    // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
-    // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
-    if ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) & (EFFECT_FLAG_VOLUME_CTRL|EFFECT_FLAG_VOLUME_IND)) {
-        status_t cmdStatus;
-        uint32_t volume[2];
-        uint32_t *pVolume = NULL;
-        int size = sizeof(volume);
-        volume[0] = *left;
-        volume[1] = *right;
-        if (controller) {
-            pVolume = volume;
-        }
-        status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_SET_VOLUME, size, volume, &size, pVolume);
-        if (controller && status == NO_ERROR && size == sizeof(volume)) {
-            *left = volume[0];
-            *right = volume[1];
-        }
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::setDevice(uint32_t device)
-{
-    Mutex::Autolock _l(mLock);
-    status_t status = NO_ERROR;
-    if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
-        // convert device bit field from AudioSystem to EffectApi format.
-        device = deviceAudioSystemToEffectApi(device);
-        if (device == 0) {
-            return BAD_VALUE;
-        }
-        status_t cmdStatus;
-        int size = sizeof(status_t);
-        status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_SET_DEVICE, sizeof(uint32_t), &device, &size, &cmdStatus);
-        if (status == NO_ERROR) {
-            status = cmdStatus;
-        }
-    }
-    return status;
-}
-
-status_t AudioFlinger::EffectModule::setMode(uint32_t mode)
-{
-    Mutex::Autolock _l(mLock);
-    status_t status = NO_ERROR;
-    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
-        // convert audio mode from AudioSystem to EffectApi format.
-        int effectMode = modeAudioSystemToEffectApi(mode);
-        if (effectMode < 0) {
-            return BAD_VALUE;
-        }
-        status_t cmdStatus;
-        int size = sizeof(status_t);
-        status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_SET_AUDIO_MODE, sizeof(int), &effectMode, &size, &cmdStatus);
-        if (status == NO_ERROR) {
-            status = cmdStatus;
-        }
-    }
-    return status;
-}
-
-// update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sDeviceConvTable[] = {
-    DEVICE_EARPIECE, // AudioSystem::DEVICE_OUT_EARPIECE
-    DEVICE_SPEAKER, // AudioSystem::DEVICE_OUT_SPEAKER
-    DEVICE_WIRED_HEADSET, // case AudioSystem::DEVICE_OUT_WIRED_HEADSET
-    DEVICE_WIRED_HEADPHONE, // AudioSystem::DEVICE_OUT_WIRED_HEADPHONE
-    DEVICE_BLUETOOTH_SCO, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO
-    DEVICE_BLUETOOTH_SCO_HEADSET, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET
-    DEVICE_BLUETOOTH_SCO_CARKIT, //  AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT
-    DEVICE_BLUETOOTH_A2DP, //  AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP
-    DEVICE_BLUETOOTH_A2DP_HEADPHONES, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
-    DEVICE_BLUETOOTH_A2DP_SPEAKER, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
-    DEVICE_AUX_DIGITAL // AudioSystem::DEVICE_OUT_AUX_DIGITAL
-};
-
-uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t device)
-{
-    uint32_t deviceOut = 0;
-    while (device) {
-        const uint32_t i = 31 - __builtin_clz(device);
-        device &= ~(1 << i);
-        if (i >= sizeof(sDeviceConvTable)/sizeof(uint32_t)) {
-            LOGE("device convertion error for AudioSystem device 0x%08x", device);
-            return 0;
-        }
-        deviceOut |= (uint32_t)sDeviceConvTable[i];
-    }
-    return deviceOut;
-}
-
-// update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
-const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
-    AUDIO_MODE_NORMAL,   // AudioSystem::MODE_NORMAL
-    AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE
-    AUDIO_MODE_IN_CALL   // AudioSystem::MODE_IN_CALL
-};
-
-int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)
-{
-    int modeOut = -1;
-    if (mode < sizeof(sModeConvTable) / sizeof(uint32_t)) {
-        modeOut = (int)sModeConvTable[mode];
-    }
-    return modeOut;
-}
-
-status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
-    result.append(buffer);
-
-    bool locked = tryLock(mLock);
-    // failed to lock - AudioFlinger is probably deadlocked
-    if (!locked) {
-        result.append("\t\tCould not lock Fx mutex:\n");
-    }
-
-    result.append("\t\tSession Status State Engine:\n");
-    snprintf(buffer, SIZE, "\t\t%05d   %03d    %03d   0x%08x\n",
-            mSessionId, mStatus, mState, (uint32_t)mEffectInterface);
-    result.append(buffer);
-
-    result.append("\t\tDescriptor:\n");
-    snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
-            mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
-            mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],mDescriptor.uuid.node[2],
-            mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
-                mDescriptor.type.timeLow, mDescriptor.type.timeMid, mDescriptor.type.timeHiAndVersion,
-                mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2],
-                mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\t\t- apiVersion: %04X\n\t\t- flags: %08X\n",
-            mDescriptor.apiVersion,
-            mDescriptor.flags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\t\t- name: %s\n",
-            mDescriptor.name);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
-            mDescriptor.implementor);
-    result.append(buffer);
-
-    result.append("\t\t- Input configuration:\n");
-    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
-    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
-            (uint32_t)mConfig.inputCfg.buffer.raw,
-            mConfig.inputCfg.buffer.frameCount,
-            mConfig.inputCfg.samplingRate,
-            mConfig.inputCfg.channels,
-            mConfig.inputCfg.format);
-    result.append(buffer);
-
-    result.append("\t\t- Output configuration:\n");
-    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
-    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
-            (uint32_t)mConfig.outputCfg.buffer.raw,
-            mConfig.outputCfg.buffer.frameCount,
-            mConfig.outputCfg.samplingRate,
-            mConfig.outputCfg.channels,
-            mConfig.outputCfg.format);
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size());
-    result.append(buffer);
-    result.append("\t\t\tPid   Priority Ctrl Locked client server\n");
-    for (size_t i = 0; i < mHandles.size(); ++i) {
-        sp<EffectHandle> handle = mHandles[i].promote();
-        if (handle != 0) {
-            handle->dump(buffer, SIZE);
-            result.append(buffer);
-        }
-    }
-
-    result.append("\n");
-
-    write(fd, result.string(), result.length());
-
-    if (locked) {
-        mLock.unlock();
-    }
-
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-//  EffectHandle implementation
-// ----------------------------------------------------------------------------
-
-#undef LOG_TAG
-#define LOG_TAG "AudioFlinger::EffectHandle"
-
-AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
-                                        const sp<AudioFlinger::Client>& client,
-                                        const sp<IEffectClient>& effectClient,
-                                        int32_t priority)
-    : BnEffect(),
-    mEffect(effect), mEffectClient(effectClient), mClient(client), mPriority(priority), mHasControl(false)
-{
-    LOGV("constructor %p", this);
-
-    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
-    mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
-    if (mCblkMemory != 0) {
-        mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer());
-
-        if (mCblk) {
-            new(mCblk) effect_param_cblk_t();
-            mBuffer = (uint8_t *)mCblk + bufOffset;
-         }
-    } else {
-        LOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE + sizeof(effect_param_cblk_t));
-        return;
-    }
-}
-
-AudioFlinger::EffectHandle::~EffectHandle()
-{
-    LOGV("Destructor %p", this);
-    disconnect();
-}
-
-status_t AudioFlinger::EffectHandle::enable()
-{
-    if (!mHasControl) return INVALID_OPERATION;
-    if (mEffect == 0) return DEAD_OBJECT;
-
-    return mEffect->setEnabled(true);
-}
-
-status_t AudioFlinger::EffectHandle::disable()
-{
-    if (!mHasControl) return INVALID_OPERATION;
-    if (mEffect == NULL) return DEAD_OBJECT;
-
-    return mEffect->setEnabled(false);
-}
-
-void AudioFlinger::EffectHandle::disconnect()
-{
-    if (mEffect == 0) {
-        return;
-    }
-    mEffect->disconnect(this);
-    // release sp on module => module destructor can be called now
-    mEffect.clear();
-    if (mCblk) {
-        mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
-    }
-    mCblkMemory.clear();            // and free the shared memory
-    if (mClient != 0) {
-        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
-        mClient.clear();
-    }
-}
-
-status_t AudioFlinger::EffectHandle::command(int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData)
-{
-//    LOGV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p", cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
-
-    // only get parameter command is permitted for applications not controlling the effect
-    if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
-        return INVALID_OPERATION;
-    }
-    if (mEffect == 0) return DEAD_OBJECT;
-
-    // handle commands that are not forwarded transparently to effect engine
-    if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
-        // No need to trylock() here as this function is executed in the binder thread serving a particular client process:
-        // no risk to block the whole media server process or mixer threads is we are stuck here
-        Mutex::Autolock _l(mCblk->lock);
-        if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
-            mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
-            mCblk->serverIndex = 0;
-            mCblk->clientIndex = 0;
-            return BAD_VALUE;
-        }
-        status_t status = NO_ERROR;
-        while (mCblk->serverIndex < mCblk->clientIndex) {
-            int reply;
-            int rsize = sizeof(int);
-            int *p = (int *)(mBuffer + mCblk->serverIndex);
-            int size = *p++;
-            if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
-                LOGW("command(): invalid parameter block size");
-                break;
-            }
-            effect_param_t *param = (effect_param_t *)p;
-            if (param->psize == 0 || param->vsize == 0) {
-                LOGW("command(): null parameter or value size");
-                mCblk->serverIndex += size;
-                continue;
-            }
-            int psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
-            status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM, psize, p, &rsize, &reply);
-            if (ret == NO_ERROR) {
-                if (reply != NO_ERROR) {
-                    status = reply;
-                }
-            } else {
-                status = ret;
-            }
-            mCblk->serverIndex += size;
-        }
-        mCblk->serverIndex = 0;
-        mCblk->clientIndex = 0;
-        return status;
-    } else if (cmdCode == EFFECT_CMD_ENABLE) {
-        return enable();
-    } else if (cmdCode == EFFECT_CMD_DISABLE) {
-        return disable();
-    }
-
-    return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
-}
-
-sp<IMemory> AudioFlinger::EffectHandle::getCblk() const {
-    return mCblkMemory;
-}
-
-void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal)
-{
-    LOGV("setControl %p control %d", this, hasControl);
-
-    mHasControl = hasControl;
-    if (signal && mEffectClient != 0) {
-        mEffectClient->controlStatusChanged(hasControl);
-    }
-}
-
-void AudioFlinger::EffectHandle::commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData)
-{
-    if (mEffectClient != 0) {
-        mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
-    }
-}
-
-
-
-void AudioFlinger::EffectHandle::setEnabled(bool enabled)
-{
-    if (mEffectClient != 0) {
-        mEffectClient->enableStatusChanged(enabled);
-    }
-}
-
-status_t AudioFlinger::EffectHandle::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnEffect::onTransact(code, data, reply, flags);
-}
-
-
-void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
-{
-    bool locked = tryLock(mCblk->lock);
-
-    snprintf(buffer, size, "\t\t\t%05d %05d    %01u    %01u      %05u  %05u\n",
-            (mClient == NULL) ? getpid() : mClient->pid(),
-            mPriority,
-            mHasControl,
-            !locked,
-            mCblk->clientIndex,
-            mCblk->serverIndex
-            );
-
-    if (locked) {
-        mCblk->lock.unlock();
-    }
-}
-
-#undef LOG_TAG
-#define LOG_TAG "AudioFlinger::EffectChain"
-
-AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
-                                        int sessionId)
-    : mThread(wThread), mSessionId(sessionId), mVolumeCtrlIdx(-1), mActiveTrackCnt(0), mOwnInBuffer(false)
-{
-
-}
-
-AudioFlinger::EffectChain::~EffectChain()
-{
-    if (mOwnInBuffer) {
-        delete mInBuffer;
-    }
-
-}
-
-sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc(effect_descriptor_t *descriptor)
-{
-    sp<EffectModule> effect;
-    size_t size = mEffects.size();
-
-    for (size_t i = 0; i < size; i++) {
-        if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
-            effect = mEffects[i];
-            break;
-        }
-    }
-    return effect;
-}
-
-sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId(int id)
-{
-    sp<EffectModule> effect;
-    size_t size = mEffects.size();
-
-    for (size_t i = 0; i < size; i++) {
-        if (mEffects[i]->id() == id) {
-            effect = mEffects[i];
-            break;
-        }
-    }
-    return effect;
-}
-
-// Must be called with EffectChain::mLock locked
-void AudioFlinger::EffectChain::process_l()
-{
-    size_t size = mEffects.size();
-    for (size_t i = 0; i < size; i++) {
-        mEffects[i]->process();
-    }
-    for (size_t i = 0; i < size; i++) {
-        mEffects[i]->updateState();
-    }
-    // if no track is active, input buffer must be cleared here as the mixer process
-    // will not do it
-    if (mSessionId > 0 && activeTracks() == 0) {
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread != 0) {
-            size_t numSamples = thread->frameCount() * thread->channelCount();
-            memset(mInBuffer, 0, numSamples * sizeof(int16_t));
-        }
-    }
-}
-
-status_t AudioFlinger::EffectChain::addEffect(sp<EffectModule>& effect)
-{
-    effect_descriptor_t desc = effect->desc();
-    uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
-
-    Mutex::Autolock _l(mLock);
-
-    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
-        // Auxiliary effects are inserted at the beginning of mEffects vector as
-        // they are processed first and accumulated in chain input buffer
-        mEffects.insertAt(effect, 0);
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread == 0) {
-            return NO_INIT;
-        }
-        // the input buffer for auxiliary effect contains mono samples in
-        // 32 bit format. This is to avoid saturation in AudoMixer
-        // accumulation stage. Saturation is done in EffectModule::process() before
-        // calling the process in effect engine
-        size_t numSamples = thread->frameCount();
-        int32_t *buffer = new int32_t[numSamples];
-        memset(buffer, 0, numSamples * sizeof(int32_t));
-        effect->setInBuffer((int16_t *)buffer);
-        // auxiliary effects output samples to chain input buffer for further processing
-        // by insert effects
-        effect->setOutBuffer(mInBuffer);
-    } else {
-        // Insert effects are inserted at the end of mEffects vector as they are processed
-        //  after track and auxiliary effects.
-        // Insert effect order as a function of indicated preference:
-        //  if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
-        //  another effect is present
-        //  else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
-        //  last effect claiming first position
-        //  else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
-        //  first effect claiming last position
-        //  else if EFFECT_FLAG_INSERT_ANY insert after first or before last
-        // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
-        // already present
-
-        int size = (int)mEffects.size();
-        int idx_insert = size;
-        int idx_insert_first = -1;
-        int idx_insert_last = -1;
-
-        for (int i = 0; i < size; i++) {
-            effect_descriptor_t d = mEffects[i]->desc();
-            uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
-            uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
-            if (iMode == EFFECT_FLAG_TYPE_INSERT) {
-                // check invalid effect chaining combinations
-                if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
-                    iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
-                    LOGW("addEffect() could not insert effect %s: exclusive conflict with %s", desc.name, d.name);
-                    return INVALID_OPERATION;
-                }
-                // remember position of first insert effect and by default
-                // select this as insert position for new effect
-                if (idx_insert == size) {
-                    idx_insert = i;
-                }
-                // remember position of last insert effect claiming
-                // first position
-                if (iPref == EFFECT_FLAG_INSERT_FIRST) {
-                    idx_insert_first = i;
-                }
-                // remember position of first insert effect claiming
-                // last position
-                if (iPref == EFFECT_FLAG_INSERT_LAST &&
-                    idx_insert_last == -1) {
-                    idx_insert_last = i;
-                }
-            }
-        }
-
-        // modify idx_insert from first position if needed
-        if (insertPref == EFFECT_FLAG_INSERT_LAST) {
-            if (idx_insert_last != -1) {
-                idx_insert = idx_insert_last;
-            } else {
-                idx_insert = size;
-            }
-        } else {
-            if (idx_insert_first != -1) {
-                idx_insert = idx_insert_first + 1;
-            }
-        }
-
-        // always read samples from chain input buffer
-        effect->setInBuffer(mInBuffer);
-
-        // if last effect in the chain, output samples to chain
-        // output buffer, otherwise to chain input buffer
-        if (idx_insert == size) {
-            if (idx_insert != 0) {
-                mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
-                mEffects[idx_insert-1]->configure();
-            }
-            effect->setOutBuffer(mOutBuffer);
-        } else {
-            effect->setOutBuffer(mInBuffer);
-        }
-        mEffects.insertAt(effect, idx_insert);
-        // Always give volume control to last effect in chain with volume control capability
-        if (((desc.flags & EFFECT_FLAG_VOLUME_MASK) & EFFECT_FLAG_VOLUME_CTRL) &&
-                mVolumeCtrlIdx < idx_insert) {
-            mVolumeCtrlIdx = idx_insert;
-        }
-
-        LOGV("addEffect() effect %p, added in chain %p at rank %d", effect.get(), this, idx_insert);
-    }
-    effect->configure();
-    return NO_ERROR;
-}
-
-size_t AudioFlinger::EffectChain::removeEffect(const sp<EffectModule>& effect)
-{
-    Mutex::Autolock _l(mLock);
-
-    int size = (int)mEffects.size();
-    int i;
-    uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
-
-    for (i = 0; i < size; i++) {
-        if (effect == mEffects[i]) {
-            if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
-                delete[] effect->inBuffer();
-            } else {
-                if (i == size - 1 && i != 0) {
-                    mEffects[i - 1]->setOutBuffer(mOutBuffer);
-                    mEffects[i - 1]->configure();
-                }
-            }
-            mEffects.removeAt(i);
-            LOGV("removeEffect() effect %p, removed from chain %p at rank %d", effect.get(), this, i);
-            break;
-        }
-    }
-    // Return volume control to last effect in chain with volume control capability
-    if (mVolumeCtrlIdx == i) {
-        size = (int)mEffects.size();
-        for (i = size; i > 0; i--) {
-            if ((mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) & EFFECT_FLAG_VOLUME_CTRL) {
-                break;
-            }
-        }
-        // mVolumeCtrlIdx reset to -1 if no effect found with volume control flag set
-        mVolumeCtrlIdx = i - 1;
-    }
-
-    return mEffects.size();
-}
-
-void AudioFlinger::EffectChain::setDevice(uint32_t device)
-{
-    size_t size = mEffects.size();
-    for (size_t i = 0; i < size; i++) {
-        mEffects[i]->setDevice(device);
-    }
-}
-
-void AudioFlinger::EffectChain::setMode(uint32_t mode)
-{
-    size_t size = mEffects.size();
-    for (size_t i = 0; i < size; i++) {
-        mEffects[i]->setMode(mode);
-    }
-}
-
-bool AudioFlinger::EffectChain::setVolume(uint32_t *left, uint32_t *right)
-{
-    uint32_t newLeft = *left;
-    uint32_t newRight = *right;
-    bool hasControl = false;
-
-    // first get volume update from volume controller
-    if (mVolumeCtrlIdx >= 0) {
-        mEffects[mVolumeCtrlIdx]->setVolume(&newLeft, &newRight, true);
-        hasControl = true;
-    }
-    // then indicate volume to all other effects in chain.
-    // Pass altered volume to effects before volume controller
-    // and requested volume to effects after controller
-    uint32_t lVol = newLeft;
-    uint32_t rVol = newRight;
-    size_t size = mEffects.size();
-    for (size_t i = 0; i < size; i++) {
-        if ((int)i == mVolumeCtrlIdx) continue;
-        // this also works for mVolumeCtrlIdx == -1 when there is no volume controller
-        if ((int)i > mVolumeCtrlIdx) {
-            lVol = *left;
-            rVol = *right;
-        }
-        mEffects[i]->setVolume(&lVol, &rVol, false);
-    }
-    *left = newLeft;
-    *right = newRight;
-
-    return hasControl;
-}
-
-sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getVolumeController()
-{
-    sp<EffectModule> effect;
-    if (mVolumeCtrlIdx >= 0) {
-        effect = mEffects[mVolumeCtrlIdx];
-    }
-    return effect;
-}
-
-
-status_t AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "Effects for session %d:\n", mSessionId);
-    result.append(buffer);
-
-    bool locked = tryLock(mLock);
-    // failed to lock - AudioFlinger is probably deadlocked
-    if (!locked) {
-        result.append("\tCould not lock mutex:\n");
-    }
-
-    result.append("\tNum fx In buffer   Out buffer   Vol ctrl Active tracks:\n");
-    snprintf(buffer, SIZE, "\t%02d     0x%08x  0x%08x   %02d       %d\n",
-            mEffects.size(),
-            (uint32_t)mInBuffer,
-            (uint32_t)mOutBuffer,
-            (mVolumeCtrlIdx == -1) ? 0 : mEffects[mVolumeCtrlIdx]->id(),
-            mActiveTrackCnt);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    for (size_t i = 0; i < mEffects.size(); ++i) {
-        sp<EffectModule> effect = mEffects[i];
-        if (effect != 0) {
-            effect->dump(fd, args);
-        }
-    }
-
-    if (locked) {
-        mLock.unlock();
-    }
-
-    return NO_ERROR;
-}
-
-#undef LOG_TAG
-#define LOG_TAG "AudioFlinger"
-
-// ----------------------------------------------------------------------------
-
-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/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
deleted file mode 100644
index 507c9ac..0000000
--- a/libs/audioflinger/AudioFlinger.h
+++ /dev/null
@@ -1,1148 +0,0 @@
-/* //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 effect_param_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:
-    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,
-                                int *sessionId,
-                                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);
-
-    virtual int newAudioSessionId();
-
-    virtual status_t loadEffectLibrary(const char *libPath, int *handle);
-
-    virtual status_t unloadEffectLibrary(int handle);
-
-    virtual status_t queryNumberEffects(uint32_t *numEffects);
-
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
-
-    virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor);
-
-    virtual sp<IEffect> createEffect(pid_t pid,
-                        effect_descriptor_t *pDesc,
-                        const sp<IEffectClient>& effectClient,
-                        int32_t priority,
-                        int output,
-                        int sessionId,
-                        status_t *status,
-                        int *id,
-                        int *enabled);
-
-            status_t registerEffectResource_l(effect_descriptor_t *desc);
-            void     unregisterEffectResource_l(effect_descriptor_t *desc);
-
-    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,
-                                int *sessionId,
-                                status_t *status);
-
-    virtual     status_t    onTransact(
-                                uint32_t code,
-                                const Parcel& data,
-                                Parcel* reply,
-                                uint32_t flags);
-
-                uint32_t    getMode() { return mMode; }
-
-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;
-    };
-
-    // --- Notification Client ---
-    class NotificationClient : public IBinder::DeathRecipient {
-    public:
-                            NotificationClient(const sp<AudioFlinger>& audioFlinger,
-                                                const sp<IAudioFlingerClient>& client,
-                                                pid_t pid);
-        virtual             ~NotificationClient();
-
-                sp<IAudioFlingerClient>    client() { return mClient; }
-
-                // IBinder::DeathRecipient
-                virtual     void        binderDied(const wp<IBinder>& who);
-
-    private:
-                            NotificationClient(const NotificationClient&);
-                            NotificationClient& operator = (const NotificationClient&);
-
-        sp<AudioFlinger>        mAudioFlinger;
-        pid_t                   mPid;
-        sp<IAudioFlingerClient> mClient;
-    };
-
-    class TrackHandle;
-    class RecordHandle;
-    class RecordThread;
-    class PlaybackThread;
-    class MixerThread;
-    class DirectOutputThread;
-    class DuplicatingThread;
-    class Track;
-    class RecordTrack;
-    class EffectModule;
-    class EffectHandle;
-    class EffectChain;
-
-    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,
-                                        int sessionId);
-                                ~TrackBase();
-
-            virtual status_t    start() = 0;
-            virtual void        stop() = 0;
-                    sp<IMemory> getCblk() const;
-                    audio_track_cblk_t* cblk() const { return mCblk; }
-                    int         sessionId() { return mSessionId; }
-
-        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;
-            int                 mSessionId;
-        };
-
-        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_l(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;
-                    uint32_t                mChannels;
-                    uint16_t                mChannelCount;
-                    uint16_t                mFrameSize;
-                    int                     mFormat;
-                    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,
-                                        int sessionId);
-                                ~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;
-                    }
-                    status_t    attachAuxEffect(int EffectId);
-                    void        setAuxBuffer(int EffectId, int32_t *buffer);
-                    int32_t     *auxBuffer() { return mAuxBuffer; }
-                    void        setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; }
-                    int16_t     *mainBuffer() { return mMainBuffer; }
-                    int         auxEffectId() { return mAuxEffectId; }
-
-
-        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;
-            int16_t             *mMainBuffer;
-            int32_t             *mAuxBuffer;
-            int                 mAuxEffectId;
-        };  // 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, uint32_t device);
-        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,
-                                    int sessionId,
-                                    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_l(int event, int param = 0);
-        virtual     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
-                    int16_t     *mixBuffer() { return mMixBuffer; };
-
-                    sp<EffectHandle> createEffect_l(
-                                        const sp<AudioFlinger::Client>& client,
-                                        const sp<IEffectClient>& effectClient,
-                                        int32_t priority,
-                                        int sessionId,
-                                        effect_descriptor_t *desc,
-                                        int *enabled,
-                                        status_t *status);
-                    void disconnectEffect(const sp< EffectModule>& effect,
-                                          const wp<EffectHandle>& handle);
-
-                    bool hasAudioSession(int sessionId);
-                    sp<EffectChain> getEffectChain(int sessionId);
-                    sp<EffectChain> getEffectChain_l(int sessionId);
-                    status_t addEffectChain_l(const sp<EffectChain>& chain);
-                    size_t removeEffectChain_l(const sp<EffectChain>& chain);
-                    void lockEffectChains_l();
-                    void unlockEffectChains();
-
-                    sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
-                    void detachAuxEffect_l(int effectId);
-                    status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId);
-                    status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId);
-                    void setMode(uint32_t mode);
-
-        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();
-
-        uint32_t    device() { return mDevice; }
-
-        virtual status_t    dumpInternals(int fd, const Vector<String16>& args);
-        status_t    dumpTracks(int fd, const Vector<String16>& args);
-        status_t    dumpEffectChains(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;
-        Vector< sp<EffectChain> >       mEffectChains;
-        uint32_t                        mDevice;
-    };
-
-    class MixerThread : public PlaybackThread {
-    public:
-        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device);
-        virtual             ~MixerThread();
-
-        // Thread virtuals
-        virtual     bool        threadLoop();
-
-                    void        invalidateTracks(int streamType);
-        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, uint32_t device);
-        ~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:
-        void applyVolume(uint16_t leftVol, uint16_t rightVol, bool ramp);
-
-        float mLeftVolFloat;
-        float mRightVolFloat;
-        uint16_t mLeftVolShort;
-        uint16_t mRightVolShort;
-    };
-
-    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);
-
-              int  nextUniqueId();
-
-    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    attachAuxEffect(int effectId);
-        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);
-                void        removeNotificationClient(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,
-                                        int sessionId);
-                                ~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_l(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;
-    };
-
-    //--- Audio Effect Management
-
-    // EffectModule and EffectChain classes both have their own mutex to protect
-    // state changes or resource modifications. Always respect the following order
-    // if multiple mutexes must be acquired to avoid cross deadlock:
-    // AudioFlinger -> ThreadBase -> EffectChain -> EffectModule
-
-    // The EffectModule class is a wrapper object controlling the effect engine implementation
-    // in the effect library. It prevents concurrent calls to process() and command() functions
-    // from different client threads. It keeps a list of EffectHandle objects corresponding
-    // to all client applications using this effect and notifies applications of effect state,
-    // control or parameter changes. It manages the activation state machine to send appropriate
-    // reset, enable, disable commands to effect engine and provide volume
-    // ramping when effects are activated/deactivated.
-    // When controlling an auxiliary effect, the EffectModule also provides an input buffer used by
-    // the attached track(s) to accumulate their auxiliary channel.
-    class EffectModule: public RefBase {
-    public:
-        EffectModule(const wp<ThreadBase>& wThread,
-                        const wp<AudioFlinger::EffectChain>& chain,
-                        effect_descriptor_t *desc,
-                        int id,
-                        int sessionId);
-        ~EffectModule();
-
-        enum effect_state {
-            IDLE,
-            RESTART,
-            STARTING,
-            ACTIVE,
-            STOPPING,
-            STOPPED
-        };
-
-        int         id() { return mId; }
-        void process();
-        void updateState();
-        status_t command(int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData);
-
-        void reset_l();
-        status_t configure();
-        status_t init();
-        uint32_t state() {
-            return mState;
-        }
-        uint32_t status() {
-            return mStatus;
-        }
-        status_t    setEnabled(bool enabled);
-        bool isEnabled();
-
-        void        setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; }
-        int16_t     *inBuffer() { return mConfig.inputCfg.buffer.s16; }
-        void        setOutBuffer(int16_t *buffer) { mConfig.outputCfg.buffer.s16 = buffer; }
-        int16_t     *outBuffer() { return mConfig.outputCfg.buffer.s16; }
-
-        status_t addHandle(sp<EffectHandle>& handle);
-        void disconnect(const wp<EffectHandle>& handle);
-        size_t removeHandle (const wp<EffectHandle>& handle);
-
-        effect_descriptor_t& desc() { return mDescriptor; }
-        wp<EffectChain>&     chain() { return mChain; }
-
-        status_t         setDevice(uint32_t device);
-        status_t         setVolume(uint32_t *left, uint32_t *right, bool controller);
-        status_t         setMode(uint32_t mode);
-
-        status_t         dump(int fd, const Vector<String16>& args);
-
-    protected:
-
-        // Maximum time allocated to effect engines to complete the turn off sequence
-        static const uint32_t MAX_DISABLE_TIME_MS = 10000;
-
-        EffectModule(const EffectModule&);
-        EffectModule& operator = (const EffectModule&);
-
-        status_t start_l();
-        status_t stop_l();
-
-        // update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
-        static const uint32_t sDeviceConvTable[];
-        static uint32_t deviceAudioSystemToEffectApi(uint32_t device);
-
-        // update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
-        static const uint32_t sModeConvTable[];
-        static int modeAudioSystemToEffectApi(uint32_t mode);
-
-        Mutex               mLock;      // mutex for process, commands and handles list protection
-        wp<ThreadBase>      mThread;    // parent thread
-        wp<EffectChain>     mChain;     // parent effect chain
-        int                 mId;        // this instance unique ID
-        int                 mSessionId; // audio session ID
-        effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
-        effect_config_t     mConfig;    // input and output audio configuration
-        effect_interface_t  mEffectInterface; // Effect module C API
-        status_t mStatus;               // initialization status
-        uint32_t mState;                // current activation state (effect_state)
-        Vector< wp<EffectHandle> > mHandles;    // list of client handles
-        uint32_t mMaxDisableWaitCnt;    // maximum grace period before forcing an effect off after
-                                        // sending disable command.
-        uint32_t mDisableWaitCnt;       // current process() calls count during disable period.
-    };
-
-    // The EffectHandle class implements the IEffect interface. It provides resources
-    // to receive parameter updates, keeps track of effect control
-    // ownership and state and has a pointer to the EffectModule object it is controlling.
-    // There is one EffectHandle object for each application controlling (or using)
-    // an effect module.
-    // The EffectHandle is obtained by calling AudioFlinger::createEffect().
-    class EffectHandle: public android::BnEffect {
-    public:
-
-        EffectHandle(const sp<EffectModule>& effect,
-                const sp<AudioFlinger::Client>& client,
-                const sp<IEffectClient>& effectClient,
-                int32_t priority);
-        virtual ~EffectHandle();
-
-        // IEffect
-        virtual status_t enable();
-        virtual status_t disable();
-        virtual status_t command(int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData);
-        virtual void disconnect();
-        virtual sp<IMemory> getCblk() const;
-        virtual status_t onTransact(uint32_t code, const Parcel& data,
-                Parcel* reply, uint32_t flags);
-
-
-        // Give or take control of effect module
-        void setControl(bool hasControl, bool signal);
-        void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData);
-        void setEnabled(bool enabled);
-
-        // Getters
-        int id() { return mEffect->id(); }
-        int priority() { return mPriority; }
-        bool hasControl() { return mHasControl; }
-        sp<EffectModule> effect() { return mEffect; }
-
-        void dump(char* buffer, size_t size);
-
-    protected:
-
-        EffectHandle(const EffectHandle&);
-        EffectHandle& operator =(const EffectHandle&);
-
-        sp<EffectModule> mEffect;           // pointer to controlled EffectModule
-        sp<IEffectClient> mEffectClient;    // callback interface for client notifications
-        sp<Client>          mClient;        // client for shared memory allocation
-        sp<IMemory>         mCblkMemory;    // shared memory for control block
-        effect_param_cblk_t* mCblk;         // control block for deferred parameter setting via shared memory
-        uint8_t*            mBuffer;        // pointer to parameter area in shared memory
-        int mPriority;                      // client application priority to control the effect
-        bool mHasControl;                   // true if this handle is controlling the effect
-    };
-
-    // the EffectChain class represents a group of effects associated to one audio session.
-    // There can be any number of EffectChain objects per output mixer thread (PlaybackThread).
-    // The EffecChain with session ID 0 contains global effects applied to the output mix.
-    // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to tracks)
-    // are insert only. The EffectChain maintains an ordered list of effect module, the order corresponding
-    // in the effect process order. When attached to a track (session ID != 0), it also provide it's own
-    // input buffer used by the track as accumulation buffer.
-    class EffectChain: public RefBase {
-    public:
-        EffectChain(const wp<ThreadBase>& wThread, int sessionId);
-        ~EffectChain();
-
-        void process_l();
-
-        void lock() {
-            mLock.lock();
-        }
-        void unlock() {
-            mLock.unlock();
-        }
-
-        status_t addEffect(sp<EffectModule>& handle);
-        size_t removeEffect(const sp<EffectModule>& handle);
-
-        int sessionId() {
-            return mSessionId;
-        }
-        sp<EffectModule> getEffectFromDesc(effect_descriptor_t *descriptor);
-        sp<EffectModule> getEffectFromId(int id);
-        sp<EffectModule> getVolumeController();
-        bool setVolume(uint32_t *left, uint32_t *right);
-        void setDevice(uint32_t device);
-        void setMode(uint32_t mode);
-
-
-        void setInBuffer(int16_t *buffer, bool ownsBuffer = false) {
-            mInBuffer = buffer;
-            mOwnInBuffer = ownsBuffer;
-        }
-        int16_t *inBuffer() {
-            return mInBuffer;
-        }
-        void setOutBuffer(int16_t *buffer) {
-            mOutBuffer = buffer;
-        }
-        int16_t *outBuffer() {
-            return mOutBuffer;
-        }
-
-        void startTrack() {mActiveTrackCnt++;}
-        void stopTrack() {mActiveTrackCnt--;}
-        int activeTracks() { return mActiveTrackCnt;}
-
-        status_t dump(int fd, const Vector<String16>& args);
-
-    protected:
-
-        EffectChain(const EffectChain&);
-        EffectChain& operator =(const EffectChain&);
-
-        wp<ThreadBase> mThread;     // parent mixer thread
-        Mutex mLock;                // mutex protecting effect list
-        Vector<sp<EffectModule> > mEffects; // list of effect modules
-        int mSessionId;             // audio session ID
-        int16_t *mInBuffer;         // chain input buffer
-        int16_t *mOutBuffer;        // chain output buffer
-        int mVolumeCtrlIdx;         // index of insert effect having control over volume
-        int mActiveTrackCnt;        // number of active tracks connected
-        bool mOwnInBuffer;          // true if the chain owns its input buffer
-    };
-
-    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;
-
-                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
-                volatile int32_t                    mNextUniqueId;
-#ifdef LVMX
-                int mLifeVibesClientPid;
-#endif
-                uint32_t mMode;
-
-                // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
-                static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
-                // Maximum memory allocated to audio effects in KB
-                static const uint32_t MAX_EFFECTS_MEMORY = 512;
-                uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
-                uint32_t mTotalEffectsMemory;  // current memory used by effects
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
deleted file mode 100644
index d63c031..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
-**
-** 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/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
deleted file mode 100644
index aa4e78d..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-**
-** 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/libs/audioflinger/AudioHardwareInterface.cpp b/libs/audioflinger/AudioHardwareInterface.cpp
deleted file mode 100644
index 9a4a7f9..0000000
--- a/libs/audioflinger/AudioHardwareInterface.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-**
-** 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/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
deleted file mode 100644
index d481150..0000000
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* //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/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
deleted file mode 100644
index 06a29de..0000000
--- a/libs/audioflinger/AudioHardwareStub.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* //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/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp
deleted file mode 100644
index 8aaa325..0000000
--- a/libs/audioflinger/AudioMixer.cpp
+++ /dev/null
@@ -1,1195 +0,0 @@
-/* //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->auxLevel = 0;
-        t->auxInc = 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->mainBuffer = NULL;
-        t->auxBuffer = NULL;
-        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, void *value)
-{
-    int valueInt = (int)value;
-    int32_t *valueBuf = (int32_t *)value;
-
-    switch (target) {
-    case TRACK:
-        if (name == CHANNEL_COUNT) {
-            if ((uint32_t(valueInt) <= MAX_NUM_CHANNELS) && (valueInt)) {
-                if (mState.tracks[ mActiveTrack ].channelCount != valueInt) {
-                    mState.tracks[ mActiveTrack ].channelCount = valueInt;
-                    LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", valueInt);
-                    invalidateState(1<<mActiveTrack);
-                }
-                return NO_ERROR;
-            }
-        }
-        if (name == MAIN_BUFFER) {
-            if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
-                mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
-                LOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
-                invalidateState(1<<mActiveTrack);
-            }
-            return NO_ERROR;
-        }
-        if (name == AUX_BUFFER) {
-            if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
-                mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
-                LOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
-                invalidateState(1<<mActiveTrack);
-            }
-            return NO_ERROR;
-        }
-
-        break;
-    case RESAMPLE:
-        if (name == SAMPLE_RATE) {
-            if (valueInt > 0) {
-                track_t& track = mState.tracks[ mActiveTrack ];
-                if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
-                    LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
-                            uint32_t(valueInt));
-                    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] != valueInt) {
-                LOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
-                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
-                track.volume[name-VOLUME0] = valueInt;
-                if (target == VOLUME) {
-                    track.prevVolume[name-VOLUME0] = valueInt << 16;
-                    track.volumeInc[name-VOLUME0] = 0;
-                } else {
-                    int32_t d = (valueInt<<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] = valueInt << 16;
-                    }
-                }
-                invalidateState(1<<mActiveTrack);
-            }
-            return NO_ERROR;
-        } else if (name == AUXLEVEL) {
-            track_t& track = mState.tracks[ mActiveTrack ];
-            if (track.auxLevel != valueInt) {
-                LOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
-                track.prevAuxLevel = track.auxLevel << 16;
-                track.auxLevel = valueInt;
-                if (target == VOLUME) {
-                    track.prevAuxLevel = valueInt << 16;
-                    track.auxInc = 0;
-                } else {
-                    int32_t d = (valueInt<<16) - track.prevAuxLevel;
-                    int32_t volInc = d / int32_t(mState.frameCount);
-                    track.auxInc = volInc;
-                    if (volInc == 0) {
-                        track.prevAuxLevel = valueInt << 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(bool aux)
-{
-    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;
-        }
-    }
-    if (aux) {
-        if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
-            ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
-            auxInc = 0;
-            prevAuxLevel = auxLevel<<16;
-        }
-    }
-}
-
-
-status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
-{
-    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
-    return NO_ERROR;
-}
-
-
-
-void AudioMixer::process()
-{
-    mState.hook(&mState);
-}
-
-
-void AudioMixer::process__validate(state_t* state)
-{
-    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.auxLevel != 0 && t.auxBuffer != NULL) {
-            n |= NEEDS_AUX_ENABLED;
-        }
-
-        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_AUX__MASK) == NEEDS_AUX_ENABLED) {
-                all16BitsStereoNoResample = 0;
-            }
-            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);
-
-   // 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 (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, int32_t* aux)
-{
-    t->resampler->setSampleRate(t->sampleRate);
-
-    // ramp gain - resample to temp buffer and scale/mix in 2nd step
-    if (aux != NULL) {
-        // always resample with unity gain when sending to auxiliary buffer to be able
-        // to apply send level after resampling
-        // TODO: modify each resampler to support aux channel?
-        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
-        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
-        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
-            volumeRampStereo(t, out, outFrameCount, temp, aux);
-        } else {
-            volumeStereo(t, out, outFrameCount, temp, aux);
-        }
-    } else {
-        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, aux);
-        }
-
-        // 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, int32_t* aux)
-{
-}
-
-void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
-{
-    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
-    if UNLIKELY(aux != NULL) {
-        int32_t va = t->prevAuxLevel;
-        const int32_t vaInc = t->auxInc;
-        int32_t l;
-        int32_t r;
-
-        do {
-            l = (*temp++ >> 12);
-            r = (*temp++ >> 12);
-            *out++ += (vl >> 16) * l;
-            *out++ += (vr >> 16) * r;
-            *aux++ += (va >> 17) * (l + r);
-            vl += vlInc;
-            vr += vrInc;
-            va += vaInc;
-        } while (--frameCount);
-        t->prevAuxLevel = va;
-    } else {
-        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((aux != NULL));
-}
-
-void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
-{
-    const int16_t vl = t->volume[0];
-    const int16_t vr = t->volume[1];
-
-    if UNLIKELY(aux != NULL) {
-        const int16_t va = (int16_t)t->auxLevel;
-        do {
-            int16_t l = (int16_t)(*temp++ >> 12);
-            int16_t r = (int16_t)(*temp++ >> 12);
-            out[0] = mulAdd(l, vl, out[0]);
-            int16_t a = (int16_t)(((int32_t)l + r) >> 1);
-            out[1] = mulAdd(r, vr, out[1]);
-            out += 2;
-            aux[0] = mulAdd(a, va, aux[0]);
-            aux++;
-        } while (--frameCount);
-    } else {
-        do {
-            int16_t l = (int16_t)(*temp++ >> 12);
-            int16_t r = (int16_t)(*temp++ >> 12);
-            out[0] = mulAdd(l, vl, out[0]);
-            out[1] = mulAdd(r, vr, out[1]);
-            out += 2;
-        } while (--frameCount);
-    }
-}
-
-void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
-{
-    int16_t const *in = static_cast<int16_t const *>(t->in);
-
-    if UNLIKELY(aux != NULL) {
-        int32_t l;
-        int32_t r;
-        // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
-            int32_t vl = t->prevVolume[0];
-            int32_t vr = t->prevVolume[1];
-            int32_t va = t->prevAuxLevel;
-            const int32_t vlInc = t->volumeInc[0];
-            const int32_t vrInc = t->volumeInc[1];
-            const int32_t vaInc = t->auxInc;
-            // 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 {
-                l = (int32_t)*in++;
-                r = (int32_t)*in++;
-                *out++ += (vl >> 16) * l;
-                *out++ += (vr >> 16) * r;
-                *aux++ += (va >> 17) * (l + r);
-                vl += vlInc;
-                vr += vrInc;
-                va += vaInc;
-            } while (--frameCount);
-
-            t->prevVolume[0] = vl;
-            t->prevVolume[1] = vr;
-            t->prevAuxLevel = va;
-            t->adjustVolumeRamp(true);
-        }
-
-        // constant gain
-        else {
-            const uint32_t vrl = t->volumeRL;
-            const int16_t va = (int16_t)t->auxLevel;
-            do {
-                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
-                int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
-                in += 2;
-                out[0] = mulAddRL(1, rl, vrl, out[0]);
-                out[1] = mulAddRL(0, rl, vrl, out[1]);
-                out += 2;
-                aux[0] = mulAdd(a, va, aux[0]);
-                aux++;
-            } while (--frameCount);
-        }
-    } else {
-        // 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(false);
-        }
-
-        // 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, int32_t* aux)
-{
-    int16_t const *in = static_cast<int16_t const *>(t->in);
-
-    if UNLIKELY(aux != NULL) {
-        // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
-            int32_t vl = t->prevVolume[0];
-            int32_t vr = t->prevVolume[1];
-            int32_t va = t->prevAuxLevel;
-            const int32_t vlInc = t->volumeInc[0];
-            const int32_t vrInc = t->volumeInc[1];
-            const int32_t vaInc = t->auxInc;
-
-            // 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;
-                *aux++ += (va >> 16) * l;
-                vl += vlInc;
-                vr += vrInc;
-                va += vaInc;
-            } while (--frameCount);
-
-            t->prevVolume[0] = vl;
-            t->prevVolume[1] = vr;
-            t->prevAuxLevel = va;
-            t->adjustVolumeRamp(true);
-        }
-        // constant gain
-        else {
-            const int16_t vl = t->volume[0];
-            const int16_t vr = t->volume[1];
-            const int16_t va = (int16_t)t->auxLevel;
-            do {
-                int16_t l = *in++;
-                out[0] = mulAdd(l, vl, out[0]);
-                out[1] = mulAdd(l, vr, out[1]);
-                out += 2;
-                aux[0] = mulAdd(l, va, aux[0]);
-                aux++;
-            } while (--frameCount);
-        }
-    } else {
-        // 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(false);
-        }
-        // 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)
-{
-    uint32_t e0 = state->enabledTracks;
-    size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
-    while (e0) {
-        // process by group of tracks with same output buffer to
-        // avoid multiple memset() on same buffer
-        uint32_t e1 = e0, e2 = e0;
-        int i = 31 - __builtin_clz(e1);
-        track_t& t1 = state->tracks[i];
-        e2 &= ~(1<<i);
-        while (e2) {
-            i = 31 - __builtin_clz(e2);
-            e2 &= ~(1<<i);
-            track_t& t2 = state->tracks[i];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
-                e1 &= ~(1<<i);
-            }
-        }
-        e0 &= ~(e1);
-
-        memset(t1.mainBuffer, 0, bufSize);
-
-        while (e1) {
-            i = 31 - __builtin_clz(e1);
-            e1 &= ~(1<<i);
-            t1 = state->tracks[i];
-            size_t outFrames = state->frameCount;
-            while (outFrames) {
-                t1.buffer.frameCount = outFrames;
-                t1.bufferProvider->getNextBuffer(&t1.buffer);
-                if (!t1.buffer.raw) break;
-                outFrames -= t1.buffer.frameCount;
-                t1.bufferProvider->releaseBuffer(&t1.buffer);
-            }
-        }
-    }
-}
-
-// generic code without resampling
-void AudioMixer::process__genericNoResampling(state_t* state)
-{
-    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
-
-    // acquire each track's buffer
-    uint32_t enabledTracks = state->enabledTracks;
-    uint32_t e0 = enabledTracks;
-    while (e0) {
-        const int i = 31 - __builtin_clz(e0);
-        e0 &= ~(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);
-    }
-
-    e0 = enabledTracks;
-    while (e0) {
-        // process by group of tracks with same output buffer to
-        // optimize cache use
-        uint32_t e1 = e0, e2 = e0;
-        int j = 31 - __builtin_clz(e1);
-        track_t& t1 = state->tracks[j];
-        e2 &= ~(1<<j);
-        while (e2) {
-            j = 31 - __builtin_clz(e2);
-            e2 &= ~(1<<j);
-            track_t& t2 = state->tracks[j];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
-                e1 &= ~(1<<j);
-            }
-        }
-        e0 &= ~(e1);
-        // this assumes output 16 bits stereo, no resampling
-        int32_t *out = t1.mainBuffer;
-        size_t numFrames = 0;
-        do {
-            memset(outTemp, 0, sizeof(outTemp));
-            e2 = e1;
-            while (e2) {
-                const int i = 31 - __builtin_clz(e2);
-                e2 &= ~(1<<i);
-                track_t& t = state->tracks[i];
-                size_t outFrames = BLOCKSIZE;
-                int32_t *aux = NULL;
-                if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
-                    aux = t.auxBuffer + numFrames;
-                }
-                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, aux);
-                        t.frameCount -= inFrames;
-                        outFrames -= inFrames;
-                        if UNLIKELY(aux != NULL) {
-                            aux += inFrames;
-                        }
-                    }
-                    if (t.frameCount == 0 && outFrames) {
-                        t.bufferProvider->releaseBuffer(&t.buffer);
-                        t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
-                        t.bufferProvider->getNextBuffer(&t.buffer);
-                        t.in = t.buffer.raw;
-                        if (t.in == NULL) {
-                            enabledTracks &= ~(1<<i);
-                            e1 &= ~(1<<i);
-                            break;
-                        }
-                        t.frameCount = t.buffer.frameCount;
-                    }
-                }
-            }
-            ditherAndClamp(out, outTemp, BLOCKSIZE);
-            out += BLOCKSIZE;
-            numFrames += BLOCKSIZE;
-        } while (numFrames < state->frameCount);
-    }
-
-    // release each track's buffer
-    e0 = enabledTracks;
-    while (e0) {
-        const int i = 31 - __builtin_clz(e0);
-        e0 &= ~(1<<i);
-        track_t& t = state->tracks[i];
-        t.bufferProvider->releaseBuffer(&t.buffer);
-    }
-}
-
-
-  // generic code with resampling
-void AudioMixer::process__genericResampling(state_t* state)
-{
-    int32_t* const outTemp = state->outputTemp;
-    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
-    memset(outTemp, 0, size);
-
-    size_t numFrames = state->frameCount;
-
-    uint32_t e0 = state->enabledTracks;
-    while (e0) {
-        // process by group of tracks with same output buffer
-        // to optimize cache use
-        uint32_t e1 = e0, e2 = e0;
-        int j = 31 - __builtin_clz(e1);
-        track_t& t1 = state->tracks[j];
-        e2 &= ~(1<<j);
-        while (e2) {
-            j = 31 - __builtin_clz(e2);
-            e2 &= ~(1<<j);
-            track_t& t2 = state->tracks[j];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
-                e1 &= ~(1<<j);
-            }
-        }
-        e0 &= ~(e1);
-        int32_t *out = t1.mainBuffer;
-        while (e1) {
-            const int i = 31 - __builtin_clz(e1);
-            e1 &= ~(1<<i);
-            track_t& t = state->tracks[i];
-            int32_t *aux = NULL;
-            if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
-                aux = t.auxBuffer;
-            }
-
-            // 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, aux);
-            } else {
-
-                size_t outFrames = 0;
-
-                while (outFrames < numFrames) {
-                    t.buffer.frameCount = numFrames - 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;
-
-                    if UNLIKELY(aux != NULL) {
-                        aux += outFrames;
-                    }
-                    (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
-                    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)
-{
-    const int i = 31 - __builtin_clz(state->enabledTracks);
-    const track_t& t = state->tracks[i];
-
-    AudioBufferProvider::Buffer& b(t.buffer);
-
-    int32_t* out = t.mainBuffer;
-    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
-// NEVER used in current implementation of process__validate()
-// only use if the 2 tracks have the same output buffer
-void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
-{
-    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;
-
-    //FIXME: only works if two tracks use same buffer
-    int32_t* out = t0.mainBuffer;
-    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/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
deleted file mode 100644
index aee3e17..0000000
--- a/libs/audioflinger/AudioMixer.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/* //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,
-        MAIN_BUFFER     = 0x4002,
-        AUX_BUFFER      = 0x4003,
-        // for TARGET RESAMPLE
-        SAMPLE_RATE     = 0x4100,
-        // for TARGET VOLUME (8 channels max)
-        VOLUME0         = 0x4200,
-        VOLUME1         = 0x4201,
-        AUXLEVEL        = 0x4210,
-    };
-
-
-    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, void *value);
-
-    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
-    void        process();
-
-    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,
-        NEEDS_AUX__MASK             = 0x00010000,
-    };
-
-    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,
-
-        NEEDS_AUX_DISABLED     = 0x00000000,
-        NEEDS_AUX_ENABLED      = 0x00010000,
-    };
-
-    static inline int32_t applyVolume(int32_t in, int32_t v) {
-        return in * v;
-    }
-
-
-    struct state_t;
-    struct track_t;
-
-    typedef void (*mix_t)(state_t* state);
-    typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
-    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];
-        int32_t     auxLevel;
-        int32_t     auxInc;
-        int32_t     prevAuxLevel;
-
-        uint16_t    frameCount;
-
-        uint8_t     channelCount : 4;
-        uint8_t     enabled      : 1;
-        uint8_t     reserved0    : 3;
-        uint8_t     format;
-
-        AudioBufferProvider*                bufferProvider;
-        mutable AudioBufferProvider::Buffer buffer;
-
-        hook_t      hook;
-        void const* in;             // current location in buffer
-
-        AudioResampler*     resampler;
-        uint32_t            sampleRate;
-        int32_t*           mainBuffer;
-        int32_t*           auxBuffer;
-
-        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
-        bool        doesResample() const;
-        void        adjustVolumeRamp(bool aux);
-    };
-
-    // 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, int32_t* aux);
-    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
-    static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
-
-    static void process__validate(state_t* state);
-    static void process__nop(state_t* state);
-    static void process__genericNoResampling(state_t* state);
-    static void process__genericResampling(state_t* state);
-    static void process__OneTrack16BitsStereoNoResampling(state_t* state);
-    static void process__TwoTracks16BitsStereoNoResampling(state_t* state);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_AUDIO_MIXER_H
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
deleted file mode 100644
index 381a958..0000000
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ /dev/null
@@ -1,1973 +0,0 @@
-/*
- * 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) {
-        AudioOutputDescriptor *dupOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
-        AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-        // As all active tracks on duplicated output will be deleted,
-        // and as they were also referenced on hardware output, the reference
-        // count for their stream type must be adjusted accordingly on
-        // hardware output.
-        for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
-            int refCount = dupOutputDesc->mRefCount[i];
-            hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
-        }
-
-        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);
-            }
-        }
-        // 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);
-            }
-        }
-    }
-}
-
-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/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp
deleted file mode 100644
index bb3905c..0000000
--- a/libs/audioflinger/AudioPolicyService.cpp
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h
deleted file mode 100644
index a13d0bd..0000000
--- a/libs/audioflinger/AudioPolicyService.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
deleted file mode 100644
index 5dabacb..0000000
--- a/libs/audioflinger/AudioResampler.cpp
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
deleted file mode 100644
index 2dfac76..0000000
--- a/libs/audioflinger/AudioResampler.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResamplerCubic.cpp b/libs/audioflinger/AudioResamplerCubic.cpp
deleted file mode 100644
index 1d247bd..0000000
--- a/libs/audioflinger/AudioResamplerCubic.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResamplerCubic.h b/libs/audioflinger/AudioResamplerCubic.h
deleted file mode 100644
index b72b62a..0000000
--- a/libs/audioflinger/AudioResamplerCubic.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResamplerSinc.cpp b/libs/audioflinger/AudioResamplerSinc.cpp
deleted file mode 100644
index 9e5e254..0000000
--- a/libs/audioflinger/AudioResamplerSinc.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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/libs/audioflinger/AudioResamplerSinc.h b/libs/audioflinger/AudioResamplerSinc.h
deleted file mode 100644
index e6cb90b..0000000
--- a/libs/audioflinger/AudioResamplerSinc.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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/libs/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
similarity index 100%
rename from libs/surfaceflinger/Android.mk
rename to services/surfaceflinger/Android.mk
diff --git a/libs/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
similarity index 100%
rename from libs/surfaceflinger/Barrier.h
rename to services/surfaceflinger/Barrier.h
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/services/surfaceflinger/BlurFilter.cpp
similarity index 100%
rename from libs/surfaceflinger/BlurFilter.cpp
rename to services/surfaceflinger/BlurFilter.cpp
diff --git a/libs/surfaceflinger/BlurFilter.h b/services/surfaceflinger/BlurFilter.h
similarity index 100%
rename from libs/surfaceflinger/BlurFilter.h
rename to services/surfaceflinger/BlurFilter.h
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
rename to services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardware.h
rename to services/surfaceflinger/DisplayHardware/DisplayHardware.h
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
rename to services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
rename to services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
diff --git a/libs/surfaceflinger/GLExtensions.cpp b/services/surfaceflinger/GLExtensions.cpp
similarity index 100%
rename from libs/surfaceflinger/GLExtensions.cpp
rename to services/surfaceflinger/GLExtensions.cpp
diff --git a/libs/surfaceflinger/GLExtensions.h b/services/surfaceflinger/GLExtensions.h
similarity index 100%
rename from libs/surfaceflinger/GLExtensions.h
rename to services/surfaceflinger/GLExtensions.h
diff --git a/libs/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
similarity index 100%
rename from libs/surfaceflinger/Layer.cpp
rename to services/surfaceflinger/Layer.cpp
diff --git a/libs/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
similarity index 100%
rename from libs/surfaceflinger/Layer.h
rename to services/surfaceflinger/Layer.h
diff --git a/libs/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerBase.cpp
rename to services/surfaceflinger/LayerBase.cpp
diff --git a/libs/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
similarity index 100%
rename from libs/surfaceflinger/LayerBase.h
rename to services/surfaceflinger/LayerBase.h
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerBlur.cpp
rename to services/surfaceflinger/LayerBlur.cpp
diff --git a/libs/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h
similarity index 100%
rename from libs/surfaceflinger/LayerBlur.h
rename to services/surfaceflinger/LayerBlur.h
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerBuffer.cpp
rename to services/surfaceflinger/LayerBuffer.cpp
diff --git a/libs/surfaceflinger/LayerBuffer.h b/services/surfaceflinger/LayerBuffer.h
similarity index 100%
rename from libs/surfaceflinger/LayerBuffer.h
rename to services/surfaceflinger/LayerBuffer.h
diff --git a/libs/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerDim.cpp
rename to services/surfaceflinger/LayerDim.cpp
diff --git a/libs/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
similarity index 100%
rename from libs/surfaceflinger/LayerDim.h
rename to services/surfaceflinger/LayerDim.h
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/services/surfaceflinger/MODULE_LICENSE_APACHE2
similarity index 100%
rename from libs/surfaceflinger/MODULE_LICENSE_APACHE2
rename to services/surfaceflinger/MODULE_LICENSE_APACHE2
diff --git a/libs/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
similarity index 100%
rename from libs/surfaceflinger/MessageQueue.cpp
rename to services/surfaceflinger/MessageQueue.cpp
diff --git a/libs/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
similarity index 100%
rename from libs/surfaceflinger/MessageQueue.h
rename to services/surfaceflinger/MessageQueue.h
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
similarity index 100%
rename from libs/surfaceflinger/SurfaceFlinger.cpp
rename to services/surfaceflinger/SurfaceFlinger.cpp
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
similarity index 100%
rename from libs/surfaceflinger/SurfaceFlinger.h
rename to services/surfaceflinger/SurfaceFlinger.h
diff --git a/libs/surfaceflinger/TextureManager.cpp b/services/surfaceflinger/TextureManager.cpp
similarity index 100%
rename from libs/surfaceflinger/TextureManager.cpp
rename to services/surfaceflinger/TextureManager.cpp
diff --git a/libs/surfaceflinger/TextureManager.h b/services/surfaceflinger/TextureManager.h
similarity index 100%
rename from libs/surfaceflinger/TextureManager.h
rename to services/surfaceflinger/TextureManager.h
diff --git a/libs/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
similarity index 100%
rename from libs/surfaceflinger/Transform.cpp
rename to services/surfaceflinger/Transform.cpp
diff --git a/libs/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
similarity index 100%
rename from libs/surfaceflinger/Transform.h
rename to services/surfaceflinger/Transform.h
diff --git a/libs/surfaceflinger/clz.cpp b/services/surfaceflinger/clz.cpp
similarity index 100%
rename from libs/surfaceflinger/clz.cpp
rename to services/surfaceflinger/clz.cpp
diff --git a/libs/surfaceflinger/clz.h b/services/surfaceflinger/clz.h
similarity index 100%
rename from libs/surfaceflinger/clz.h
rename to services/surfaceflinger/clz.h
diff --git a/libs/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/Android.mk
rename to services/surfaceflinger/tests/Android.mk
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/services/surfaceflinger/tests/overlays/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/overlays/Android.mk
rename to services/surfaceflinger/tests/overlays/Android.mk
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/services/surfaceflinger/tests/overlays/overlays.cpp
similarity index 100%
rename from libs/surfaceflinger/tests/overlays/overlays.cpp
rename to services/surfaceflinger/tests/overlays/overlays.cpp
diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/services/surfaceflinger/tests/resize/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/resize/Android.mk
rename to services/surfaceflinger/tests/resize/Android.mk
diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
similarity index 100%
rename from libs/surfaceflinger/tests/resize/resize.cpp
rename to services/surfaceflinger/tests/resize/resize.cpp
