am 0ac53364: Merge "Fix non-monotonic AudioTrack::getTimestamp after pause" into lmp-preview-dev

* commit '0ac53364b79dc72ee0c09f0efc46a22ab4374dbf':
  Fix non-monotonic AudioTrack::getTimestamp after pause
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 20da925..d0890fe 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -55,6 +55,10 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicy.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicyservice_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicymanager_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicyservice.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicymanager.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicyservice_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicymanager_intermediates)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 55376b0..04694cd 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -49,7 +49,7 @@
         DeathNotifier() {
         }
 
-        virtual void binderDied(const wp<IBinder>& who) {
+        virtual void binderDied(const wp<IBinder>& /*who*/) {
             ALOGV("binderDied");
             Mutex::Autolock _l(gLock);
             gCameraService.clear();
@@ -153,7 +153,7 @@
 }
 
 template <typename TCam, typename TCamTraits>
-void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& who) {
+void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& /*who*/) {
     ALOGW("mediaserver's remote binder Camera object died");
     notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0);
 }
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index 1567cd1..043437f 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -590,7 +590,8 @@
         const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment);
         offset = metadataStart - reinterpret_cast<uintptr_t>(blob.data());
         ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu",
-                __FUNCTION__, alignment, metadataStart, offset);
+                __FUNCTION__, alignment,
+                reinterpret_cast<const void *>(metadataStart), offset);
         copy_camera_metadata(reinterpret_cast<void*>(metadataStart), metadataSize, metadata);
 
         // Not too big of a problem since receiving side does hard validation
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 161f842..25d632d 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -457,7 +457,7 @@
 
 void CameraParameters::dump() const
 {
-    ALOGD("dump: mMap.size = %d", mMap.size());
+    ALOGD("dump: mMap.size = %zu", mMap.size());
     for (size_t i = 0; i < mMap.size(); i++) {
         String8 k, v;
         k = mMap.keyAt(i);
@@ -466,7 +466,7 @@
     }
 }
 
-status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
+status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp
index 59dce91..0dda6b6 100644
--- a/camera/VendorTagDescriptor.cpp
+++ b/camera/VendorTagDescriptor.cpp
@@ -213,7 +213,7 @@
             return res;
         }
         if (sectionCount < (maxSectionIndex + 1)) {
-            ALOGE("%s: Incorrect number of sections defined, received %d, needs %d.",
+            ALOGE("%s: Incorrect number of sections defined, received %zu, needs %d.",
                     __FUNCTION__, sectionCount, (maxSectionIndex + 1));
             return BAD_VALUE;
         }
@@ -222,14 +222,16 @@
         for (size_t i = 0; i < sectionCount; ++i) {
             String8 sectionName = parcel->readString8();
             if (sectionName.isEmpty()) {
-                ALOGE("%s: parcel section name was NULL for section %d.", __FUNCTION__, i);
+                ALOGE("%s: parcel section name was NULL for section %zu.",
+                      __FUNCTION__, i);
                 return NOT_ENOUGH_DATA;
             }
             desc->mSections.add(sectionName);
         }
     }
 
-    LOG_ALWAYS_FATAL_IF(tagCount != allTags.size(), "tagCount must be the same as allTags size");
+    LOG_ALWAYS_FATAL_IF(static_cast<size_t>(tagCount) != allTags.size(),
+                        "tagCount must be the same as allTags size");
     // Set up reverse mapping
     for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
         uint32_t tag = allTags[i];
@@ -349,18 +351,18 @@
 
     size_t size = mTagToNameMap.size();
     if (size == 0) {
-        fdprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
+        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
                 indentation, "");
         return;
     }
 
-    fdprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
+    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
             indentation, "", size);
     for (size_t i = 0; i < size; ++i) {
         uint32_t tag =  mTagToNameMap.keyAt(i);
 
         if (verbosity < 1) {
-            fdprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
+            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
             continue;
         }
         String8 name = mTagToNameMap.valueAt(i);
@@ -369,7 +371,7 @@
         int type = mTagToTypeMap.valueFor(tag);
         const char* typeName = (type >= 0 && type < NUM_TYPES) ?
                 camera_metadata_type_names[type] : "UNKNOWN";
-        fdprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
+        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
             "", tag, name.string(), type, typeName, sectionName.string());
     }
 
@@ -409,7 +411,7 @@
 
 extern "C" {
 
-int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v) {
+int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
     Mutex::Autolock al(sLock);
     if (sGlobalVendorTagDescriptor == NULL) {
         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
@@ -418,7 +420,7 @@
     return sGlobalVendorTagDescriptor->getTagCount();
 }
 
-void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray) {
+void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
     Mutex::Autolock al(sLock);
     if (sGlobalVendorTagDescriptor == NULL) {
         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
@@ -427,7 +429,7 @@
     sGlobalVendorTagDescriptor->getTagArray(tagArray);
 }
 
-const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag) {
+const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
     Mutex::Autolock al(sLock);
     if (sGlobalVendorTagDescriptor == NULL) {
         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
@@ -436,7 +438,7 @@
     return sGlobalVendorTagDescriptor->getSectionName(tag);
 }
 
-const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag) {
+const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
     Mutex::Autolock al(sLock);
     if (sGlobalVendorTagDescriptor == NULL) {
         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
@@ -445,7 +447,7 @@
     return sGlobalVendorTagDescriptor->getTagName(tag);
 }
 
-int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag) {
+int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
     Mutex::Autolock al(sLock);
     if (sGlobalVendorTagDescriptor == NULL) {
         ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
index 49c4f9b..33f9d3b 100644
--- a/drm/libdrmframework/Android.mk
+++ b/drm/libdrmframework/Android.mk
@@ -19,12 +19,14 @@
 
 LOCAL_SRC_FILES:= \
     DrmManagerClientImpl.cpp \
-    DrmManagerClient.cpp
+    DrmManagerClient.cpp \
+    NoOpDrmManagerClientImpl.cpp
 
 LOCAL_MODULE:= libdrmframework
 
 LOCAL_SHARED_LIBRARIES := \
     libutils \
+    libcutils \
     liblog \
     libbinder \
     libdl
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index ea30d01..440dd91 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -29,7 +29,7 @@
 }
 
 DrmManagerClient::~DrmManagerClient() {
-    DrmManagerClientImpl::remove(mUniqueId);
+    mDrmManagerClientImpl->remove(mUniqueId);
     mDrmManagerClientImpl->removeClient(mUniqueId);
     mDrmManagerClientImpl->setOnInfoListener(mUniqueId, NULL);
 }
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index ffefd74..2d2c90e 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -21,8 +21,10 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <binder/IServiceManager.h>
+#include <cutils/properties.h>
 
 #include "DrmManagerClientImpl.h"
+#include "NoOpDrmManagerClientImpl.h"
 
 using namespace android;
 
@@ -35,9 +37,12 @@
 
 DrmManagerClientImpl* DrmManagerClientImpl::create(
         int* pUniqueId, bool isNative) {
-    *pUniqueId = getDrmManagerService()->addUniqueId(isNative);
-
-    return new DrmManagerClientImpl();
+    sp<IDrmManagerService> service = getDrmManagerService();
+    if (service != NULL) {
+        *pUniqueId = getDrmManagerService()->addUniqueId(isNative);
+        return new DrmManagerClientImpl();
+    }
+    return new NoOpDrmManagerClientImpl();
 }
 
 void DrmManagerClientImpl::remove(int uniqueId) {
@@ -47,6 +52,12 @@
 const sp<IDrmManagerService>& DrmManagerClientImpl::getDrmManagerService() {
     Mutex::Autolock lock(sMutex);
     if (NULL == sDrmManagerService.get()) {
+        char value[PROPERTY_VALUE_MAX];
+        if (property_get("drm.service.enabled", value, NULL) == 0) {
+            // Drm is undefined for this device
+            return sDrmManagerService;
+        }
+
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
         do {
diff --git a/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp b/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp
new file mode 100644
index 0000000..dab583d
--- /dev/null
+++ b/drm/libdrmframework/NoOpDrmManagerClientImpl.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 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 "NoOpDrmManagerClientImpl.h"
+
+namespace android {
+
+void NoOpDrmManagerClientImpl::remove(int uniqueId) {
+}
+
+void NoOpDrmManagerClientImpl::addClient(int uniqueId) {
+}
+
+void NoOpDrmManagerClientImpl::removeClient(int uniqueId) {
+}
+
+status_t NoOpDrmManagerClientImpl::setOnInfoListener(
+            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+    return UNKNOWN_ERROR;
+}
+
+DrmConstraints* NoOpDrmManagerClientImpl::getConstraints(int uniqueId, const String8* path, const int action) {
+    return NULL;
+}
+
+DrmMetadata* NoOpDrmManagerClientImpl::getMetadata(int uniqueId, const String8* path) {
+    return NULL;
+}
+
+bool NoOpDrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+    return false;
+}
+
+DrmInfoStatus* NoOpDrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    return NULL;
+}
+
+DrmInfo* NoOpDrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    return NULL;
+}
+
+status_t NoOpDrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    return UNKNOWN_ERROR;
+}
+
+String8 NoOpDrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
+    return String8();
+}
+
+int NoOpDrmManagerClientImpl::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
+    return -1;
+}
+
+int NoOpDrmManagerClientImpl::checkRightsStatus(int uniqueId, const String8& path, int action) {
+    return -1;
+}
+
+status_t NoOpDrmManagerClientImpl::consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve) {
+    return UNKNOWN_ERROR;
+}
+
+status_t NoOpDrmManagerClientImpl::setPlaybackStatus(
+            int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position) {
+    return UNKNOWN_ERROR;
+}
+
+bool NoOpDrmManagerClientImpl::validateAction(
+        int uniqueId, const String8& path, int action, const ActionDescription& description) {
+    return false;
+}
+
+status_t NoOpDrmManagerClientImpl::removeRights(int uniqueId, const String8& path) {
+    return UNKNOWN_ERROR;
+}
+
+status_t NoOpDrmManagerClientImpl::removeAllRights(int uniqueId) {
+    return UNKNOWN_ERROR;
+}
+
+int NoOpDrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+    return -1;
+}
+
+DrmConvertedStatus* NoOpDrmManagerClientImpl::convertData(int uniqueId, int convertId, const DrmBuffer* inputData) {
+    return NULL;
+}
+
+DrmConvertedStatus* NoOpDrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+    return NULL;
+}
+
+status_t NoOpDrmManagerClientImpl::getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+    return UNKNOWN_ERROR;
+}
+
+sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(
+            int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
+    return NULL;
+}
+
+sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(
+            int uniqueId, const char* uri, const char* mime) {
+    return NULL;
+}
+
+sp<DecryptHandle> NoOpDrmManagerClientImpl::openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType) {
+    return NULL;
+}
+
+status_t NoOpDrmManagerClientImpl::closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle) {
+    return UNKNOWN_ERROR;
+}
+
+status_t NoOpDrmManagerClientImpl::initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    return UNKNOWN_ERROR;
+}
+
+status_t NoOpDrmManagerClientImpl::decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+    return UNKNOWN_ERROR;
+}
+
+status_t NoOpDrmManagerClientImpl::finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
+    return UNKNOWN_ERROR;
+}
+
+ssize_t NoOpDrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
+            void* buffer, ssize_t numBytes, off64_t offset) {
+    return -1;
+}
+
+status_t NoOpDrmManagerClientImpl::notify(const DrmInfoEvent& event) {
+    return UNKNOWN_ERROR;
+}
+
+}
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 3400cb1..3858675 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -34,30 +34,30 @@
  *
  */
 class DrmManagerClientImpl : public BnDrmServiceListener {
-private:
+protected:
     DrmManagerClientImpl() { }
 
 public:
     static DrmManagerClientImpl* create(int* pUniqueId, bool isNative);
 
-    static void remove(int uniqueId);
-
     virtual ~DrmManagerClientImpl() { }
 
 public:
+    virtual void remove(int uniqueId);
+
     /**
      * Adds the client respective to given unique id.
      *
      * @param[in] uniqueId Unique identifier for a session
      */
-    void addClient(int uniqueId);
+    virtual void addClient(int uniqueId);
 
     /**
      * Removes the client respective to given unique id.
      *
      * @param[in] uniqueId Unique identifier for a session
      */
-    void removeClient(int uniqueId);
+    virtual void removeClient(int uniqueId);
 
     /**
      * Register a callback to be invoked when the caller required to
@@ -68,7 +68,7 @@
      * @return status_t
      *            Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t setOnInfoListener(
+    virtual status_t setOnInfoListener(
             int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener);
 
     /**
@@ -83,7 +83,7 @@
      * @note
      *     In case of error, return NULL
      */
-    DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
+    virtual DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
 
     /**
      * Get metadata information associated with input content.
@@ -95,7 +95,7 @@
      * @note
      *    In case of error, return NULL
      */
-    DrmMetadata* getMetadata(int uniqueId, const String8* path);
+    virtual DrmMetadata* getMetadata(int uniqueId, const String8* path);
 
     /**
      * Check whether the given mimetype or path can be handled
@@ -106,7 +106,7 @@
      * @return
      *     True if DrmManager can handle given path or mime type.
      */
-    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+    virtual bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
 
     /**
      * Executes given drm information based on its type
@@ -116,7 +116,7 @@
      * @return DrmInfoStatus
      *     instance as a result of processing given input
      */
-    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+    virtual DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
 
     /**
      * Retrieves necessary information for registration, unregistration or rights
@@ -127,7 +127,7 @@
      * @return DrmInfo
      *     instance as a result of processing given input
      */
-    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+    virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
 
     /**
      * Save DRM rights to specified rights path
@@ -140,7 +140,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t saveRights(int uniqueId, const DrmRights& drmRights,
+    virtual status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     /**
@@ -152,7 +152,7 @@
      * @return String8
      *     Returns mime-type of the original content, such as "video/mpeg"
      */
-    String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
+    virtual String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
 
     /**
      * Retrieves the type of the protected object (content, rights, etc..)
@@ -165,7 +165,7 @@
      * @return type of the DRM content,
      *     such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT
      */
-    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+    virtual int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
 
     /**
      * Check whether the given content has valid rights or not
@@ -176,7 +176,7 @@
      * @return the status of the rights for the protected content,
      *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
      */
-    int checkRightsStatus(int uniqueId, const String8& path, int action);
+    virtual int checkRightsStatus(int uniqueId, const String8& path, int action);
 
     /**
      * Consumes the rights for a content.
@@ -190,7 +190,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
+    virtual status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
 
     /**
      * Informs the DRM engine about the playback actions performed on the DRM files.
@@ -203,7 +203,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t setPlaybackStatus(
+    virtual status_t setPlaybackStatus(
             int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
 
     /**
@@ -215,7 +215,7 @@
      * @param[in] description Detailed description of the action
      * @return true if the action is allowed.
      */
-    bool validateAction(
+    virtual bool validateAction(
         int uniqueId, const String8& path, int action, const ActionDescription& description);
 
     /**
@@ -226,7 +226,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t removeRights(int uniqueId, const String8& path);
+    virtual status_t removeRights(int uniqueId, const String8& path);
 
     /**
      * Removes all the rights information of each plug-in associated with
@@ -236,7 +236,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t removeAllRights(int uniqueId);
+    virtual status_t removeAllRights(int uniqueId);
 
     /**
      * This API is for Forward Lock based DRM scheme.
@@ -248,7 +248,7 @@
      * @param[in] mimeType Description/MIME type of the input data packet
      * @return Return handle for the convert session
      */
-    int openConvertSession(int uniqueId, const String8& mimeType);
+    virtual int openConvertSession(int uniqueId, const String8& mimeType);
 
     /**
      * Accepts and converts the input data which is part of DRM file.
@@ -263,7 +263,7 @@
      *     the output converted data and offset. In this case the
      *     application will ignore the offset information.
      */
-    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+    virtual DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
 
     /**
      * Informs the Drm Agent when there is no more data which need to be converted
@@ -279,7 +279,7 @@
      *     the application on which offset these signature data
      *     should be appended.
      */
-    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+    virtual DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
 
     /**
      * Retrieves all DrmSupportInfo instance that native DRM framework can handle.
@@ -292,7 +292,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+    virtual status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
 
     /**
      * Open the decrypt session to decrypt the given protected content
@@ -305,7 +305,7 @@
      * @return
      *     Handle for the decryption session
      */
-    sp<DecryptHandle> openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
             int uniqueId, int fd, off64_t offset, off64_t length, const char* mime);
 
     /**
@@ -317,7 +317,7 @@
      * @return
      *     Handle for the decryption session
      */
-    sp<DecryptHandle> openDecryptSession(
+    virtual sp<DecryptHandle> openDecryptSession(
             int uniqueId, const char* uri, const char* mime);
 
     /**
@@ -329,7 +329,7 @@
      * @return
      *     Handle for the decryption session
      */
-    sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
+    virtual sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
             const String8& mimeType);
 
     /**
@@ -340,7 +340,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
+    virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -352,7 +352,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
+    virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
     /**
@@ -372,7 +372,7 @@
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+    virtual status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
     /**
@@ -384,7 +384,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
+    virtual status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -397,7 +397,7 @@
      *
      * @return Number of bytes read. Returns -1 for Failure.
      */
-    ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
+    virtual ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
     /**
@@ -407,7 +407,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t notify(const DrmInfoEvent& event);
+    virtual status_t notify(const DrmInfoEvent& event);
 
 private:
     Mutex mLock;
diff --git a/drm/libdrmframework/include/NoOpDrmManagerClientImpl.h b/drm/libdrmframework/include/NoOpDrmManagerClientImpl.h
new file mode 100644
index 0000000..e8e8f42
--- /dev/null
+++ b/drm/libdrmframework/include/NoOpDrmManagerClientImpl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 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 __NO_OP_DRM_MANAGER_CLIENT_IMPL_H__
+#define __NO_OP_DRM_MANAGER_CLIENT_IMPL_H__
+
+#include "DrmManagerClientImpl.h"
+
+namespace android {
+
+class NoOpDrmManagerClientImpl : public DrmManagerClientImpl {
+public:
+    NoOpDrmManagerClientImpl() { }
+
+    void remove(int uniqueId);
+    void addClient(int uniqueId);
+    void removeClient(int uniqueId);
+    status_t setOnInfoListener(
+            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener);
+    DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
+
+    DrmMetadata* getMetadata(int uniqueId, const String8* path);
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+    String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+    int checkRightsStatus(int uniqueId, const String8& path, int action);
+    status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
+    status_t setPlaybackStatus(
+            int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
+    bool validateAction(
+        int uniqueId, const String8& path, int action, const ActionDescription& description);
+    status_t removeRights(int uniqueId, const String8& path);
+    status_t removeAllRights(int uniqueId);
+    int openConvertSession(int uniqueId, const String8& mimeType);
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+    sp<DecryptHandle> openDecryptSession(
+            int uniqueId, int fd, off64_t offset, off64_t length, const char* mime);
+    sp<DecryptHandle> openDecryptSession(
+            int uniqueId, const char* uri, const char* mime);
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
+    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+    status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
+    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
+    ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
+            void* buffer, ssize_t numBytes, off64_t offset);
+    status_t notify(const DrmInfoEvent& event);
+};
+
+}
+
+#endif // __NO_OP_DRM_MANAGER_CLIENT_IMPL_H
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 9fc962c..d202fbc 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -33,7 +33,8 @@
     CAMCORDER_QUALITY_720P = 5,
     CAMCORDER_QUALITY_1080P = 6,
     CAMCORDER_QUALITY_QVGA = 7,
-    CAMCORDER_QUALITY_LIST_END = 7,
+    CAMCORDER_QUALITY_2160P = 8,
+    CAMCORDER_QUALITY_LIST_END = 8,
 
     CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
@@ -44,7 +45,8 @@
     CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
     CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
     CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
-    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1007,
+    CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
+    CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
 };
 
 /**
diff --git a/include/soundtrigger/ISoundTrigger.h b/include/soundtrigger/ISoundTrigger.h
new file mode 100644
index 0000000..5fd8eb2
--- /dev/null
+++ b/include/soundtrigger/ISoundTrigger.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 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_ISOUNDTRIGGER_H
+#define ANDROID_HARDWARE_ISOUNDTRIGGER_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <system/sound_trigger.h>
+
+namespace android {
+
+class ISoundTrigger : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SoundTrigger);
+
+    virtual void detach() = 0;
+
+    virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
+                                    sound_model_handle_t *handle) = 0;
+
+    virtual status_t unloadSoundModel(sound_model_handle_t handle) = 0;
+
+    virtual status_t startRecognition(sound_model_handle_t handle,
+                                      const sp<IMemory>& dataMemory) = 0;
+    virtual status_t stopRecognition(sound_model_handle_t handle) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSoundTrigger: public BnInterface<ISoundTrigger>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_H
diff --git a/include/soundtrigger/ISoundTriggerClient.h b/include/soundtrigger/ISoundTriggerClient.h
new file mode 100644
index 0000000..7f86d02
--- /dev/null
+++ b/include/soundtrigger/ISoundTriggerClient.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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_ISOUNDTRIGGER_CLIENT_H
+#define ANDROID_HARDWARE_ISOUNDTRIGGER_CLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class ISoundTriggerClient : public IInterface
+{
+public:
+
+    DECLARE_META_INTERFACE(SoundTriggerClient);
+
+    virtual void onRecognitionEvent(const sp<IMemory>& eventMemory) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSoundTriggerClient : public BnInterface<ISoundTriggerClient>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_CLIENT_H
diff --git a/include/soundtrigger/ISoundTriggerHwService.h b/include/soundtrigger/ISoundTriggerHwService.h
new file mode 100644
index 0000000..05a764a
--- /dev/null
+++ b/include/soundtrigger/ISoundTriggerHwService.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 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_ISOUNDTRIGGER_SERVICE_H
+#define ANDROID_HARDWARE_ISOUNDTRIGGER_SERVICE_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <system/sound_trigger.h>
+
+namespace android {
+
+class ISoundTrigger;
+class ISoundTriggerClient;
+
+class ISoundTriggerHwService : public IInterface
+{
+public:
+
+    DECLARE_META_INTERFACE(SoundTriggerHwService);
+
+    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+                                 uint32_t *numModules) = 0;
+
+    virtual status_t attach(const sound_trigger_module_handle_t handle,
+                                      const sp<ISoundTriggerClient>& client,
+                                      sp<ISoundTrigger>& module) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSoundTriggerHwService: public BnInterface<ISoundTriggerHwService>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_SERVICE_H
diff --git a/include/soundtrigger/SoundTrigger.h b/include/soundtrigger/SoundTrigger.h
new file mode 100644
index 0000000..1f7f286
--- /dev/null
+++ b/include/soundtrigger/SoundTrigger.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 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_SOUNDTRIGGER_H
+#define ANDROID_HARDWARE_SOUNDTRIGGER_H
+
+#include <binder/IBinder.h>
+#include <soundtrigger/SoundTriggerCallback.h>
+#include <soundtrigger/ISoundTrigger.h>
+#include <soundtrigger/ISoundTriggerHwService.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+#include <system/sound_trigger.h>
+
+namespace android {
+
+class MemoryDealer;
+
+class SoundTrigger : public BnSoundTriggerClient,
+                        public IBinder::DeathRecipient
+{
+public:
+    static  status_t listModules(struct sound_trigger_module_descriptor *modules,
+                                 uint32_t *numModules);
+    static  sp<SoundTrigger> attach(const sound_trigger_module_handle_t module,
+                                       const sp<SoundTriggerCallback>& callback);
+
+            virtual ~SoundTrigger();
+
+            void detach();
+
+            status_t loadSoundModel(const sp<IMemory>& modelMemory,
+                                            sound_model_handle_t *handle);
+
+            status_t unloadSoundModel(sound_model_handle_t handle);
+
+            status_t startRecognition(sound_model_handle_t handle, const sp<IMemory>& dataMemory);
+            status_t stopRecognition(sound_model_handle_t handle);
+
+            // BpSoundTriggerClient
+            virtual void onRecognitionEvent(const sp<IMemory>& eventMemory);
+
+            //IBinder::DeathRecipient
+            virtual void binderDied(const wp<IBinder>& who);
+
+            static status_t stringToGuid(const char *str, sound_trigger_uuid_t *guid);
+            static status_t guidToString(const sound_trigger_uuid_t *guid,
+                                         char *str, size_t maxLen);
+
+private:
+            SoundTrigger(sound_trigger_module_handle_t module,
+                            const sp<SoundTriggerCallback>&);
+            static const sp<ISoundTriggerHwService>& getSoundTriggerHwService();
+
+            Mutex                               mLock;
+            sp<ISoundTrigger>                   mISoundTrigger;
+            const sound_trigger_module_handle_t mModule;
+            sp<SoundTriggerCallback>            mCallback;
+};
+
+}; // namespace android
+
+#endif //ANDROID_HARDWARE_SOUNDTRIGGER_H
diff --git a/include/soundtrigger/SoundTriggerCallback.h b/include/soundtrigger/SoundTriggerCallback.h
new file mode 100644
index 0000000..8a5ba02
--- /dev/null
+++ b/include/soundtrigger/SoundTriggerCallback.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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_SOUNDTRIGGER_CALLBACK_H
+#define ANDROID_HARDWARE_SOUNDTRIGGER_CALLBACK_H
+
+#include <utils/RefBase.h>
+#include <system/sound_trigger.h>
+
+namespace android {
+
+class SoundTriggerCallback : public RefBase
+{
+public:
+
+            SoundTriggerCallback() {}
+    virtual ~SoundTriggerCallback() {}
+
+    virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event) = 0;
+
+    virtual void onServiceDied() = 0;
+
+};
+
+}; // namespace android
+
+#endif //ANDROID_HARDWARE_SOUNDTRIGGER_CALLBACK_H
diff --git a/media/libcpustats/Android.mk b/media/libcpustats/Android.mk
index b506353..ee283a6 100644
--- a/media/libcpustats/Android.mk
+++ b/media/libcpustats/Android.mk
@@ -1,4 +1,4 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
@@ -8,4 +8,6 @@
 
 LOCAL_MODULE := libcpustats
 
+LOCAL_CFLAGS := -std=gnu++11 -Werror
+
 include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libcpustats/ThreadCpuUsage.cpp b/media/libcpustats/ThreadCpuUsage.cpp
index 637402a..cfdcb51 100644
--- a/media/libcpustats/ThreadCpuUsage.cpp
+++ b/media/libcpustats/ThreadCpuUsage.cpp
@@ -21,7 +21,6 @@
 #include <stdlib.h>
 #include <time.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 
 #include <cpustats/ThreadCpuUsage.h>
@@ -218,7 +217,7 @@
 #define FREQ_SIZE 64
             char freq_path[FREQ_SIZE];
 #define FREQ_DIGIT 27
-            COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
+            static_assert(MAX_CPU <= 10, "MAX_CPU too large");
 #define FREQ_PATH "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq"
             strlcpy(freq_path, FREQ_PATH, sizeof(freq_path));
             freq_path[FREQ_DIGIT] = cpuNum + '0';
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 98b183a..0d5f990 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -131,7 +131,7 @@
         data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
         if (secure) {
-            data.writeIntPtr((intptr_t)dstPtr);
+            data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
         }
 
         remote()->transact(DECRYPT, data, &reply);
@@ -249,7 +249,7 @@
 
             void *dstPtr;
             if (secure) {
-                dstPtr = (void *)data.readIntPtr();
+                dstPtr = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
             } else {
                 dstPtr = malloc(totalSize);
             }
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 1074da9..28238c4 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -69,6 +69,7 @@
     {"480p", CAMCORDER_QUALITY_480P},
     {"720p", CAMCORDER_QUALITY_720P},
     {"1080p", CAMCORDER_QUALITY_1080P},
+    {"2160p", CAMCORDER_QUALITY_2160P},
     {"qvga", CAMCORDER_QUALITY_QVGA},
 
     {"timelapselow",  CAMCORDER_QUALITY_TIME_LAPSE_LOW},
@@ -78,6 +79,7 @@
     {"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P},
     {"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P},
     {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P},
+    {"timelapse2160p", CAMCORDER_QUALITY_TIME_LAPSE_2160P},
     {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA},
 };
 
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index caf2dfc..48d44c1 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -26,6 +26,7 @@
 LOCAL_SHARED_LIBRARIES :=       \
     libbinder                   \
     libcamera_client            \
+    libcrypto                   \
     libcutils                   \
     liblog                      \
     libdl                       \
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index a9820e0..194abbb 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -95,7 +95,8 @@
 status_t MediaRecorderClient::setVideoSource(int vs)
 {
     ALOGV("setVideoSource(%d)", vs);
-    if (!checkPermission(cameraPermission)) {
+    // Check camera permission for sources other than SURFACE
+    if (vs != VIDEO_SOURCE_SURFACE && !checkPermission(cameraPermission)) {
         return PERMISSION_DENIED;
     }
     Mutex::Autolock lock(mLock);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 5b7a236..bfc075c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -932,6 +932,10 @@
             MediaCodecSource::Create(mLooper, format, audioSource);
     mAudioSourceNode = audioSource;
 
+    if (audioEncoder == NULL) {
+        ALOGE("Failed to create audio encoder");
+    }
+
     return audioEncoder;
 }
 
@@ -1487,7 +1491,7 @@
     sp<MediaCodecSource> encoder =
             MediaCodecSource::Create(mLooper, format, cameraSource, flags);
     if (encoder == NULL) {
-        ALOGW("Failed to create the encoder");
+        ALOGE("Failed to create video encoder");
         // When the encoder fails to be created, we need
         // release the camera source due to the camera's lock
         // and unlock mechanism.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d8d939a..857e703 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1376,16 +1376,15 @@
 
             sp<NuPlayerDriver> driver = mDriver.promote();
             if (driver != NULL) {
+                // notify duration first, so that it's definitely set when
+                // the app received the "prepare complete" callback.
+                int64_t durationUs;
+                if (mSource->getDuration(&durationUs) == OK) {
+                    driver->notifyDuration(durationUs);
+                }
                 driver->notifyPrepareCompleted(err);
             }
 
-            int64_t durationUs;
-            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
-                sp<NuPlayerDriver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    driver->notifyDuration(durationUs);
-                }
-            }
             break;
         }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index e4850f0..280b5af 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -284,6 +284,10 @@
         case STATE_PREPARED:
         {
             mStartupSeekTimeUs = seekTimeUs;
+            // pretend that the seek completed. It will actually happen when starting playback.
+            // TODO: actually perform the seek here, so the player is ready to go at the new
+            // location
+            notifySeekComplete();
             break;
         }
 
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index 4d9a1fa..4d14904 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -438,7 +438,7 @@
 void NBLog::Reader::dumpLine(const String8& timestamp, String8& body)
 {
     if (mFd >= 0) {
-        fdprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
+        dprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
     } else {
         ALOGI("%.*s%s %s", mIndent, "", timestamp.string(), body.string());
     }
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index aabe0ec..297f4fc 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -2510,8 +2510,9 @@
         }
     }
 
-    if (!track->sampleTable->isValid()) {
+    if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
         // Make sure we have all the metadata we need.
+        ALOGE("stbl atom missing/invalid.");
         return ERROR_MALFORMED;
     }
 
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/MediaBuffer.cpp
index 11b80bf..8af0880 100644
--- a/media/libstagefright/MediaBuffer.cpp
+++ b/media/libstagefright/MediaBuffer.cpp
@@ -27,7 +27,6 @@
 #include <media/stagefright/MetaData.h>
 
 #include <ui/GraphicBuffer.h>
-#include <sys/atomics.h>
 
 namespace android {
 
@@ -92,7 +91,7 @@
         return;
     }
 
-    int prevCount = __atomic_dec(&mRefCount);
+    int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
     if (prevCount == 1) {
         if (mObserver == NULL) {
             delete this;
@@ -112,7 +111,7 @@
 }
 
 void MediaBuffer::add_ref() {
-    (void) __atomic_inc(&mRefCount);
+    (void) __sync_fetch_and_add(&mRefCount, 1);
 }
 
 void *MediaBuffer::data() const {
diff --git a/media/libstagefright/codecs/aacdec/Android.mk b/media/libstagefright/codecs/aacdec/Android.mk
index 49ff238..afb00aa 100644
--- a/media/libstagefright/codecs/aacdec/Android.mk
+++ b/media/libstagefright/codecs/aacdec/Android.mk
@@ -3,7 +3,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-      SoftAAC2.cpp
+      SoftAAC2.cpp \
+      DrcPresModeWrap.cpp
 
 LOCAL_C_INCLUDES := \
       frameworks/av/media/libstagefright/include \
diff --git a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
new file mode 100644
index 0000000..129ad65
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2014 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 "DrcPresModeWrap.h"
+
+#include <assert.h>
+
+#define LOG_TAG "SoftAAC2_DrcWrapper"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+//#define DRC_PRES_MODE_WRAP_DEBUG
+
+#define GPM_ENCODER_TARGET_LEVEL 64
+#define MAX_TARGET_LEVEL 64
+
+CDrcPresModeWrapper::CDrcPresModeWrapper()
+{
+    mDataUpdate = true;
+
+    /* Data from streamInfo. */
+    /* Initialized to the same values as in the aac decoder */
+    mStreamPRL = -1;
+    mStreamDRCPresMode = -1;
+    mStreamNrAACChan = 0;
+    mStreamNrOutChan = 0;
+
+    /* Desired values (set by user). */
+    /* Initialized to the same values as in the aac decoder */
+    mDesTarget = -1;
+    mDesAttFactor = 0;
+    mDesBoostFactor = 0;
+    mDesHeavy = 0;
+
+    mEncoderTarget = -1;
+
+    /* Values from last time. */
+    /* Initialized to the same values as the desired values */
+    mLastTarget = -1;
+    mLastAttFactor = 0;
+    mLastBoostFactor = 0;
+    mLastHeavy = 0;
+}
+
+CDrcPresModeWrapper::~CDrcPresModeWrapper()
+{
+}
+
+void
+CDrcPresModeWrapper::setDecoderHandle(const HANDLE_AACDECODER handle)
+{
+    mHandleDecoder = handle;
+}
+
+void
+CDrcPresModeWrapper::submitStreamData(CStreamInfo* pStreamInfo)
+{
+    assert(pStreamInfo);
+
+    if (mStreamPRL != pStreamInfo->drcProgRefLev) {
+        mStreamPRL = pStreamInfo->drcProgRefLev;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: drcProgRefLev is %d\n", mStreamPRL);
+#endif
+    }
+
+    if (mStreamDRCPresMode != pStreamInfo->drcPresMode) {
+        mStreamDRCPresMode = pStreamInfo->drcPresMode;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: drcPresMode is %d\n", mStreamDRCPresMode);
+#endif
+    }
+
+    if (mStreamNrAACChan != pStreamInfo->aacNumChannels) {
+        mStreamNrAACChan = pStreamInfo->aacNumChannels;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: aacNumChannels is %d\n", mStreamNrAACChan);
+#endif
+    }
+
+    if (mStreamNrOutChan != pStreamInfo->numChannels) {
+        mStreamNrOutChan = pStreamInfo->numChannels;
+        mDataUpdate = true;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC presentation mode wrapper: numChannels is %d\n", mStreamNrOutChan);
+#endif
+    }
+
+
+
+    if (mStreamNrOutChan<mStreamNrAACChan) {
+        mIsDownmix = true;
+    } else {
+        mIsDownmix = false;
+    }
+
+    if (mIsDownmix && (mStreamNrOutChan == 1)) {
+        mIsMonoDownmix = true;
+    } else {
+        mIsMonoDownmix = false;
+    }
+
+    if (mIsDownmix && mStreamNrOutChan == 2){
+        mIsStereoDownmix = true;
+    } else {
+        mIsStereoDownmix = false;
+    }
+
+}
+
+void
+CDrcPresModeWrapper::setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value)
+{
+    switch (param) {
+    case DRC_PRES_MODE_WRAP_DESIRED_TARGET:
+        mDesTarget = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR:
+        mDesAttFactor = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR:
+        mDesBoostFactor = value;
+        break;
+    case DRC_PRES_MODE_WRAP_DESIRED_HEAVY:
+        mDesHeavy = value;
+        break;
+    case DRC_PRES_MODE_WRAP_ENCODER_TARGET:
+        mEncoderTarget = value;
+        break;
+    default:
+        break;
+    }
+    mDataUpdate = true;
+}
+
+void
+CDrcPresModeWrapper::update()
+{
+    // Get Data from Decoder
+    int progRefLevel = mStreamPRL;
+    int drcPresMode = mStreamDRCPresMode;
+
+    // by default, do as desired
+    int newTarget         = mDesTarget;
+    int newAttFactor      = mDesAttFactor;
+    int newBoostFactor    = mDesBoostFactor;
+    int newHeavy          = mDesHeavy;
+
+    if (mDataUpdate) {
+        // sanity check
+        if (mDesTarget < MAX_TARGET_LEVEL){
+            mDesTarget = MAX_TARGET_LEVEL;  // limit target level to -16 dB or below
+            newTarget = MAX_TARGET_LEVEL;
+        }
+
+        if (mEncoderTarget != -1) {
+            if (mDesTarget<124) { // if target level > -31 dB
+                if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
+                    // no stereo or mono downmixing, calculated scaling of light DRC
+                    /* use as little compression as possible */
+                    newAttFactor = 0;
+                    newBoostFactor = 0;
+                    if (mDesTarget<progRefLevel) { // if target level > PRL
+                        if (mEncoderTarget < mDesTarget) { // if mEncoderTarget > target level
+                            // mEncoderTarget > target level > PRL
+                            int calcFactor;
+                            float calcFactor_norm;
+                            // 0.0f < calcFactor_norm < 1.0f
+                            calcFactor_norm = (float)(mDesTarget - progRefLevel) /
+                                    (float)(mEncoderTarget - progRefLevel);
+                            calcFactor = (int)(calcFactor_norm*127.0f); // 0 <= calcFactor < 127
+                            // calcFactor is the lower limit
+                            newAttFactor = (calcFactor>newAttFactor) ? calcFactor : newAttFactor;
+                            // new AttFactor will be always = calcFactor, as it is set to 0 before.
+                            newBoostFactor = newAttFactor;
+                        } else {
+                            /* target level > mEncoderTarget > PRL */
+                            // newTDLimiterEnable = 1;
+                            // the time domain limiter must always be active in this case.
+                            //     It is assumed that the framework activates it by default
+                            newAttFactor = 127;
+                            newBoostFactor = 127;
+                        }
+                    } else { // target level <= PRL
+                        // no restrictions required
+                        // newAttFactor = newAttFactor;
+                    }
+                } else { // downmixing
+                    // if target level > -23 dB or mono downmix
+                    if ( (mDesTarget<92) || mIsMonoDownmix ) {
+                        newHeavy = 1;
+                    } else {
+                        // we perform a downmix, so, we need at least full light DRC
+                        newAttFactor = 127;
+                    }
+                }
+            } else { // target level <= -31 dB
+                // playback -31 dB: light DRC only needed if we perform downmixing
+                if (mIsDownmix) {   // we do downmixing
+                    newAttFactor = 127;
+                }
+            }
+        }
+        else { // handle other used encoder target levels
+
+            // Sanity check: DRC presentation mode is only specified for max. 5.1 channels
+            if (mStreamNrAACChan > 6) {
+                drcPresMode = 0;
+            }
+
+            switch (drcPresMode) {
+            case 0:
+            default: // presentation mode not indicated
+            {
+
+                if (mDesTarget<124) { // if target level > -31 dB
+                    // no stereo or mono downmixing
+                    if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
+                        if (mDesTarget<progRefLevel) { // if target level > PRL
+                            // newTDLimiterEnable = 1;
+                            // the time domain limiter must always be active in this case.
+                            //    It is assumed that the framework activates it by default
+                            newAttFactor = 127; // at least, use light compression
+                        } else { // target level <= PRL
+                            // no restrictions required
+                            // newAttFactor = newAttFactor;
+                        }
+                    } else { // downmixing
+                        // newTDLimiterEnable = 1;
+                        // the time domain limiter must always be active in this case.
+                        //    It is assumed that the framework activates it by default
+
+                        // if target level > -23 dB or mono downmix
+                        if ( (mDesTarget < 92) || mIsMonoDownmix ) {
+                            newHeavy = 1;
+                        } else{
+                            // we perform a downmix, so, we need at least full light DRC
+                            newAttFactor = 127;
+                        }
+                    }
+                } else { // target level <= -31 dB
+                    if (mIsDownmix) {   // we do downmixing.
+                        // newTDLimiterEnable = 1;
+                        // the time domain limiter must always be active in this case.
+                        //    It is assumed that the framework activates it by default
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            // Presentation mode 1 and 2 according to ETSI TS 101 154:
+            // Digital Video Broadcasting (DVB); Specification for the use of Video and Audio Coding
+            // in Broadcasting Applications based on the MPEG-2 Transport Stream,
+            // section C.5.4., "Decoding", and Table C.33
+            // ISO DRC            -> newHeavy = 0  (Use light compression, MPEG-style)
+            // Compression_value  -> newHeavy = 1  (Use heavy compression, DVB-style)
+            // scaling restricted -> newAttFactor = 127
+
+            case 1: // presentation mode 1, Light:-31/Heavy:-23
+            {
+                if (mDesTarget < 124) { // if target level > -31 dB
+                    // playback up to -23 dB
+                    newHeavy = 1;
+                } else { // target level <= -31 dB
+                    // playback -31 dB
+                    if (mIsDownmix) {   // we do downmixing.
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            case 2: // presentation mode 2, Light:-23/Heavy:-23
+            {
+                if (mDesTarget < 124) { // if target level > -31 dB
+                    // playback up to -23 dB
+                    if (mIsMonoDownmix) { // if mono downmix
+                        newHeavy = 1;
+                    } else {
+                        newHeavy = 0;
+                        newAttFactor = 127;
+                    }
+                } else { // target level <= -31 dB
+                    // playback -31 dB
+                    newHeavy = 0;
+                    if (mIsDownmix) {   // we do downmixing.
+                        newAttFactor = 127;
+                    }
+                }
+            }
+            break;
+
+            } // switch()
+        } // if (mEncoderTarget  == GPM_ENCODER_TARGET_LEVEL)
+
+        // sanity again
+        if (newHeavy == 1) {
+            newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
+            newAttFactor = 127;
+        }
+
+        // update the decoder
+        if (newTarget != mLastTarget) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_REFERENCE_LEVEL, newTarget);
+            mLastTarget = newTarget;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newTarget != mDesTarget)
+                ALOGV("DRC presentation mode wrapper: forced target level to %d (from %d)\n", newTarget, mDesTarget);
+            else
+                ALOGV("DRC presentation mode wrapper: set target level to %d\n", newTarget);
+#endif
+        }
+
+        if (newAttFactor != mLastAttFactor) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_ATTENUATION_FACTOR, newAttFactor);
+            mLastAttFactor = newAttFactor;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newAttFactor != mDesAttFactor)
+                ALOGV("DRC presentation mode wrapper: forced attenuation factor to %d (from %d)\n", newAttFactor, mDesAttFactor);
+            else
+                ALOGV("DRC presentation mode wrapper: set attenuation factor to %d\n", newAttFactor);
+#endif
+        }
+
+        if (newBoostFactor != mLastBoostFactor) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_BOOST_FACTOR, newBoostFactor);
+            mLastBoostFactor = newBoostFactor;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newBoostFactor != mDesBoostFactor)
+                ALOGV("DRC presentation mode wrapper: forced boost factor to %d (from %d)\n",
+                        newBoostFactor, mDesBoostFactor);
+            else
+                ALOGV("DRC presentation mode wrapper: set boost factor to %d\n", newBoostFactor);
+#endif
+        }
+
+        if (newHeavy != mLastHeavy) {
+            aacDecoder_SetParam(mHandleDecoder, AAC_DRC_HEAVY_COMPRESSION, newHeavy);
+            mLastHeavy = newHeavy;
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+            if (newHeavy != mDesHeavy)
+                ALOGV("DRC presentation mode wrapper: forced heavy compression to %d (from %d)\n",
+                        newHeavy, mDesHeavy);
+            else
+                ALOGV("DRC presentation mode wrapper: set heavy compression to %d\n", newHeavy);
+#endif
+        }
+
+#ifdef DRC_PRES_MODE_WRAP_DEBUG
+        ALOGV("DRC config: tgt_lev: %3d, cut: %3d, boost: %3d, heavy: %d\n", newTarget,
+                newAttFactor, newBoostFactor, newHeavy);
+#endif
+        mDataUpdate = false;
+
+    } // if (mDataUpdate)
+}
diff --git a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.h b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.h
new file mode 100644
index 0000000..f0b6cf2
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+#pragma once
+#include "aacdecoder_lib.h"
+
+typedef enum
+{
+    DRC_PRES_MODE_WRAP_DESIRED_TARGET         = 0x0000,
+    DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR     = 0x0001,
+    DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR   = 0x0002,
+    DRC_PRES_MODE_WRAP_DESIRED_HEAVY          = 0x0003,
+    DRC_PRES_MODE_WRAP_ENCODER_TARGET         = 0x0004
+} DRC_PRES_MODE_WRAP_PARAM;
+
+
+class CDrcPresModeWrapper {
+public:
+    CDrcPresModeWrapper();
+    ~CDrcPresModeWrapper();
+    void setDecoderHandle(const HANDLE_AACDECODER handle);
+    void setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value);
+    void submitStreamData(CStreamInfo*);
+    void update();
+
+protected:
+    HANDLE_AACDECODER mHandleDecoder;
+    int mDesTarget;
+    int mDesAttFactor;
+    int mDesBoostFactor;
+    int mDesHeavy;
+
+    int mEncoderTarget;
+
+    int mLastTarget;
+    int mLastAttFactor;
+    int mLastBoostFactor;
+    int mLastHeavy;
+
+    SCHAR mStreamPRL;
+    SCHAR mStreamDRCPresMode;
+    INT mStreamNrAACChan;
+    INT mStreamNrOutChan;
+
+    bool mIsDownmix;
+    bool mIsMonoDownmix;
+    bool mIsStereoDownmix;
+
+    bool mDataUpdate;
+};
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 532e36f..64bf2b6 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -25,16 +25,22 @@
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaErrors.h>
 
