diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
new file mode 100644
index 0000000..f09e79e
--- /dev/null
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -0,0 +1,566 @@
+/*
+ * 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;
+    }
+    mModels.removeItem(handle);
+
+    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
