Move ExtendedAudioBufferProvider and SingleStateQueue

Move ExtendedAudioBufferProvider.h to libaudioclient. This is
a more appropriate location because EABP extends AudioBufferProvider.

Move SingleStateQueue.h to libnbaio_mono. This is a more appropriate
location because SSQ is a non-blocking queue.

This allows to remove the dependency of libnbaio on libmedia
which is a good thing because libnbaio provides more low-level
abstractions than libmedia.

Also, replace a dependency of libnbaio on libbinder with
a dependency on libaudiohal header library.

Test: make
Change-Id: Ie48b523790cd8230695ec2e4710e50981b616289
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index 6345742..04ddcff 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -8,15 +8,14 @@
     header_libs: [
         "libaudioclient_headers",
         "libaudio_system_headers",
-        "libmedia_headers",
     ],
     export_header_lib_headers: [
         "libaudioclient_headers",
-        "libmedia_headers",
     ],
 
     shared_libs: [
         "libaudioutils",
+        "libcutils",
         "liblog",
         "libutils",
     ],
@@ -25,6 +24,11 @@
     ],
 
     export_include_dirs: ["include_mono"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
 }
 
 // libnbaio_mono is the part of libnbaio that is available for vendors to use. Vendor modules can't
@@ -55,18 +59,7 @@
     // ],
     // static_libs: ["libsndfile"],
 
-    shared_libs: [
-        "libaudioutils",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
+    header_libs: ["libaudiohal_headers"],
 
     export_include_dirs: ["include"],
 }
diff --git a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
index c51d0fe..926d84a 100644
--- a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
+++ b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
@@ -19,7 +19,7 @@
 
 #include <time.h>
 #include <audio_utils/fifo.h>
-#include <media/SingleStateQueue.h>
+#include <media/nbaio/SingleStateQueue.h>
 #include <media/nbaio/NBAIO.h>
 
 namespace android {
diff --git a/media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h b/media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
new file mode 100644
index 0000000..d423962
--- /dev/null
+++ b/media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 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 SINGLE_STATE_QUEUE_H
+#define SINGLE_STATE_QUEUE_H
+
+// Non-blocking single element state queue, or
+// Non-blocking single-reader / single-writer multi-word atomic load / store
+
+#include <stdint.h>
+#include <cutils/atomic.h>
+
+namespace android {
+
+template<typename T> class SingleStateQueue {
+
+public:
+
+    class Mutator;
+    class Observer;
+
+    enum SSQ_STATUS {
+        SSQ_PENDING, /* = 0 */
+        SSQ_READ,
+        SSQ_DONE,
+    };
+
+    struct Shared {
+        // needs to be part of a union so don't define constructor or destructor
+
+        friend class Mutator;
+        friend class Observer;
+
+private:
+        void                init() { mAck = 0; mSequence = 0; }
+
+        volatile int32_t    mAck;
+        volatile int32_t    mSequence;
+        T                   mValue;
+    };
+
+    class Mutator {
+    public:
+        Mutator(Shared *shared)
+            : mSequence(0), mShared(shared)
+        {
+            // exactly one of Mutator and Observer must initialize, currently it is Observer
+            // shared->init();
+        }
+
+        // push new value onto state queue, overwriting previous value;
+        // returns a sequence number which can be used with ack()
+        int32_t push(const T& value)
+        {
+            Shared *shared = mShared;
+            int32_t sequence = mSequence;
+            sequence++;
+            android_atomic_acquire_store(sequence, &shared->mSequence);
+            shared->mValue = value;
+            sequence++;
+            android_atomic_release_store(sequence, &shared->mSequence);
+            mSequence = sequence;
+            // consider signalling a futex here, if we know that observer is waiting
+            return sequence;
+        }
+
+        // returns the status of the last state push.  This may be a stale value.
+        //
+        // SSQ_PENDING, or 0, means it has not been observed
+        // SSQ_READ means it has been read
+        // SSQ_DONE means it has been acted upon, after Observer::done() is called
+        enum SSQ_STATUS ack() const
+        {
+            // in the case of SSQ_DONE, prevent any subtle data-races of subsequent reads
+            // being performed (out-of-order) before the ack read, should the caller be
+            // depending on sequentiality of reads.
+            const int32_t ack = android_atomic_acquire_load(&mShared->mAck);
+            return ack - mSequence & ~1 ? SSQ_PENDING /* seq differ */ :
+                    ack & 1 ? SSQ_DONE : SSQ_READ;
+        }
+
+        // return true if a push with specified sequence number or later has been observed
+        bool ack(int32_t sequence) const
+        {
+            // this relies on 2's complement rollover to detect an ancient sequence number
+            return mShared->mAck - sequence >= 0;
+        }
+
+    private:
+        int32_t     mSequence;
+        Shared * const mShared;
+    };
+
+    class Observer {
+    public:
+        Observer(Shared *shared)
+            : mSequence(0), mSeed(1), mShared(shared)
+        {
+            // exactly one of Mutator and Observer must initialize, currently it is Observer
+            shared->init();
+        }
+
+        // return true if value has changed
+        bool poll(T& value)
+        {
+            Shared *shared = mShared;
+            int32_t before = shared->mSequence;
+            if (before == mSequence) {
+                return false;
+            }
+            for (int tries = 0; ; ) {
+                const int MAX_TRIES = 5;
+                if (before & 1) {
+                    if (++tries >= MAX_TRIES) {
+                        return false;
+                    }
+                    before = shared->mSequence;
+                } else {
+                    android_memory_barrier();
+                    T temp = shared->mValue;
+                    int32_t after = android_atomic_release_load(&shared->mSequence);
+                    if (after == before) {
+                        value = temp;
+                        shared->mAck = before;
+                        mSequence = before; // mSequence is even after poll success
+                        return true;
+                    }
+                    if (++tries >= MAX_TRIES) {
+                        return false;
+                    }
+                    before = after;
+                }
+            }
+        }
+
+        // (optional) used to indicate to the Mutator that the state that has been polled
+        // has also been acted upon.
+        void done()
+        {
+            const int32_t ack = mShared->mAck + 1;
+            // ensure all previous writes have been performed.
+            android_atomic_release_store(ack, &mShared->mAck); // mSequence is odd after "done"
+        }
+
+    private:
+        int32_t     mSequence;
+        int         mSeed;  // for PRNG
+        Shared * const mShared;
+    };
+
+#if 0
+    SingleStateQueue(void /*Shared*/ *shared);
+    /*virtual*/ ~SingleStateQueue() { }
+
+    static size_t size() { return sizeof(Shared); }
+#endif
+
+};
+
+}   // namespace android
+
+#endif  // SINGLE_STATE_QUEUE_H