+#include <math.h>
+
 #define FILEREAD_MAX_LAYERS 2
 
 #define DRC_DEFAULT_MOBILE_REF_LEVEL 64  /* 64*-0.25dB = -16 dB below full scale for mobile conf */
 #define DRC_DEFAULT_MOBILE_DRC_CUT   127 /* maximum compression of dynamic range for mobile conf */
 #define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1   /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL -1 /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
 #define MAX_CHANNEL_COUNT            8  /* maximum number of audio channels that can be decoded */
 // names of properties that can be used to override the default DRC settings
 #define PROP_DRC_OVERRIDE_REF_LEVEL  "aac_drc_reference_level"
 #define PROP_DRC_OVERRIDE_CUT        "aac_drc_cut"
 #define PROP_DRC_OVERRIDE_BOOST      "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY      "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
 
 namespace android {
 
@@ -57,18 +63,19 @@
       mStreamInfo(NULL),
       mIsADTS(false),
       mInputBufferCount(0),
+      mOutputBufferCount(0),
       mSignalledError(false),
-      mSawInputEos(false),
-      mSignalledOutputEos(false),
-      mAnchorTimeUs(0),
-      mNumSamplesOutput(0),
       mOutputPortSettingsChange(NONE) {
+    for (unsigned int i = 0; i < kNumDelayBlocksMax; i++) {
+        mAnchorTimeUs[i] = 0;
+    }
     initPorts();
     CHECK_EQ(initDecoder(), (status_t)OK);
 }
 
 SoftAAC2::~SoftAAC2() {
     aacDecoder_Close(mAACDecoder);
+    delete mOutputDelayRingBuffer;
 }
 
 void SoftAAC2::initPorts() {
@@ -121,36 +128,72 @@
             status = OK;
         }
     }
-    mDecoderHasData = false;
 
-    // for streams that contain metadata, use the mobile profile DRC settings unless overridden
-    // by platform properties:
+    mEndOfInput = false;
+    mEndOfOutput = false;
+    mOutputDelayCompensated = 0;
+    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
+    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
+    mOutputDelayRingBufferWritePos = 0;
+    mOutputDelayRingBufferReadPos = 0;
+
+    if (mAACDecoder == NULL) {
+        ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
+    }
+
+    //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
+
+    //init DRC wrapper
+    mDrcWrap.setDecoderHandle(mAACDecoder);
+    mDrcWrap.submitStreamData(mStreamInfo);
+
+    // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
+    // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
     char value[PROPERTY_VALUE_MAX];
-    //  * AAC_DRC_REFERENCE_LEVEL
+    //  DRC_PRES_MODE_WRAP_DESIRED_TARGET
     if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
         unsigned refLevel = atoi(value);
-        ALOGV("AAC decoder using AAC_DRC_REFERENCE_LEVEL of %d instead of %d",
-                refLevel, DRC_DEFAULT_MOBILE_REF_LEVEL);
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, refLevel);
+        ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
+                DRC_DEFAULT_MOBILE_REF_LEVEL);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
     } else {
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_REFERENCE_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
     }
-    //  * AAC_DRC_ATTENUATION_FACTOR
+    //  DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
     if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
         unsigned cut = atoi(value);
-        ALOGV("AAC decoder using AAC_DRC_ATTENUATION_FACTOR of %d instead of %d",
-                        cut, DRC_DEFAULT_MOBILE_DRC_CUT);
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, cut);
+        ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
+                DRC_DEFAULT_MOBILE_DRC_CUT);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
     } else {
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_ATTENUATION_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
     }
-    //  * AAC_DRC_BOOST_FACTOR (note: no default, using cut)
+    //  DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
     if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
         unsigned boost = atoi(value);
-        ALOGV("AAC decoder using AAC_DRC_BOOST_FACTOR of %d", boost);
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, boost);
+        ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
+                DRC_DEFAULT_MOBILE_DRC_BOOST);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
     } else {
-        aacDecoder_SetParam(mAACDecoder, AAC_DRC_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
+    }
+    //  DRC_PRES_MODE_WRAP_DESIRED_HEAVY
+    if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
+        unsigned heavy = atoi(value);
+        ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
+                DRC_DEFAULT_MOBILE_DRC_HEAVY);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
+    } else {
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
+    }
+    // DRC_PRES_MODE_WRAP_ENCODER_TARGET
+    if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
+        unsigned encoderRefLevel = atoi(value);
+        ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
+                encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
+    } else {
+        mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
     }
 
     return status;
@@ -290,19 +333,101 @@
     return mInputBufferCount > 0;
 }
 
-void SoftAAC2::maybeConfigureDownmix() const {
-    if (mStreamInfo->numChannels > 2) {
-        char value[PROPERTY_VALUE_MAX];
-        if (!(property_get("media.aac_51_output_enabled", value, NULL) &&
-                (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
-            ALOGI("Downmixing multichannel AAC to stereo");
-            aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2);
-            mStreamInfo->numChannels = 2;
-            // By default, the decoder creates a 5.1 channel downmix signal
-            // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output
-            // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1)
+void SoftAAC2::configureDownmix() const {
+    char value[PROPERTY_VALUE_MAX];
+    if (!(property_get("media.aac_51_output_enabled", value, NULL)
+            && (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
+        ALOGI("limiting to stereo output");
+        aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2);
+        // By default, the decoder creates a 5.1 channel downmix signal
+        // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output
+        // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1)
+    }
+}
+
+bool SoftAAC2::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
+    if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
+            && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
+                    || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
+        // faster memcopy loop without checks, if the preconditions allow this
+        for (int32_t i = 0; i < numSamples; i++) {
+            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
+        }
+
+        if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
+            mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
+        }
+        if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
+            ALOGE("RING BUFFER OVERFLOW");
+            return false;
+        }
+    } else {
+        ALOGV("slow SoftAAC2::outputDelayRingBufferPutSamples()");
+
+        for (int32_t i = 0; i < numSamples; i++) {
+            mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
+            mOutputDelayRingBufferWritePos++;
+            if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
+                mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
+            }
+            if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
+                ALOGE("RING BUFFER OVERFLOW");
+                return false;
+            }
         }
     }
