Merge "audio policy: fix service fuzz test crash" into lmp-dev
diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/StateQueue.cpp
index 7e01c9f..40d7bcd 100644
--- a/services/audioflinger/StateQueue.cpp
+++ b/services/audioflinger/StateQueue.cpp
@@ -41,13 +41,14 @@
 // Constructor and destructor
 
 template<typename T> StateQueue<T>::StateQueue() :
-    mNext(NULL), mAck(NULL), mCurrent(NULL),
+    mAck(NULL), mCurrent(NULL),
     mMutating(&mStates[0]), mExpecting(NULL),
     mInMutation(false), mIsDirty(false), mIsInitialized(false)
 #ifdef STATE_QUEUE_DUMP
     , mObserverDump(&mObserverDummyDump), mMutatorDump(&mMutatorDummyDump)
 #endif
 {
+    atomic_init(&mNext, 0);
 }
 
 template<typename T> StateQueue<T>::~StateQueue()
@@ -58,11 +59,8 @@
 
 template<typename T> const T* StateQueue<T>::poll()
 {
-#ifdef __LP64__
-    const T *next = (const T *) android_atomic_acquire_load64((volatile int64_t *) &mNext);
-#else
-    const T *next = (const T *) android_atomic_acquire_load((volatile int32_t *) &mNext);
-#endif
+    const T *next = (const T *) atomic_load_explicit(&mNext, memory_order_acquire);
+
     if (next != mCurrent) {
         mAck = next;    // no additional barrier needed
         mCurrent = next;
@@ -144,11 +142,7 @@
         }
 
         // publish
-#ifdef __LP64__
-        android_atomic_release_store64((int64_t) mMutating, (volatile int64_t *) &mNext);
-#else
-        android_atomic_release_store((int32_t) mMutating, (volatile int32_t *) &mNext);
-#endif
+        atomic_store_explicit(&mNext, (uintptr_t)mMutating, memory_order_release);
         mExpecting = mMutating;
 
         // copy with circular wraparound
diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/StateQueue.h
index 9e176c4..27f6a28 100644
--- a/services/audioflinger/StateQueue.h
+++ b/services/audioflinger/StateQueue.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_AUDIO_STATE_QUEUE_H
 #define ANDROID_AUDIO_STATE_QUEUE_H
 
+#include <stdatomic.h>
+
 // The state queue template class was originally driven by this use case / requirements:
 //  There are two threads: a fast mixer, and a normal mixer, and they share state.
 //  The interesting part of the shared state is a set of active fast tracks,
@@ -186,7 +188,7 @@
     T                 mStates[kN];      // written by mutator, read by observer
 
     // "volatile" is meaningless with SMP, but here it indicates that we're using atomic ops
-    volatile const T* mNext; // written by mutator to advance next, read by observer
+    atomic_uintptr_t  mNext; // written by mutator to advance next, read by observer
     volatile const T* mAck;  // written by observer to acknowledge advance of next, read by mutator
 
     // only used by observer
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index b7ccaab..51eb845 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -33,8 +33,11 @@
     libhardware \
     libsoundtrigger
 
-#LOCAL_C_INCLUDES += \
+LOCAL_STATIC_LIBRARIES := \
+    libserviceutility
 
+LOCAL_C_INCLUDES += \
+    $(TOPDIR)frameworks/av/services/audioflinger
 
 LOCAL_MODULE:= libsoundtriggerservice
 
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 747af79..3654136 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -22,18 +22,18 @@
 #include <sys/types.h>
 #include <pthread.h>
 
+#include <system/sound_trigger.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+#include <utils/Errors.h>
+#include <utils/Log.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>
+#include <ServiceUtilities.h>
+#include "SoundTriggerHwService.h"
 
 namespace android {
 
@@ -103,6 +103,10 @@
                              uint32_t *numModules)
 {
     ALOGV("listModules");
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
     AutoMutex lock(mServiceLock);
     if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
         return BAD_VALUE;
@@ -120,6 +124,10 @@
                         sp<ISoundTrigger>& moduleInterface)
 {
     ALOGV("attach module %d", handle);
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
     AutoMutex lock(mServiceLock);
     moduleInterface.clear();
     if (client == 0) {
@@ -139,8 +147,8 @@
 }
 
 void SoundTriggerHwService::detachModule(sp<Module> module) {
-    AutoMutex lock(mServiceLock);
     ALOGV("detachModule");
+    AutoMutex lock(mServiceLock);
     module->clearClient();
 }
 
@@ -310,6 +318,9 @@
 
 void SoundTriggerHwService::Module::detach() {
     ALOGV("detach()");
+    if (!captureHotwordAllowed()) {
+        return;
+    }
     {
         AutoMutex lock(mLock);
         for (size_t i = 0; i < mModels.size(); i++) {
@@ -337,6 +348,9 @@
                                 sound_model_handle_t *handle)
 {
     ALOGV("loadSoundModel() handle");
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
 
     if (modelMemory == 0 || modelMemory->pointer() == NULL) {
         ALOGE("loadSoundModel() modelMemory is 0 or has NULL pointer()");
@@ -361,6 +375,9 @@
 status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
 {
     ALOGV("unloadSoundModel() model handle %d", handle);
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
 
     AutoMutex lock(mLock);
     ssize_t index = mModels.indexOfKey(handle);
@@ -380,6 +397,9 @@
                                  const sp<IMemory>& dataMemory)
 {
     ALOGV("startRecognition() model handle %d", handle);
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
 
     if (dataMemory != 0 && dataMemory->pointer() == NULL) {
         ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
@@ -415,6 +435,9 @@
 status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
 {
     ALOGV("stopRecognition() model handle %d", handle);
+    if (!captureHotwordAllowed()) {
+        return PERMISSION_DENIED;
+    }
 
     AutoMutex lock(mLock);
     sp<Model> model = getModel(handle);