liboboe: rename Oboe to AAudio
All of the edits were done using scripts in media/liboboe/scripts.
The conversion is done using SED, which is called from
convert_oboe_aaudio.sh
The conversion can be reverted when debugging using revert_all_aaudio.sh
The string substitutions are in oboe_to_aaudio.sed
Bug: 34749573
Test: cts/tests/tests/nativemedia/aaudio
Change-Id: Ia10b34472a90df2652b87607c99156e9084e57aa
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/liboboe/tests/Android.mk b/media/liboboe/tests/Android.mk
index 165669b..16279ec 100644
--- a/media/liboboe/tests/Android.mk
+++ b/media/liboboe/tests/Android.mk
@@ -6,11 +6,11 @@
frameworks/av/media/liboboe/include \
frameworks/av/media/liboboe/src/core \
frameworks/av/media/liboboe/src/utility
-LOCAL_SRC_FILES := test_oboe_api.cpp
+LOCAL_SRC_FILES := test_aaudio_api.cpp
LOCAL_SHARED_LIBRARIES := libaudioclient libaudioutils libbinder \
libcutils liblog libmedia libutils
LOCAL_STATIC_LIBRARIES := liboboe
-LOCAL_MODULE := test_oboe_api
+LOCAL_MODULE := test_aaudio_api
include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
diff --git a/media/liboboe/tests/test_aaudio_api.cpp b/media/liboboe/tests/test_aaudio_api.cpp
new file mode 100644
index 0000000..7db3688
--- /dev/null
+++ b/media/liboboe/tests/test_aaudio_api.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Unit tests for AAudio 'C' API.
+
+#include <stdlib.h>
+#include <math.h>
+
+#include <gtest/gtest.h>
+
+#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
+#include "AAudioUtilities.h"
+
+#define DEFAULT_STATE_TIMEOUT (500 * AAUDIO_NANOS_PER_MILLISECOND)
+
+// Test AAudioStreamBuilder
+TEST(test_aaudio_api, aaudio_stream_builder) {
+ const aaudio_sample_rate_t requestedSampleRate1 = 48000;
+ const aaudio_sample_rate_t requestedSampleRate2 = 44100;
+ const int32_t requestedSamplesPerFrame = 2;
+ const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM16;
+
+ aaudio_sample_rate_t sampleRate = 0;
+ int32_t samplesPerFrame = 0;
+ aaudio_audio_format_t actualDataFormat;
+ AAudioStreamBuilder aaudioBuilder1;
+ AAudioStreamBuilder aaudioBuilder2;
+
+ aaudio_result_t result = AAUDIO_OK;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ result = AAudio_createStreamBuilder(&aaudioBuilder1);
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ // Request stream properties.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder1, requestedSampleRate1));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSamplesPerFrame(aaudioBuilder1, requestedSamplesPerFrame));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setFormat(aaudioBuilder1, requestedDataFormat));
+
+ // Check to make sure builder saved the properties.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate));
+ EXPECT_EQ(requestedSampleRate1, sampleRate);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSamplesPerFrame(aaudioBuilder1, &samplesPerFrame));
+ EXPECT_EQ(requestedSamplesPerFrame, samplesPerFrame);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getFormat(aaudioBuilder1, &actualDataFormat));
+ EXPECT_EQ(requestedDataFormat, actualDataFormat);
+
+ result = AAudioStreamBuilder_getSampleRate(0x0BADCAFE, &sampleRate); // ridiculous token
+ EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, result);
+
+ // Create a second builder and make sure they do not collide.
+ ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder2));
+ ASSERT_NE(aaudioBuilder1, aaudioBuilder2);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder2, requestedSampleRate2));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate));
+ EXPECT_EQ(requestedSampleRate1, sampleRate);
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
+ EXPECT_EQ(requestedSampleRate2, sampleRate);
+
+ // Delete the builder.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder1));
+
+ // Now it should no longer be valid.
+ // Note that test assumes we are using the HandleTracker. If we use plain pointers
+ // then it will be difficult to detect this kind of error.
+ result = AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate); // stale token
+ EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, result);
+
+ // Second builder should still be valid.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
+ EXPECT_EQ(requestedSampleRate2, sampleRate);
+
+ // Delete the second builder.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder2));
+
+ // Now it should no longer be valid. Assumes HandlerTracker used.
+ EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
+}
+
+// Test creating a default stream with everything unspecified.
+TEST(test_aaudio_api, aaudio_stream_unspecified) {
+ AAudioStreamBuilder aaudioBuilder;
+ AAudioStream aaudioStream;
+ aaudio_result_t result = AAUDIO_OK;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ result = AAudio_createStreamBuilder(&aaudioBuilder);
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ // Create an AAudioStream using the Builder.
+ ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+
+ // Cleanup
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
+}
+
+// Test Writing to an AAudioStream
+void runtest_aaudio_stream(aaudio_sharing_mode_t requestedSharingMode) {
+ const aaudio_sample_rate_t requestedSampleRate = 48000;
+ const aaudio_sample_rate_t requestedSamplesPerFrame = 2;
+ const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM16;
+
+ aaudio_sample_rate_t actualSampleRate = -1;
+ int32_t actualSamplesPerFrame = -1;
+ aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_INVALID;
+ aaudio_sharing_mode_t actualSharingMode;
+ aaudio_size_frames_t framesPerBurst = -1;
+ int writeLoops = 0;
+
+ aaudio_size_frames_t framesWritten = 0;
+ aaudio_size_frames_t framesPrimed = 0;
+ aaudio_position_frames_t framesTotal = 0;
+ aaudio_position_frames_t aaudioFramesRead = 0;
+ aaudio_position_frames_t aaudioFramesRead1 = 0;
+ aaudio_position_frames_t aaudioFramesRead2 = 0;
+ aaudio_position_frames_t aaudioFramesWritten = 0;
+
+ aaudio_nanoseconds_t timeoutNanos;
+
+ aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNINITIALIZED;
+ AAudioStreamBuilder aaudioBuilder;
+ AAudioStream aaudioStream;
+
+ aaudio_result_t result = AAUDIO_OK;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ result = AAudio_createStreamBuilder(&aaudioBuilder);
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ // Request stream properties.
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder, requestedSampleRate));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSamplesPerFrame(aaudioBuilder, requestedSamplesPerFrame));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setFormat(aaudioBuilder, requestedDataFormat));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSharingMode(aaudioBuilder, requestedSharingMode));
+
+ // Create an AAudioStream using the Builder.
+ ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getState(aaudioStream, &state));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
+
+ // Check to see what kind of stream we actually got.
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getSampleRate(aaudioStream, &actualSampleRate));
+ ASSERT_TRUE(actualSampleRate >= 44100 && actualSampleRate <= 96000); // TODO what is range?
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getSamplesPerFrame(aaudioStream, &actualSamplesPerFrame));
+ ASSERT_TRUE(actualSamplesPerFrame >= 1 && actualSamplesPerFrame <= 16); // TODO what is max?
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getSharingMode(aaudioStream, &actualSharingMode));
+ ASSERT_TRUE(actualSharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE
+ || actualSharingMode == AAUDIO_SHARING_MODE_LEGACY);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFormat(aaudioStream, &actualDataFormat));
+ EXPECT_NE(AAUDIO_FORMAT_INVALID, actualDataFormat);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesPerBurst(aaudioStream, &framesPerBurst));
+ ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
+
+ // Allocate a buffer for the audio data.
+ // TODO handle possibility of other data formats
+ ASSERT_TRUE(actualDataFormat == AAUDIO_FORMAT_PCM16);
+ size_t dataSizeSamples = framesPerBurst * actualSamplesPerFrame;
+ int16_t *data = new int16_t[dataSizeSamples];
+ ASSERT_TRUE(nullptr != data);
+ memset(data, 0, sizeof(int16_t) * dataSizeSamples);
+
+ // Prime the buffer.
+ timeoutNanos = 0;
+ do {
+ framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
+ // There should be some room for priming the buffer.
+ framesTotal += framesWritten;
+ ASSERT_GE(framesWritten, 0);
+ ASSERT_LE(framesWritten, framesPerBurst);
+ } while (framesWritten > 0);
+ ASSERT_TRUE(framesTotal > 0);
+
+ // Start/write/pause more than once to see if it fails after the first time.
+ // Write some data and measure the rate to see if the timing is OK.
+ for (int numLoops = 0; numLoops < 2; numLoops++) {
+ // Start and wait for server to respond.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+ AAUDIO_STREAM_STATE_STARTING,
+ &state,
+ DEFAULT_STATE_TIMEOUT));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
+
+ // Write some data while we are running. Read counter should be advancing.
+ writeLoops = 1 * actualSampleRate / framesPerBurst; // 1 second
+ ASSERT_LT(2, writeLoops); // detect absurdly high framesPerBurst
+ timeoutNanos = 10 * AAUDIO_NANOS_PER_SECOND * framesPerBurst / actualSampleRate; // bursts
+ framesWritten = 1;
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
+ aaudioFramesRead1 = aaudioFramesRead;
+ aaudio_nanoseconds_t beginTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
+ do {
+ framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
+ ASSERT_GE(framesWritten, 0);
+ ASSERT_LE(framesWritten, framesPerBurst);
+
+ framesTotal += framesWritten;
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesWritten(aaudioStream, &aaudioFramesWritten));
+ EXPECT_EQ(framesTotal, aaudioFramesWritten);
+
+ // Try to get a more accurate measure of the sample rate.
+ if (beginTime == 0) {
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
+ if (aaudioFramesRead > aaudioFramesRead1) { // is read pointer advancing
+ beginTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
+ aaudioFramesRead1 = aaudioFramesRead;
+ }
+ }
+ } while (framesWritten > 0 && writeLoops-- > 0);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead2));
+ aaudio_nanoseconds_t endTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
+ ASSERT_GT(aaudioFramesRead2, 0);
+ ASSERT_GT(aaudioFramesRead2, aaudioFramesRead1);
+ ASSERT_LE(aaudioFramesRead2, aaudioFramesWritten);
+
+ // TODO why is legacy so inaccurate?
+ const double rateTolerance = 200.0; // arbitrary tolerance for sample rate
+ if (requestedSharingMode != AAUDIO_SHARING_MODE_LEGACY) {
+ // Calculate approximate sample rate and compare with stream rate.
+ double seconds = (endTime - beginTime) / (double) AAUDIO_NANOS_PER_SECOND;
+ double measuredRate = (aaudioFramesRead2 - aaudioFramesRead1) / seconds;
+ ASSERT_NEAR(actualSampleRate, measuredRate, rateTolerance);
+ }
+
+ // Request async pause and wait for server to say that it has completed the pause.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+ AAUDIO_STREAM_STATE_PAUSING,
+ &state,
+ DEFAULT_STATE_TIMEOUT));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
+ }
+
+ // Make sure the read counter is not advancing when we are paused.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
+ ASSERT_GE(aaudioFramesRead, aaudioFramesRead2); // monotonic increase
+
+ // Use this to sleep by waiting for something that won't happen.
+ AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state, timeoutNanos);
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead2));
+ EXPECT_EQ(aaudioFramesRead, aaudioFramesRead2);
+
+ // ------------------- TEST FLUSH -----------------
+ // Prime the buffer.
+ timeoutNanos = 0;
+ writeLoops = 100;
+ do {
+ framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
+ framesTotal += framesWritten;
+ } while (framesWritten > 0 && writeLoops-- > 0);
+ EXPECT_EQ(0, framesWritten);
+
+ // Flush and wait for server to respond.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestFlush(aaudioStream));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+ AAUDIO_STREAM_STATE_FLUSHING,
+ &state,
+ DEFAULT_STATE_TIMEOUT));
+ EXPECT_EQ(AAUDIO_STREAM_STATE_FLUSHED, state);
+
+ // After a flush, the read counter should be caught up with the write counter.
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesWritten(aaudioStream, &aaudioFramesWritten));
+ EXPECT_EQ(framesTotal, aaudioFramesWritten);
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
+ EXPECT_EQ(aaudioFramesRead, aaudioFramesWritten);
+
+ // The buffer should be empty after a flush so we should be able to write.
+ framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
+ // There should be some room for priming the buffer.
+ ASSERT_TRUE(framesWritten > 0 && framesWritten <= framesPerBurst);
+
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
+}
+
+// Test Writing to an AAudioStream using LEGACY sharing mode.
+TEST(test_aaudio_api, aaudio_stream_legacy) {
+ runtest_aaudio_stream(AAUDIO_SHARING_MODE_LEGACY);
+}
+
+// Test Writing to an AAudioStream using EXCLUSIVE sharing mode.
+TEST(test_aaudio_api, aaudio_stream_exclusive) {
+ runtest_aaudio_stream(AAUDIO_SHARING_MODE_EXCLUSIVE);
+}
+
+#define AAUDIO_THREAD_ANSWER 1826375
+#define AAUDIO_THREAD_DURATION_MSEC 500
+
+static void *TestAAudioStreamThreadProc(void *arg) {
+ AAudioStream aaudioStream = (AAudioStream) reinterpret_cast<size_t>(arg);
+ aaudio_stream_state_t state;
+
+ // Use this to sleep by waiting for something that won't happen.
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_getState(aaudioStream, &state));
+ AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state,
+ AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND);
+ return reinterpret_cast<void *>(AAUDIO_THREAD_ANSWER);
+}
+
+// Test creating a stream related thread.
+TEST(test_aaudio_api, aaudio_stream_thread_basic) {
+ AAudioStreamBuilder aaudioBuilder;
+ AAudioStream aaudioStream;
+ aaudio_result_t result = AAUDIO_OK;
+ void *threadResult;
+
+ // Use an AAudioStreamBuilder to define the stream.
+ result = AAudio_createStreamBuilder(&aaudioBuilder);
+ ASSERT_EQ(AAUDIO_OK, result);
+
+ // Create an AAudioStream using the Builder.
+ ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+
+ // Start a thread.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_createThread(aaudioStream,
+ 10 * AAUDIO_NANOS_PER_MILLISECOND,
+ TestAAudioStreamThreadProc,
+ reinterpret_cast<void *>(aaudioStream)));
+ // Thread already started.
+ ASSERT_NE(AAUDIO_OK, AAudioStream_createThread(aaudioStream, // should fail!
+ 10 * AAUDIO_NANOS_PER_MILLISECOND,
+ TestAAudioStreamThreadProc,
+ reinterpret_cast<void *>(aaudioStream)));
+
+ // Wait for the thread to finish.
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_joinThread(aaudioStream,
+ &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND));
+ // The thread returns a special answer.
+ ASSERT_EQ(AAUDIO_THREAD_ANSWER, (int)reinterpret_cast<size_t>(threadResult));
+
+ // Thread should already be joined.
+ ASSERT_NE(AAUDIO_OK, AAudioStream_joinThread(aaudioStream, // should fail!
+ &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND));
+
+ // Cleanup
+ EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
+ EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
+}
diff --git a/media/liboboe/tests/test_handle_tracker.cpp b/media/liboboe/tests/test_handle_tracker.cpp
index a146e76..e51c39c 100644
--- a/media/liboboe/tests/test_handle_tracker.cpp
+++ b/media/liboboe/tests/test_handle_tracker.cpp
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-// Unit tests for Oboe Handle Tracker
+// Unit tests for AAudio Handle Tracker
#include <stdlib.h>
#include <math.h>
#include <gtest/gtest.h>
-#include <oboe/OboeDefinitions.h>
+#include <aaudio/AAudioDefinitions.h>
#include "HandleTracker.h"
// Test adding one address.
-TEST(test_handle_tracker, oboe_handle_tracker) {
+TEST(test_handle_tracker, aaudio_handle_tracker) {
const int MAX_HANDLES = 4;
HandleTracker tracker(MAX_HANDLES);
handle_tracker_type_t type = 3; // arbitrary generic type
@@ -40,7 +40,7 @@
EXPECT_EQ(nullptr, found);
// create a valid handle and use it to lookup the object again
- oboe_handle_t dataHandle = tracker.put(type, &data);
+ aaudio_handle_t dataHandle = tracker.put(type, &data);
ASSERT_TRUE(dataHandle > 0);
found = tracker.get(type, dataHandle);
EXPECT_EQ(&data, found);
@@ -61,12 +61,12 @@
}
// Test filling the tracker.
-TEST(test_handle_tracker, oboe_full_up) {
+TEST(test_handle_tracker, aaudio_full_up) {
const int MAX_HANDLES = 5;
HandleTracker tracker(MAX_HANDLES);
handle_tracker_type_t type = 4; // arbitrary generic type
int data[MAX_HANDLES];
- oboe_handle_t handles[MAX_HANDLES];
+ aaudio_handle_t handles[MAX_HANDLES];
handle_tracker_address_t found;
// repeat the test several times to see if it breaks
@@ -81,7 +81,7 @@
}
// Now that it is full, try to add one more.
- oboe_handle_t handle = tracker.put(type, &data[0]);
+ aaudio_handle_t handle = tracker.put(type, &data[0]);
EXPECT_TRUE(handle < 0);
for (int i = 0; i < MAX_HANDLES; i++) {
diff --git a/media/liboboe/tests/test_marshalling.cpp b/media/liboboe/tests/test_marshalling.cpp
index 8f4cc2c..b1f77c0 100644
--- a/media/liboboe/tests/test_marshalling.cpp
+++ b/media/liboboe/tests/test_marshalling.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-// Unit tests for Oboe Marshalling of RingBuffer information.
+// Unit tests for AAudio Marshalling of RingBuffer information.
#include <stdlib.h>
#include <math.h>
@@ -25,14 +25,14 @@
#include <gtest/gtest.h>
#include <sys/mman.h>
-#include <oboe/OboeDefinitions.h>
+#include <aaudio/AAudioDefinitions.h>
#include <binding/AudioEndpointParcelable.h>
using namespace android;
-using namespace oboe;
+using namespace aaudio;
// Test adding one value.
-TEST(test_marshalling, oboe_one_read_write) {
+TEST(test_marshalling, aaudio_one_read_write) {
Parcel parcel;
size_t pos = parcel.dataPosition();
const int arbitraryValue = 235;
@@ -44,7 +44,7 @@
}
// Test SharedMemoryParcel.
-TEST(test_marshalling, oboe_shared_memory) {
+TEST(test_marshalling, aaudio_shared_memory) {
SharedMemoryParcelable sharedMemoryA;
SharedMemoryParcelable sharedMemoryB;
const size_t memSizeBytes = 840;
@@ -52,10 +52,10 @@
ASSERT_LE(0, fd);
sharedMemoryA.setup(fd, memSizeBytes);
void *region1;
- EXPECT_EQ(OBOE_OK, sharedMemoryA.resolve(0, 16, ®ion1)); // fits in region
- EXPECT_NE(OBOE_OK, sharedMemoryA.resolve(-2, 16, ®ion1)); // offset is negative
- EXPECT_NE(OBOE_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, ®ion1)); // size too big
- EXPECT_NE(OBOE_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, ®ion1)); // goes past the end
+ EXPECT_EQ(AAUDIO_OK, sharedMemoryA.resolve(0, 16, ®ion1)); // fits in region
+ EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(-2, 16, ®ion1)); // offset is negative
+ EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, ®ion1)); // size too big
+ EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, ®ion1)); // goes past the end
int32_t *buffer1 = (int32_t *)region1;
buffer1[0] = 98735; // arbitrary value
@@ -69,14 +69,14 @@
// should see same value at two different addresses
void *region2;
- EXPECT_EQ(OBOE_OK, sharedMemoryB.resolve(0, 16, ®ion2));
+ EXPECT_EQ(AAUDIO_OK, sharedMemoryB.resolve(0, 16, ®ion2));
int32_t *buffer2 = (int32_t *)region2;
EXPECT_NE(buffer1, buffer2);
EXPECT_EQ(buffer1[0], buffer2[0]);
}
// Test SharedRegionParcel.
-TEST(test_marshalling, oboe_shared_region) {
+TEST(test_marshalling, aaudio_shared_region) {
SharedMemoryParcelable sharedMemories[2];
SharedRegionParcelable sharedRegionA;
SharedRegionParcelable sharedRegionB;
@@ -89,7 +89,7 @@
sharedRegionA.setup(0, regionOffset1, regionSize1);
void *region1;
- EXPECT_EQ(OBOE_OK, sharedRegionA.resolve(sharedMemories, ®ion1));
+ EXPECT_EQ(AAUDIO_OK, sharedRegionA.resolve(sharedMemories, ®ion1));
int32_t *buffer1 = (int32_t *)region1;
buffer1[0] = 336677; // arbitrary value
@@ -102,13 +102,13 @@
// should see same value
void *region2;
- EXPECT_EQ(OBOE_OK, sharedRegionB.resolve(sharedMemories, ®ion2));
+ EXPECT_EQ(AAUDIO_OK, sharedRegionB.resolve(sharedMemories, ®ion2));
int32_t *buffer2 = (int32_t *)region2;
EXPECT_EQ(buffer1[0], buffer2[0]);
}
// Test RingBufferParcelable.
-TEST(test_marshalling, oboe_ring_buffer_parcelable) {
+TEST(test_marshalling, aaudio_ring_buffer_parcelable) {
SharedMemoryParcelable sharedMemories[2];
RingBufferParcelable ringBufferA;
RingBufferParcelable ringBufferB;
@@ -136,7 +136,7 @@
// setup A
RingBufferDescriptor descriptorA;
- EXPECT_EQ(OBOE_OK, ringBufferA.resolve(sharedMemories, &descriptorA));
+ EXPECT_EQ(AAUDIO_OK, ringBufferA.resolve(sharedMemories, &descriptorA));
descriptorA.dataAddress[0] = 95;
descriptorA.dataAddress[1] = 57;
descriptorA.readCounterAddress[0] = 17;
@@ -152,7 +152,7 @@
ringBufferB.readFromParcel(&parcel);
RingBufferDescriptor descriptorB;
- EXPECT_EQ(OBOE_OK, ringBufferB.resolve(sharedMemories, &descriptorB));
+ EXPECT_EQ(AAUDIO_OK, ringBufferB.resolve(sharedMemories, &descriptorB));
// A and B should match
EXPECT_EQ(descriptorA.dataAddress[0], descriptorB.dataAddress[0]);
diff --git a/media/liboboe/tests/test_oboe_api.cpp b/media/liboboe/tests/test_oboe_api.cpp
deleted file mode 100644
index 0bc469f..0000000
--- a/media/liboboe/tests/test_oboe_api.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-// Unit tests for Oboe 'C' API.
-
-#include <stdlib.h>
-#include <math.h>
-
-#include <gtest/gtest.h>
-
-#include <oboe/OboeDefinitions.h>
-#include <oboe/OboeAudio.h>
-#include "OboeUtilities.h"
-
-#define DEFAULT_STATE_TIMEOUT (500 * OBOE_NANOS_PER_MILLISECOND)
-
-// Test OboeStreamBuilder
-TEST(test_oboe_api, oboe_stream_builder) {
- const oboe_sample_rate_t requestedSampleRate1 = 48000;
- const oboe_sample_rate_t requestedSampleRate2 = 44100;
- const int32_t requestedSamplesPerFrame = 2;
- const oboe_audio_format_t requestedDataFormat = OBOE_AUDIO_FORMAT_PCM16;
-
- oboe_sample_rate_t sampleRate = 0;
- int32_t samplesPerFrame = 0;
- oboe_audio_format_t actualDataFormat;
- OboeStreamBuilder oboeBuilder1;
- OboeStreamBuilder oboeBuilder2;
-
- oboe_result_t result = OBOE_OK;
-
- // Use an OboeStreamBuilder to define the stream.
- result = Oboe_createStreamBuilder(&oboeBuilder1);
- ASSERT_EQ(OBOE_OK, result);
-
- // Request stream properties.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSampleRate(oboeBuilder1, requestedSampleRate1));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSamplesPerFrame(oboeBuilder1, requestedSamplesPerFrame));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setFormat(oboeBuilder1, requestedDataFormat));
-
- // Check to make sure builder saved the properties.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getSampleRate(oboeBuilder1, &sampleRate));
- EXPECT_EQ(requestedSampleRate1, sampleRate);
-
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getSamplesPerFrame(oboeBuilder1, &samplesPerFrame));
- EXPECT_EQ(requestedSamplesPerFrame, samplesPerFrame);
-
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getFormat(oboeBuilder1, &actualDataFormat));
- EXPECT_EQ(requestedDataFormat, actualDataFormat);
-
- result = OboeStreamBuilder_getSampleRate(0x0BADCAFE, &sampleRate); // ridiculous token
- EXPECT_EQ(OBOE_ERROR_INVALID_HANDLE, result);
-
- // Create a second builder and make sure they do not collide.
- ASSERT_EQ(OBOE_OK, Oboe_createStreamBuilder(&oboeBuilder2));
- ASSERT_NE(oboeBuilder1, oboeBuilder2);
-
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSampleRate(oboeBuilder2, requestedSampleRate2));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getSampleRate(oboeBuilder1, &sampleRate));
- EXPECT_EQ(requestedSampleRate1, sampleRate);
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getSampleRate(oboeBuilder2, &sampleRate));
- EXPECT_EQ(requestedSampleRate2, sampleRate);
-
- // Delete the builder.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_delete(oboeBuilder1));
-
- // Now it should no longer be valid.
- // Note that test assumes we are using the HandleTracker. If we use plain pointers
- // then it will be difficult to detect this kind of error.
- result = OboeStreamBuilder_getSampleRate(oboeBuilder1, &sampleRate); // stale token
- EXPECT_EQ(OBOE_ERROR_INVALID_HANDLE, result);
-
- // Second builder should still be valid.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_getSampleRate(oboeBuilder2, &sampleRate));
- EXPECT_EQ(requestedSampleRate2, sampleRate);
-
- // Delete the second builder.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_delete(oboeBuilder2));
-
- // Now it should no longer be valid. Assumes HandlerTracker used.
- EXPECT_EQ(OBOE_ERROR_INVALID_HANDLE, OboeStreamBuilder_getSampleRate(oboeBuilder2, &sampleRate));
-}
-
-// Test creating a default stream with everything unspecified.
-TEST(test_oboe_api, oboe_stream_unspecified) {
- OboeStreamBuilder oboeBuilder;
- OboeStream oboeStream;
- oboe_result_t result = OBOE_OK;
-
- // Use an OboeStreamBuilder to define the stream.
- result = Oboe_createStreamBuilder(&oboeBuilder);
- ASSERT_EQ(OBOE_OK, result);
-
- // Create an OboeStream using the Builder.
- ASSERT_EQ(OBOE_OK, OboeStreamBuilder_openStream(oboeBuilder, &oboeStream));
-
- // Cleanup
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_delete(oboeBuilder));
- EXPECT_EQ(OBOE_OK, OboeStream_close(oboeStream));
-}
-
-// Test Writing to an OboeStream
-void runtest_oboe_stream(oboe_sharing_mode_t requestedSharingMode) {
- const oboe_sample_rate_t requestedSampleRate = 48000;
- const oboe_sample_rate_t requestedSamplesPerFrame = 2;
- const oboe_audio_format_t requestedDataFormat = OBOE_AUDIO_FORMAT_PCM16;
-
- oboe_sample_rate_t actualSampleRate = -1;
- int32_t actualSamplesPerFrame = -1;
- oboe_audio_format_t actualDataFormat = OBOE_AUDIO_FORMAT_INVALID;
- oboe_sharing_mode_t actualSharingMode;
- oboe_size_frames_t framesPerBurst = -1;
- int writeLoops = 0;
-
- oboe_size_frames_t framesWritten = 0;
- oboe_size_frames_t framesPrimed = 0;
- oboe_position_frames_t framesTotal = 0;
- oboe_position_frames_t oboeFramesRead = 0;
- oboe_position_frames_t oboeFramesRead1 = 0;
- oboe_position_frames_t oboeFramesRead2 = 0;
- oboe_position_frames_t oboeFramesWritten = 0;
-
- oboe_nanoseconds_t timeoutNanos;
-
- oboe_stream_state_t state = OBOE_STREAM_STATE_UNINITIALIZED;
- OboeStreamBuilder oboeBuilder;
- OboeStream oboeStream;
-
- oboe_result_t result = OBOE_OK;
-
- // Use an OboeStreamBuilder to define the stream.
- result = Oboe_createStreamBuilder(&oboeBuilder);
- ASSERT_EQ(OBOE_OK, result);
-
- // Request stream properties.
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSampleRate(oboeBuilder, requestedSampleRate));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSamplesPerFrame(oboeBuilder, requestedSamplesPerFrame));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setFormat(oboeBuilder, requestedDataFormat));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_setSharingMode(oboeBuilder, requestedSharingMode));
-
- // Create an OboeStream using the Builder.
- ASSERT_EQ(OBOE_OK, OboeStreamBuilder_openStream(oboeBuilder, &oboeStream));
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_delete(oboeBuilder));
-
- EXPECT_EQ(OBOE_OK, OboeStream_getState(oboeStream, &state));
- EXPECT_EQ(OBOE_STREAM_STATE_OPEN, state);
-
- // Check to see what kind of stream we actually got.
- EXPECT_EQ(OBOE_OK, OboeStream_getSampleRate(oboeStream, &actualSampleRate));
- ASSERT_TRUE(actualSampleRate >= 44100 && actualSampleRate <= 96000); // TODO what is range?
-
- EXPECT_EQ(OBOE_OK, OboeStream_getSamplesPerFrame(oboeStream, &actualSamplesPerFrame));
- ASSERT_TRUE(actualSamplesPerFrame >= 1 && actualSamplesPerFrame <= 16); // TODO what is max?
-
- EXPECT_EQ(OBOE_OK, OboeStream_getSharingMode(oboeStream, &actualSharingMode));
- ASSERT_TRUE(actualSharingMode == OBOE_SHARING_MODE_EXCLUSIVE
- || actualSharingMode == OBOE_SHARING_MODE_LEGACY);
-
- EXPECT_EQ(OBOE_OK, OboeStream_getFormat(oboeStream, &actualDataFormat));
- EXPECT_NE(OBOE_AUDIO_FORMAT_INVALID, actualDataFormat);
-
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesPerBurst(oboeStream, &framesPerBurst));
- ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
-
- // Allocate a buffer for the audio data.
- // TODO handle possibility of other data formats
- ASSERT_TRUE(actualDataFormat == OBOE_AUDIO_FORMAT_PCM16);
- size_t dataSizeSamples = framesPerBurst * actualSamplesPerFrame;
- int16_t *data = new int16_t[dataSizeSamples];
- ASSERT_TRUE(nullptr != data);
- memset(data, 0, sizeof(int16_t) * dataSizeSamples);
-
- // Prime the buffer.
- timeoutNanos = 0;
- do {
- framesWritten = OboeStream_write(oboeStream, data, framesPerBurst, timeoutNanos);
- // There should be some room for priming the buffer.
- framesTotal += framesWritten;
- ASSERT_GE(framesWritten, 0);
- ASSERT_LE(framesWritten, framesPerBurst);
- } while (framesWritten > 0);
- ASSERT_TRUE(framesTotal > 0);
-
- // Start/write/pause more than once to see if it fails after the first time.
- // Write some data and measure the rate to see if the timing is OK.
- for (int numLoops = 0; numLoops < 2; numLoops++) {
- // Start and wait for server to respond.
- ASSERT_EQ(OBOE_OK, OboeStream_requestStart(oboeStream));
- ASSERT_EQ(OBOE_OK, OboeStream_waitForStateChange(oboeStream,
- OBOE_STREAM_STATE_STARTING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(OBOE_STREAM_STATE_STARTED, state);
-
- // Write some data while we are running. Read counter should be advancing.
- writeLoops = 1 * actualSampleRate / framesPerBurst; // 1 second
- ASSERT_LT(2, writeLoops); // detect absurdly high framesPerBurst
- timeoutNanos = 10 * OBOE_NANOS_PER_SECOND * framesPerBurst / actualSampleRate; // bursts
- framesWritten = 1;
- ASSERT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead));
- oboeFramesRead1 = oboeFramesRead;
- oboe_nanoseconds_t beginTime = Oboe_getNanoseconds(OBOE_CLOCK_MONOTONIC);
- do {
- framesWritten = OboeStream_write(oboeStream, data, framesPerBurst, timeoutNanos);
- ASSERT_GE(framesWritten, 0);
- ASSERT_LE(framesWritten, framesPerBurst);
-
- framesTotal += framesWritten;
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesWritten(oboeStream, &oboeFramesWritten));
- EXPECT_EQ(framesTotal, oboeFramesWritten);
-
- // Try to get a more accurate measure of the sample rate.
- if (beginTime == 0) {
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead));
- if (oboeFramesRead > oboeFramesRead1) { // is read pointer advancing
- beginTime = Oboe_getNanoseconds(OBOE_CLOCK_MONOTONIC);
- oboeFramesRead1 = oboeFramesRead;
- }
- }
- } while (framesWritten > 0 && writeLoops-- > 0);
-
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead2));
- oboe_nanoseconds_t endTime = Oboe_getNanoseconds(OBOE_CLOCK_MONOTONIC);
- ASSERT_GT(oboeFramesRead2, 0);
- ASSERT_GT(oboeFramesRead2, oboeFramesRead1);
- ASSERT_LE(oboeFramesRead2, oboeFramesWritten);
-
- // TODO why is legacy so inaccurate?
- const double rateTolerance = 200.0; // arbitrary tolerance for sample rate
- if (requestedSharingMode != OBOE_SHARING_MODE_LEGACY) {
- // Calculate approximate sample rate and compare with stream rate.
- double seconds = (endTime - beginTime) / (double) OBOE_NANOS_PER_SECOND;
- double measuredRate = (oboeFramesRead2 - oboeFramesRead1) / seconds;
- ASSERT_NEAR(actualSampleRate, measuredRate, rateTolerance);
- }
-
- // Request async pause and wait for server to say that it has completed the pause.
- ASSERT_EQ(OBOE_OK, OboeStream_requestPause(oboeStream));
- EXPECT_EQ(OBOE_OK, OboeStream_waitForStateChange(oboeStream,
- OBOE_STREAM_STATE_PAUSING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(OBOE_STREAM_STATE_PAUSED, state);
- }
-
- // Make sure the read counter is not advancing when we are paused.
- ASSERT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead));
- ASSERT_GE(oboeFramesRead, oboeFramesRead2); // monotonic increase
-
- // Use this to sleep by waiting for something that won't happen.
- OboeStream_waitForStateChange(oboeStream, OBOE_STREAM_STATE_PAUSED, &state, timeoutNanos);
- ASSERT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead2));
- EXPECT_EQ(oboeFramesRead, oboeFramesRead2);
-
- // ------------------- TEST FLUSH -----------------
- // Prime the buffer.
- timeoutNanos = 0;
- writeLoops = 100;
- do {
- framesWritten = OboeStream_write(oboeStream, data, framesPerBurst, timeoutNanos);
- framesTotal += framesWritten;
- } while (framesWritten > 0 && writeLoops-- > 0);
- EXPECT_EQ(0, framesWritten);
-
- // Flush and wait for server to respond.
- ASSERT_EQ(OBOE_OK, OboeStream_requestFlush(oboeStream));
- EXPECT_EQ(OBOE_OK, OboeStream_waitForStateChange(oboeStream,
- OBOE_STREAM_STATE_FLUSHING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(OBOE_STREAM_STATE_FLUSHED, state);
-
- // After a flush, the read counter should be caught up with the write counter.
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesWritten(oboeStream, &oboeFramesWritten));
- EXPECT_EQ(framesTotal, oboeFramesWritten);
- EXPECT_EQ(OBOE_OK, OboeStream_getFramesRead(oboeStream, &oboeFramesRead));
- EXPECT_EQ(oboeFramesRead, oboeFramesWritten);
-
- // The buffer should be empty after a flush so we should be able to write.
- framesWritten = OboeStream_write(oboeStream, data, framesPerBurst, timeoutNanos);
- // There should be some room for priming the buffer.
- ASSERT_TRUE(framesWritten > 0 && framesWritten <= framesPerBurst);
-
- EXPECT_EQ(OBOE_OK, OboeStream_close(oboeStream));
-}
-
-// Test Writing to an OboeStream using LEGACY sharing mode.
-TEST(test_oboe_api, oboe_stream_legacy) {
- runtest_oboe_stream(OBOE_SHARING_MODE_LEGACY);
-}
-
-// Test Writing to an OboeStream using EXCLUSIVE sharing mode.
-TEST(test_oboe_api, oboe_stream_exclusive) {
- runtest_oboe_stream(OBOE_SHARING_MODE_EXCLUSIVE);
-}
-
-#define OBOE_THREAD_ANSWER 1826375
-#define OBOE_THREAD_DURATION_MSEC 500
-
-static void *TestOboeStreamThreadProc(void *arg) {
- OboeStream oboeStream = (OboeStream) reinterpret_cast<size_t>(arg);
- oboe_stream_state_t state;
-
- // Use this to sleep by waiting for something that won't happen.
- EXPECT_EQ(OBOE_OK, OboeStream_getState(oboeStream, &state));
- OboeStream_waitForStateChange(oboeStream, OBOE_STREAM_STATE_PAUSED, &state,
- OBOE_THREAD_DURATION_MSEC * OBOE_NANOS_PER_MILLISECOND);
- return reinterpret_cast<void *>(OBOE_THREAD_ANSWER);
-}
-
-// Test creating a stream related thread.
-TEST(test_oboe_api, oboe_stream_thread_basic) {
- OboeStreamBuilder oboeBuilder;
- OboeStream oboeStream;
- oboe_result_t result = OBOE_OK;
- void *threadResult;
-
- // Use an OboeStreamBuilder to define the stream.
- result = Oboe_createStreamBuilder(&oboeBuilder);
- ASSERT_EQ(OBOE_OK, result);
-
- // Create an OboeStream using the Builder.
- ASSERT_EQ(OBOE_OK, OboeStreamBuilder_openStream(oboeBuilder, &oboeStream));
-
- // Start a thread.
- ASSERT_EQ(OBOE_OK, OboeStream_createThread(oboeStream,
- 10 * OBOE_NANOS_PER_MILLISECOND,
- TestOboeStreamThreadProc,
- reinterpret_cast<void *>(oboeStream)));
- // Thread already started.
- ASSERT_NE(OBOE_OK, OboeStream_createThread(oboeStream, // should fail!
- 10 * OBOE_NANOS_PER_MILLISECOND,
- TestOboeStreamThreadProc,
- reinterpret_cast<void *>(oboeStream)));
-
- // Wait for the thread to finish.
- ASSERT_EQ(OBOE_OK, OboeStream_joinThread(oboeStream,
- &threadResult, 2 * OBOE_THREAD_DURATION_MSEC * OBOE_NANOS_PER_MILLISECOND));
- // The thread returns a special answer.
- ASSERT_EQ(OBOE_THREAD_ANSWER, (int)reinterpret_cast<size_t>(threadResult));
-
- // Thread should already be joined.
- ASSERT_NE(OBOE_OK, OboeStream_joinThread(oboeStream, // should fail!
- &threadResult, 2 * OBOE_THREAD_DURATION_MSEC * OBOE_NANOS_PER_MILLISECOND));
-
- // Cleanup
- EXPECT_EQ(OBOE_OK, OboeStreamBuilder_delete(oboeBuilder));
- EXPECT_EQ(OBOE_OK, OboeStream_close(oboeStream));
-}