+    return true;
+}
+
+int32_t SoftAAC2::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
+    if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
+            && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
+                    || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
+        // faster memcopy loop without checks, if the preconditions allow this
+        if (samples != 0) {
+            for (int32_t i = 0; i < numSamples; i++) {
+                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
+            }
+        } else {
+            mOutputDelayRingBufferReadPos += numSamples;
+        }
+        if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
+            mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
+        }
+    } else {
+        ALOGV("slow SoftAAC2::outputDelayRingBufferGetSamples()");
+
+        for (int32_t i = 0; i < numSamples; i++) {
+            if (mOutputDelayRingBufferWritePos == mOutputDelayRingBufferReadPos) {
+                ALOGE("RING BUFFER UNDERRUN");
+                return -1;
+            }
+            if (samples != 0) {
+                samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
+            }
+            mOutputDelayRingBufferReadPos++;
+            if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
+                mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
+            }
+        }
+    }
+    return numSamples;
+}
+
+int32_t SoftAAC2::outputDelayRingBufferSamplesAvailable() {
+    int32_t available = mOutputDelayRingBufferWritePos - mOutputDelayRingBufferReadPos;
+    if (available < 0) {
+        available += mOutputDelayRingBufferSize;
+    }
+    if (available < 0) {
+        ALOGE("FATAL RING BUFFER ERROR");
+        return 0;
+    }
+    return available;
+}
+
+int32_t SoftAAC2::outputDelayRingBufferSamplesLeft() {
+    return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
 }
 
 void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
@@ -318,12 +443,11 @@
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
     if (portIndex == 0 && mInputBufferCount == 0) {
-        ++mInputBufferCount;
-        BufferInfo *info = *inQueue.begin();
-        OMX_BUFFERHEADERTYPE *header = info->mHeader;
+        BufferInfo *inInfo = *inQueue.begin();
+        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
 
-        inBuffer[0] = header->pBuffer + header->nOffset;
-        inBufferLength[0] = header->nFilledLen;
+        inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
+        inBufferLength[0] = inHeader->nFilledLen;
 
         AAC_DECODER_ERROR decoderErr =
             aacDecoder_ConfigRaw(mAACDecoder,
@@ -331,19 +455,25 @@
                                  inBufferLength);
 
         if (decoderErr != AAC_DEC_OK) {
+            ALOGW("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
             mSignalledError = true;
             notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
             return;
         }
 
-        inQueue.erase(inQueue.begin());
-        info->mOwnedByUs = false;
-        notifyEmptyBufferDone(header);
+        mInputBufferCount++;
+        mOutputBufferCount++; // fake increase of outputBufferCount to keep the counters aligned
 
+        inInfo->mOwnedByUs = false;
+        inQueue.erase(inQueue.begin());
+        inInfo = NULL;
+        notifyEmptyBufferDone(inHeader);
+        inHeader = NULL;
+
+        configureDownmix();
         // Only send out port settings changed event if both sample rate
         // and numChannels are valid.
         if (mStreamInfo->sampleRate && mStreamInfo->numChannels) {
-            maybeConfigureDownmix();
             ALOGI("Initially configuring decoder: %d Hz, %d channels",
                 mStreamInfo->sampleRate,
                 mStreamInfo->numChannels);
@@ -355,146 +485,20 @@
         return;
     }
 
-    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
-        BufferInfo *inInfo = NULL;
-        OMX_BUFFERHEADERTYPE *inHeader = NULL;
+    while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
         if (!inQueue.empty()) {
-            inInfo = *inQueue.begin();
-            inHeader = inInfo->mHeader;
-        }
+            INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
+            BufferInfo *inInfo = *inQueue.begin();
+            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
 
-        BufferInfo *outInfo = *outQueue.begin();
-        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
-        outHeader->nFlags = 0;
-
-        if (inHeader) {
             if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
-                mSawInputEos = true;
-            }
-
-            if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
-                mAnchorTimeUs = inHeader->nTimeStamp;
-                mNumSamplesOutput = 0;
-            }
-
-            if (mIsADTS && inHeader->nFilledLen) {
-                size_t adtsHeaderSize = 0;
-                // skip 30 bits, aac_frame_length follows.
-                // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
-
-                const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
-
-                bool signalError = false;
-                if (inHeader->nFilledLen < 7) {
-                    ALOGE("Audio data too short to contain even the ADTS header. "
-                          "Got %d bytes.", inHeader->nFilledLen);
-                    hexdump(adtsHeader, inHeader->nFilledLen);
-                    signalError = true;
-                } else {
-                    bool protectionAbsent = (adtsHeader[1] & 1);
-
-                    unsigned aac_frame_length =
-                        ((adtsHeader[3] & 3) << 11)
-                        | (adtsHeader[4] << 3)
-                        | (adtsHeader[5] >> 5);
-
-                    if (inHeader->nFilledLen < aac_frame_length) {
-                        ALOGE("Not enough audio data for the complete frame. "
-                              "Got %d bytes, frame size according to the ADTS "
-                              "header is %u bytes.",
-                              inHeader->nFilledLen, aac_frame_length);
-                        hexdump(adtsHeader, inHeader->nFilledLen);
-                        signalError = true;
-                    } else {
-                        adtsHeaderSize = (protectionAbsent ? 7 : 9);
-
-                        inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
-                        inBufferLength[0] = aac_frame_length - adtsHeaderSize;
-
-                        inHeader->nOffset += adtsHeaderSize;
-                        inHeader->nFilledLen -= adtsHeaderSize;
-                    }
-                }
-
-                if (signalError) {
-                    mSignalledError = true;
-
-                    notify(OMX_EventError,
-                           OMX_ErrorStreamCorrupt,
-                           ERROR_MALFORMED,
-                           NULL);
-
-                    return;
-                }
+                mEndOfInput = true;
             } else {
-                inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
-                inBufferLength[0] = inHeader->nFilledLen;
+                mEndOfInput = false;
             }
-        } else {
-            inBufferLength[0] = 0;
-        }
-
-        // Fill and decode
-        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(
-                outHeader->pBuffer + outHeader->nOffset);
-
-        bytesValid[0] = inBufferLength[0];
-
-        int prevSampleRate = mStreamInfo->sampleRate;
-        int prevNumChannels = mStreamInfo->numChannels;
-
-        AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
-        while ((bytesValid[0] > 0 || mSawInputEos) && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
-            mDecoderHasData |= (bytesValid[0] > 0);
-            aacDecoder_Fill(mAACDecoder,
-                            inBuffer,
-                            inBufferLength,
-                            bytesValid);
-
-            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
-                                                outBuffer,
-                                                outHeader->nAllocLen,
-                                                0 /* flags */);
-            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
-                if (mSawInputEos && bytesValid[0] <= 0) {
-                    if (mDecoderHasData) {
-                        // flush out the decoder's delayed data by calling DecodeFrame
-                        // one more time, with the AACDEC_FLUSH flag set
-                        decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
-                                                            outBuffer,
-                                                            outHeader->nAllocLen,
-                                                            AACDEC_FLUSH);
-                        mDecoderHasData = false;
-                    }
-                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-                    mSignalledOutputEos = true;
-                    break;
-                } else {
-                    ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
-                }
-            }
-        }
-
-        size_t numOutBytes =
-            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
-
-        if (inHeader) {
-            if (decoderErr == AAC_DEC_OK) {
-                UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
-                inHeader->nFilledLen -= inBufferUsedLength;
-                inHeader->nOffset += inBufferUsedLength;
-            } else {
-                ALOGW("AAC decoder returned error %d, substituting silence",
-                      decoderErr);
-
-                memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
-
-                // Discard input buffer.
-                inHeader->nFilledLen = 0;
-
-                aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
-
-                // fall through
+            if (inHeader->nOffset == 0) { // TODO: does nOffset != 0 happen?
+                mAnchorTimeUs[mInputBufferCount % kNumDelayBlocksMax] =
+                        inHeader->nTimeStamp;
             }
 
             if (inHeader->nFilledLen == 0) {
@@ -503,54 +507,282 @@
                 inInfo = NULL;
                 notifyEmptyBufferDone(inHeader);
                 inHeader = NULL;
+            } else {
+                if (mIsADTS) {
+                    size_t adtsHeaderSize = 0;
+                    // skip 30 bits, aac_frame_length follows.
+                    // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+
+                    const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
+
+                    bool signalError = false;
+                    if (inHeader->nFilledLen < 7) {
+                        ALOGE("Audio data too short to contain even the ADTS header. "
+                                "Got %d bytes.", inHeader->nFilledLen);
+                        hexdump(adtsHeader, inHeader->nFilledLen);
+                        signalError = true;
+                    } else {
+                        bool protectionAbsent = (adtsHeader[1] & 1);
+
+                        unsigned aac_frame_length =
+                            ((adtsHeader[3] & 3) << 11)
+                            | (adtsHeader[4] << 3)
+                            | (adtsHeader[5] >> 5);
+
+                        if (inHeader->nFilledLen < aac_frame_length) {
+                            ALOGE("Not enough audio data for the complete frame. "
+                                    "Got %d bytes, frame size according to the ADTS "
+                                    "header is %u bytes.",
+                                    inHeader->nFilledLen, aac_frame_length);
+                            hexdump(adtsHeader, inHeader->nFilledLen);
+                            signalError = true;
+                        } else {
+                            adtsHeaderSize = (protectionAbsent ? 7 : 9);
+
+                            inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
+                            inBufferLength[0] = aac_frame_length - adtsHeaderSize;
+
+                            inHeader->nOffset += adtsHeaderSize;
+                            inHeader->nFilledLen -= adtsHeaderSize;
+                        }
+                    }
+
+                    if (signalError) {
+                        mSignalledError = true;
+
+                        notify(OMX_EventError,
+                               OMX_ErrorStreamCorrupt,
+                               ERROR_MALFORMED,
+                               NULL);
+
+                        return;
+                    }
+                } else {
+                    inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
+                    inBufferLength[0] = inHeader->nFilledLen;
+                }
+
+                // Fill and decode
+                bytesValid[0] = inBufferLength[0];
+
+                INT prevSampleRate = mStreamInfo->sampleRate;
+                INT prevNumChannels = mStreamInfo->numChannels;
+
+                aacDecoder_Fill(mAACDecoder,
+                                inBuffer,
+                                inBufferLength,
+                                bytesValid);
+
+                 // run DRC check
+                 mDrcWrap.submitStreamData(mStreamInfo);
+                 mDrcWrap.update();
+
+                AAC_DECODER_ERROR decoderErr =
+                    aacDecoder_DecodeFrame(mAACDecoder,
+                                           tmpOutBuffer,
+                                           2048 * MAX_CHANNEL_COUNT,
+                                           0 /* flags */);
+
+                if (decoderErr != AAC_DEC_OK) {
+                    ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
+                }
+
+                if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+                    ALOGE("AAC_DEC_NOT_ENOUGH_BITS should never happen");
+                    mSignalledError = true;
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    return;
+                }
+
+                if (bytesValid[0] != 0) {
+                    ALOGE("bytesValid[0] != 0 should never happen");
+                    mSignalledError = true;
+                    notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    return;
+                }
+
+                size_t numOutBytes =
+                    mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
+
+                if (decoderErr == AAC_DEC_OK) {
+                    if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
+                            mStreamInfo->frameSize * mStreamInfo->numChannels)) {
+                        mSignalledError = true;
+                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                        return;
+                    }
+                    UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
+                    inHeader->nFilledLen -= inBufferUsedLength;
+                    inHeader->nOffset += inBufferUsedLength;
+                } else {
+                    ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
+
+                    memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
+
+                    if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
+                            mStreamInfo->frameSize * mStreamInfo->numChannels)) {
+                        mSignalledError = true;
+                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                        return;
+                    }
+
+                    // Discard input buffer.
+                    inHeader->nFilledLen = 0;
+
+                    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+
+                    // fall through
+                }
+
+                /*
+                 * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
+                 * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
+                 * rate system and the sampling rate in the final output is actually
+                 * doubled compared with the core AAC decoder sampling rate.
+                 *
+                 * Explicit signalling is done by explicitly defining SBR audio object
+                 * type in the bitstream. Implicit signalling is done by embedding
+                 * SBR content in AAC extension payload specific to SBR, and hence
+                 * requires an AAC decoder to perform pre-checks on actual audio frames.
+                 *
+                 * Thus, we could not say for sure whether a stream is
+                 * AAC+/eAAC+ until the first data frame is decoded.
+                 */
+                if (mOutputBufferCount > 1) {
+                    if (mStreamInfo->sampleRate != prevSampleRate ||
+                        mStreamInfo->numChannels != prevNumChannels) {
+                        ALOGE("can not reconfigure AAC output");
+                        mSignalledError = true;
+                        notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                        return;
+                    }
+                }
+                if (mInputBufferCount <= 2) { // TODO: <= 1
+                    if (mStreamInfo->sampleRate != prevSampleRate ||
+                        mStreamInfo->numChannels != prevNumChannels) {
+                        ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+                              prevSampleRate, mStreamInfo->sampleRate,
+                              prevNumChannels, mStreamInfo->numChannels);
+
+                        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                        mOutputPortSettingsChange = AWAITING_DISABLED;
+
+                        if (inHeader->nFilledLen == 0) {
+                            inInfo->mOwnedByUs = false;
+                            mInputBufferCount++;
+                            inQueue.erase(inQueue.begin());
+                            inInfo = NULL;
+                            notifyEmptyBufferDone(inHeader);
+                            inHeader = NULL;
+                        }
+                        return;
+                    }
+                } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
+                    ALOGW("Invalid AAC stream");
+                    mSignalledError = true;
+                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                    return;
+                }
+                if (inHeader->nFilledLen == 0) {
+                    inInfo->mOwnedByUs = false;
+                    mInputBufferCount++;
+                    inQueue.erase(inQueue.begin());
+                    inInfo = NULL;
+                    notifyEmptyBufferDone(inHeader);
+                    inHeader = NULL;
+                } else {
+                    ALOGW("inHeader->nFilledLen = %d", inHeader->nFilledLen);
+                }
             }
         }
 
-        /*
-         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
-         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
-         * rate system and the sampling rate in the final output is actually
-         * doubled compared with the core AAC decoder sampling rate.
-         *
-         * Explicit signalling is done by explicitly defining SBR audio object
-         * type in the bitstream. Implicit signalling is done by embedding
-         * SBR content in AAC extension payload specific to SBR, and hence
-         * requires an AAC decoder to perform pre-checks on actual audio frames.
-         *
-         * Thus, we could not say for sure whether a stream is
-         * AAC+/eAAC+ until the first data frame is decoded.
-         */
-        if (mInputBufferCount <= 2) {
-            if (mStreamInfo->sampleRate != prevSampleRate ||
-                mStreamInfo->numChannels != prevNumChannels) {
-                maybeConfigureDownmix();
-                ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
-                      prevSampleRate, mStreamInfo->sampleRate,
-                      prevNumChannels, mStreamInfo->numChannels);
+        int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
 
-                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-                mOutputPortSettingsChange = AWAITING_DISABLED;
+        if (!mEndOfInput && mOutputDelayCompensated < outputDelay) {
+            // discard outputDelay at the beginning
+            int32_t toCompensate = outputDelay - mOutputDelayCompensated;
+            int32_t discard = outputDelayRingBufferSamplesAvailable();
+            if (discard > toCompensate) {
+                discard = toCompensate;
+            }
+            int32_t discarded = outputDelayRingBufferGetSamples(0, discard);
+            mOutputDelayCompensated += discarded;
+            continue;
+        }
+
+        if (mEndOfInput) {
+            while (mOutputDelayCompensated > 0) {
+                // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
+                INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
+ 
+                 // run DRC check
+                 mDrcWrap.submitStreamData(mStreamInfo);
+                 mDrcWrap.update();
+
+                AAC_DECODER_ERROR decoderErr =
+                    aacDecoder_DecodeFrame(mAACDecoder,
+                                           tmpOutBuffer,
+                                           2048 * MAX_CHANNEL_COUNT,
+                                           AACDEC_FLUSH);
+                if (decoderErr != AAC_DEC_OK) {
+                    ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
+                }
+
+                int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
+                if (tmpOutBufferSamples > mOutputDelayCompensated) {
+                    tmpOutBufferSamples = mOutputDelayCompensated;
+                }
+                outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
+                mOutputDelayCompensated -= tmpOutBufferSamples;
+            }
+        }
+
+        while (!outQueue.empty()
+                && outputDelayRingBufferSamplesAvailable()
+                        >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
+            BufferInfo *outInfo = *outQueue.begin();
+            OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+            if (outHeader->nOffset != 0) {
+                ALOGE("outHeader->nOffset != 0 is not handled");
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
                 return;
             }
-        } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
-            ALOGW("Invalid AAC stream");
-            mSignalledError = true;
-            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-            return;
-        }
 
-        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
-            // We'll only output data if we successfully decoded it or
-            // we've previously decoded valid data, in the latter case
-            // (decode failed) we'll output a silent frame.
-            outHeader->nFilledLen = numOutBytes;
+            INT_PCM *outBuffer =
+                    reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
+            if (outHeader->nOffset
+                    + mStreamInfo->frameSize * mStreamInfo->numChannels * sizeof(int16_t)
+                    > outHeader->nAllocLen) {
+                ALOGE("buffer overflow");
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
 
-            outHeader->nTimeStamp =
-                mAnchorTimeUs
-                    + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
+            }
+            int32_t ns = outputDelayRingBufferGetSamples(outBuffer,
+                    mStreamInfo->frameSize * mStreamInfo->numChannels); // TODO: check for overflow
+            if (ns != mStreamInfo->frameSize * mStreamInfo->numChannels) {
+                ALOGE("not a complete frame of samples available");
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
+            }
 
-            mNumSamplesOutput += mStreamInfo->frameSize;
+            outHeader->nFilledLen = mStreamInfo->frameSize * mStreamInfo->numChannels
+                    * sizeof(int16_t);
+            if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) {
+                outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+                mEndOfOutput = true;
+            } else {
+                outHeader->nFlags = 0;
+            }
 
+            outHeader->nTimeStamp = mAnchorTimeUs[mOutputBufferCount
+                    % kNumDelayBlocksMax];
+
+            mOutputBufferCount++;
             outInfo->mOwnedByUs = false;
             outQueue.erase(outQueue.begin());
             outInfo = NULL;
@@ -558,8 +790,48 @@
             outHeader = NULL;
         }
 
-        if (decoderErr == AAC_DEC_OK) {
-            ++mInputBufferCount;
+        if (mEndOfInput) {
+            if (outputDelayRingBufferSamplesAvailable() > 0
+                    && outputDelayRingBufferSamplesAvailable()
+                            < mStreamInfo->frameSize * mStreamInfo->numChannels) {
+                ALOGE("not a complete frame of samples available");
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
+            }
+
+            if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) {
+                if (!mEndOfOutput) {
+                    // send empty block signaling EOS
+                    mEndOfOutput = true;
+                    BufferInfo *outInfo = *outQueue.begin();
+                    OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+                    if (outHeader->nOffset != 0) {
+                        ALOGE("outHeader->nOffset != 0 is not handled");
+                        mSignalledError = true;
+                        notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                        return;
+                    }
+
+                    INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer
+                            + outHeader->nOffset);
+                    int32_t ns = 0;
+                    outHeader->nFilledLen = 0;
+                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+
+                    outHeader->nTimeStamp = mAnchorTimeUs[mOutputBufferCount
+                            % kNumDelayBlocksMax];
+
+                    mOutputBufferCount++;
+                    outInfo->mOwnedByUs = false;
+                    outQueue.erase(outQueue.begin());
+                    outInfo = NULL;
+                    notifyFillBufferDone(outHeader);
+                    outHeader = NULL;
+                }
+                break; // if outQueue not empty but no more output
+            }
         }
     }
 }
@@ -570,38 +842,66 @@
         // depend on fragments from the last one decoded.
         // drain all existing data
         drainDecoder();
-        // force decoder loop to drop the first decoded buffer by resetting these state variables,
-        // but only if initialization has already happened.
-        if (mInputBufferCount != 0) {
-            mInputBufferCount = 1;
-            mStreamInfo->sampleRate = 0;
+    } else {
+        while (outputDelayRingBufferSamplesAvailable() > 0) {
+            int32_t ns = outputDelayRingBufferGetSamples(0,
+                    mStreamInfo->frameSize * mStreamInfo->numChannels);
+            if (ns != mStreamInfo->frameSize * mStreamInfo->numChannels) {
+                ALOGE("not a complete frame of samples available");
+            }
+            mOutputBufferCount++;
         }
+        mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
     }
 }
 
 void SoftAAC2::drainDecoder() {
-    // a buffer big enough for 6 channels of decoded HE-AAC
-    short buf [2048*6];
-    aacDecoder_DecodeFrame(mAACDecoder,
-            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
-    aacDecoder_DecodeFrame(mAACDecoder,
-            buf, sizeof(buf), AACDEC_FLUSH | AACDEC_CLRHIST | AACDEC_INTR);
-    aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
-    mDecoderHasData = false;
+    int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
+
+    // flush decoder until outputDelay is compensated
+    while (mOutputDelayCompensated > 0) {
+        // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
+        INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
+
+        // run DRC check
+        mDrcWrap.submitStreamData(mStreamInfo);
+        mDrcWrap.update();
+
+        AAC_DECODER_ERROR decoderErr =
+            aacDecoder_DecodeFrame(mAACDecoder,
+                                   tmpOutBuffer,
+                                   2048 * MAX_CHANNEL_COUNT,
+                                   AACDEC_FLUSH);
+        if (decoderErr != AAC_DEC_OK) {
+            ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
+        }
+
+        int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
+        if (tmpOutBufferSamples > mOutputDelayCompensated) {
+            tmpOutBufferSamples = mOutputDelayCompensated;
+        }
+        outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
+
+        mOutputDelayCompensated -= tmpOutBufferSamples;
+    }
 }
 
 void SoftAAC2::onReset() {
     drainDecoder();
     // reset the "configured" state
     mInputBufferCount = 0;
-    mNumSamplesOutput = 0;
+    mOutputBufferCount = 0;
+    mOutputDelayCompensated = 0;
+    mOutputDelayRingBufferWritePos = 0;
+    mOutputDelayRingBufferReadPos = 0;
+    mEndOfInput = false;
+    mEndOfOutput = false;
+
     // To make the codec behave the same before and after a reset, we need to invalidate the
     // streaminfo struct. This does that:
-    mStreamInfo->sampleRate = 0;
+    mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
 
     mSignalledError = false;
-    mSawInputEos = false;
-    mSignalledOutputEos = false;
     mOutputPortSettingsChange = NONE;
 }
 
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index a7ea1e2..5cde03a 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -20,6 +20,7 @@
 #include "SimpleSoftOMXComponent.h"
 
 #include "aacdecoder_lib.h"
+#include "DrcPresModeWrap.h"
 
 namespace android {
 
@@ -47,18 +48,19 @@
     enum {
         kNumInputBuffers        = 4,
         kNumOutputBuffers       = 4,
+        kNumDelayBlocksMax      = 8,
     };
 
     HANDLE_AACDECODER mAACDecoder;
     CStreamInfo *mStreamInfo;
     bool mIsADTS;
-    bool mDecoderHasData;
+    bool mIsFirst;
     size_t mInputBufferCount;
+    size_t mOutputBufferCount;
     bool mSignalledError;
-    bool mSawInputEos;
-    bool mSignalledOutputEos;
-    int64_t mAnchorTimeUs;
-    int64_t mNumSamplesOutput;
+    int64_t mAnchorTimeUs[kNumDelayBlocksMax];
+
+    CDrcPresModeWrapper mDrcWrap;
 
     enum {
         NONE,
@@ -69,9 +71,22 @@
     void initPorts();
     status_t initDecoder();
     bool isConfigured() const;
-    void maybeConfigureDownmix() const;
+    void configureDownmix() const;
     void drainDecoder();
 
+//      delay compensation
+    bool mEndOfInput;
+    bool mEndOfOutput;
+    int32_t mOutputDelayCompensated;
+    int32_t mOutputDelayRingBufferSize;
+    short *mOutputDelayRingBuffer;
+    int32_t mOutputDelayRingBufferWritePos;
+    int32_t mOutputDelayRingBufferReadPos;
+    bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
+    int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
+    int32_t outputDelayRingBufferSamplesAvailable();
+    int32_t outputDelayRingBufferSamplesLeft();
+
     DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
 };
 
diff --git a/media/libstagefright/codecs/hevcdec/Android.mk b/media/libstagefright/codecs/hevcdec/Android.mk
index 2fe347b..960602f 100644
--- a/media/libstagefright/codecs/hevcdec/Android.mk
+++ b/media/libstagefright/codecs/hevcdec/Android.mk
@@ -1,3 +1,5 @@
+ifeq ($(if $(wildcard external/libhevc),1,0),1)
+
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -20,3 +22,5 @@
 
 
 include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s
deleted file mode 100644
index 3a6dd4f..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s
+++ /dev/null
@@ -1,210 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; 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.
-; -------------------------------------------------------------------
-
-;
-;
-;   Filename: pvmp3_dct_9.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who:                                   Date: MM/DD/YYYY
-; Description: 
-;
-;------------------------------------------------------------------------------
-
-  AREA  |.drectve|, DRECTVE
-
-    DCB "-defaultlib:coredll.lib "
-    DCB "-defaultlib:corelibc.lib "
-
-  IMPORT pvmp3_mdct_18 ; pvmp3_mdct_18.cpp
-
-;------------------------------------------------------------------------------
-
-  AREA  |.rdata|, DATA, READONLY
-  % 4
-
-
-;------------------------------------------------------------------------------
-
-  AREA  |.text|, CODE, READONLY
-
-
-;------------------------------------------------------------------------------
-
- EXPORT |pvmp3_dct_9|
-
-|pvmp3_dct_9| PROC
-        stmfd    sp!,{r4-r10,lr}
-        ldr      r2, [r0, #0x20]
-        ldr      r3, [r0]
-        ldr      r12,[r0, #4]
-        add      r1,r2,r3
-        sub      lr,r2,r3
-        ldr      r3,[r0, #0x1c]
-        ldr      r4,[r0, #0x18]
-        add      r2,r3,r12
-        ldr      r5,[r0,#8]
-        sub      r3,r3,r12
-        add      r12,r4,r5
-        sub      r4,r4,r5
-        ldr      r5,[r0, #0x14]
-        ldr      r7,[r0, #0xc]
-        ldr      r9,[r0, #0x10]
-        add      r6,r5,r7
-        sub      r5,r5,r7
-        add      r7,r1,r12
-        add      r8,r9,r2
-        add      r7,r7,r6
-        add      r10,r7,r8
-        rsb      r7,r8,r7,asr #1
-        str      r7,[r0, #0x18]
-        rsb      r2,r9,r2,asr #1
-        str      r10,[r0]
-        ldr      r11,|cos_2pi_9|
-        rsb      r7,r2,#0
-
-        mov      r9,r1,lsl #1
-		mov      r1,r9			;;;;;;  !!!!!!
-        mov      r8,r7
-
-;    vec[4]  = fxp_mac32_Q32( vec[4], tmp0<<1, cos_2pi_9); 
-
-        smlal    r1,r8,r11,r9
-        ldr      r10,|cos_4pi_9|
-        ldr      r11,|cos_pi_9|
-
-;    vec[8]  = fxp_mac32_Q32( vec[8], tmp0<<1, cos_4pi_9);
-
-        smlal    r1,r7,r10,r9
-
-
-
-;    vec[2]  = fxp_mac32_Q32( vec[2], tmp0<<1, cos_pi_9);
-
-        smlal    r9,r2,r11,r9
-        mov      r1,r12,lsl #1
-        rsb      r9,r10,#0
-        ldr      r11,|cos_5pi_9|
-
-        smlal    r12,r2,r9,r1
-
-
-
-;    vec[2]  = fxp_mac32_Q32( vec[2], tmp2<<1, cos_5pi_9);
-
-        ldr      r9,|cos_2pi_9|
-        mov      r12,r1			;;;;;;  !!!!!!
-        smlal    r12,r8,r11,r1
-
-
-;    vec[8]  = fxp_mac32_Q32( vec[8], tmp2<<1, cos_2pi_9);
-
-        smlal    r1,r7,r9,r1
-        mov      r1,r6,lsl #1
-        smlal    r12,r7,r11,r1
-        and      r6,r10,r11,asr #14
-        smlal    r12,r8,r6,r1
-        ldr      r10,|cos_11pi_18|
-        add      r12,r11,r6
-        smlal    r1,r2,r12,r1
-        ldr      r9,|cos_8pi_9|
-        str      r2,[r0,#8]
-        mov      r1,r5,lsl #1
-
-;    vec[8]  = fxp_mac32_Q32( vec[8], tmp3<<1, cos_8pi_9);
-
-        smull    r2,r6,r9,r1
-        str      r7,[r0,#0x20]
-        mov      r2,r4,lsl #1
-        ldr      r7,|cos_13pi_18|
-        smlal    r12,r6,r10,r2
-
-        mov      r3,r3,lsl #1
-
-;    vec[5]  = fxp_mac32_Q32( vec[5], tmp8<<1, cos_13pi_18);
-
-        smlal    r12,r6,r7,r3
-        add      r4,r5,r4
-        mov      r12,lr,lsl #1
-        sub      lr,r4,lr
-        ldr      r7,|cos_17pi_18|
-        str      r8,[r0, #0x10]
-        ldr      r4,|cos_pi_6|
-
-        mov      lr,lr,lsl #1
-
-;    vec[1]  = fxp_mac32_Q32( vec[1], tmp8<<1, cos_17pi_18);
-
-        smlal    r8,r6,r7,r12
-
-;    vec[3]  = fxp_mul32_Q32((tmp5 + tmp6  - tmp8)<<1, cos_pi_6);
-
-        smull    r5,lr,r4,lr
-        str      r6,[r0, #4]
-        str      lr,[r0, #0xc]
-
-
-;    vec[5]  = fxp_mul32_Q32(tmp5<<1, cos_17pi_18);
-        smull    r5,lr,r7,r1
-        rsb      r6,r9,#0
-;    vec[5]  = fxp_mac32_Q32( vec[5], tmp6<<1,  cos_7pi_18);
-        smlal    r5,lr,r6,r2
-;    vec[5]  = fxp_mac32_Q32( vec[5], tmp7<<1,    cos_pi_6);
-        smlal    r5,lr,r4,r3
-;    vec[5]  = fxp_mac32_Q32( vec[5], tmp8<<1, cos_13pi_18);
-        smlal    r5,lr,r10,r12
-        str      lr,[r0, #0x14]
-        rsb      lr,r10,#0
-
-;    vec[7]  = fxp_mul32_Q32(tmp5<<1, cos_5pi_18);
-        smull    r5,r1,lr,r1
-;    vec[7]  = fxp_mac32_Q32( vec[7], tmp6<<1, cos_17pi_18);
-        smlal    r2,r1,r7,r2
-;    vec[7]  = fxp_mac32_Q32( vec[7], tmp7<<1,    cos_pi_6);
-        smlal    r3,r1,r4,r3
-;    vec[7]  = fxp_mac32_Q32( vec[7], tmp8<<1, cos_11pi_18);
-        smlal    r12,r1,r9,r12
-        str      r1,[r0, #0x1c]
-        ldmfd    sp!,{r4-r10,pc}
-|cos_2pi_9|
-        DCD      0x620dbe80
-|cos_4pi_9|
-        DCD      0x163a1a80
-|cos_pi_9|
-        DCD      0x7847d900
-|cos_5pi_9|
-        DCD      0x87b82700
-|cos_8pi_9|
-        DCD      0xd438af00
-|cos_11pi_18|
-        DCD      0xadb92280
-|cos_13pi_18|
-        DCD      0x91261480
-|cos_17pi_18|
-        DCD      0x81f1d200
-|cos_pi_6|
-        DCD      0x6ed9eb80
-        ENDP
-
-
-
-
-
-        END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s
deleted file mode 100644
index 9401d8c..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s
+++ /dev/null
@@ -1,369 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; 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.
-; -------------------------------------------------------------------
-
-;
-;
-;   Filename: pvmp3_dct_18.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who:                                   Date: MM/DD/YYYY
-; Description: 
-;
-;------------------------------------------------------------------------------
-
-        EXPORT pvmp3_mdct_18
-
-        IMPORT ||Lib$$Request$$armlib|| [WEAK]
-        IMPORT ||Lib$$Request$$cpplib|| [WEAK]
-        IMPORT pvmp3_dct_9
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_mdct_18| PROC
-        stmfd    sp!,{r4-r10,lr}
-        mov      r7,r2
-        ldr      r2,table
-        mov      r6,r1
-        add      r3,r2,#0x24
-        add      r12,r3,#0x44
-        add      r1,r0,#0x44
-        mov      r5,r0
-
-;    for ( i=9; i!=0; i--)
-;    {
-
-        mov      r4,#9
-Loop_1
-
-;       tmp  = *(pt_vec);
-;		tmp1 = *(pt_vec_o);
-
-        ldr      lr,[r0]		;; tmp  == lr
-        ldr      r8,[r3],#4		;; tmp1 == r8
-
-;        tmp  = fxp_mul32_Q32( tmp<<1,  *(pt_cos++  ));
-;        tmp1 = fxp_mul32_Q27( tmp1, *(pt_cos_x--));
-
-        mov      lr,lr,lsl #1
-        smull    r10,lr,r8,lr
-        ldr      r8,[r12],#-4
-        ldr      r9,[r1]
-        subs     r4,r4,#1
-        smull    r9,r10,r8,r9
-        mov      r8,r9,lsr #27
-        add      r8,r8,r10,lsl #5
-
-;        *(pt_vec++)   =   tmp + tmp1 ;
-;        *(pt_vec_o--) = fxp_mul32_Q28( (tmp - tmp1), *(pt_cos_split++));
-
-        add      r9,lr,r8
-        sub      r8,lr,r8
-        ldr      lr,[r2],#4
-        str      r9,[r0],#4
-        smull    r8,r9,lr,r8
-        mov      lr,r8,lsr #28
-        add      lr,lr,r9,lsl #4
-        str      lr,[r1],#-4
-        bne      Loop_1
-
-;		}
-
-        mov      r0,r5			;; r0 = vec
-        bl       pvmp3_dct_9
-        add      r0,r5,#0x24	;; r0 = &vec[9]
-        bl       pvmp3_dct_9
-
-        ldr      r0,[r5,#0x20]
-        ldr      r2,[r5,#0x40]
-        str      r0,[r5,#0x40]
-        ldr      r0,[r5,#0x1c]
-        ldr      r3,[r5,#0x38]
-        str      r0,[r5,#0x38]
-        ldr      r1,[r5,#0x18]
-        ldr      r0,[r5,#0x30]
-        str      r1,[r5,#0x30]
-        ldr      r12,[r5,#0x14]
-        ldr      r1,[r5,#0x28]
-        str      r12,[r5,#0x28]
-        ldr      r12,[r5,#0x10]
-        str      r12,[r5,#0x20]
-        ldr      r12,[r5,#0xc]
-        str      r12,[r5,#0x18]
-        ldr      r12,[r5,#8]
-        str      r12,[r5,#0x10]
-        ldr      r12,[r5,#4]
-        str      r12,[r5,#8]
-        ldr      r12,[r5,#0x24]
-        sub      r12,r12,r1
-        str      r12,[r5,#4]
-        ldr      r12,[r5,#0x2c]
-        sub      r1,r12,r1
-        str      r1,[r5,#0xc]
-        sub      r1,r12,r0
-        str      r1,[r5,#0x14]
-        ldr      r1,[r5,#0x34]
-        sub      r0,r1,r0
-        str      r0,[r5,#0x1c]
-        sub      r0,r1,r3
-        str      r0,[r5,#0x24]
-        ldr      r1,[r5,#0x3c]
-        sub      r3,r1,r3
-        sub      r1,r1,r2
-        str      r1,[r5,#0x34]
-        str      r3,[r5,#0x2c]
-        ldr      r1,[r5,#0x44]
-        sub      r1,r1,r2
-        str      r1,[r5,#0x3c]
-        ldr      r12,[r5,#0]
-
-Loop_2
-        add      r1,r5,r4,lsl #2
-        ldr      r2,[r1,#0x28]
-        ldr      r3,[r6,r4,lsl #2]
-        add      r0,r0,r2
-        str      r0,[r1,#0x28]
-        ldr      lr,[r7,r4,lsl #2]
-        ldr      r1,[r1,#4]
-        smlal    r0,r3,lr,r0
-        mov      r0,r2
-        add      r2,r12,r1
-        rsb      r2,r2,#0
-        str      r3,[r5,r4,lsl #2]
-        str      r2,[r6,r4,lsl #2]
-        add      r4,r4,#1
-        cmp      r4,#6
-        mov      r12,r1
-
-        blt      Loop_2
-
-        ldr      r1,[r5,#0x40]
-        ldr      r2,[r6,#0x18]
-        add      r3,r0,r1
-        str      r3,[r5,#0x40]
-        ldr      lr,[r7,r4,lsl #2]
-        mov      r3,r3,lsl #1
-        ldr      r0,[r5,#0x1c]
-        smlal    r3,r2,lr,r3
-        add      r3,r12,r0
-        str      r2,[r5,#0x18]
-        ldr      r2,[r6,#0x1c]
-        rsb      r3,r3,#0
-        str      r3,[r6,#0x18]
-        ldr      r3,[r5,#0x20]
-        add      r0,r3,r0
-        rsb      r0,r0,#0
-        str      r0,[r6,#0x1c]
-        ldr      r3,[r5,#0x44]
-        ldr      r0,[r6,#0x20]
-        add      r3,r3,r1
-        mov      r1,r2
-        ldr      r10,[r7,#0x1c]
-        mov      r2,r3,lsl #1
-        smlal    r12,r1,r10,r2
-        str      r1,[r5,#0x1c]
-        ldr      r1,[r5,#0x20]
-        ldr      r3,[r5,#0x24]
-        add      r1,r1,r3
-        rsb      r1,r1,#0
-        str      r1,[r6,#0x20]
-        ldr      r1,[r5,#0x44]
-        ldr      r3,[r7,#0x20]
-        mov      r1,r1,lsl #1
-        smlal    r12,r0,r3,r1
-        ldr      lr,[r7,#0x24]
-        ldr      r3,[r6,#0x24]
-        str      r0,[r5,#0x20]
-        smlal    r1,r3,lr,r1
-        ldr      r0,[r6,#0x40]
-        ldr      r12,[r6,#0x44]
-        str      r3,[r5,#0x24]
-        ldr      r1,[r5,#0x28]
-        ldr      r3,[r7,#0x44]
-        mov      r1,r1,lsl #1
-        smlal    r1,r12,r3,r1
-        ldr      r1,[r5,#0x40]
-        str      r12,[r5,#0x44]
-        rsb      r8,r1,#0
-        str      r8,[r5,#0x28]
-        ldr      r1,[r5,#0x2c]
-        ldr      r3,[r7,#0x40]
-        mov      r1,r1,lsl #1
-        smlal    r1,r0,r3,r1
-        str      r0,[r5,#0x40]
-        ldr      r0,[r5,#0x3c]
-        ldr      r1,[r6,#0x38]
-        ldr      r3,[r6,#0x3c]
-        rsb      r9,r0,#0
-        str      r9,[r5,#0x2c]
-        ldr      r0,[r5,#0x30]
-        ldr      r12,[r7,#0x3c]
-        mov      r0,r0,lsl #1
-        smlal    r0,r3,r12,r0
-        str      r3,[r5,#0x3c]
-        ldr      r0,[r5,#0x38]
-        rsb      r0,r0,#0
-        str      r0,[r5,#0x30]
-        ldr      r3,[r5,#0x34]
-        ldr      r12,[r7,#0x38]
-        mov      r3,r3,lsl #1
-        smlal    r3,r1,r12,r3
-        mov      r0,r0,lsl #1
-        str      r1,[r5,#0x38]
-        ldr      r4,[r7,#0x34]
-        ldr      r1,[r6,#0x34]
-        ldr      r3,[r6,#0x30]
-        smlal    r0,r1,r4,r0
-        ldr      r12,[r6,#0x2c]
-        ldr      lr,[r6,#0x28]
-        str      r1,[r5,#0x34]
-        ldr      r1,[r7,#0x30]
-        mov      r0,r9,lsl #1
-        smlal    r0,r3,r1,r0
-        mov      r0,r8,lsl #1
-        ldr      r1,[r7,#0x2c]
-        str      r3,[r5,#0x30]
-        smlal    r0,r12,r1,r0
-        ldr      r0,[r7,#0x28]
-        str      r12,[r5,#0x2c]
-        smlal    r2,lr,r0,r2
-        str      lr,[r5,#0x28]
-        ldr      r1,[r6,#4]
-        ldr      r12,[r7,#0x48]
-        mov      r2,r1,lsl #1
-        ldr      r1,[r6,#0x20]
-        ldr      r0,[r6]
-        mov      r1,r1,lsl #1
-        smull    r4,lr,r12,r1
-        ldr      r3,[r6,#0x1c]
-        str      lr,[r6]
-        ldr      r12,[r7,#0x4c]
-        mov      r3,r3,lsl #1
-        smull    r4,lr,r12,r3
-        mov      r0,r0,lsl #1
-        ldr      r12,[r7,#0x64]
-        str      lr,[r6,#4]
-        smull    r4,lr,r12,r2
-        ldr      r12,[r7,#0x68]
-        str      lr,[r6,#0x1c]
-        smull    r4,lr,r12,r0
-        ldr      r12,[r7,#0x6c]
-        str      lr,[r6,#0x20]
-        smull    lr,r0,r12,r0
-        ldr      r12,[r7,#0x70]
-        str      r0,[r6,#0x24]
-        smull    r0,r2,r12,r2
-        ldr      r0,[r7,#0x88]
-        str      r2,[r6,#0x28]
-        smull    r3,r2,r0,r3
-        ldr      r0,[r7,#0x8c]
-        str      r2,[r6,#0x40]
-        smull    r2,r1,r0,r1
-        str      r1,[r6,#0x44]
-        ldr      r0,[r6,#0x18]
-        ldr      lr,[r7,#0x50]
-        mov      r1,r0,lsl #1
-        ldr      r0,[r6,#0x14]
-        smull    r5,r4,lr,r1
-        ldr      r12,[r6,#0x10]
-        mov      r3,r0,lsl #1
-        ldr      r0,[r6,#0xc]
-        mov      r12,r12,lsl #1
-        mov      r2,r0,lsl #1
-        ldr      r0,[r6,#8]
-        str      r4,[r6,#8]
-        ldr      lr,[r7,#0x54]
-        mov      r0,r0,lsl #1
-        smull    r5,r4,lr,r3
-        ldr      lr,[r7,#0x58]
-        str      r4,[r6,#0xc]
-        smull    r5,r4,lr,r12
-        ldr      lr,[r7,#0x5c]
-        str      r4,[r6,#0x10]
-        smull    r5,r4,lr,r2
-        ldr      lr,[r7,#0x60]
-        str      r4,[r6,#0x14]
-        smull    r5,r4,lr,r0
-        ldr      lr,[r7,#0x74]
-        str      r4,[r6,#0x18]
-        smull    r4,r0,lr,r0
-        ldr      lr,[r7,#0x78]
-        str      r0,[r6,#0x2c]
-        smull    r0,r2,lr,r2
-        ldr      r0,[r7,#0x7c]
-        str      r2,[r6,#0x30]
-        smull    r12,r2,r0,r12
-        ldr      r0,[r7,#0x80]
-        str      r2,[r6,#0x34]
-        smull    r3,r2,r0,r3
-        ldr      r0,[r7,#0x84]
-        str      r2,[r6,#0x38]
-        smull    r2,r1,r0,r1
-        str      r1,[r6,#0x3c]
-        ldmfd    sp!,{r4-r10,pc}
-table
-        DCD      ||.constdata$1||
-        ENDP
-
-;------------------------------------------------------------------------------
-
- AREA |.constdata|, DATA, READONLY, ALIGN=2
-
-;------------------------------------------------------------------------------
-
-||.constdata$1||
-cosTerms_dct18
-        DCD      0x0807d2b0
-        DCD      0x08483ee0
-        DCD      0x08d3b7d0
-        DCD      0x09c42570
-        DCD      0x0b504f30
-        DCD      0x0df29440
-        DCD      0x12edfb20
-        DCD      0x1ee8dd40
-        DCD      0x5bca2a00
-cosTerms_1_ov_cos_phi
-        DCD      0x400f9c00
-        DCD      0x408d6080
-        DCD      0x418dcb80
-        DCD      0x431b1a00
-        DCD      0x4545ea00
-        DCD      0x48270680
-        DCD      0x4be25480
-        DCD      0x50ab9480
-        DCD      0x56ce4d80
-        DCD      0x05ebb630
-        DCD      0x06921a98
-        DCD      0x0771d3a8
-        DCD      0x08a9a830
-        DCD      0x0a73d750
-        DCD      0x0d4d5260
-        DCD      0x127b1ca0
-        DCD      0x1ea52b40
-        DCD      0x5bb3cc80
-
-
-
-        END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm
deleted file mode 100644
index 5be75d4..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm
+++ /dev/null
@@ -1,366 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; 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.
-; -------------------------------------------------------------------
-
-;
-;
-;   Filename: pvmp3_dct_18.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who:                                   Date: MM/DD/YYYY
-; Description: 
-;
-;------------------------------------------------------------------------------
-
-        EXPORT |pvmp3_mdct_18|
-
-        IMPORT pvmp3_dct_9
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_mdct_18| PROC
-        stmfd    sp!,{r4-r10,lr}
-        mov      r7,r2
-        ldr      r2,table
-        mov      r6,r1
-        add      r3,r2,#0x24
-        add      r12,r3,#0x44
-        add      r1,r0,#0x44
-        mov      r5,r0
-
-;    for ( i=9; i!=0; i--)
-;    {
-
-        mov      r4,#9
-Loop_1
-
-;       tmp  = *(pt_vec);
-;		tmp1 = *(pt_vec_o);
-
-        ldr      lr,[r0]		;; tmp  == lr
-        ldr      r8,[r3],#4		;; tmp1 == r8
-
-;        tmp  = fxp_mul32_Q32( tmp<<1,  *(pt_cos++  ));
-;        tmp1 = fxp_mul32_Q27( tmp1, *(pt_cos_x--));
-
-        mov      lr,lr,lsl #1
-        smull    r10,lr,r8,lr
-        ldr      r8,[r12],#-4
-        ldr      r9,[r1]
-        subs     r4,r4,#1
-        smull    r9,r10,r8,r9
-        mov      r8,r9,lsr #27
-        add      r8,r8,r10,lsl #5
-
-;        *(pt_vec++)   =   tmp + tmp1 ;
-;        *(pt_vec_o--) = fxp_mul32_Q28( (tmp - tmp1), *(pt_cos_split++));
-
-        add      r9,lr,r8
-        sub      r8,lr,r8
-        ldr      lr,[r2],#4
-        str      r9,[r0],#4
-        smull    r8,r9,lr,r8
-        mov      lr,r8,lsr #28
-        add      lr,lr,r9,lsl #4
-        str      lr,[r1],#-4
-        bne      Loop_1
-
-;		}
-
-        mov      r0,r5			;; r0 = vec
-        bl       pvmp3_dct_9
-        add      r0,r5,#0x24	;; r0 = &vec[9]
-        bl       pvmp3_dct_9
-
-        ldr      r0,[r5,#0x20]
-        ldr      r2,[r5,#0x40]
-        str      r0,[r5,#0x40]
-        ldr      r0,[r5,#0x1c]
-        ldr      r3,[r5,#0x38]
-        str      r0,[r5,#0x38]
-        ldr      r1,[r5,#0x18]
-        ldr      r0,[r5,#0x30]
-        str      r1,[r5,#0x30]
-        ldr      r12,[r5,#0x14]
-        ldr      r1,[r5,#0x28]
-        str      r12,[r5,#0x28]
-        ldr      r12,[r5,#0x10]
-        str      r12,[r5,#0x20]
-        ldr      r12,[r5,#0xc]
-        str      r12,[r5,#0x18]
-        ldr      r12,[r5,#8]
-        str      r12,[r5,#0x10]
-        ldr      r12,[r5,#4]
-        str      r12,[r5,#8]
-        ldr      r12,[r5,#0x24]
-        sub      r12,r12,r1
-        str      r12,[r5,#4]
-        ldr      r12,[r5,#0x2c]
-        sub      r1,r12,r1
-        str      r1,[r5,#0xc]
-        sub      r1,r12,r0
-        str      r1,[r5,#0x14]
-        ldr      r1,[r5,#0x34]
-        sub      r0,r1,r0
-        str      r0,[r5,#0x1c]
-        sub      r0,r1,r3
-        str      r0,[r5,#0x24]
-        ldr      r1,[r5,#0x3c]
-        sub      r3,r1,r3
-        sub      r1,r1,r2
-        str      r1,[r5,#0x34]
-        str      r3,[r5,#0x2c]
-        ldr      r1,[r5,#0x44]
-        sub      r1,r1,r2
-        str      r1,[r5,#0x3c]
-        ldr      r12,[r5,#0]
-
-Loop_2
-        add      r1,r5,r4,lsl #2
-        ldr      r2,[r1,#0x28]
-        ldr      r3,[r6,r4,lsl #2]
-        add      r0,r0,r2
-        str      r0,[r1,#0x28]
-        ldr      lr,[r7,r4,lsl #2]
-        ldr      r1,[r1,#4]
-        smlal    r0,r3,lr,r0
-        mov      r0,r2
-        add      r2,r12,r1
-        rsb      r2,r2,#0
-        str      r3,[r5,r4,lsl #2]
-        str      r2,[r6,r4,lsl #2]
-        add      r4,r4,#1
-        cmp      r4,#6
-        mov      r12,r1
-
-        blt      Loop_2
-
-        ldr      r1,[r5,#0x40]
-        ldr      r2,[r6,#0x18]
-        add      r3,r0,r1
-        str      r3,[r5,#0x40]
-        ldr      lr,[r7,r4,lsl #2]
-        mov      r3,r3,lsl #1
-        ldr      r0,[r5,#0x1c]
-        smlal    r3,r2,lr,r3
-        add      r3,r12,r0
-        str      r2,[r5,#0x18]
-        ldr      r2,[r6,#0x1c]
-        rsb      r3,r3,#0
-        str      r3,[r6,#0x18]
-        ldr      r3,[r5,#0x20]
-        add      r0,r3,r0
-        rsb      r0,r0,#0
-        str      r0,[r6,#0x1c]
-        ldr      r3,[r5,#0x44]
-        ldr      r0,[r6,#0x20]
-        add      r3,r3,r1
-        mov      r1,r2
-        ldr      r10,[r7,#0x1c]
-        mov      r2,r3,lsl #1
-        smlal    r12,r1,r10,r2
-        str      r1,[r5,#0x1c]
-        ldr      r1,[r5,#0x20]
-        ldr      r3,[r5,#0x24]
-        add      r1,r1,r3
-        rsb      r1,r1,#0
-        str      r1,[r6,#0x20]
-        ldr      r1,[r5,#0x44]
-        ldr      r3,[r7,#0x20]
-        mov      r1,r1,lsl #1
-        smlal    r12,r0,r3,r1
-        ldr      lr,[r7,#0x24]
-        ldr      r3,[r6,#0x24]
-        str      r0,[r5,#0x20]
-        smlal    r1,r3,lr,r1
-        ldr      r0,[r6,#0x40]
-        ldr      r12,[r6,#0x44]
-        str      r3,[r5,#0x24]
-        ldr      r1,[r5,#0x28]
-        ldr      r3,[r7,#0x44]
-        mov      r1,r1,lsl #1
-        smlal    r1,r12,r3,r1
-        ldr      r1,[r5,#0x40]
-        str      r12,[r5,#0x44]
-        rsb      r8,r1,#0
-        str      r8,[r5,#0x28]
-        ldr      r1,[r5,#0x2c]
-        ldr      r3,[r7,#0x40]
-        mov      r1,r1,lsl #1
-        smlal    r1,r0,r3,r1
-        str      r0,[r5,#0x40]
-        ldr      r0,[r5,#0x3c]
-        ldr      r1,[r6,#0x38]
-        ldr      r3,[r6,#0x3c]
-        rsb      r9,r0,#0
-        str      r9,[r5,#0x2c]
-        ldr      r0,[r5,#0x30]
-        ldr      r12,[r7,#0x3c]
-        mov      r0,r0,lsl #1
-        smlal    r0,r3,r12,r0
-        str      r3,[r5,#0x3c]
-        ldr      r0,[r5,#0x38]
-        rsb      r0,r0,#0
-        str      r0,[r5,#0x30]
-        ldr      r3,[r5,#0x34]
-        ldr      r12,[r7,#0x38]
-        mov      r3,r3,lsl #1
-        smlal    r3,r1,r12,r3
-        mov      r0,r0,lsl #1
-        str      r1,[r5,#0x38]
-        ldr      r4,[r7,#0x34]
-        ldr      r1,[r6,#0x34]
-        ldr      r3,[r6,#0x30]
-        smlal    r0,r1,r4,r0
-        ldr      r12,[r6,#0x2c]
-        ldr      lr,[r6,#0x28]
-        str      r1,[r5,#0x34]
-        ldr      r1,[r7,#0x30]
-        mov      r0,r9,lsl #1
-        smlal    r0,r3,r1,r0
-        mov      r0,r8,lsl #1
-        ldr      r1,[r7,#0x2c]
-        str      r3,[r5,#0x30]
-        smlal    r0,r12,r1,r0
-        ldr      r0,[r7,#0x28]
-        str      r12,[r5,#0x2c]
-        smlal    r2,lr,r0,r2
-        str      lr,[r5,#0x28]
-        ldr      r1,[r6,#4]
-        ldr      r12,[r7,#0x48]
-        mov      r2,r1,lsl #1
-        ldr      r1,[r6,#0x20]
-        ldr      r0,[r6]
-        mov      r1,r1,lsl #1
-        smull    r4,lr,r12,r1
-        ldr      r3,[r6,#0x1c]
-        str      lr,[r6]
-        ldr      r12,[r7,#0x4c]
-        mov      r3,r3,lsl #1
-        smull    r4,lr,r12,r3
-        mov      r0,r0,lsl #1
-        ldr      r12,[r7,#0x64]
-        str      lr,[r6,#4]
-        smull    r4,lr,r12,r2
-        ldr      r12,[r7,#0x68]
-        str      lr,[r6,#0x1c]
-        smull    r4,lr,r12,r0
-        ldr      r12,[r7,#0x6c]
-        str      lr,[r6,#0x20]
-        smull    lr,r0,r12,r0
-        ldr      r12,[r7,#0x70]
-        str      r0,[r6,#0x24]
-        smull    r0,r2,r12,r2
-        ldr      r0,[r7,#0x88]
-        str      r2,[r6,#0x28]
-        smull    r3,r2,r0,r3
-        ldr      r0,[r7,#0x8c]
-        str      r2,[r6,#0x40]
-        smull    r2,r1,r0,r1
-        str      r1,[r6,#0x44]
-        ldr      r0,[r6,#0x18]
-        ldr      lr,[r7,#0x50]
-        mov      r1,r0,lsl #1
-        ldr      r0,[r6,#0x14]
-        smull    r5,r4,lr,r1
-        ldr      r12,[r6,#0x10]
-        mov      r3,r0,lsl #1
-        ldr      r0,[r6,#0xc]
-        mov      r12,r12,lsl #1
-        mov      r2,r0,lsl #1
-        ldr      r0,[r6,#8]
-        str      r4,[r6,#8]
-        ldr      lr,[r7,#0x54]
-        mov      r0,r0,lsl #1
-        smull    r5,r4,lr,r3
-        ldr      lr,[r7,#0x58]
-        str      r4,[r6,#0xc]
-        smull    r5,r4,lr,r12
-        ldr      lr,[r7,#0x5c]
-        str      r4,[r6,#0x10]
-        smull    r5,r4,lr,r2
-        ldr      lr,[r7,#0x60]
-        str      r4,[r6,#0x14]
-        smull    r5,r4,lr,r0
-        ldr      lr,[r7,#0x74]
-        str      r4,[r6,#0x18]
-        smull    r4,r0,lr,r0
-        ldr      lr,[r7,#0x78]
-        str      r0,[r6,#0x2c]
-        smull    r0,r2,lr,r2
-        ldr      r0,[r7,#0x7c]
-        str      r2,[r6,#0x30]
-        smull    r12,r2,r0,r12
-        ldr      r0,[r7,#0x80]
-        str      r2,[r6,#0x34]
-        smull    r3,r2,r0,r3
-        ldr      r0,[r7,#0x84]
-        str      r2,[r6,#0x38]
-        smull    r2,r1,r0,r1
-        str      r1,[r6,#0x3c]
-        ldmfd    sp!,{r4-r10,pc}
-table
-        DCD      cosTerms_dct18
-        ENDP
-
-;------------------------------------------------------------------------------
-
- AREA |.constdata|, DATA, READONLY, ALIGN=2
-
-;------------------------------------------------------------------------------
-
-cosTerms_dct18
-        DCD      0x0807d2b0
-        DCD      0x08483ee0
-        DCD      0x08d3b7d0
-        DCD      0x09c42570
-        DCD      0x0b504f30
-        DCD      0x0df29440
-        DCD      0x12edfb20
-        DCD      0x1ee8dd40
-        DCD      0x5bca2a00
-cosTerms_1_ov_cos_phi
-        DCD      0x400f9c00
-        DCD      0x408d6080
-        DCD      0x418dcb80
-        DCD      0x431b1a00
-        DCD      0x4545ea00
-        DCD      0x48270680
-        DCD      0x4be25480
-        DCD      0x50ab9480
-        DCD      0x56ce4d80
-        DCD      0x05ebb630
-        DCD      0x06921a98
-        DCD      0x0771d3a8
-        DCD      0x08a9a830
-        DCD      0x0a73d750
-        DCD      0x0d4d5260
-        DCD      0x127b1ca0
-        DCD      0x1ea52b40
-        DCD      0x5bb3cc80
-
-
-
-        END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s
deleted file mode 100644
index abec599..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s
+++ /dev/null
@@ -1,237 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; 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.
-; -------------------------------------------------------------------
-
-;
-;
-;   Filename: pvmp3_polyphase_filter_window.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who:                                   Date: MM/DD/YYYY
-; Description: 
-;
-;------------------------------------------------------------------------------
-
-        EXPORT pvmp3_polyphase_filter_window
-
-        IMPORT ||Lib$$Request$$armlib|| [WEAK]
-        IMPORT ||Lib$$Request$$cpplib|| [WEAK]
-        IMPORT pqmfSynthWin
-
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_polyphase_filter_window| PROC
-
-        stmfd    sp!,{r0-r2,r4-r11,lr}
-
-        sub      sp,sp,#4
-        ldr      r2,[sp,#0xc]
-        ldr      r1,PolyPh_filter_coeff
-		
-        sub      r2,r2,#1
-        mov      r10,#1
-        str      r2,[sp]
-
-; Accumulators r9, r11::> Initialization
-
-Loop_j
-        mov      r9,  #0x20
-        mov      r11, #0x20
-        mov      r4,  #0x10
-Loop_i
-        add      r2,r4,r10
-        add      r3,r0,r2,lsl #2
-        sub      r2,r4,r10
-        ldr      r5,[r3]
-        ldr      lr,[r1]
-        add      r12,r0,r2,lsl #2
-        ldr      r6,[r12,#0x780]
-        smlal    r2,r9,lr,r5
-        smlal    r2,r11,lr,r6
-        ldr      r2,[r1,#4]
-        ldr      r7,[r12,#0x80]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        sub      r9,r9,r5
-        ldr      r5,[r1,#8]
-        ldr      r8,[r3,#0x700]
-        add      r4,r4,#0x200
-        smlal    r6,r9,r5,r7
-        smull    r6,r2,r5,r8
-        ldr      r5,[r1,#0xc]
-        sub      r11,r11,r2
-        smlal    r8,r9,r5,r8
-        smlal    r7,r11,r5,r7
-        ldr      r5,[r3,#0x100]
-        ldr      r2,[r1,#0x10]
-        ldr      r6,[r12,#0x680]
-        smlal    lr,r9,r2,r5
-        smlal    lr,r11,r2,r6
-        ldr      r2,[r1,#0x14]
-        ldr      r7,[r12,#0x180]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        ldr      r6,[r1,#0x18]
-        ldr      r8,[r3,#0x600]
-        sub      r9,r9,r5
-        smlal    r5,r9,r6,r7
-        smull    r2,r5,r6,r8
-        ldr      r6,[r1,#0x1c]
-        sub      r11,r11,r5
-        smlal    r8,r9,r6,r8
-        ldr      r2,[r1,#0x20]
-        ldr      r5,[r3,#0x200]
-        smlal    r7,r11,r6,r7
-        ldr      r6,[r12,#0x580]
-        smlal    lr,r9,r2,r5
-        smlal    lr,r11,r2,r6
-        ldr      r2,[r1,#0x24]
-        ldr      r7,[r12,#0x280]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        ldr      r6,[r1,#0x28]
-        ldr      r8,[r3,#0x500]
-        sub      r9,r9,r5
-        smlal    r5,r9,r6,r7
-        smull    r2,r5,r6,r8
-        ldr      r6,[r1,#0x2c]
-        sub      r11,r11,r5
-
-        smlal    r8,r9,r6,r8
-        smlal    r7,r11,r6,r7
-        ldr      r5,[r3,#0x300]
-        ldr      r8,[r1,#0x30]
-        ldr      r6,[r12,#0x480]
-        smlal    r7,r9,r8,r5
-        smlal    r7,r11,r8,r6
-        ldr      r8,[r1,#0x34]
-        ldr      r12,[r12,#0x380]
-        smlal    r5,r11,r8,r5
-        smull    r6,r5,r8,r6
-        ldr      r6,[r1,#0x38]
-
-
-        ldr      r3,[r3,#0x400]
-        sub      r9,r9,r5
-        smlal    r7,r9,r6,r12
-        smull    r8,r7,r6,r3
-        cmp      r4,#0x210
-        sub      r11,r11,r7
-
-        ldr      r2,[r1,#0x3c]
-        add      r1,r1,#0x40
-        smlal    r3,r9,r2,r3
-        smlal    r12,r11,r2,r12
-
-        blt      Loop_i
-
-        mov      r3,r9, asr #6
-        mov      r4,r3, asr #15
-        teq      r4,r3, asr #31
-        ldr      r12,LOW_16BITS
-        ldr      r2,[sp]
-        eorne    r3,r12,r3,asr #31
-        ldr      r4,[sp,#8]
-        mov      r2,r10,lsl r2
-        add      r4,r4,r2,lsl #1
-        strh     r3,[r4]
-
-        mov      r3,r11,asr #6
-        mov      r4,r3,asr #15
-        teq      r4,r3,asr #31
-        eorne    r3,r12,r3,asr #31
-        ldr      r12,[sp,#0xc]
-        ldr      r11,[sp,#8]
-        rsb      r2,r2,r12,lsl #5
-        add      r2,r11,r2,lsl #1
-        strh     r3,[r2]
-
-        add      r10,r10,#1
-        cmp      r10,#0x10
-        blt      Loop_j
-
-; Accumulators r4, r5 Initialization
-
-        mov      r4,#0x20
-        mov      r5,#0x20
-        mov      r3,#0x10
-PolyPh_filter_loop2
-        add      r2,r0,r3,lsl #2
-        ldr      r12,[r2]
-        ldr      r8,[r1]
-        ldr      r6,[r2,#0x80]
-        smlal    r12,r4,r8,r12
-        ldr      r12,[r1,#4]
-        ldr      r7,[r2,#0x40]
-        smlal    r6,r4,r12,r6
-
-        ldr      r12,[r1,#8]
-        ldr      r6,[r2,#0x180]
-        smlal    r7,r5,r12,r7
-        ldr      r12,[r2,#0x100]
-        ldr      r7,[r1,#0xc]
-        ldr      r2,[r2,#0x140]
-        smlal    r12,r4,r7,r12
-        ldr      r12,[r1,#0x10]
-        add      r3,r3,#0x80
-        smlal    r6,r4,r12,r6
-        ldr      r6,[r1,#0x14]
-        cmp      r3,#0x210
-        smlal    r2,r5,r6,r2
-        add      r1,r1,#0x18
-
-        blt      PolyPh_filter_loop2
-        mov      r0,r4,asr #6
-        mov      r2,r0,asr #15
-        teq      r2,r0,asr #31
-        ldrne    r12,LOW_16BITS
-        ldr      r1,[sp,#8]
-        eorne    r0,r12,r0,asr #31
-        strh     r0,[r1,#0]
-        mov      r0,r5,asr #6
-        mov      r2,r0,asr #15
-        teq      r2,r0,asr #31
-        ldrne    r12,LOW_16BITS
-        ldr      r2,[sp]
-        mov      r1,#0x10
-        eorne    r0,r12,r0,asr #31
-        ldr      r12,[sp,#8]
-        mov      r1,r1,lsl r2
-        add      r1,r12,r1,lsl #1
-        strh     r0,[r1]
-        add      sp,sp,#0x10
-        ldmfd    sp!,{r4-r11,pc}
-
-
-PolyPh_filter_coeff
-        DCD      pqmfSynthWin
-LOW_16BITS
-        DCD      0x00007fff
-
-        ENDP
-
-
-        END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm
deleted file mode 100644
index f957267..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm
+++ /dev/null
@@ -1,231 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; 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.
-; -------------------------------------------------------------------
-
-;
-;
-;   Filename: pvmp3_polyphase_filter_window.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who:                                   Date: MM/DD/YYYY
-; Description: 
-;
-;------------------------------------------------------------------------------
-
-	CODE32
-
-	AREA	|.drectve|, DRECTVE
-
-	EXPORT	|pvmp3_polyphase_filter_window|
-	IMPORT	|pqmfSynthWin|
-
-	AREA	|.pdata|, PDATA
-
-	AREA	|.text|, CODE, ARM
-
-|pvmp3_polyphase_filter_window| PROC
-        stmfd    sp!,{r0-r2,r4-r11,lr}
-
-        sub      sp,sp,#4
-        ldr      r2,[sp,#0xc]
-        ldr      r1,PolyPh_filter_coeff
-		
-        sub      r2,r2,#1
-        mov      r10,#1
-        str      r2,[sp]
-
-; Accumulators r9, r11::> Initialization
-
-Loop_j
-        mov      r9,  #0x20
-        mov      r11, #0x20
-        mov      r4,  #0x10
-Loop_i
-        add      r2,r4,r10
-        add      r3,r0,r2,lsl #2
-        sub      r2,r4,r10
-        ldr      r5,[r3]
-        ldr      lr,[r1]
-        add      r12,r0,r2,lsl #2
-        ldr      r6,[r12,#0x780]
-        smlal    r2,r9,lr,r5
-        smlal    r2,r11,lr,r6
-        ldr      r2,[r1,#4]
-        ldr      r7,[r12,#0x80]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        sub      r9,r9,r5
-        ldr      r5,[r1,#8]
-        ldr      r8,[r3,#0x700]
-        add      r4,r4,#0x200
-        smlal    r6,r9,r5,r7
-        smull    r6,r2,r5,r8
-        ldr      r5,[r1,#0xc]
-        sub      r11,r11,r2
-        smlal    r8,r9,r5,r8
-        smlal    r7,r11,r5,r7
-        ldr      r5,[r3,#0x100]
-        ldr      r2,[r1,#0x10]
-        ldr      r6,[r12,#0x680]
-        smlal    lr,r9,r2,r5
-        smlal    lr,r11,r2,r6
-        ldr      r2,[r1,#0x14]
-        ldr      r7,[r12,#0x180]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        ldr      r6,[r1,#0x18]
-        ldr      r8,[r3,#0x600]
-        sub      r9,r9,r5
-        smlal    r5,r9,r6,r7
-        smull    r2,r5,r6,r8
-        ldr      r6,[r1,#0x1c]
-        sub      r11,r11,r5
-        smlal    r8,r9,r6,r8
-        ldr      r2,[r1,#0x20]
-        ldr      r5,[r3,#0x200]
-        smlal    r7,r11,r6,r7
-        ldr      r6,[r12,#0x580]
-        smlal    lr,r9,r2,r5
-        smlal    lr,r11,r2,r6
-        ldr      r2,[r1,#0x24]
-        ldr      r7,[r12,#0x280]
-        smlal    r5,r11,r2,r5
-        smull    r6,r5,r2,r6
-        ldr      r6,[r1,#0x28]
-        ldr      r8,[r3,#0x500]
-        sub      r9,r9,r5
-        smlal    r5,r9,r6,r7
-        smull    r2,r5,r6,r8
-        ldr      r6,[r1,#0x2c]
-        sub      r11,r11,r5
-
-        smlal    r8,r9,r6,r8
-        smlal    r7,r11,r6,r7
-        ldr      r5,[r3,#0x300]
-        ldr      r8,[r1,#0x30]
-        ldr      r6,[r12,#0x480]
-        smlal    r7,r9,r8,r5
-        smlal    r7,r11,r8,r6
-        ldr      r8,[r1,#0x34]
-        ldr      r12,[r12,#0x380]
-        smlal    r5,r11,r8,r5
-        smull    r6,r5,r8,r6
-        ldr      r6,[r1,#0x38]
-
-
-        ldr      r3,[r3,#0x400]
-        sub      r9,r9,r5
-        smlal    r7,r9,r6,r12
-        smull    r8,r7,r6,r3
-        cmp      r4,#0x210
-        sub      r11,r11,r7
-
-        ldr      r2,[r1,#0x3c]
-        add      r1,r1,#0x40
-        smlal    r3,r9,r2,r3
-        smlal    r12,r11,r2,r12
-
-        blt      Loop_i
-
-        mov      r3,r9, asr #6
-        mov      r4,r3, asr #15
-        teq      r4,r3, asr #31
-        ldr      r12,LOW_16BITS
-        ldr      r2,[sp]
-        eorne    r3,r12,r3,asr #31
-        ldr      r4,[sp,#8]
-        mov      r2,r10,lsl r2
-        add      r4,r4,r2,lsl #1
-        strh     r3,[r4]
-
-        mov      r3,r11,asr #6
-        mov      r4,r3,asr #15
-        teq      r4,r3,asr #31
-        eorne    r3,r12,r3,asr #31
-        ldr      r12,[sp,#0xc]
-        ldr      r11,[sp,#8]
-        rsb      r2,r2,r12,lsl #5
-        add      r2,r11,r2,lsl #1
-        strh     r3,[r2]
-
-        add      r10,r10,#1
-        cmp      r10,#0x10
-        blt      Loop_j
-
-; Accumulators r4, r5 Initialization
-
-        mov      r4,#0x20
-        mov      r5,#0x20
-        mov      r3,#0x10
-PolyPh_filter_loop2
-        add      r2,r0,r3,lsl #2
-        ldr      r12,[r2]
-        ldr      r8,[r1]
-        ldr      r6,[r2,#0x80]
-        smlal    r12,r4,r8,r12
-        ldr      r12,[r1,#4]
-        ldr      r7,[r2,#0x40]
-        smlal    r6,r4,r12,r6
-
-        ldr      r12,[r1,#8]
-        ldr      r6,[r2,#0x180]
-        smlal    r7,r5,r12,r7
-        ldr      r12,[r2,#0x100]
-        ldr      r7,[r1,#0xc]
-        ldr      r2,[r2,#0x140]
-        smlal    r12,r4,r7,r12
-        ldr      r12,[r1,#0x10]
-        add      r3,r3,#0x80
-        smlal    r6,r4,r12,r6
-        ldr      r6,[r1,#0x14]
-        cmp      r3,#0x210
-        smlal    r2,r5,r6,r2
-        add      r1,r1,#0x18
-
-        blt      PolyPh_filter_loop2
-        mov      r0,r4,asr #6
-        mov      r2,r0,asr #15
-        teq      r2,r0,asr #31
-        ldrne    r12,LOW_16BITS
-        ldr      r1,[sp,#8]
-        eorne    r0,r12,r0,asr #31
-        strh     r0,[r1,#0]
-        mov      r0,r5,asr #6
-        mov      r2,r0,asr #15
-        teq      r2,r0,asr #31
-        ldrne    r12,LOW_16BITS
-        ldr      r2,[sp]
-        mov      r1,#0x10
-        eorne    r0,r12,r0,asr #31
-        ldr      r12,[sp,#8]
-        mov      r1,r1,lsl r2
-        add      r1,r12,r1,lsl #1
-        strh     r0,[r1]
-        add      sp,sp,#0x10
-        ldmfd    sp!,{r4-r11,pc}
-
-
-PolyPh_filter_coeff
-        DCD      pqmfSynthWin
-LOW_16BITS
-        DCD      0x00007fff
-	
-		ENDP  ; |pvmp3_polyphase_filter_window|
-		END
-
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index d1afd8b..338e899 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -555,7 +555,9 @@
         }
 #endif
 
-        return OK;
+        if (!payload_unit_start_indicator) {
+            return OK;
+        }
     }
 
     mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index 39eedc0..d60dc2f 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -32,6 +32,8 @@
 
 LOCAL_CFLAGS += -Werror
 
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
 include $(BUILD_STATIC_LIBRARY)
 
 ################################################################################
@@ -57,4 +59,6 @@
 
 LOCAL_MODULE:= rtp_test
 
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
 # include $(BUILD_EXECUTABLE)
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 786bf0d..3a280f0 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -25,7 +25,8 @@
 	libmediaplayerservice \
 	libutils \
 	liblog \
-	libbinder
+	libbinder \
+	libsoundtriggerservice
 
 LOCAL_STATIC_LIBRARIES := \
 	libregistermsext
@@ -36,7 +37,8 @@
     frameworks/av/services/audioflinger \
     frameworks/av/services/audiopolicy \
     frameworks/av/services/camera/libcameraservice \
-    $(call include-path-for, audio-utils)
+    $(call include-path-for, audio-utils) \
+    frameworks/av/services/soundtrigger
 
 LOCAL_MODULE:= mediaserver
 LOCAL_32_BIT_ONLY := true
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index a347951..af1c9e6 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -34,6 +34,7 @@
 #include "MediaLogService.h"
 #include "MediaPlayerService.h"
 #include "AudioPolicyService.h"
+#include "SoundTriggerHwService.h"
 
 using namespace android;
 
@@ -128,6 +129,7 @@
         MediaPlayerService::instantiate();
         CameraService::instantiate();
         AudioPolicyService::instantiate();
+        SoundTriggerHwService::instantiate();
         registerExtensions();
         ProcessState::self()->startThreadPool();
         IPCThreadState::self()->joinThreadPool();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a4cad4e..527fd65 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -431,7 +431,7 @@
         if (mLogMemoryDealer != 0) {
             sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
             if (binder != 0) {
-                fdprintf(fd, "\nmedia.log:\n");
+                dprintf(fd, "\nmedia.log:\n");
                 Vector<String16> args;
                 binder->dump(fd, args);
             }
@@ -1266,7 +1266,7 @@
     :   RefBase(),
         mAudioFlinger(audioFlinger),
         // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
-        mMemoryDealer(new MemoryDealer(4 * 1024*1024, "AudioFlinger::Client")),
+        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
         mPid(pid),
         mTimedTrackCount(0)
 {
@@ -2609,7 +2609,7 @@
             }
         } else {
             if (fd >= 0) {
-                fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
+                dprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
             }
         }
         char teeTime[16];
@@ -2663,11 +2663,11 @@
             write(teeFd, &temp, sizeof(temp));
             close(teeFd);
             if (fd >= 0) {
-                fdprintf(fd, "tee copied to %s\n", teePath);
+                dprintf(fd, "tee copied to %s\n", teePath);
             }
         } else {
             if (fd >= 0) {
-                fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
+                dprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
             }
         }
     }
diff --git a/services/audioflinger/AudioWatchdog.cpp b/services/audioflinger/AudioWatchdog.cpp
index 93d185e..877e776 100644
--- a/services/audioflinger/AudioWatchdog.cpp
+++ b/services/audioflinger/AudioWatchdog.cpp
@@ -34,7 +34,7 @@
     } else {
         strcpy(buf, "N/A\n");
     }
-    fdprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
+    dprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
             mUnderruns, mLogs, buf);
 }
 
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index c9a3f10..c486630 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -26,7 +26,6 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include "Configuration.h"
-#include <sys/atomics.h>
 #include <time.h>
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -492,7 +491,7 @@
 void FastMixerDumpState::dump(int fd) const
 {
     if (mCommand == FastMixerState::INITIAL) {
-        fdprintf(fd, "  FastMixer not initialized\n");
+        dprintf(fd, "  FastMixer not initialized\n");
         return;
     }
 #define COMMAND_MAX 32
@@ -526,10 +525,10 @@
     double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
             (mMeasuredWarmupTs.tv_nsec / 1000000.0);
     double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
-    fdprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
-                 "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
-                 "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
-                 "            mixPeriod=%.2f ms\n",
+    dprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
+                "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
+                "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
+                "            mixPeriod=%.2f ms\n",
                  string, mWriteSequence, mFramesWritten,
                  mNumTracks, mWriteErrors, mUnderruns, mOverruns,
                  mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
@@ -581,26 +580,26 @@
 #endif
     }
     if (n) {
-        fdprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
-                     wall.n() * mixPeriodSec);
-        fdprintf(fd, "    wall clock time in ms per mix cycle:\n"
-                     "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                     wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
-                     wall.stddev()*1e-6);
-        fdprintf(fd, "    raw CPU load in us per mix cycle:\n"
-                     "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                     loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
-                     loadNs.stddev()*1e-3);
+        dprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
+                    wall.n() * mixPeriodSec);
+        dprintf(fd, "    wall clock time in ms per mix cycle:\n"
+                    "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+                    wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
+                    wall.stddev()*1e-6);
+        dprintf(fd, "    raw CPU load in us per mix cycle:\n"
+                    "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+                    loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
+                    loadNs.stddev()*1e-3);
     } else {
-        fdprintf(fd, "  No FastMixer statistics available currently\n");
+        dprintf(fd, "  No FastMixer statistics available currently\n");
     }
 #ifdef CPU_FREQUENCY_STATISTICS
-    fdprintf(fd, "  CPU clock frequency in MHz:\n"
-                 "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                 kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
-    fdprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
-                 "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
-                 loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
+    dprintf(fd, "  CPU clock frequency in MHz:\n"
+                "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+                kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
+    dprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
+                "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
+                loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
 #endif
     if (tail != NULL) {
         qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
@@ -611,12 +610,12 @@
             left.sample(tail[i]);
             right.sample(tail[n - (i + 1)]);
         }
-        fdprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
-                     "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
-                     "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                     left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
-                     right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
-                     right.stddev()*1e-6);
+        dprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
+                    "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
+                    "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+                    left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
+                    right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
+                    right.stddev()*1e-6);
         delete[] tail;
     }
 #endif
@@ -626,9 +625,9 @@
     // Instead we always display all tracks, with an indication
     // of whether we think the track is active.
     uint32_t trackMask = mTrackMask;
-    fdprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
+    dprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
             FastMixerState::kMaxFastTracks, trackMask);
-    fdprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
+    dprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
     for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
         bool isActive = trackMask & 1;
         const FastTrackDump *ftDump = &mTracks[i];
@@ -648,7 +647,7 @@
             mostRecent = "?";
             break;
         }
-        fdprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
+        dprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
                 (underruns.mBitFields.mFull) & UNDERRUN_MASK,
                 (underruns.mBitFields.mPartial) & UNDERRUN_MASK,
                 (underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/StateQueue.cpp
index 48399c0..7e01c9f 100644
--- a/services/audioflinger/StateQueue.cpp
+++ b/services/audioflinger/StateQueue.cpp
@@ -28,12 +28,12 @@
 #ifdef STATE_QUEUE_DUMP
 void StateQueueObserverDump::dump(int fd)
 {
-    fdprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
+    dprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
 }
 
 void StateQueueMutatorDump::dump(int fd)
 {
-    fdprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
+    dprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
             mPushDirty, mPushAck, mBlockedSequence);
 }
 #endif
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d6333be..d08c966 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -574,30 +574,30 @@
 
     bool locked = AudioFlinger::dumpTryLock(mLock);
     if (!locked) {
-        fdprintf(fd, "thread %p maybe dead locked\n", this);
+        dprintf(fd, "thread %p maybe dead locked\n", this);
     }
 
-    fdprintf(fd, "  I/O handle: %d\n", mId);
-    fdprintf(fd, "  TID: %d\n", getTid());
-    fdprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
-    fdprintf(fd, "  Sample rate: %u\n", mSampleRate);
-    fdprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
-    fdprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
-    fdprintf(fd, "  Channel Count: %u\n", mChannelCount);
-    fdprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
+    dprintf(fd, "  I/O handle: %d\n", mId);
+    dprintf(fd, "  TID: %d\n", getTid());
+    dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
+    dprintf(fd, "  Sample rate: %u\n", mSampleRate);
+    dprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
+    dprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
+    dprintf(fd, "  Channel Count: %u\n", mChannelCount);
+    dprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
             channelMaskToString(mChannelMask, mType != RECORD).string());
-    fdprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
-    fdprintf(fd, "  Frame size: %zu\n", mFrameSize);
-    fdprintf(fd, "  Pending config events:");
+    dprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
+    dprintf(fd, "  Frame size: %zu\n", mFrameSize);
+    dprintf(fd, "  Pending config events:");
     size_t numConfig = mConfigEvents.size();
     if (numConfig) {
         for (size_t i = 0; i < numConfig; i++) {
             mConfigEvents[i]->dump(buffer, SIZE);
-            fdprintf(fd, "\n    %s", buffer);
+            dprintf(fd, "\n    %s", buffer);
         }
-        fdprintf(fd, "\n");
+        dprintf(fd, "\n");
     } else {
-        fdprintf(fd, " none\n");
+        dprintf(fd, " none\n");
     }
 
     if (locked) {
@@ -1260,15 +1260,15 @@
 
     // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
     FastTrackUnderruns underruns = getFastTrackUnderruns(0);
-    fdprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
+    dprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
             underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
 
     size_t numtracks = mTracks.size();
     size_t numactive = mActiveTracks.size();
-    fdprintf(fd, "  %d Tracks", numtracks);
+    dprintf(fd, "  %d Tracks", numtracks);
     size_t numactiveseen = 0;
     if (numtracks) {
-        fdprintf(fd, " of which %d are active\n", numactive);
+        dprintf(fd, " of which %d are active\n", numactive);
         Track::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks; ++i) {
             sp<Track> track = mTracks[i];
@@ -1300,22 +1300,21 @@
     }
 
     write(fd, result.string(), result.size());
-
 }
 
 void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
 {
-    fdprintf(fd, "\nOutput thread %p:\n", this);
-    fdprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
-    fdprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
-    fdprintf(fd, "  Total writes: %d\n", mNumWrites);
-    fdprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
-    fdprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
-    fdprintf(fd, "  Suspend count: %d\n", mSuspended);
-    fdprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
-    fdprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
-    fdprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
-    fdprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
+    dprintf(fd, "\nOutput thread %p:\n", this);
+    dprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
+    dprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    dprintf(fd, "  Total writes: %d\n", mNumWrites);
+    dprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
+    dprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
+    dprintf(fd, "  Suspend count: %d\n", mSuspended);
+    dprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
+    dprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
+    dprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
+    dprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
 
     dumpBase(fd, args);
 }
@@ -3799,7 +3798,7 @@
 
     PlaybackThread::dumpInternals(fd, args);
 
-    fdprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
+    dprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
 
     // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
     const FastMixerDumpState copy(mFastMixerDumpState);
@@ -5717,12 +5716,12 @@
 
 void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
 {
-    fdprintf(fd, "\nInput thread %p:\n", this);
+    dprintf(fd, "\nInput thread %p:\n", this);
 
     if (mActiveTracks.size() > 0) {
-        fdprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
+        dprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
     } else {
-        fdprintf(fd, "  No active record clients\n");
+        dprintf(fd, "  No active record clients\n");
     }
     dprintf(fd, "  Fast track available: %s\n", mFastTrackAvail ? "yes" : "no");
 
@@ -5738,9 +5737,9 @@
     size_t numtracks = mTracks.size();
     size_t numactive = mActiveTracks.size();
     size_t numactiveseen = 0;
-    fdprintf(fd, "  %d Tracks", numtracks);
+    dprintf(fd, "  %d Tracks", numtracks);
     if (numtracks) {
-        fdprintf(fd, " of which %d are active\n", numactive);
+        dprintf(fd, " of which %d are active\n", numactive);
         RecordTrack::appendDumpHeader(result);
         for (size_t i = 0; i < numtracks ; ++i) {
             sp<RecordTrack> track = mTracks[i];
@@ -5754,7 +5753,7 @@
             }
         }
     } else {
-        fdprintf(fd, "\n");
+        dprintf(fd, "\n");
     }
 
     if (numactiveseen != numactive) {
diff --git a/services/audioflinger/tests/Android.mk b/services/audioflinger/tests/Android.mk
new file mode 100644
index 0000000..874f18f
--- /dev/null
+++ b/services/audioflinger/tests/Android.mk
@@ -0,0 +1,31 @@
+# Build the unit tests for audioflinger
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SHARED_LIBRARIES := \
+	liblog \
+	libutils \
+	libcutils \
+	libstlport \
+	libaudioutils \
+	libaudioresampler
+
+LOCAL_STATIC_LIBRARIES := \
+	libgtest \
+	libgtest_main
+
+LOCAL_C_INCLUDES := \
+	bionic \
+	bionic/libstdc++/include \
+	external/gtest/include \
+	external/stlport/stlport \
+	frameworks/av/services/audioflinger
+
+LOCAL_SRC_FILES := \
+	resampler_tests.cpp
+
+LOCAL_MODULE := resampler_tests
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/audioflinger/tests/build_and_run_all_unit_tests.sh b/services/audioflinger/tests/build_and_run_all_unit_tests.sh
new file mode 100755
index 0000000..2c453b0
--- /dev/null
+++ b/services/audioflinger/tests/build_and_run_all_unit_tests.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Android build environment not set"
+    exit -1
+fi
+
+# ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+pushd $ANDROID_BUILD_TOP/frameworks/av/services/audioflinger/
+pwd
+mm
+
+echo "waiting for device"
+adb root && adb wait-for-device remount
+adb push $OUT/system/lib/libaudioresampler.so /system/lib
+adb push $OUT/system/bin/resampler_tests /system/bin
+
+sh $ANDROID_BUILD_TOP/frameworks/av/services/audioflinger/tests/run_all_unit_tests.sh
+
+popd
diff --git a/services/audioflinger/tests/resampler_tests.cpp b/services/audioflinger/tests/resampler_tests.cpp
new file mode 100644
index 0000000..8f9c270
--- /dev/null
+++ b/services/audioflinger/tests/resampler_tests.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2014 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_NDEBUG 0
+#define LOG_TAG "audioflinger_resampler_tests"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <time.h>
+#include <math.h>
+#include <vector>
+#include <utility>
+#include <cutils/log.h>
+#include <gtest/gtest.h>
+#include <media/AudioBufferProvider.h>
+#include "AudioResampler.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+template<typename T, typename U>
+struct is_same
+{
+    static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T>  // partial specialization
+{
+    static const bool value = true;
+};
+
+template<typename T>
+static inline T convertValue(double val)
+{
+    if (is_same<T, int16_t>::value) {
+        return floor(val * 32767.0 + 0.5);
+    } else if (is_same<T, int32_t>::value) {
+        return floor(val * (1UL<<31) + 0.5);
+    }
+    return val; // assume float or double
+}
+
+/* Creates a type-independent audio buffer provider from
+ * a buffer base address, size, framesize, and input increment array.
+ *
+ * No allocation or deallocation of the provided buffer is done.
+ */
+class TestProvider : public android::AudioBufferProvider {
+public:
+    TestProvider(const void* addr, size_t frames, size_t frameSize,
+            const std::vector<size_t>& inputIncr)
+    : mAddr(addr),
+      mNumFrames(frames),
+      mFrameSize(frameSize),
+      mNextFrame(0), mUnrel(0), mInputIncr(inputIncr), mNextIdx(0)
+    {
+    }
+
+    virtual android::status_t getNextBuffer(Buffer* buffer, int64_t pts __unused = kInvalidPTS )
+    {
+        size_t requestedFrames = buffer->frameCount;
+        if (requestedFrames > mNumFrames - mNextFrame) {
+            buffer->frameCount = mNumFrames - mNextFrame;
+        }
+        if (!mInputIncr.empty()) {
+            size_t provided = mInputIncr[mNextIdx++];
+            ALOGV("getNextBuffer() mValue[%d]=%u not %u",
+                    mNextIdx-1, provided, buffer->frameCount);
+            if (provided < buffer->frameCount) {
+                buffer->frameCount = provided;
+            }
+            if (mNextIdx >= mInputIncr.size()) {
+                mNextIdx = 0;
+            }
+        }
+        ALOGV("getNextBuffer() requested %u frames out of %u frames available"
+                " and returned %u frames\n",
+                requestedFrames, mNumFrames - mNextFrame, buffer->frameCount);
+        mUnrel = buffer->frameCount;
+        if (buffer->frameCount > 0) {
+            buffer->raw = (char *)mAddr + mFrameSize * mNextFrame;
+            return android::NO_ERROR;
+        } else {
+            buffer->raw = NULL;
+            return android::NOT_ENOUGH_DATA;
+        }
+    }
+
+    virtual void releaseBuffer(Buffer* buffer)
+    {
+        if (buffer->frameCount > mUnrel) {
+            ALOGE("releaseBuffer() released %u frames but only %u available "
+                    "to release\n", buffer->frameCount, mUnrel);
+            mNextFrame += mUnrel;
+            mUnrel = 0;
+        } else {
+
+            ALOGV("releaseBuffer() released %u frames out of %u frames available "
+                    "to release\n", buffer->frameCount, mUnrel);
+            mNextFrame += buffer->frameCount;
+            mUnrel -= buffer->frameCount;
+        }
+        buffer->frameCount = 0;
+        buffer->raw = NULL;
+    }
+
+    void reset()
+    {
+        mNextFrame = 0;
+    }
+
+    size_t getNumFrames()
+    {
+        return mNumFrames;
+    }
+
+    void setIncr(const std::vector<size_t> inputIncr)
+    {
+        mNextIdx = 0;
+        mInputIncr = inputIncr;
+    }
+
+protected:
+    const void* mAddr;   // base address
+    size_t mNumFrames;   // total frames
+    int mFrameSize;      // frame size (# channels * bytes per sample)
+    size_t mNextFrame;   // index of next frame to provide
+    size_t mUnrel;       // number of frames not yet released
+    std::vector<size_t> mInputIncr; // number of frames provided per call
+    size_t mNextIdx;     // index of next entry in mInputIncr to use
+};
+
+/* Creates a buffer filled with a sine wave.
+ *
+ * Returns a pair consisting of the sine signal buffer and the number of frames.
+ * The caller must delete[] the buffer when no longer needed (no shared_ptr<>).
+ */
+template<typename T>
+static std::pair<T*, size_t> createSine(size_t channels,
+        double freq, double samplingRate, double time)
+{
+    double tscale = 1. / samplingRate;
+    size_t frames = static_cast<size_t>(samplingRate * time);
+    T* buffer = new T[frames * channels];
+    for (size_t i = 0; i < frames; ++i) {
+        double t = i * tscale;
+        double y = sin(2. * M_PI * freq * t);
+        T yt = convertValue<T>(y);
+
+        for (size_t j = 0; j < channels; ++j) {
+            buffer[i*channels + j] = yt / (j + 1);
+        }
+    }
+    return std::make_pair(buffer, frames);
+}
+
+/* Creates a buffer filled with a chirp signal (a sine wave sweep).
+ *
+ * Returns a pair consisting of the chirp signal buffer and the number of frames.
+ * The caller must delete[] the buffer when no longer needed (no shared_ptr<>).
+ *
+ * When creating the Chirp, note that the frequency is the true sinusoidal
+ * frequency not the sampling rate.
+ *
+ * http://en.wikipedia.org/wiki/Chirp
+ */
+template<typename T>
+static std::pair<T*, size_t> createChirp(size_t channels,
+        double minfreq, double maxfreq, double samplingRate, double time)
+{
+    double tscale = 1. / samplingRate;
+    size_t frames = static_cast<size_t>(samplingRate * time);
+    T *buffer = new T[frames * channels];
+    // note the chirp constant k has a divide-by-two.
+    double k = (maxfreq - minfreq) / (2. * time);
+    for (size_t i = 0; i < frames; ++i) {
+        double t = i * tscale;
+        double y = sin(2. * M_PI * (k * t + minfreq) * t);
+        T yt = convertValue<T>(y);
+
+        for (size_t j = 0; j < channels; ++j) {
+            buffer[i*channels + j] = yt / (j + 1);
+        }
+    }
+    return std::make_pair(buffer, frames);
+}
+
+/* This derived class creates a buffer provider of datatype T,
+ * consisting of an input signal, e.g. from createChirp().
+ * The number of frames can be obtained from the base class
+ * TestProvider::getNumFrames().
+ */
+template <typename T>
+class SignalProvider : public TestProvider {
+public:
+    SignalProvider(const std::pair<T*, size_t>& bufferInfo, size_t channels,
+            const std::vector<size_t>& values)
+    : TestProvider(bufferInfo.first, bufferInfo.second, channels * sizeof(T), values),
+      mManagedPtr(bufferInfo.first)
+    {
+    }
+
+    virtual ~SignalProvider()
+    {
+        delete[] mManagedPtr;
+    }
+
+protected:
+    T* mManagedPtr;
+};
+
+void resample(void *output, size_t outputFrames, const std::vector<size_t> &outputIncr,
+        android::AudioBufferProvider *provider, android::AudioResampler *resampler)
+{
+    for (size_t i = 0, j = 0; i < outputFrames; ) {
+        size_t thisFrames = outputIncr[j++];
+        if (j >= outputIncr.size()) {
+            j = 0;
+        }
+        if (thisFrames == 0 || thisFrames > outputFrames - i) {
+            thisFrames = outputFrames - i;
+        }
+        resampler->resample((int32_t*) output + 2*i, thisFrames, provider);
+        i += thisFrames;
+    }
+}
+
+void buffercmp(const void *reference, const void *test,
+        size_t outputFrameSize, size_t outputFrames)
+{
+    for (size_t i = 0; i < outputFrames; ++i) {
+        int check = memcmp((const char*)reference + i * outputFrameSize,
+                (const char*)test + i * outputFrameSize, outputFrameSize);
+        if (check) {
+            ALOGE("Failure at frame %d", i);
+            ASSERT_EQ(check, 0); /* fails */
+        }
+    }
+}
+
+void testBufferIncrement(size_t channels, unsigned inputFreq, unsigned outputFreq,
+        enum android::AudioResampler::src_quality quality)
+{
+    // create the provider
+    std::vector<size_t> inputIncr;
+    SignalProvider<int16_t> provider(createChirp<int16_t>(channels,
+            0., outputFreq/2., outputFreq, outputFreq/2000.),
+            channels, inputIncr);
+
+    // calculate the output size
+    size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq;
+    size_t outputFrameSize = 2 * sizeof(int32_t);
+    size_t outputSize = outputFrameSize * outputFrames;
+    outputSize &= ~7;
+
+    // create the resampler
+    const int volumePrecision = 12; /* typical unity gain */
+    android::AudioResampler* resampler;
+
+    resampler = android::AudioResampler::create(16, channels, outputFreq, quality);
+    resampler->setSampleRate(inputFreq);
+    resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
+
+    // set up the reference run
+    std::vector<size_t> refIncr;
+    refIncr.push_back(outputFrames);
+    void* reference = malloc(outputSize);
+    resample(reference, outputFrames, refIncr, &provider, resampler);
+
+    provider.reset();
+
+#if 0
+    /* this test will fail - API interface issue: reset() does not clear internal buffers */
+    resampler->reset();
+#else
+    delete resampler;
+    resampler = android::AudioResampler::create(16, channels, outputFreq, quality);
+    resampler->setSampleRate(inputFreq);
+    resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
+#endif
+
+    // set up the test run
+    std::vector<size_t> outIncr;
+    outIncr.push_back(1);
+    outIncr.push_back(2);
+    outIncr.push_back(3);
+    void* test = malloc(outputSize);
+    resample(test, outputFrames, outIncr, &provider, resampler);
+
+    // check
+    buffercmp(reference, test, outputFrameSize, outputFrames);
+
+    free(reference);
+    free(test);
+    delete resampler;
+}
+
+template <typename T>
+inline double sqr(T v)
+{
+    double dv = static_cast<double>(v);
+    return dv * dv;
+}
+
+template <typename T>
+double signalEnergy(T *start, T *end, unsigned stride)
+{
+    double accum = 0;
+
+    for (T *p = start; p < end; p += stride) {
+        accum += sqr(*p);
+    }
+    unsigned count = (end - start + stride - 1) / stride;
+    return accum / count;
+}
+
+void testStopbandDownconversion(size_t channels,
+        unsigned inputFreq, unsigned outputFreq,
+        unsigned passband, unsigned stopband,
+        enum android::AudioResampler::src_quality quality)
+{
+    // create the provider
+    std::vector<size_t> inputIncr;
+    SignalProvider<int16_t> provider(createChirp<int16_t>(channels,
+            0., inputFreq/2., inputFreq, inputFreq/2000.),
+            channels, inputIncr);
+
+    // calculate the output size
+    size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq;
+    size_t outputFrameSize = 2 * sizeof(int32_t);
+    size_t outputSize = outputFrameSize * outputFrames;
+    outputSize &= ~7;
+
+    // create the resampler
+    const int volumePrecision = 12; /* typical unity gain */
+    android::AudioResampler* resampler;
+
+    resampler = android::AudioResampler::create(16, channels, outputFreq, quality);
+    resampler->setSampleRate(inputFreq);
+    resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
+
+    // set up the reference run
+    std::vector<size_t> refIncr;
+    refIncr.push_back(outputFrames);
+    void* reference = malloc(outputSize);
+    resample(reference, outputFrames, refIncr, &provider, resampler);
+
+    int32_t *out = reinterpret_cast<int32_t *>(reference);
+
+    // check signal energy in passband
+    const unsigned passbandFrame = passband * outputFreq / 1000.;
+    const unsigned stopbandFrame = stopband * outputFreq / 1000.;
+
+    // check each channel separately
+    for (size_t i = 0; i < channels; ++i) {
+        double passbandEnergy = signalEnergy(out, out + passbandFrame * channels, channels);
+        double stopbandEnergy = signalEnergy(out + stopbandFrame * channels,
+                out + outputFrames * channels, channels);
+        double dbAtten = -10. * log10(stopbandEnergy / passbandEnergy);
+        ASSERT_GT(dbAtten, 60.);
+
+#if 0
+        // internal verification
+        printf("if:%d  of:%d  pbf:%d  sbf:%d  sbe: %f  pbe: %f  db: %.2f\n",
+                provider.getNumFrames(), outputFrames,
+                passbandFrame, stopbandFrame, stopbandEnergy, passbandEnergy, dbAtten);
+        for (size_t i = 0; i < 10; ++i) {
+            printf("%d\n", out[i+passbandFrame*channels]);
+        }
+        for (size_t i = 0; i < 10; ++i) {
+            printf("%d\n", out[i+stopbandFrame*channels]);
+        }
+#endif
+    }
+
+    free(reference);
+    delete resampler;
+}
+
+/* Buffer increment test
+ *
+ * We compare a reference output, where we consume and process the entire
+ * buffer at a time, and a test output, where we provide small chunks of input
+ * data and process small chunks of output (which may not be equivalent in size).
+ *
+ * Two subtests - fixed phase (3:2 down) and interpolated phase (147:320 up)
+ */
+TEST(audioflinger_resampler, bufferincrement_fixedphase) {
+    // all of these work
+    static const enum android::AudioResampler::src_quality kQualityArray[] = {
+            android::AudioResampler::LOW_QUALITY,
+            android::AudioResampler::MED_QUALITY,
+            android::AudioResampler::HIGH_QUALITY,
+            android::AudioResampler::VERY_HIGH_QUALITY,
+            android::AudioResampler::DYN_LOW_QUALITY,
+            android::AudioResampler::DYN_MED_QUALITY,
+            android::AudioResampler::DYN_HIGH_QUALITY,
+    };
+
+    for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
+        testBufferIncrement(2, 48000, 32000, kQualityArray[i]);
+    }
+}
+
+TEST(audioflinger_resampler, bufferincrement_interpolatedphase) {
+    // all of these work except low quality
+    static const enum android::AudioResampler::src_quality kQualityArray[] = {
+//           android::AudioResampler::LOW_QUALITY,
+            android::AudioResampler::MED_QUALITY,
+            android::AudioResampler::HIGH_QUALITY,
+            android::AudioResampler::VERY_HIGH_QUALITY,
+            android::AudioResampler::DYN_LOW_QUALITY,
+            android::AudioResampler::DYN_MED_QUALITY,
+            android::AudioResampler::DYN_HIGH_QUALITY,
+    };
+
+    for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
+        testBufferIncrement(2, 22050, 48000, kQualityArray[i]);
+    }
+}
+
+/* Simple aliasing test
+ *
+ * This checks stopband response of the chirp signal to make sure frequencies
+ * are properly suppressed.  It uses downsampling because the stopband can be
+ * clearly isolated by input frequencies exceeding the output sample rate (nyquist).
+ */
+TEST(audioflinger_resampler, stopbandresponse) {
+    // not all of these may work (old resamplers fail on downsampling)
+    static const enum android::AudioResampler::src_quality kQualityArray[] = {
+            //android::AudioResampler::LOW_QUALITY,
+            //android::AudioResampler::MED_QUALITY,
+            //android::AudioResampler::HIGH_QUALITY,
+            //android::AudioResampler::VERY_HIGH_QUALITY,
+            android::AudioResampler::DYN_LOW_QUALITY,
+            android::AudioResampler::DYN_MED_QUALITY,
+            android::AudioResampler::DYN_HIGH_QUALITY,
+    };
+
+    // in this test we assume a maximum transition band between 12kHz and 20kHz.
+    // there must be at least 60dB relative attenuation between stopband and passband.
+    for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
+        testStopbandDownconversion(2, 48000, 32000, 12000, 20000, kQualityArray[i]);
+    }
+
+    // in this test we assume a maximum transition band between 7kHz and 15kHz.
+    // there must be at least 60dB relative attenuation between stopband and passband.
+    // (the weird ratio triggers interpolative resampling)
+    for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
+        testStopbandDownconversion(2, 48000, 22101, 7000, 15000, kQualityArray[i]);
+    }
+}
diff --git a/services/audioflinger/tests/run_all_unit_tests.sh b/services/audioflinger/tests/run_all_unit_tests.sh
new file mode 100755
index 0000000..ffae6ae
--- /dev/null
+++ b/services/audioflinger/tests/run_all_unit_tests.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Android build environment not set"
+    exit -1
+fi
+
+echo "waiting for device"
+adb root && adb wait-for-device remount
+
+adb shell /system/bin/resampler_tests
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index a22ad9d..cddc503 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -46,8 +46,8 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+
 ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
-ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
 
 include $(CLEAR_VARS)
 
@@ -62,6 +62,20 @@
 LOCAL_STATIC_LIBRARIES := \
     libmedia_helper
 
+LOCAL_MODULE:= libaudiopolicymanagerdefault
+
+include $(BUILD_SHARED_LIBRARY)
+
+ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyFactory.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudiopolicymanagerdefault
+
 LOCAL_MODULE:= libaudiopolicymanager
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/AudioPolicyFactory.cpp b/services/audiopolicy/AudioPolicyFactory.cpp
new file mode 100644
index 0000000..2ae7bc1
--- /dev/null
+++ b/services/audiopolicy/AudioPolicyFactory.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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 "AudioPolicyManager.h"
+
+namespace android {
+
+extern "C" AudioPolicyInterface* createAudioPolicyManager(
+        AudioPolicyClientInterface *clientInterface)
+{
+    return new AudioPolicyManager(clientInterface);
+}
+
+extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
+{
+    delete interface;
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 61edac2..d4c9374 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -100,6 +100,7 @@
     STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
 };
 
 const StringToEnum sFlagNameToEnumTable[] = {
@@ -284,16 +285,8 @@
                             0);
         }
 
-        if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) {
-            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
-        } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
-                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
-                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
-            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
-        } else {
-            mpClientInterface->onAudioPortListUpdate();
-            return NO_ERROR;
-        }
+        mpClientInterface->onAudioPortListUpdate();
+        return NO_ERROR;
     }  // end if is output device
 
     // handle input devices
@@ -3809,6 +3802,12 @@
 
     case AUDIO_SOURCE_DEFAULT:
     case AUDIO_SOURCE_MIC:
+    if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
+        device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+        break;
+    }
+    // FALL THROUGH
+
     case AUDIO_SOURCE_VOICE_RECOGNITION:
     case AUDIO_SOURCE_HOTWORD:
     case AUDIO_SOURCE_VOICE_COMMUNICATION:
@@ -3985,6 +3984,11 @@
 };
 
 const AudioPolicyManager::VolumeCurvePoint
+    AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
+    {1, -56.0f}, {20, -34.0f}, {86, -10.0f}, {100, 0.0f}
+};
+
+const AudioPolicyManager::VolumeCurvePoint
     AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
     {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
 };
@@ -4098,6 +4102,8 @@
                 sSpeakerSonificationVolumeCurveDrc;
         mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
                 sSpeakerSonificationVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
+                sSpeakerMediaVolumeCurveDrc;
     }
 }
 
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index adf1b33..1abeb6a 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -374,6 +374,7 @@
         static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT];
         // volume curve for media strategy on speakers
         static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT];
+        static const VolumeCurvePoint sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT];
         // volume curve for sonification strategy on speakers
         static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT];
         static const VolumeCurvePoint sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT];
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index a2a0461..93fab11 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -108,7 +108,7 @@
     ALOGI("AudioPolicyService CSTOR in new mode");
 
     mAudioPolicyClient = new AudioPolicyClient(this);
-    mAudioPolicyManager = new AudioPolicyManager(mAudioPolicyClient);
+    mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
 #endif
 
     // load audio pre processing modules
@@ -145,7 +145,7 @@
         audio_policy_dev_close(mpAudioPolicyDev);
     }
 #else
-    delete mAudioPolicyManager;
+    destroyAudioPolicyManager(mAudioPolicyManager);
     delete mAudioPolicyClient;
 #endif
 
@@ -399,7 +399,8 @@
     mLock.lock();
     while (!exitPending())
     {
-        while (!mAudioCommands.isEmpty()) {
+        sp<AudioPolicyService> svc;
+        while (!mAudioCommands.isEmpty() && !exitPending()) {
             nsecs_t curTime = systemTime();
             // commands are sorted by increasing time stamp: execute them from index 0 and up
             if (mAudioCommands[0]->mTime <= curTime) {
@@ -452,7 +453,7 @@
                     StopOutputData *data = (StopOutputData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing stop output %d",
                             data->mIO);
-                    sp<AudioPolicyService> svc = mService.promote();
+                    svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
@@ -464,7 +465,7 @@
                     ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing release output %d",
                             data->mIO);
-                    sp<AudioPolicyService> svc = mService.promote();
+                    svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
@@ -494,7 +495,7 @@
                     } break;
                 case UPDATE_AUDIOPORT_LIST: {
                     ALOGV("AudioCommandThread() processing update audio port list");
-                    sp<AudioPolicyService> svc = mService.promote();
+                    svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
@@ -504,7 +505,7 @@
                     }break;
                 case UPDATE_AUDIOPATCH_LIST: {
                     ALOGV("AudioCommandThread() processing update audio patch list");
-                    sp<AudioPolicyService> svc = mService.promote();
+                    svc = mService.promote();
                     if (svc == 0) {
                         break;
                     }
@@ -542,9 +543,16 @@
         if (mAudioCommands.isEmpty()) {
             release_wake_lock(mName.string());
         }
-        ALOGV("AudioCommandThread() going to sleep");
-        mWaitWorkCV.waitRelative(mLock, waitTime);
-        ALOGV("AudioCommandThread() waking up");
+        // release mLock before releasing strong reference on the service as
+        // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock.
+        mLock.unlock();
+        svc.clear();
+        mLock.lock();
+        if (!exitPending()) {
+            ALOGV("AudioCommandThread() going to sleep");
+            mWaitWorkCV.waitRelative(mLock, waitTime);
+            ALOGV("AudioCommandThread() waking up");
+        }
     }
     mLock.unlock();
     return false;
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index 40f589b..66d9cad 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -539,7 +539,7 @@
     sp<AudioCommandThread> mOutputCommandThread;    // process stop and release output
     struct audio_policy_device *mpAudioPolicyDev;
     struct audio_policy *mpAudioPolicy;
-    AudioPolicyManager *mAudioPolicyManager;
+    AudioPolicyInterface *mAudioPolicyManager;
     AudioPolicyClient *mAudioPolicyClient;
 
     KeyedVector< audio_source_t, InputSourceDesc* > mInputSources;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 638b871..9fd35e1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -852,12 +852,13 @@
 
         switch(deviceVersion) {
           case CAMERA_DEVICE_API_VERSION_1_0:
+            ALOGW("Camera using old HAL version: %d", deviceVersion);
+            return -EOPNOTSUPP;
+           // TODO: don't allow 2.0  Only allow 2.1 and higher
           case CAMERA_DEVICE_API_VERSION_2_0:
           case CAMERA_DEVICE_API_VERSION_2_1:
           case CAMERA_DEVICE_API_VERSION_3_0:
           case CAMERA_DEVICE_API_VERSION_3_1:
-            ALOGW("Camera using old HAL version: %d", deviceVersion);
-            return -EOPNOTSUPP;
           case CAMERA_DEVICE_API_VERSION_3_2:
             client = new CameraDeviceClient(this, cameraCb, String16(),
                     cameraId, facing, callingPid, USE_CALLING_UID, getpid());
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index dece764..51b1980 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -29,6 +29,8 @@
 
 #include "Parameters.h"
 #include "system/camera.h"
+#include <media/MediaProfiles.h>
+#include <media/mediarecorder.h>
 
 namespace android {
 namespace camera2 {
@@ -59,7 +61,17 @@
     if (res != OK) return res;
 
     const Size MAX_PREVIEW_SIZE = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
-    res = getFilteredPreviewSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
+    // Treat the H.264 max size as the max supported video size.
+    MediaProfiles *videoEncoderProfiles = MediaProfiles::getInstance();
+    int32_t maxVideoWidth = videoEncoderProfiles->getVideoEncoderParamByName(
+                            "enc.vid.width.max", VIDEO_ENCODER_H264);
+    int32_t maxVideoHeight = videoEncoderProfiles->getVideoEncoderParamByName(
+                            "enc.vid.height.max", VIDEO_ENCODER_H264);
+    const Size MAX_VIDEO_SIZE = {maxVideoWidth, maxVideoHeight};
+
+    res = getFilteredSizes(MAX_PREVIEW_SIZE, &availablePreviewSizes);
+    if (res != OK) return res;
+    res = getFilteredSizes(MAX_VIDEO_SIZE, &availableVideoSizes);
     if (res != OK) return res;
 
     // TODO: Pick more intelligently
@@ -84,8 +96,17 @@
         ALOGV("Supported preview sizes are: %s", supportedPreviewSizes.string());
         params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
                 supportedPreviewSizes);
+
+        String8 supportedVideoSizes;
+        for (size_t i = 0; i < availableVideoSizes.size(); i++) {
+            if (i != 0) supportedVideoSizes += ",";
+            supportedVideoSizes += String8::format("%dx%d",
+                    availableVideoSizes[i].width,
+                    availableVideoSizes[i].height);
+        }
+        ALOGV("Supported video sizes are: %s", supportedVideoSizes.string());
         params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
-                supportedPreviewSizes);
+                supportedVideoSizes);
     }
 
     camera_metadata_ro_entry_t availableFpsRanges =
@@ -1660,13 +1681,13 @@
                     __FUNCTION__);
             return BAD_VALUE;
         }
-        for (i = 0; i < availablePreviewSizes.size(); i++) {
-            if ((availablePreviewSizes[i].width ==
+        for (i = 0; i < availableVideoSizes.size(); i++) {
+            if ((availableVideoSizes[i].width ==
                     validatedParams.videoWidth) &&
-                (availablePreviewSizes[i].height ==
+                (availableVideoSizes[i].height ==
                     validatedParams.videoHeight)) break;
         }
-        if (i == availablePreviewSizes.size()) {
+        if (i == availableVideoSizes.size()) {
             ALOGE("%s: Requested video size %d x %d is not supported",
                     __FUNCTION__, validatedParams.videoWidth,
                     validatedParams.videoHeight);
@@ -2497,7 +2518,7 @@
     return cropYToArray(normalizedYToCrop(y));
 }
 
-status_t Parameters::getFilteredPreviewSizes(Size limit, Vector<Size> *sizes) {
+status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) {
     if (info == NULL) {
         ALOGE("%s: Static metadata is not initialized", __FUNCTION__);
         return NO_INIT;
@@ -2512,14 +2533,14 @@
         staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, SIZE_COUNT);
     if (availableProcessedSizes.count < SIZE_COUNT) return BAD_VALUE;
 
-    Size previewSize;
+    Size filteredSize;
     for (size_t i = 0; i < availableProcessedSizes.count; i += SIZE_COUNT) {
-        previewSize.width = availableProcessedSizes.data.i32[i];
-        previewSize.height = availableProcessedSizes.data.i32[i+1];
+        filteredSize.width = availableProcessedSizes.data.i32[i];
+        filteredSize.height = availableProcessedSizes.data.i32[i+1];
             // Need skip the preview sizes that are too large.
-            if (previewSize.width <= limit.width &&
-                    previewSize.height <= limit.height) {
-                sizes->push(previewSize);
+            if (filteredSize.width <= limit.width &&
+                    filteredSize.height <= limit.height) {
+                sizes->push(filteredSize);
             }
     }
     if (sizes->isEmpty()) {
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 60c4687..28dd788 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -341,8 +341,9 @@
     int normalizedYToCrop(int y) const;
 
     Vector<Size> availablePreviewSizes;
+    Vector<Size> availableVideoSizes;
     // Get size list (that are no larger than limit) from static metadata.
-    status_t getFilteredPreviewSizes(Size limit, Vector<Size> *sizes);
+    status_t getFilteredSizes(Size limit, Vector<Size> *sizes);
     // Get max size (from the size array) that matches the given aspect ratio.
     Size getMaxSizeForRatio(float ratio, const int32_t* sizeArray, size_t count);
 };
diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp
index 346e15f..374dc5e 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.cpp
+++ b/services/camera/libcameraservice/utils/CameraTraces.cpp
@@ -74,10 +74,10 @@
         return BAD_VALUE;
     }
 
-    fdprintf(fd, "Camera traces (%zu):\n", pcsList.size());
+    dprintf(fd, "Camera traces (%zu):\n", pcsList.size());
 
     if (pcsList.empty()) {
-        fdprintf(fd, "  No camera traces collected.\n");
+        dprintf(fd, "  No camera traces collected.\n");
     }
 
     // Print newest items first
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index 0c7fbbd..41dab1f 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -60,7 +60,7 @@
     static const String16 sDump("android.permission.DUMP");
     if (!(IPCThreadState::self()->getCallingUid() == AID_MEDIA ||
             PermissionCache::checkCallingPermission(sDump))) {
-        fdprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
+        dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
                 IPCThreadState::self()->getCallingPid(),
                 IPCThreadState::self()->getCallingUid());
         return NO_ERROR;
@@ -74,7 +74,7 @@
     for (size_t i = 0; i < namedReaders.size(); i++) {
         const NamedReader& namedReader = namedReaders[i];
         if (fd >= 0) {
-            fdprintf(fd, "\n%s:\n", namedReader.name());
+            dprintf(fd, "\n%s:\n", namedReader.name());
         } else {
             ALOGI("%s:", namedReader.name());
         }
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
new file mode 100644
index 0000000..b7ccaab
--- /dev/null
+++ b/services/soundtrigger/Android.mk
@@ -0,0 +1,41 @@
+# Copyright 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+
+ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1)
+    LOCAL_CFLAGS += -DSOUND_TRIGGER_USE_STUB_MODULE
+endif
+
+LOCAL_SRC_FILES:=               \
+    SoundTriggerHwService.cpp
+
+LOCAL_SHARED_LIBRARIES:= \
+    libui \
+    liblog \
+    libutils \
+    libbinder \
+    libcutils \
+    libhardware \
+    libsoundtrigger
+
+#LOCAL_C_INCLUDES += \
+
+
+LOCAL_MODULE:= libsoundtriggerservice
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
new file mode 100644
index 0000000..fa59388
--- /dev/null
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2014 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 "SoundTriggerHwService"
+//#define LOG_NDEBUG 0
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+#include <hardware/hardware.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "SoundTriggerHwService.h"
+#include <system/sound_trigger.h>
+#include <hardware/sound_trigger.h>
+
+namespace android {
+
+#ifdef SOUND_TRIGGER_USE_STUB_MODULE
+#define HW_MODULE_PREFIX "stub"
+#else
+#define HW_MODULE_PREFIX "primary"
+#endif
+
+SoundTriggerHwService::SoundTriggerHwService()
+    : BnSoundTriggerHwService(),
+      mNextUniqueId(1)
+{
+}
+
+void SoundTriggerHwService::onFirstRef()
+{
+    const hw_module_t *mod;
+    int rc;
+    sound_trigger_hw_device *dev;
+
+    rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, HW_MODULE_PREFIX, &mod);
+    if (rc != 0) {
+        ALOGE("couldn't load sound trigger module %s.%s (%s)",
+              SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
+        return;
+    }
+    rc = sound_trigger_hw_device_open(mod, &dev);
+    if (rc != 0) {
+        ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
+              SOUND_TRIGGER_HARDWARE_MODULE_ID, "primary", strerror(-rc));
+        return;
+    }
+    if (dev->common.version != SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
+        ALOGE("wrong sound trigger hw device version %04x", dev->common.version);
+        return;
+    }
+
+    sound_trigger_module_descriptor descriptor;
+    rc = dev->get_properties(dev, &descriptor.properties);
+    if (rc != 0) {
+        ALOGE("could not read implementation properties");
+        return;
+    }
+    descriptor.handle =
+            (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
+    ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
+                                                 descriptor.handle);
+
+    sp<ISoundTriggerClient> client;
+    sp<Module> module = new Module(this, dev, descriptor, client);
+    mModules.add(descriptor.handle, module);
+    mCallbackThread = new CallbackThread(this);
+}
+
+SoundTriggerHwService::~SoundTriggerHwService()
+{
+    if (mCallbackThread != 0) {
+        mCallbackThread->exit();
+    }
+    for (size_t i = 0; i < mModules.size(); i++) {
+        sound_trigger_hw_device_close(mModules.valueAt(i)->hwDevice());
+    }
+}
+
+status_t SoundTriggerHwService::listModules(struct sound_trigger_module_descriptor *modules,
+                             uint32_t *numModules)
+{
+    ALOGV("listModules");
+    AutoMutex lock(mServiceLock);
+    if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
+        return BAD_VALUE;
+    }
+    size_t maxModules = *numModules;
+    *numModules = mModules.size();
+    for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
+        modules[i] = mModules.valueAt(i)->descriptor();
+    }
+    return NO_ERROR;
+}
+
+status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handle,
+                        const sp<ISoundTriggerClient>& client,
+                        sp<ISoundTrigger>& moduleInterface)
+{
+    ALOGV("attach module %d", handle);
+    AutoMutex lock(mServiceLock);
+    moduleInterface.clear();
+    if (client == 0) {
+        return BAD_VALUE;
+    }
+    ssize_t index = mModules.indexOfKey(handle);
+    if (index < 0) {
+        return BAD_VALUE;
+    }
+    sp<Module> module = mModules.valueAt(index);
+
+    module->setClient(client);
+    client->asBinder()->linkToDeath(module);
+    moduleInterface = module;
+
+    return NO_ERROR;
+}
+
+void SoundTriggerHwService::detachModule(sp<Module> module) {
+    AutoMutex lock(mServiceLock);
+    ALOGV("detachModule");
+    module->clearClient();
+}
+
+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 SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
+    String8 result;
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
+        write(fd, result.string(), result.size());
+    } else {
+        bool locked = tryLock(mServiceLock);
+        // failed to lock - SoundTriggerHwService is probably deadlocked
+        if (!locked) {
+            result.append("SoundTriggerHwService may be deadlocked\n");
+            write(fd, result.string(), result.size());
+        }
+
+        if (locked) mServiceLock.unlock();
+    }
+    return NO_ERROR;
+}
+
+status_t SoundTriggerHwService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
+}
+
+
+// static
+void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
+                                                void *cookie)
+{
+    Module *module = (Module *)cookie;
+    if (module == NULL) {
+        return;
+    }
+    module->sendRecognitionEvent(event);
+}
+
+
+void SoundTriggerHwService::sendRecognitionEvent(const sp<RecognitionEvent>& event)
+{
+    mCallbackThread->sendRecognitionEvent(event);
+}
+
+void SoundTriggerHwService::onRecognitionEvent(const sp<RecognitionEvent>& event)
+{
+    ALOGV("onRecognitionEvent");
+    sp<Module> module;
+    {
+        AutoMutex lock(mServiceLock);
+        module = event->mModule.promote();
+        if (module == 0) {
+            return;
+        }
+    }
+    module->onRecognitionEvent(event->mEventMemory);
+}
+
+// static
+void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event __unused,
+                                               void *cookie)
+{
+    Module *module = (Module *)cookie;
+
+}
+
+#undef LOG_TAG
+#define LOG_TAG "SoundTriggerHwService::CallbackThread"
+
+SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
+    : mService(service)
+{
+}
+
+SoundTriggerHwService::CallbackThread::~CallbackThread()
+{
+    mEventQueue.clear();
+}
+
+void SoundTriggerHwService::CallbackThread::onFirstRef()
+{
+    run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+bool SoundTriggerHwService::CallbackThread::threadLoop()
+{
+    while (!exitPending()) {
+        sp<RecognitionEvent> event;
+        sp<SoundTriggerHwService> service;
+        {
+            Mutex::Autolock _l(mCallbackLock);
+            while (mEventQueue.isEmpty() && !exitPending()) {
+                ALOGV("CallbackThread::threadLoop() sleep");
+                mCallbackCond.wait(mCallbackLock);
+                ALOGV("CallbackThread::threadLoop() wake up");
+            }
+            if (exitPending()) {
+                break;
+            }
+            event = mEventQueue[0];
+            mEventQueue.removeAt(0);
+            service = mService.promote();
+        }
+        if (service != 0) {
+            service->onRecognitionEvent(event);
+        }
+    }
+    return false;
+}
+
+void SoundTriggerHwService::CallbackThread::exit()
+{
+    Mutex::Autolock _l(mCallbackLock);
+    requestExit();
+    mCallbackCond.broadcast();
+}
+
+void SoundTriggerHwService::CallbackThread::sendRecognitionEvent(
+                        const sp<SoundTriggerHwService::RecognitionEvent>& event)
+{
+    AutoMutex lock(mCallbackLock);
+    mEventQueue.add(event);
+    mCallbackCond.signal();
+}
+
+SoundTriggerHwService::RecognitionEvent::RecognitionEvent(
+                                            sp<IMemory> eventMemory,
+                                            wp<Module> module)
+    : mEventMemory(eventMemory), mModule(module)
+{
+}
+
+SoundTriggerHwService::RecognitionEvent::~RecognitionEvent()
+{
+}
+
+#undef LOG_TAG
+#define LOG_TAG "SoundTriggerHwService::Module"
+
+SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
+                                      sound_trigger_hw_device* hwDevice,
+                                      sound_trigger_module_descriptor descriptor,
+                                      const sp<ISoundTriggerClient>& client)
+ : mService(service), mHwDevice(hwDevice), mDescriptor(descriptor),
+   mClient(client)
+{
+}
+
+SoundTriggerHwService::Module::~Module() {
+}
+
+void SoundTriggerHwService::Module::detach() {
+    ALOGV("detach()");
+    {
+        AutoMutex lock(mLock);
+        for (size_t i = 0; i < mModels.size(); i++) {
+            sp<Model> model = mModels.valueAt(i);
+            ALOGV("detach() unloading model %d", model->mHandle);
+            if (model->mState == Model::STATE_ACTIVE) {
+                mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+                model->deallocateMemory();
+            }
+            mHwDevice->unload_sound_model(mHwDevice, model->mHandle);
+        }
+        mModels.clear();
+    }
+    if (mClient != 0) {
+        mClient->asBinder()->unlinkToDeath(this);
+    }
+    sp<SoundTriggerHwService> service = mService.promote();
+    if (service == 0) {
+        return;
+    }
+    service->detachModule(this);
+}
+
+status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
+                                sound_model_handle_t *handle)
+{
+    ALOGV("loadSoundModel() handle");
+
+    if (modelMemory == 0 || modelMemory->pointer() == NULL) {
+        ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
+        return BAD_VALUE;
+    }
+    struct sound_trigger_sound_model *sound_model =
+            (struct sound_trigger_sound_model *)modelMemory->pointer();
+
+    AutoMutex lock(mLock);
+    status_t status = mHwDevice->load_sound_model(mHwDevice,
+                                                  sound_model,
+                                                  SoundTriggerHwService::soundModelCallback,
+                                                  this,
+                                                  handle);
+    if (status == NO_ERROR) {
+        mModels.replaceValueFor(*handle, new Model(*handle));
+    }
+
+    return status;
+}
+
+status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
+{
+    ALOGV("unloadSoundModel() model handle %d", handle);
+
+    AutoMutex lock(mLock);
+    ssize_t index = mModels.indexOfKey(handle);
+    if (index < 0) {
+        return BAD_VALUE;
+    }
+    sp<Model> model = mModels.valueAt(index);
+    mModels.removeItem(handle);
+    if (model->mState == Model::STATE_ACTIVE) {
+        mHwDevice->stop_recognition(mHwDevice, model->mHandle);
+        model->deallocateMemory();
+    }
+    return mHwDevice->unload_sound_model(mHwDevice, handle);
+}
+
+status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
+                                  const sp<IMemory>& dataMemory)
+{
+    ALOGV("startRecognition() model handle %d", handle);
+
+    if (dataMemory != 0 && dataMemory->pointer() == NULL) {
+        ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
+        return BAD_VALUE;
+
+    }
+    AutoMutex lock(mLock);
+    sp<Model> model = getModel(handle);
+    if (model == 0) {
+        return BAD_VALUE;
+    }
+
+    if (model->mState == Model::STATE_ACTIVE) {
+        return INVALID_OPERATION;
+    }
+    model->mState = Model::STATE_ACTIVE;
+
+    char *data = NULL;
+    unsigned int data_size = 0;
+    if (dataMemory != 0 && dataMemory->size() != 0) {
+        data_size = (unsigned int)dataMemory->size();
+        data = (char *)dataMemory->pointer();
+        ALOGV("startRecognition() data size %d data %d - %d",
+                      data_size, data[0], data[data_size - 1]);
+    }
+
+    //TODO: get capture handle and device from audio policy service
+    audio_io_handle_t capture_handle = 0;
+    return mHwDevice->start_recognition(mHwDevice, handle, capture_handle, AUDIO_DEVICE_NONE,
+                                        SoundTriggerHwService::recognitionCallback,
+                                        this,
+                                        data_size,
+                                        data);
+}
+
+status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
+{
+    ALOGV("stopRecognition() model handle %d", handle);
+
+    AutoMutex lock(mLock);
+    sp<Model> model = getModel(handle);
+    if (model == 0) {
+        return BAD_VALUE;
+    }
+
+    if (model->mState != Model::STATE_ACTIVE) {
+        return INVALID_OPERATION;
+    }
+    mHwDevice->stop_recognition(mHwDevice, handle);
+    model->deallocateMemory();
+    model->mState = Model::STATE_IDLE;
+    return NO_ERROR;
+}
+
+void SoundTriggerHwService::Module::sendRecognitionEvent(
+                                                    struct sound_trigger_recognition_event *event)
+{
+    sp<SoundTriggerHwService> service;
+    sp<IMemory> eventMemory;
+    ALOGV("sendRecognitionEvent for model %d", event->model);
+    {
+        AutoMutex lock(mLock);
+        sp<Model> model = getModel(event->model);
+        if (model == 0) {
+            return;
+        }
+        if (model->mState != Model::STATE_ACTIVE) {
+            ALOGV("sendRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
+            return;
+        }
+        if (mClient == 0) {
+            return;
+        }
+        service = mService.promote();
+        if (service == 0) {
+            return;
+        }
+
+        //sanitize event
+        switch (event->type) {
+        case SOUND_MODEL_TYPE_KEYPHRASE:
+            ALOGW_IF(event->data_offset !=
+                        sizeof(struct sound_trigger_phrase_recognition_event),
+                        "sendRecognitionEvent(): invalid data offset %u for keyphrase event type",
+                        event->data_offset);
+            event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
+            break;
+        case SOUND_MODEL_TYPE_UNKNOWN:
+            ALOGW_IF(event->data_offset !=
+                        sizeof(struct sound_trigger_recognition_event),
+                        "sendRecognitionEvent(): invalid data offset %u for unknown event type",
+                        event->data_offset);
+            event->data_offset = sizeof(struct sound_trigger_recognition_event);
+            break;
+        default:
+                return;
+        }
+
+        size_t size = event->data_offset + event->data_size;
+        eventMemory = model->allocateMemory(size);
+        if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+            return;
+        }
+        memcpy(eventMemory->pointer(), event, size);
+    }
+    service->sendRecognitionEvent(new RecognitionEvent(eventMemory, this));
+}
+
+void SoundTriggerHwService::Module::onRecognitionEvent(sp<IMemory> eventMemory)
+{
+    ALOGV("Module::onRecognitionEvent");
+
+    AutoMutex lock(mLock);
+
+    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+        return;
+    }
+    struct sound_trigger_recognition_event *event =
+            (struct sound_trigger_recognition_event *)eventMemory->pointer();
+
+    sp<Model> model = getModel(event->model);
+    if (model == 0) {
+        ALOGI("%s model == 0", __func__);
+        return;
+    }
+    if (model->mState != Model::STATE_ACTIVE) {
+        ALOGV("onRecognitionEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
+        return;
+    }
+    if (mClient == 0) {
+        ALOGI("%s mClient == 0", __func__);
+        return;
+    }
+    mClient->onRecognitionEvent(eventMemory);
+    model->mState = Model::STATE_IDLE;
+    model->deallocateMemory();
+}
+
+sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
+        sound_model_handle_t handle)
+{
+    sp<Model> model;
+    ssize_t index = mModels.indexOfKey(handle);
+    if (index >= 0) {
+        model = mModels.valueAt(index);
+    }
+    return model;
+}
+
+void SoundTriggerHwService::Module::binderDied(
+    const wp<IBinder> &who __unused) {
+    ALOGW("client binder died for module %d", mDescriptor.handle);
+    detach();
+}
+
+
+SoundTriggerHwService::Model::Model(sound_model_handle_t handle) :
+    mHandle(handle), mState(STATE_IDLE), mInputHandle(AUDIO_IO_HANDLE_NONE),
+    mCaptureSession(AUDIO_SESSION_ALLOCATE),
+    mMemoryDealer(new MemoryDealer(sizeof(struct sound_trigger_recognition_event),
+                                   "SoundTriggerHwService::Event"))
+{
+
+}
+
+
+sp<IMemory> SoundTriggerHwService::Model::allocateMemory(size_t size)
+{
+    sp<IMemory> memory;
+    if (mMemoryDealer->getMemoryHeap()->getSize() < size) {
+        mMemoryDealer = new MemoryDealer(size, "SoundTriggerHwService::Event");
+    }
+    memory = mMemoryDealer->allocate(size);
+    return memory;
+}
+
+void SoundTriggerHwService::Model::deallocateMemory()
+{
+    mMemoryDealer->deallocate(0);
+}
+
+status_t SoundTriggerHwService::Module::dump(int fd __unused,
+                                             const Vector<String16>& args __unused) {
+    String8 result;
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
new file mode 100644
index 0000000..377f2a1
--- /dev/null
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -0,0 +1,185 @@
+/*
+ * 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 ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
+#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
+
+#include <utils/Vector.h>
+//#include <binder/AppOpsManager.h>
+#include <binder/MemoryDealer.h>
+#include <binder/BinderService.h>
+#include <binder/IAppOpsCallback.h>
+#include <soundtrigger/ISoundTriggerHwService.h>
+#include <soundtrigger/ISoundTrigger.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+#include <system/sound_trigger.h>
+#include <hardware/sound_trigger.h>
+
+namespace android {
+
+class MemoryHeapBase;
+
+class SoundTriggerHwService :
+    public BinderService<SoundTriggerHwService>,
+    public BnSoundTriggerHwService
+{
+    friend class BinderService<SoundTriggerHwService>;
+public:
+    class Module;
+
+    static char const* getServiceName() { return "media.sound_trigger_hw"; }
+
+                        SoundTriggerHwService();
+    virtual             ~SoundTriggerHwService();
+
+    // ISoundTriggerHwService
+    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+                                 uint32_t *numModules);
+
+    virtual status_t attach(const sound_trigger_module_handle_t handle,
+                            const sp<ISoundTriggerClient>& client,
+                            sp<ISoundTrigger>& module);
+
+    virtual status_t    onTransact(uint32_t code, const Parcel& data,
+                                   Parcel* reply, uint32_t flags);
+
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    class Model : public RefBase {
+     public:
+
+        enum {
+            STATE_IDLE,
+            STATE_ACTIVE
+        };
+
+        Model(sound_model_handle_t handle);
+        ~Model() {}
+
+        sp<IMemory> allocateMemory(size_t size);
+        void deallocateMemory();
+
+        sound_model_handle_t    mHandle;
+        int                     mState;
+        audio_io_handle_t       mInputHandle;
+        audio_session_t         mCaptureSession;
+        sp<MemoryDealer>        mMemoryDealer;
+    };
+
+    class Module : public virtual RefBase,
+                   public BnSoundTrigger,
+                   public IBinder::DeathRecipient     {
+    public:
+
+       Module(const sp<SoundTriggerHwService>& service,
+              sound_trigger_hw_device* hwDevice,
+              sound_trigger_module_descriptor descriptor,
+              const sp<ISoundTriggerClient>& client);
+
+       virtual ~Module();
+
+       virtual void detach();
+
+       virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
+                                       sound_model_handle_t *handle);
+
+       virtual status_t unloadSoundModel(sound_model_handle_t handle);
+
+       virtual status_t startRecognition(sound_model_handle_t handle,
+                                         const sp<IMemory>& dataMemory);
+       virtual status_t stopRecognition(sound_model_handle_t handle);
+
+       virtual status_t dump(int fd, const Vector<String16>& args);
+
+
+       sound_trigger_hw_device *hwDevice() const { return mHwDevice; }
+       struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
+       void setClient(sp<ISoundTriggerClient> client) { mClient = client; }
+       void clearClient() { mClient.clear(); }
+       sp<ISoundTriggerClient> client() { return mClient; }
+
+       void sendRecognitionEvent(struct sound_trigger_recognition_event *event);
+       void onRecognitionEvent(sp<IMemory> eventMemory);
+
+       sp<Model> getModel(sound_model_handle_t handle);
+
+       // IBinder::DeathRecipient implementation
+       virtual void        binderDied(const wp<IBinder> &who);
+
+    private:
+        Mutex                                  mLock;
+        wp<SoundTriggerHwService>              mService;
+        struct sound_trigger_hw_device*        mHwDevice;
+        struct sound_trigger_module_descriptor mDescriptor;
+        sp<ISoundTriggerClient>                mClient;
+        DefaultKeyedVector< sound_model_handle_t, sp<Model> >     mModels;
+    }; // class Module
+
+    class RecognitionEvent : public RefBase {
+    public:
+
+        RecognitionEvent(sp<IMemory> eventMemory, wp<Module> module);
+
+        virtual             ~RecognitionEvent();
+
+        sp<IMemory> mEventMemory;
+        wp<Module> mModule;
+    };
+
+    class CallbackThread : public Thread {
+    public:
+
+        CallbackThread(const wp<SoundTriggerHwService>& service);
+
+        virtual             ~CallbackThread();
+
+        // Thread virtuals
+        virtual bool        threadLoop();
+
+        // RefBase
+        virtual void        onFirstRef();
+
+                void        exit();
+                void        sendRecognitionEvent(const sp<RecognitionEvent>& event);
+
+    private:
+        wp<SoundTriggerHwService>   mService;
+        Condition                   mCallbackCond;
+        Mutex                       mCallbackLock;
+        Vector< sp<RecognitionEvent> > mEventQueue;
+    };
+
+    void detachModule(sp<Module> module);
+
+    static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
+    void sendRecognitionEvent(const sp<RecognitionEvent>& event);
+    void onRecognitionEvent(const sp<RecognitionEvent>& event);
+
+    static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
+
+private:
+
+    virtual void onFirstRef();
+
+    Mutex               mServiceLock;
+    volatile int32_t    mNextUniqueId;
+    DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> >     mModules;
+    sp<CallbackThread>  mCallbackThread;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
diff --git a/soundtrigger/Android.mk b/soundtrigger/Android.mk
new file mode 100644
index 0000000..d91c4c2
--- /dev/null
+++ b/soundtrigger/Android.mk
@@ -0,0 +1,38 @@
+# Copyright 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	SoundTrigger.cpp \
+	ISoundTrigger.cpp \
+	ISoundTriggerClient.cpp \
+	ISoundTriggerHwService.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	liblog \
+	libbinder \
+	libhardware
+
+#LOCAL_C_INCLUDES += \
+	system/media/camera/include \
+	system/media/private/camera/include
+
+LOCAL_MODULE:= libsoundtrigger
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/soundtrigger/ISoundTrigger.cpp b/soundtrigger/ISoundTrigger.cpp
new file mode 100644
index 0000000..42280d1
--- /dev/null
+++ b/soundtrigger/ISoundTrigger.cpp
@@ -0,0 +1,177 @@
+/*
+**
+** Copyright 2014, 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 "ISoundTrigger"
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <binder/IMemory.h>
+#include <soundtrigger/ISoundTrigger.h>
+#include <soundtrigger/ISoundTriggerHwService.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+#include <system/sound_trigger.h>
+
+namespace android {
+
+enum {
+    DETACH = IBinder::FIRST_CALL_TRANSACTION,
+    LOAD_SOUND_MODEL,
+    UNLOAD_SOUND_MODEL,
+    START_RECOGNITION,
+    STOP_RECOGNITION,
+};
+
+class BpSoundTrigger: public BpInterface<ISoundTrigger>
+{
+public:
+    BpSoundTrigger(const sp<IBinder>& impl)
+        : BpInterface<ISoundTrigger>(impl)
+    {
+    }
+
+    void detach()
+    {
+        ALOGV("detach");
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        remote()->transact(DETACH, data, &reply);
+    }
+
+    status_t loadSoundModel(const sp<IMemory>&  modelMemory,
+                                    sound_model_handle_t *handle)
+    {
+        if (modelMemory == 0 || handle == NULL) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        data.writeStrongBinder(modelMemory->asBinder());
+        status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply);
+        if (status != NO_ERROR ||
+                (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            return status;
+        }
+        reply.read(handle, sizeof(sound_model_handle_t));
+        return status;
+    }
+
+    virtual status_t unloadSoundModel(sound_model_handle_t handle)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        data.write(&handle, sizeof(sound_model_handle_t));
+        status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply);
+        if (status != NO_ERROR) {
+            status = (status_t)reply.readInt32();
+        }
+        return status;
+    }
+
+    virtual status_t startRecognition(sound_model_handle_t handle,
+                                      const sp<IMemory>& dataMemory)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        data.write(&handle, sizeof(sound_model_handle_t));
+        if (dataMemory == 0) {
+            data.writeInt32(0);
+        } else {
+            data.writeInt32(dataMemory->size());
+        }
+        data.writeStrongBinder(dataMemory->asBinder());
+        status_t status = remote()->transact(START_RECOGNITION, data, &reply);
+        if (status != NO_ERROR) {
+            status = (status_t)reply.readInt32();
+        }
+        return status;
+    }
+
+    virtual status_t stopRecognition(sound_model_handle_t handle)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
+        data.write(&handle, sizeof(sound_model_handle_t));
+        status_t status = remote()->transact(STOP_RECOGNITION, data, &reply);
+        if (status != NO_ERROR) {
+            status = (status_t)reply.readInt32();
+        }
+        return status;
+    }
+
+};
+
+IMPLEMENT_META_INTERFACE(SoundTrigger, "android.hardware.ISoundTrigger");
+
+// ----------------------------------------------------------------------
+
+status_t BnSoundTrigger::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case DETACH: {
+            ALOGV("DETACH");
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            detach();
+            return NO_ERROR;
+        } break;
+        case LOAD_SOUND_MODEL: {
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            sp<IMemory> modelMemory = interface_cast<IMemory>(
+                data.readStrongBinder());
+            sound_model_handle_t handle;
+            status_t status = loadSoundModel(modelMemory, &handle);
+            reply->writeInt32(status);
+            if (status == NO_ERROR) {
+                reply->write(&handle, sizeof(sound_model_handle_t));
+            }
+            return NO_ERROR;
+        }
+        case UNLOAD_SOUND_MODEL: {
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            sound_model_handle_t handle;
+            data.read(&handle, sizeof(sound_model_handle_t));
+            status_t status = unloadSoundModel(handle);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+        case START_RECOGNITION: {
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            sound_model_handle_t handle;
+            data.read(&handle, sizeof(sound_model_handle_t));
+            sp<IMemory> dataMemory;
+            if (data.readInt32() != 0) {
+                dataMemory = interface_cast<IMemory>(data.readStrongBinder());
+            }
+            status_t status = startRecognition(handle, dataMemory);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+        case STOP_RECOGNITION: {
+            CHECK_INTERFACE(ISoundTrigger, data, reply);
+            sound_model_handle_t handle;
+            data.read(&handle, sizeof(sound_model_handle_t));
+            status_t status = stopRecognition(handle);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/soundtrigger/ISoundTriggerClient.cpp b/soundtrigger/ISoundTriggerClient.cpp
new file mode 100644
index 0000000..1d0c0ec
--- /dev/null
+++ b/soundtrigger/ISoundTriggerClient.cpp
@@ -0,0 +1,75 @@
+/*
+**
+** Copyright 2014, 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 <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+
+namespace android {
+
+enum {
+    ON_RECOGNITION_EVENT = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpSoundTriggerClient: public BpInterface<ISoundTriggerClient>
+{
+
+public:
+    BpSoundTriggerClient(const sp<IBinder>& impl)
+        : BpInterface<ISoundTriggerClient>(impl)
+    {
+    }
+
+    virtual void onRecognitionEvent(const sp<IMemory>& eventMemory)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTriggerClient::getInterfaceDescriptor());
+        data.writeStrongBinder(eventMemory->asBinder());
+        remote()->transact(ON_RECOGNITION_EVENT,
+                           data,
+                           &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SoundTriggerClient,
+                         "android.hardware.ISoundTriggerClient");
+
+// ----------------------------------------------------------------------
+
+status_t BnSoundTriggerClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case ON_RECOGNITION_EVENT: {
+            CHECK_INTERFACE(ISoundTriggerClient, data, reply);
+            sp<IMemory> eventMemory = interface_cast<IMemory>(
+                data.readStrongBinder());
+            onRecognitionEvent(eventMemory);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/soundtrigger/ISoundTriggerHwService.cpp b/soundtrigger/ISoundTriggerHwService.cpp
new file mode 100644
index 0000000..c9a0c24
--- /dev/null
+++ b/soundtrigger/ISoundTriggerHwService.cpp
@@ -0,0 +1,150 @@
+/*
+**
+** Copyright 2014, 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 "BpSoundTriggerHwService"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <soundtrigger/ISoundTriggerHwService.h>
+#include <soundtrigger/ISoundTrigger.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+
+namespace android {
+
+enum {
+    LIST_MODULES = IBinder::FIRST_CALL_TRANSACTION,
+    ATTACH,
+};
+
+class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService>
+{
+public:
+    BpSoundTriggerHwService(const sp<IBinder>& impl)
+        : BpInterface<ISoundTriggerHwService>(impl)
+    {
+    }
+
+    virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
+                                 uint32_t *numModules)
+    {
+        if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
+        unsigned int numModulesReq = (modules == NULL) ? 0 : *numModules;
+        data.writeInt32(numModulesReq);
+        status_t status = remote()->transact(LIST_MODULES, data, &reply);
+        if (status == NO_ERROR) {
+            status = (status_t)reply.readInt32();
+            *numModules = (unsigned int)reply.readInt32();
+        }
+        ALOGV("listModules() status %d got *numModules %d", status, *numModules);
+        if (status == NO_ERROR) {
+            if (numModulesReq > *numModules) {
+                numModulesReq = *numModules;
+            }
+            if (numModulesReq > 0) {
+                reply.read(modules, numModulesReq * sizeof(struct sound_trigger_module_descriptor));
+            }
+        }
+        return status;
+    }
+
+    virtual status_t attach(const sound_trigger_module_handle_t handle,
+                            const sp<ISoundTriggerClient>& client,
+                            sp<ISoundTrigger>& module)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
+        data.write(&handle, sizeof(sound_trigger_module_handle_t));
+        data.writeStrongBinder(client->asBinder());
+        remote()->transact(ATTACH, data, &reply);
+        status_t status = reply.readInt32();
+        if (reply.readInt32() != 0) {
+            module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
+        }
+        return status;
+    }
+
+};
+
+IMPLEMENT_META_INTERFACE(SoundTriggerHwService, "android.hardware.ISoundTriggerHwService");
+
+// ----------------------------------------------------------------------
+
+status_t BnSoundTriggerHwService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case LIST_MODULES: {
+            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
+            unsigned int numModulesReq = data.readInt32();
+            unsigned int numModules = numModulesReq;
+            struct sound_trigger_module_descriptor *modules =
+                    (struct sound_trigger_module_descriptor *)calloc(numModulesReq,
+                                                   sizeof(struct sound_trigger_module_descriptor));
+            status_t status = listModules(modules, &numModules);
+            reply->writeInt32(status);
+            reply->writeInt32(numModules);
+            ALOGV("LIST_MODULES status %d got numModules %d", status, numModules);
+
+            if (status == NO_ERROR) {
+                if (numModulesReq > numModules) {
+                    numModulesReq = numModules;
+                }
+                reply->write(modules,
+                             numModulesReq * sizeof(struct sound_trigger_module_descriptor));
+            }
+            free(modules);
+            return NO_ERROR;
+        }
+
+        case ATTACH: {
+            CHECK_INTERFACE(ISoundTriggerHwService, data, reply);
+            sound_trigger_module_handle_t handle;
+            data.read(&handle, sizeof(sound_trigger_module_handle_t));
+            sp<ISoundTriggerClient> client =
+                    interface_cast<ISoundTriggerClient>(data.readStrongBinder());
+            sp<ISoundTrigger> module;
+            status_t status = attach(handle, client, module);
+            reply->writeInt32(status);
+            if (module != 0) {
+                reply->writeInt32(1);
+                reply->writeStrongBinder(module->asBinder());
+            } else {
+                reply->writeInt32(0);
+            }
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/soundtrigger/SoundTrigger.cpp b/soundtrigger/SoundTrigger.cpp
new file mode 100644
index 0000000..e43acd0
--- /dev/null
+++ b/soundtrigger/SoundTrigger.cpp
@@ -0,0 +1,253 @@
+/*
+**
+** Copyright (C) 2014, 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 "SoundTrigger"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/IMemory.h>
+
+#include <soundtrigger/SoundTrigger.h>
+#include <soundtrigger/ISoundTrigger.h>
+#include <soundtrigger/ISoundTriggerHwService.h>
+#include <soundtrigger/ISoundTriggerClient.h>
+#include <soundtrigger/SoundTriggerCallback.h>
+
+namespace android {
+
+namespace {
+    sp<ISoundTriggerHwService> gSoundTriggerHwService;
+    const int                  kSoundTriggerHwServicePollDelay = 500000; // 0.5s
+    const char*                kSoundTriggerHwServiceName      = "media.sound_trigger_hw";
+    Mutex                      gLock;
+
+    class DeathNotifier : public IBinder::DeathRecipient
+    {
+    public:
+        DeathNotifier() {
+        }
+
+        virtual void binderDied(const wp<IBinder>& who __unused) {
+            ALOGV("binderDied");
+            Mutex::Autolock _l(gLock);
+            gSoundTriggerHwService.clear();
+            ALOGW("Sound trigger service died!");
+        }
+    };
+
+    sp<DeathNotifier>         gDeathNotifier;
+}; // namespace anonymous
+
+const sp<ISoundTriggerHwService>& SoundTrigger::getSoundTriggerHwService()
+{
+    Mutex::Autolock _l(gLock);
+    if (gSoundTriggerHwService.get() == 0) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder;
+        do {
+            binder = sm->getService(String16(kSoundTriggerHwServiceName));
+            if (binder != 0) {
+                break;
+            }
+            ALOGW("SoundTriggerHwService not published, waiting...");
+            usleep(kSoundTriggerHwServicePollDelay);
+        } while(true);
+        if (gDeathNotifier == NULL) {
+            gDeathNotifier = new DeathNotifier();
+        }
+        binder->linkToDeath(gDeathNotifier);
+        gSoundTriggerHwService = interface_cast<ISoundTriggerHwService>(binder);
+    }
+    ALOGE_IF(gSoundTriggerHwService == 0, "no SoundTriggerHwService!?");
+    return gSoundTriggerHwService;
+}
+
+// Static methods
+status_t SoundTrigger::listModules(struct sound_trigger_module_descriptor *modules,
+                                 uint32_t *numModules)
+{
+    ALOGV("listModules()");
+    const sp<ISoundTriggerHwService>& service = getSoundTriggerHwService();
+    if (service == 0) {
+        return NO_INIT;
+    }
+    return service->listModules(modules, numModules);
+}
+
+sp<SoundTrigger> SoundTrigger::attach(const sound_trigger_module_handle_t module,
+                                            const sp<SoundTriggerCallback>& callback)
+{
+    ALOGV("attach()");
+    sp<SoundTrigger> soundTrigger;
+    const sp<ISoundTriggerHwService>& service = getSoundTriggerHwService();
+    if (service == 0) {
+        return soundTrigger;
+    }
+    soundTrigger = new SoundTrigger(module, callback);
+    status_t status = service->attach(module, soundTrigger, soundTrigger->mISoundTrigger);
+
+    if (status == NO_ERROR && soundTrigger->mISoundTrigger != 0) {
+        soundTrigger->mISoundTrigger->asBinder()->linkToDeath(soundTrigger);
+    } else {
+        ALOGW("Error %d connecting to sound trigger service", status);
+        soundTrigger.clear();
+    }
+    return soundTrigger;
+}
+
+
+// SoundTrigger
+SoundTrigger::SoundTrigger(sound_trigger_module_handle_t module,
+                                 const sp<SoundTriggerCallback>& callback)
+    : mModule(module), mCallback(callback)
+{
+}
+
+SoundTrigger::~SoundTrigger()
+{
+    if (mISoundTrigger != 0) {
+        mISoundTrigger->detach();
+    }
+}
+
+
+void SoundTrigger::detach() {
+    ALOGV("detach()");
+    Mutex::Autolock _l(mLock);
+    mCallback.clear();
+    if (mISoundTrigger != 0) {
+        mISoundTrigger->detach();
+        mISoundTrigger->asBinder()->unlinkToDeath(this);
+        mISoundTrigger = 0;
+    }
+}
+
+status_t SoundTrigger::loadSoundModel(const sp<IMemory>& modelMemory,
+                                sound_model_handle_t *handle)
+{
+    Mutex::Autolock _l(mLock);
+    if (mISoundTrigger == 0) {
+        return NO_INIT;
+    }
+
+    return mISoundTrigger->loadSoundModel(modelMemory, handle);
+}
+
+status_t SoundTrigger::unloadSoundModel(sound_model_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+    if (mISoundTrigger == 0) {
+        return NO_INIT;
+    }
+    return mISoundTrigger->unloadSoundModel(handle);
+}
+
+status_t SoundTrigger::startRecognition(sound_model_handle_t handle,
+                                        const sp<IMemory>& dataMemory)
+{
+    Mutex::Autolock _l(mLock);
+    if (mISoundTrigger == 0) {
+        return NO_INIT;
+    }
+    return mISoundTrigger->startRecognition(handle, dataMemory);
+}
+
+status_t SoundTrigger::stopRecognition(sound_model_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+    if (mISoundTrigger == 0) {
+        return NO_INIT;
+    }
+    return mISoundTrigger->stopRecognition(handle);
+}
+
+// BpSoundTriggerClient
+void SoundTrigger::onRecognitionEvent(const sp<IMemory>& eventMemory)
+{
+    Mutex::Autolock _l(mLock);
+    if (eventMemory == 0 || eventMemory->pointer() == NULL) {
+        return;
+    }
+
+    if (mCallback != 0) {
+        mCallback->onRecognitionEvent(
+                (struct sound_trigger_recognition_event *)eventMemory->pointer());
+    }
+}
+
+
+//IBinder::DeathRecipient
+void SoundTrigger::binderDied(const wp<IBinder>& who __unused) {
+    Mutex::Autolock _l(mLock);
+    ALOGW("SoundTrigger server binder Died ");
+    mISoundTrigger = 0;
+    if (mCallback != 0) {
+        mCallback->onServiceDied();
+    }
+}
+
+status_t SoundTrigger::stringToGuid(const char *str, sound_trigger_uuid_t *guid)
+{
+    if (str == NULL || guid == NULL) {
+        return BAD_VALUE;
+    }
+
+    int tmp[10];
+
+    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        return BAD_VALUE;
+    }
+    guid->timeLow = (uint32_t)tmp[0];
+    guid->timeMid = (uint16_t)tmp[1];
+    guid->timeHiAndVersion = (uint16_t)tmp[2];
+    guid->clockSeq = (uint16_t)tmp[3];
+    guid->node[0] = (uint8_t)tmp[4];
+    guid->node[1] = (uint8_t)tmp[5];
+    guid->node[2] = (uint8_t)tmp[6];
+    guid->node[3] = (uint8_t)tmp[7];
+    guid->node[4] = (uint8_t)tmp[8];
+    guid->node[5] = (uint8_t)tmp[9];
+
+    return NO_ERROR;
+}
+
+status_t SoundTrigger::guidToString(const sound_trigger_uuid_t *guid, char *str, size_t maxLen)
+{
+    if (guid == NULL || str == NULL) {
+        return BAD_VALUE;
+    }
+
+    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            guid->timeLow,
+            guid->timeMid,
+            guid->timeHiAndVersion,
+            guid->clockSeq,
+            guid->node[0],
+            guid->node[1],
+            guid->node[2],
+            guid->node[3],
+            guid->node[4],
+            guid->node[5]);
+
+    return NO_ERROR;
+}
+
+}; // namespace android