cts_audio work: initial code
- volume calibration and THD test case work tuned.
- 59 unit tests pass
- local audio playback / recording works : uses tinyalsa
- host to device ptorocol in host side implemented / tested (with loopback)
- device side recording / playback works for test cases / test_io.xml
- python processing baseline added.
- spectrum algorithm implementated: calculate Transfer Function of device
over host and check if amplitudes are within margain. Needs parameter tuning
- spectrum test needs some improvements due to the non-flat response from
ref microphone.
- build is enabled only for linux host except the client code
Change-Id: I8453ac72b6fce7ddbfee7e2cc05207f09f2b3d88
diff --git a/suite/audio_quality/test/Android.mk b/suite/audio_quality/test/Android.mk
new file mode 100644
index 0000000..9e32557
--- /dev/null
+++ b/suite/audio_quality/test/Android.mk
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+# build only for linux
+ifeq ($(HOST_OS),linux)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_CPP_EXTENSION := .cpp
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(patsubst ./%,%, $(shell cd $(LOCAL_PATH); \
+ find . -name "*.cpp" -and -not -name ".*"))
+#LOCAL_SRC_FILES := AudioRecordPlayTest.cpp
+
+#$(info $(LOCAL_SRC_FILES))
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../lib/include $(LOCAL_PATH)/../lib/src external/gtest/include \
+ external/tinyalsa/include/ libcore/include
+LOCAL_STATIC_LIBRARIES := libutils libgtest_host libgtest_main_host liblog libcutils libtinyalsa \
+ libtinyxml
+# need to keep everything in libcts_.. Otherwise, linker will drop some
+# functions and linker error happens
+LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
+LOCAL_CFLAGS:= -g -fno-exceptions
+LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions
+LOCAL_MODULE:= cts_audio_quality_test
+include $(BUILD_HOST_EXECUTABLE)
+
+endif # linux
diff --git a/suite/audio_quality/test/AudioHardwareTest.cpp b/suite/audio_quality/test/AudioHardwareTest.cpp
new file mode 100644
index 0000000..35d750b
--- /dev/null
+++ b/suite/audio_quality/test/AudioHardwareTest.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <audio/AudioHardware.h>
+#include <task/TaskAll.h>
+
+
+class AudioHardwareTest : public testing::Test {
+
+};
+
+TEST_F(AudioHardwareTest, DetectTest) {
+ int hwId = AudioHardware::detectAudioHw();
+ ASSERT_TRUE(hwId >= 0);
+}
+
+TEST_F(AudioHardwareTest, LocalFactoryTest) {
+ android::sp<AudioHardware> playback = AudioHardware::createAudioHw(true, true);
+ ASSERT_TRUE(playback.get() != NULL);
+ android::sp<AudioHardware> recording = AudioHardware::createAudioHw(true, false);
+ ASSERT_TRUE(recording.get() != NULL);
+}
+
+TEST_F(AudioHardwareTest, RemoteFactoryTest) {
+ TaskCase* testCase = new TaskCase();
+ ASSERT_TRUE(testCase != NULL);
+ android::sp<AudioHardware> playback = AudioHardware::createAudioHw(false, true, testCase);
+ ASSERT_TRUE(playback.get() != NULL);
+ android::sp<AudioHardware> recording = AudioHardware::createAudioHw(false, false, testCase);
+ ASSERT_TRUE(recording.get() != NULL);
+ delete testCase;
+}
diff --git a/suite/audio_quality/test/AudioLocalTest.cpp b/suite/audio_quality/test/AudioLocalTest.cpp
new file mode 100644
index 0000000..b38c44d
--- /dev/null
+++ b/suite/audio_quality/test/AudioLocalTest.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+#include <utils/threads.h>
+#include <utils/StrongPointer.h>
+
+#include <audio/AudioLocal.h>
+#include <audio/Buffer.h>
+#include <Log.h>
+
+#include "AudioPlayTestCommon.h"
+
+class AudioPlayerDummy: public AudioLocal {
+public:
+ AudioHardware::SamplingRate mSamplingRate;
+ android::sp<Buffer> mBufferPassed;
+ bool mPrepareCalled;
+ bool mdoStartPlaybackOrRecordCalled;
+ bool mdoContinuePlaybackOrRecordCalled;
+ bool mdoStopCalled;
+ int mPlaybackUnit;
+
+ AudioPlayerDummy()
+ : mSamplingRate(AudioHardware::ESamplingRateInvald),
+ mPrepareCalled(false),
+ mdoStartPlaybackOrRecordCalled(false),
+ mdoContinuePlaybackOrRecordCalled(false),
+ mdoStopCalled(false)
+ {
+
+ }
+
+ virtual bool doPrepare(AudioHardware::SamplingRate samplingRate, int samplesInOneGo) {
+ mPlaybackUnit = samplesInOneGo * 4;
+ LOGV("doPrepare");
+ return true;
+ };
+
+ virtual bool doPlaybackOrRecord(android::sp<Buffer>& buffer) {
+ buffer->increaseHandled(mPlaybackUnit);
+ return true;
+ };
+
+ virtual void doStop() {
+ LOGV("doStop");
+ };
+
+
+};
+
+class AudioLocalTest : public AudioPlayTestCommon {
+public:
+ virtual ~AudioLocalTest() {};
+
+protected:
+ android::sp<AudioHardware> createAudioHw() {
+ android::sp<AudioHardware> hw(new AudioPlayerDummy());
+ return hw;
+ }
+};
+
+TEST_F(AudioLocalTest, PlayAllTest) {
+ playAll(1);
+}
+
+TEST_F(AudioLocalTest, PlayAllRepeatTest) {
+ playAll(4);
+}
+
+TEST_F(AudioLocalTest, StartStopTest) {
+ repeatPlayStop();
+}
+
+TEST_F(AudioLocalTest, WrongUsageTest) {
+ playWrongUsage();
+}
+
diff --git a/suite/audio_quality/test/AudioPlayTestCommon.h b/suite/audio_quality/test/AudioPlayTestCommon.h
new file mode 100644
index 0000000..96f129c
--- /dev/null
+++ b/suite/audio_quality/test/AudioPlayTestCommon.h
@@ -0,0 +1,91 @@
+/*
+ * 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 CTSAUDIO_AUDIOPLAYTESTCOMMON_H
+#define CTSAUDIO_AUDIOPLAYTESTCOMMON_H
+
+#include <gtest/gtest.h>
+#include <utils/threads.h>
+#include <utils/StrongPointer.h>
+
+#include <audio/AudioHardware.h>
+#include <audio/AudioPlaybackLocal.h>
+#include <audio/AudioRecordingLocal.h>
+#include <audio/AudioSignalFactory.h>
+#include <audio/AudioLocal.h>
+#include <audio/Buffer.h>
+
+
+#include <Log.h>
+
+
+class AudioPlayTestCommon : public testing::Test {
+protected:
+ android::sp<Buffer> mBuffer;
+ android::sp<AudioHardware> mAudioHw;
+
+ static const int MAX_POSITIVE_AMPLITUDE = 1000;
+ static const int SIGNAL_FREQ = 1000;
+ static const int SIGNAL_LENGTH = AudioHardware::SAMPLES_PER_ONE_GO * 2;
+ static const int DEFAULT_VOLUME = 10;
+
+protected:
+ virtual ~AudioPlayTestCommon() {
+ LOGV("~AudioPlayTestCommon");
+ }
+ virtual void SetUp() {
+ mAudioHw = createAudioHw();
+ ASSERT_TRUE(mAudioHw.get() != NULL);
+ mBuffer = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS,
+ MAX_POSITIVE_AMPLITUDE, AudioHardware::ESampleRate_44100,
+ SIGNAL_FREQ, SIGNAL_LENGTH);
+ ASSERT_TRUE(mBuffer.get() != NULL);
+ }
+
+ virtual void TearDown() {
+ LOGV("AudioPlayTestCommon::TearDown");
+ mAudioHw->stopPlaybackOrRecord(); // this stops the thread
+ mAudioHw.clear();
+ }
+
+ void playAll(int numberRepetition) {
+ ASSERT_TRUE(mAudioHw->prepare(AudioHardware::ESampleRate_44100, DEFAULT_VOLUME));
+ ASSERT_TRUE(mAudioHw->startPlaybackOrRecord(mBuffer, numberRepetition));
+ ASSERT_TRUE(mAudioHw->waitForCompletion());
+ mAudioHw->stopPlaybackOrRecord();
+ LOGV("size %d, handled %d", mBuffer->getSize(), mBuffer->amountHandled());
+ ASSERT_TRUE(mBuffer->amountHandled() == mBuffer->getSize());
+ }
+
+ void repeatPlayStop() {
+ for (int i = 0; i < 2; i++) {
+ ASSERT_TRUE(mAudioHw->prepare(AudioHardware::ESampleRate_44100, DEFAULT_VOLUME));
+ mBuffer->restart();
+ ASSERT_TRUE(mAudioHw->startPlaybackOrRecord(mBuffer, 10));
+ mAudioHw->stopPlaybackOrRecord();
+ }
+ }
+
+ void playWrongUsage() {
+ ASSERT_FALSE(mAudioHw->startPlaybackOrRecord(mBuffer));
+ ASSERT_TRUE(mAudioHw->prepare(AudioHardware::ESampleRate_44100, DEFAULT_VOLUME));
+ playAll(1);
+ }
+
+ virtual android::sp<AudioHardware> createAudioHw() = 0;
+};
+
+#endif // CTSAUDIO_AUDIOPLAYTESTCOMMON_H
diff --git a/suite/audio_quality/test/AudioPlaybackLocalTest.cpp b/suite/audio_quality/test/AudioPlaybackLocalTest.cpp
new file mode 100644
index 0000000..896d01c
--- /dev/null
+++ b/suite/audio_quality/test/AudioPlaybackLocalTest.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+#include <utils/threads.h>
+#include <utils/StrongPointer.h>
+
+#include <audio/AudioHardware.h>
+#include <GenericFactory.h>
+#include <audio/AudioPlaybackLocal.h>
+
+#include <Log.h>
+
+#include "AudioPlayTestCommon.h"
+
+class AudioPlaybackLocalTest : public AudioPlayTestCommon {
+public:
+ virtual ~AudioPlaybackLocalTest() {};
+protected:
+
+ android::sp<AudioHardware> createAudioHw() {
+ return AudioHardware::createAudioHw(true, true);
+ }
+};
+
+
+TEST_F(AudioPlaybackLocalTest, PlayAllTest) {
+ playAll(1);
+}
+
+TEST_F(AudioPlaybackLocalTest, PlayAllRepeatTest) {
+ playAll(4);
+}
+
+TEST_F(AudioPlaybackLocalTest, StartStopTest) {
+ repeatPlayStop();
+}
+
+TEST_F(AudioPlaybackLocalTest, WrongUsageTest) {
+ playWrongUsage();
+}
+
+
diff --git a/suite/audio_quality/test/AudioRecordPlayLocalTest.cpp b/suite/audio_quality/test/AudioRecordPlayLocalTest.cpp
new file mode 100644
index 0000000..3a94d06
--- /dev/null
+++ b/suite/audio_quality/test/AudioRecordPlayLocalTest.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#include "AudioRecordPlayTestCommon.h"
+
+#include <Log.h>
+
+class AudioRecordPlayLocalTest: public AudioRecordPlayTestCommon {
+public:
+ virtual ~AudioRecordPlayLocalTest() {};
+protected:
+ android::sp<AudioHardware> createRecordingHw() {
+ return AudioHardware::createAudioHw(true, false);
+ };
+
+ android::sp<AudioHardware> createPlaybackHw() {
+ return AudioHardware::createAudioHw(true, true);
+ }
+};
+
+
+
+TEST_F(AudioRecordPlayLocalTest, PlayAndRecordTest) {
+ PlayAndRecord(4);
+}
+
+
diff --git a/suite/audio_quality/test/AudioRecordPlayTestCommon.h b/suite/audio_quality/test/AudioRecordPlayTestCommon.h
new file mode 100644
index 0000000..28bc0a6
--- /dev/null
+++ b/suite/audio_quality/test/AudioRecordPlayTestCommon.h
@@ -0,0 +1,92 @@
+/*
+ * 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 CTSAUDIO_AUDIORECORDPLAYTESTCOMMON_H
+#define CTSAUDIO_AUDIORECORDPLAYTESTCOMMON_H
+
+#include <gtest/gtest.h>
+#include <utils/threads.h>
+#include <utils/StrongPointer.h>
+
+#include <audio/AudioHardware.h>
+#include <audio/AudioPlaybackLocal.h>
+#include <audio/AudioRecordingLocal.h>
+#include <audio/AudioSignalFactory.h>
+#include <audio/AudioLocal.h>
+#include <audio/Buffer.h>
+#include <Log.h>
+
+class AudioRecordPlayTestCommon : public testing::Test {
+protected:
+ android::sp<Buffer> mBufferRecording;
+ android::sp<Buffer> mBufferPlayback;
+ android::sp<AudioHardware> mAudioRecordingHw;
+ android::sp<AudioHardware> mAudioPlaybackHw;
+
+ static const int MAX_POSITIVE_AMPLITUDE = 10000;
+ static const int SIGNAL_FREQ = 1000;
+ static const int NUMBER_SAMPLES = AudioHardware::SAMPLES_PER_ONE_GO * 4;
+ static const int DEFAULT_VOLUME = 10;
+protected:
+ virtual void SetUp() {
+ mAudioPlaybackHw = createPlaybackHw();
+ ASSERT_TRUE(mAudioPlaybackHw.get() != NULL);
+ mAudioRecordingHw = createRecordingHw();
+ ASSERT_TRUE(mAudioRecordingHw.get() != NULL);
+ mBufferPlayback = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS,
+ MAX_POSITIVE_AMPLITUDE, AudioHardware::ESampleRate_44100,
+ SIGNAL_FREQ, NUMBER_SAMPLES);
+ ASSERT_TRUE(mBufferPlayback.get() != NULL);
+ mBufferRecording = new Buffer(NUMBER_SAMPLES * 4, NUMBER_SAMPLES * 4);
+ ASSERT_TRUE(mBufferRecording.get() != NULL);
+ }
+
+ virtual void TearDown() {
+ mAudioRecordingHw->stopPlaybackOrRecord();
+ mAudioPlaybackHw->stopPlaybackOrRecord();
+ mAudioRecordingHw.clear();
+ mAudioPlaybackHw.clear();
+ }
+
+ void PlayAndRecord(int numberRepetition) {
+ ASSERT_TRUE(mAudioPlaybackHw->prepare(AudioHardware::ESampleRate_44100, DEFAULT_VOLUME));
+ ASSERT_TRUE(mAudioRecordingHw->prepare(AudioHardware::ESampleRate_44100, DEFAULT_VOLUME));
+ ASSERT_TRUE(mAudioRecordingHw->startPlaybackOrRecord(mBufferRecording,
+ numberRepetition));
+ ASSERT_TRUE(mAudioPlaybackHw->startPlaybackOrRecord(mBufferPlayback,
+ numberRepetition));
+
+ ASSERT_TRUE(mAudioRecordingHw->waitForCompletion());
+ ASSERT_TRUE(mAudioPlaybackHw->waitForCompletion());
+ mAudioPlaybackHw->stopPlaybackOrRecord();
+ mAudioRecordingHw->stopPlaybackOrRecord();
+ LOGV("Audio playback buffer size %d, handled %d", mBufferPlayback->getSize(),
+ mBufferPlayback->amountHandled());
+ ASSERT_TRUE(mBufferPlayback->amountHandled() == mBufferPlayback->getSize());
+ LOGV("Audio recording buffer size %d, handled %d", mBufferRecording->getSize(),
+ mBufferRecording->amountHandled());
+ ASSERT_TRUE(mBufferRecording->amountHandled() == mBufferRecording->getSize());
+ }
+
+ virtual android::sp<AudioHardware> createRecordingHw() = 0;
+ virtual android::sp<AudioHardware> createPlaybackHw() = 0;
+};
+
+
+
+
+#endif // CTSAUDIO_AUDIORECORDPLAYTESTCOMMON_H
diff --git a/suite/audio_quality/test/AudioRecordingLocalTest.cpp b/suite/audio_quality/test/AudioRecordingLocalTest.cpp
new file mode 100644
index 0000000..bb9f8ba
--- /dev/null
+++ b/suite/audio_quality/test/AudioRecordingLocalTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+#include <utils/threads.h>
+#include <utils/StrongPointer.h>
+
+#include <audio/AudioHardware.h>
+#include <GenericFactory.h>
+#include <audio/AudioRecordingLocal.h>
+
+#include <Log.h>
+
+#include "AudioPlayTestCommon.h"
+
+class AudioRecordingLocalTest : public AudioPlayTestCommon {
+public:
+ virtual ~AudioRecordingLocalTest() {};
+protected:
+
+ android::sp<AudioHardware> createAudioHw() {
+ return AudioHardware::createAudioHw(true, false);
+ }
+};
+
+
+TEST_F(AudioRecordingLocalTest, PlayAllTest) {
+ playAll(1);
+}
+
+TEST_F(AudioRecordingLocalTest, PlayAllRepeatTest) {
+ playAll(4);
+}
+
+TEST_F(AudioRecordingLocalTest, StartStopTest) {
+ repeatPlayStop();
+}
+
+TEST_F(AudioRecordingLocalTest, WrongUsageTest) {
+ playWrongUsage();
+}
+
diff --git a/suite/audio_quality/test/AudioSignalFactoryTest.cpp b/suite/audio_quality/test/AudioSignalFactoryTest.cpp
new file mode 100644
index 0000000..62ff900
--- /dev/null
+++ b/suite/audio_quality/test/AudioSignalFactoryTest.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include <audio/AudioSignalFactory.h>
+
+class AudioSignalFactoryTest: public testing::Test {
+protected:
+
+ void testSignalBasic(android::sp<Buffer>& buffer, int maxPositive,
+ AudioHardware::SamplingRate samplingRate, int signalFreq, int samples) {
+ ASSERT_TRUE(buffer->getSize() == (unsigned int)(AudioHardware::E2BPS * 2 * samples));
+ int16_t* data = reinterpret_cast<int16_t*>(buffer->getData());
+ for(int i = 0; i < samples; i++) {
+ ASSERT_TRUE(*data <= maxPositive);
+ ASSERT_TRUE(*data >= -maxPositive);
+ data++;
+ ASSERT_TRUE(*data <= maxPositive);
+ ASSERT_TRUE(*data >= -maxPositive);
+ data++;
+ }
+ }
+};
+
+TEST_F(AudioSignalFactoryTest, SineTest) {
+ const int maxPositive = 1000;
+ const int signalFreq = AudioHardware::ESampleRate_44100/100;
+ const int samples = 8192 * 10;
+ android::sp<Buffer> buffer = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS,
+ maxPositive, AudioHardware::ESampleRate_44100, signalFreq, samples);
+ testSignalBasic(buffer, maxPositive, AudioHardware::ESampleRate_44100, signalFreq, samples);
+}
+
+TEST_F(AudioSignalFactoryTest, WhiteNoiseTest) {
+ const int maxPositive = 1000;
+ const int signalFreq = AudioHardware::ESampleRate_44100/100;
+ const int samples = 8192 * 10;
+ android::sp<Buffer> buffer = AudioSignalFactory::generateWhiteNoise(AudioHardware::E2BPS,
+ maxPositive, samples);
+ testSignalBasic(buffer, maxPositive, AudioHardware::ESampleRate_44100, signalFreq, samples);
+}
+
diff --git a/suite/audio_quality/test/BufferTest.cpp b/suite/audio_quality/test/BufferTest.cpp
new file mode 100644
index 0000000..2c7b20e
--- /dev/null
+++ b/suite/audio_quality/test/BufferTest.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include <UniquePtr.h>
+
+#include "audio/Buffer.h"
+
+
+class BufferTest : public testing::Test {
+public:
+
+ virtual void SetUp() {
+
+ }
+
+ virtual void TearDown() {
+
+ }
+};
+
+
+TEST_F(BufferTest, saveLoadStereoTest) {
+ const int BUFFER_SIZE = 32;
+
+ UniquePtr<Buffer> buffer(new Buffer(BUFFER_SIZE, BUFFER_SIZE, true));
+ ASSERT_TRUE(buffer.get() != NULL);
+ int16_t* data = (int16_t*)buffer->getData();
+ ASSERT_TRUE(data != NULL);
+ for (int i = 0; i < BUFFER_SIZE/4; i++) {
+ data[2*i] = i;
+ data[2*i+1] = i;
+ }
+ android::String8 file("/tmp/cts_audio_temp");
+ ASSERT_TRUE(buffer->saveToFile(file));
+ file.append(".r2s");
+ UniquePtr<Buffer> bufferRead(Buffer::loadFromFile(file));
+ ASSERT_TRUE(bufferRead.get() != NULL);
+ ASSERT_TRUE(bufferRead->getSize() == (size_t)BUFFER_SIZE);
+ ASSERT_TRUE(bufferRead->isStereo());
+ int16_t* dataRead = (int16_t*)bufferRead->getData();
+ for (int i = 0; i < BUFFER_SIZE/4; i++) {
+ ASSERT_TRUE(data[2*i] == dataRead[2*i]);
+ ASSERT_TRUE(data[2*i+1] == dataRead[2*i+1]);
+ }
+}
+
+TEST_F(BufferTest, monoLTest) {
+ const int BUFFER_SIZE = 8;
+
+ UniquePtr<Buffer> buffer(new Buffer(BUFFER_SIZE, BUFFER_SIZE, true));
+ ASSERT_TRUE(buffer.get() != NULL);
+ int16_t* data = (int16_t*)buffer->getData();
+ ASSERT_TRUE(data != NULL);
+ for (int i = 0; i < BUFFER_SIZE/2; i++) {
+ data[i] = i;
+ }
+ UniquePtr<Buffer> bufferl(new Buffer(BUFFER_SIZE/2, BUFFER_SIZE/2, false));
+ ASSERT_TRUE(bufferl.get() != NULL);
+ data = (int16_t*)bufferl->getData();
+ ASSERT_TRUE(data != NULL);
+ for (int i = 0; i < BUFFER_SIZE/4; i++) {
+ data[i] = 2 * i;
+ }
+ buffer->changeToMono(Buffer::EKeepCh0);
+ ASSERT_TRUE((*buffer) == (*bufferl));
+}
diff --git a/suite/audio_quality/test/ClientInterfaceTest.cpp b/suite/audio_quality/test/ClientInterfaceTest.cpp
new file mode 100644
index 0000000..b72be9b
--- /dev/null
+++ b/suite/audio_quality/test/ClientInterfaceTest.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <audio/AudioSignalFactory.h>
+#include <ClientInterface.h>
+#include <ClientImpl.h>
+#include <GenericFactory.h>
+#include <audio/RemoteAudio.h>
+
+
+
+class ClientInterfaceTest : public testing::Test {
+protected:
+ ClientInterface* mClient;
+
+protected:
+ virtual void SetUp() {
+ GenericFactory factory;
+ mClient = factory.createClientInterface();
+ ASSERT_TRUE(mClient != NULL);
+ android::String8 dummyParam;
+ ASSERT_TRUE(mClient->init(dummyParam));
+ }
+
+ virtual void TearDown() {
+ delete mClient;
+ mClient = NULL;
+ }
+};
+
+TEST_F(ClientInterfaceTest, InitTest) {
+ // all done in SetUp
+}
+
+TEST_F(ClientInterfaceTest, PlayTest) {
+ ClientImpl* client = reinterpret_cast<ClientImpl*>(mClient);
+ android::sp<RemoteAudio>& audio(client->getAudio());
+ const int maxPositive = 10000;
+ const int signalFreq = AudioHardware::ESampleRate_44100/100;
+ const int samples = 8192*2;
+ android::sp<Buffer> buffer = AudioSignalFactory::generateSineWave(AudioHardware::E2BPS,
+ maxPositive, AudioHardware::ESampleRate_44100, signalFreq, samples);
+ int id;
+ android::String8 name("1");
+ ASSERT_TRUE(audio->downloadData(name, buffer, id));
+ ASSERT_TRUE(audio->startPlayback(true, AudioHardware::ESampleRate_44100,
+ AudioHardware::EModeVoice, 100, id, 1));
+ ASSERT_TRUE(audio->waitForPlaybackCompletion());
+ ASSERT_TRUE(id == audio->getDataId(name));
+ android::String8 name2("2");
+ ASSERT_TRUE(audio->getDataId(name2) < 0);
+}
+
+TEST_F(ClientInterfaceTest, RecordTest) {
+ ClientImpl* client = reinterpret_cast<ClientImpl*>(mClient);
+ android::sp<RemoteAudio>& audio(client->getAudio());
+ const int maxPositive = 10000;
+ const int signalFreq = AudioHardware::ESampleRate_44100 / 100;
+ const int samples = 44100 * 4;
+ android::sp<Buffer> buffer(new Buffer(samples * 2, samples * 2, false));
+
+ ASSERT_TRUE(audio->startRecording(false, AudioHardware::ESampleRate_44100,
+ AudioHardware::EModeVoice, 100, buffer));
+ ASSERT_TRUE(audio->waitForRecordingCompletion());
+ ASSERT_TRUE(buffer->amountHandled() == (samples * 2));
+}
diff --git a/suite/audio_quality/test/FileUtilTest.cpp b/suite/audio_quality/test/FileUtilTest.cpp
new file mode 100644
index 0000000..d79b2aa
--- /dev/null
+++ b/suite/audio_quality/test/FileUtilTest.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include <UniquePtr.h>
+
+#include "Log.h"
+#include "FileUtil.h"
+
+
+class FileUtilTest : public testing::Test {
+public:
+
+};
+
+
+TEST_F(FileUtilTest, initTest) {
+ android::String8 dirPath;
+ ASSERT_TRUE(FileUtil::prepare(dirPath));
+ ASSERT_TRUE(dirPath.find("reports/") == 0);
+ LOGI("returned %s %d", dirPath.string(), dirPath.find("reports/"));
+ android::String8 dirPath2;
+ ASSERT_TRUE(FileUtil::prepare(dirPath2));
+ ASSERT_TRUE(dirPath == dirPath2);
+}
+
+
diff --git a/suite/audio_quality/test/LogTest.cpp b/suite/audio_quality/test/LogTest.cpp
new file mode 100644
index 0000000..421b904
--- /dev/null
+++ b/suite/audio_quality/test/LogTest.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include <UniquePtr.h>
+
+#include "Log.h"
+
+
+
+class LogTest : public testing::Test {
+public:
+
+};
+
+
+TEST_F(LogTest, logTest) {
+ Log::LogLevel level = Log::Instance()->getLogLevel();
+
+ // following lines should match. no automatic test yet..
+ // TODO make it automatic?
+ Log::Instance()->setLogLevel(Log::ELogV);
+ printf("printf %d %d %d %d %d %d\n", 0, 1, 2, 3, 4, 5);
+ LOGD( "logd %d %d %d %d %d %d", 0, 1, 2, 3, 4, 5);
+ LOGV( "logv %d %d %d %d %d %d", 0, 1, 2, 3, 4, 5);
+ LOGI( "logi %d %d %d %d %d %d", 0, 1, 2, 3, 4, 5);
+ LOGW( "logw %d %d %d %d %d %d", 0, 1, 2, 3, 4, 5);
+ LOGE( "loge %d %d %d %d %d %d", 0, 1, 2, 3, 4, 5);
+
+ int64_t a = 0;
+ int64_t b = 1;
+ int64_t c = 2;
+ int64_t d = 3;
+ int64_t e = 4;
+ int64_t f = 5;
+ printf("printf %lld %lld %lld %lld %lld %lld\n", a, b, c, d, e, f);
+ LOGD( "logd %lld %lld %lld %lld %lld %lld", a, b, c, d, e, f);
+ LOGV( "logv %lld %lld %lld %lld %lld %lld", a, b, c, d, e, f);
+ LOGI( "logi %lld %lld %lld %lld %lld %lld", a, b, c, d, e, f);
+ LOGW( "logw %lld %lld %lld %lld %lld %lld", a, b, c, d, e, f);
+ LOGE( "loge %lld %lld %lld %lld %lld %lld", a, b, c, d, e, f);
+
+ Log::Instance()->setLogLevel(level);
+}
+
+
+
diff --git a/suite/audio_quality/test/MixerTest.cpp b/suite/audio_quality/test/MixerTest.cpp
new file mode 100644
index 0000000..308822c
--- /dev/null
+++ b/suite/audio_quality/test/MixerTest.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include <UniquePtr.h>
+#include <tinyalsa/asoundlib.h>
+#include <Log.h>
+#include <audio/AudioHardware.h>
+
+class MixerTest : public testing::Test {
+public:
+
+ virtual void SetUp() {
+
+ }
+
+ virtual void TearDown() {
+
+ }
+};
+
+
+TEST_F(MixerTest, tryTinyAlsaTest) {
+ int hwId = AudioHardware::detectAudioHw();
+ ASSERT_TRUE(hwId >= 0);
+ struct mixer* mixerp = mixer_open(hwId);
+ ASSERT_TRUE(mixerp != NULL);
+ int num_ctls = mixer_get_num_ctls(mixerp);
+ // no mixer control for MobilePre. If this assumption fails,
+ // mixer control should be added.
+ ASSERT_TRUE(num_ctls == 0);
+ for (int i = 0; i < num_ctls; i++) {
+ struct mixer_ctl* control = mixer_get_ctl(mixerp, i);
+ ASSERT_TRUE(control != NULL);
+ LOGI("Mixer control %s type %s value %d", mixer_ctl_get_name(control),
+ mixer_ctl_get_type_string(control), mixer_ctl_get_num_values(control));
+ free(control);
+ }
+ mixer_close(mixerp);
+}
+
diff --git a/suite/audio_quality/test/ModelBuilderTest.cpp b/suite/audio_quality/test/ModelBuilderTest.cpp
new file mode 100644
index 0000000..49a0c57
--- /dev/null
+++ b/suite/audio_quality/test/ModelBuilderTest.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+
+#include <gtest/gtest.h>
+#include <task/ModelBuilder.h>
+
+
+class ModelBuilderTest : public testing::Test {
+public:
+ ModelBuilder mModelBuilder;
+};
+
+TEST_F(ModelBuilderTest, ParsingCaseNoAttribTest) {
+ android::String8 xmlFile("test_description/test/no_attrib.xml");
+ TaskGeneric* testCase = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(testCase != NULL);
+ //TODO verify TestCase
+ delete testCase;
+}
+
+TEST_F(ModelBuilderTest, ParsingCaseTest) {
+ android::String8 xmlFile("test_description/host_speaker_calibration.xml");
+ TaskGeneric* testCase = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(testCase != NULL);
+ //TODO verify TestCase
+ delete testCase;
+}
+
+TEST_F(ModelBuilderTest, ParsingBatchTest) {
+ android::String8 xmlFile("test_description/all.xml");
+ TaskGeneric* testBatch = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(testBatch != NULL);
+ //TODO verify TestCase
+ delete testBatch;
+}
+
+TEST_F(ModelBuilderTest, CaseOnlyTest) {
+ android::String8 xmlFile("test_description/all.xml");
+ TaskGeneric* task = mModelBuilder.parseTestDescriptionXml(xmlFile, true);
+ ASSERT_TRUE(task == NULL);
+
+ delete task;
+}
+
+TEST_F(ModelBuilderTest, MissingMandatoryTest) {
+ android::String8 xmlFile("test_description/test/missing_mandatory.xml");
+ TaskGeneric* task = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(task == NULL);
+ delete task;
+}
+
+TEST_F(ModelBuilderTest, UnknownElementTest) {
+ android::String8 xmlFile("test_description/test/unknown_element.xml");
+ TaskGeneric* task = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(task == NULL);
+ delete task;
+}
+
+TEST_F(ModelBuilderTest, WrongAttributeTest) {
+ android::String8 xmlFile("test_description/test/wrong_attrib.xml");
+ TaskGeneric* task = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(task == NULL);
+ delete task;
+}
+
+TEST_F(ModelBuilderTest, BuiltinRMSTest) {
+ android::String8 xmlFile("test_description/test/test_rms_vma.xml");
+ TaskGeneric* task = mModelBuilder.parseTestDescriptionXml(xmlFile);
+ ASSERT_TRUE(task != NULL);
+ TaskGeneric::ExecutionResult result = task->run();
+ ASSERT_TRUE((result == TaskGeneric::EResultOK) || (result == TaskGeneric::EResultPass));
+ delete task;
+}
+
diff --git a/suite/audio_quality/test/RemoteAudioFakeTcpTest.cpp b/suite/audio_quality/test/RemoteAudioFakeTcpTest.cpp
new file mode 100644
index 0000000..7d77a9b
--- /dev/null
+++ b/suite/audio_quality/test/RemoteAudioFakeTcpTest.cpp
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+
+// test RemoteAudio with fake TCP
+
+#include <unistd.h>
+
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <utils/StrongPointer.h>
+
+#include <Log.h>
+#include <audio/AudioHardware.h>
+#include <audio/AudioProtocol.h>
+#include <audio/AudioSignalFactory.h>
+#include <ClientSocket.h>
+#include <audio/RemoteAudio.h>
+
+
+
+void assertTrue(bool cond) {
+ ASSERT_TRUE(cond);
+}
+void assertData(const char* data1, const char* data2, int len) {
+ for (int i = 0; i < len; i++) {
+ //LOGD("0x%x vs 0x%x", data1[i], data2[i]);
+ ASSERT_TRUE(data1[i] == data2[i]);
+ }
+}
+
+class ClientSocketForTest: public ClientSocket {
+public:
+ ClientSocketForTest()
+ : mToRead(NULL),
+ mReadLength(0) {};
+
+ virtual ~ClientSocketForTest() {
+ close(mSocket);
+ close(mPipeWrFd);
+ }
+ virtual bool init(const char* hostIp, int port, bool enableTimeout = false) {
+ LOGD("ClientSocketForTest::init");
+ // use this fd to work with poll
+ int pipefd[2];
+ if (pipe(pipefd) == -1) {
+ LOGE("cannot create pipe");
+ return false;
+ }
+ LOGD("pipe %d %d", pipefd[0], pipefd[1]);
+ mSocket = pipefd[0];
+ mPipeWrFd = pipefd[1];
+ const char ipExpectation[] = "127.0.0.1";
+ assertTrue(memcmp(ipExpectation, hostIp, sizeof(ipExpectation)) == 0);
+ return true;
+ }
+ virtual bool readData(char* data, int len, int timeoutInMs = 0) {
+ read(mSocket, data, len);
+ return true;
+ }
+ virtual bool sendData(const char* data, int len) {
+ assertTrue((len + mSendPointer) <= mSendLength);
+ assertData(data, mToSend + mSendPointer, len);
+ mSendPointer += len;
+ if ((mToRead != NULL) && (mReadLength != 0)) {
+ LOGD("fake TCP copy reply %d", mReadLength);
+ write(mPipeWrFd, mToRead, mReadLength);
+ mToRead = NULL; // prevent writing the same data again
+ }
+ return true;
+ }
+
+ void setSendExpectation(const char* data, int len) {
+ mToSend = data;
+ mSendLength = len;
+ mSendPointer = 0;
+ }
+ void setReadExpectation(char* data, int len) {
+ mToRead = data;
+ mReadLength = len;
+ }
+public:
+ int mPipeWrFd; // for writing
+ const char* mToRead;
+ int mReadLength;
+ const char* mToSend;
+ int mSendLength;
+ int mSendPointer;
+};
+
+class RemoteAudioFakeTcpTest : public testing::Test {
+protected:
+ android::sp<RemoteAudio> mRemoteAudio;
+ ClientSocketForTest mTestSocket;
+
+protected:
+ virtual void SetUp() {
+ ASSERT_TRUE(U32_ENDIAN_SWAP(0x12345678) == 0x78563412);
+ mRemoteAudio = new RemoteAudio(mTestSocket);
+ ASSERT_TRUE(mRemoteAudio != NULL);
+ ASSERT_TRUE(mRemoteAudio->init(1234));
+ }
+
+ virtual void TearDown() {
+ mRemoteAudio->release();
+ mRemoteAudio.clear();
+ }
+
+ void doDownload() {
+ android::sp<Buffer> buffer = AudioSignalFactory::generateZeroSound(AudioHardware::E2BPS, 2,
+ false);
+ uint32_t prepareSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdDownload),
+ U32_ENDIAN_SWAP(8),
+ U32_ENDIAN_SWAP(0), //id
+ U32_ENDIAN_SWAP(0)
+ };
+ uint32_t prepareReply[] = {
+ U32_ENDIAN_SWAP((AudioProtocol::ECmdDownload & 0xffff) | 0x43210000),
+ 0,
+ 0
+ };
+ LOGD("reply 0x%x", prepareReply[0]);
+
+ mTestSocket.setSendExpectation((char*)prepareSend, sizeof(prepareSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)prepareReply, sizeof(prepareReply));
+
+ int id = -1;
+ android::String8 name("1");
+ ASSERT_TRUE(mRemoteAudio->downloadData(name, buffer, id));
+ ASSERT_TRUE(id >= 0);
+ }
+};
+
+TEST_F(RemoteAudioFakeTcpTest, InitTest) {
+ // all done in SetUp
+}
+
+TEST_F(RemoteAudioFakeTcpTest, DownloadTest) {
+ doDownload();
+}
+
+TEST_F(RemoteAudioFakeTcpTest, PlayTest) {
+ doDownload();
+
+ bool stereo = false;
+ int id = 0;
+ int samplingF = 44100;
+ int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
+ int volume = 0;
+ int repeat = 1;
+
+ uint32_t prepareSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdStartPlayback),
+ U32_ENDIAN_SWAP(20),
+ U32_ENDIAN_SWAP(id), //id
+ U32_ENDIAN_SWAP(samplingF),
+ U32_ENDIAN_SWAP(mode),
+ U32_ENDIAN_SWAP(volume),
+ U32_ENDIAN_SWAP(repeat)
+ };
+ uint32_t prepareReply[] = {
+ U32_ENDIAN_SWAP((AudioProtocol::ECmdStartPlayback & 0xffff) | 0x43210000),
+ 0,
+ 0
+ };
+
+ mTestSocket.setSendExpectation((char*)prepareSend, sizeof(prepareSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)prepareReply, sizeof(prepareReply));
+
+ ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
+ ASSERT_TRUE(mRemoteAudio->waitForPlaybackCompletion());
+}
+
+TEST_F(RemoteAudioFakeTcpTest, PlayStopTest) {
+ doDownload();
+
+ bool stereo = false;
+ int id = 0;
+ int samplingF = 44100;
+ int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
+ int volume = 0;
+ int repeat = 1;
+
+ uint32_t startPlaybackSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdStartPlayback),
+ U32_ENDIAN_SWAP(20),
+ U32_ENDIAN_SWAP(id),
+ U32_ENDIAN_SWAP(samplingF),
+ U32_ENDIAN_SWAP(mode),
+ U32_ENDIAN_SWAP(volume),
+ U32_ENDIAN_SWAP(repeat)
+ };
+ uint32_t startReply[] = {
+ U32_ENDIAN_SWAP((AudioProtocol::ECmdStartPlayback & 0xffff) | 0x43210000),
+ 0,
+ 0
+ };
+
+ uint32_t stopPlaybackSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdStopPlayback),
+ U32_ENDIAN_SWAP(0)
+ };
+
+ uint32_t stopReply[] = {
+ U32_ENDIAN_SWAP((AudioProtocol::ECmdStopPlayback & 0xffff) | 0x43210000),
+ 0,
+ 0
+ };
+
+ mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
+
+ ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
+ sleep(1);
+ mTestSocket.setSendExpectation((char*)stopPlaybackSend, sizeof(stopPlaybackSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
+ mRemoteAudio->stopPlayback();
+
+ mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
+ ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
+ sleep(1);
+ mTestSocket.setSendExpectation((char*)stopPlaybackSend, sizeof(stopPlaybackSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
+ mRemoteAudio->stopPlayback();
+
+ mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
+ ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
+ ASSERT_TRUE(mRemoteAudio->waitForPlaybackCompletion());
+}
+
+TEST_F(RemoteAudioFakeTcpTest, RecordingTest) {
+ bool stereo = false;
+ int id = 0;
+ int samplingF = 44100;
+ int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
+ int volume = 0;
+ int noSamples = 44; // 1ms worth
+
+ android::sp<Buffer> buffer(new Buffer(100, noSamples*2, false));
+
+ uint32_t startSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdStartRecording),
+ U32_ENDIAN_SWAP(16),
+ U32_ENDIAN_SWAP(samplingF),
+ U32_ENDIAN_SWAP(mode),
+ U32_ENDIAN_SWAP(volume),
+ U32_ENDIAN_SWAP(noSamples)
+ };
+
+ // 2bytes per sample, +2 for last samples rounded off
+ uint32_t startReply[noSamples/2 + 2 + 3];
+ memset(startReply, 0, sizeof(startReply));
+ startReply[0] = U32_ENDIAN_SWAP((AudioProtocol::ECmdStartRecording & 0xffff) | 0x43210000);
+ startReply[1] = 0;
+ startReply[2] = U32_ENDIAN_SWAP(noSamples * 2);
+
+ uint32_t stopSend[] = {
+ U32_ENDIAN_SWAP(AudioProtocol::ECmdStopRecording),
+ U32_ENDIAN_SWAP(0)
+ };
+
+ uint32_t stopReply[] = {
+ U32_ENDIAN_SWAP((AudioProtocol::ECmdStopRecording & 0xffff) | 0x43210000),
+ 0,
+ 0
+ };
+
+
+ mTestSocket.setSendExpectation((char*)startSend, sizeof(startSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)startReply, 12 + noSamples*2);
+
+ ASSERT_TRUE(mRemoteAudio->startRecording(stereo, samplingF, mode, volume, buffer));
+ ASSERT_TRUE(mRemoteAudio->waitForRecordingCompletion());
+ ASSERT_TRUE(buffer->amountHandled() == (size_t)(noSamples * 2));
+ mTestSocket.setSendExpectation((char*)startSend, sizeof(startSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)startReply, 12 + noSamples*2);
+ ASSERT_TRUE(mRemoteAudio->startRecording(stereo, samplingF, mode, volume, buffer));
+ sleep(1);
+ mTestSocket.setSendExpectation((char*)stopSend, sizeof(stopSend));
+ // this is reply, but set expectation for reply first as it is sent after send
+ mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
+ mRemoteAudio->stopRecording();
+}
diff --git a/suite/audio_quality/test/SignalProcessingInterfaceTest.cpp b/suite/audio_quality/test/SignalProcessingInterfaceTest.cpp
new file mode 100644
index 0000000..cdffeb9
--- /dev/null
+++ b/suite/audio_quality/test/SignalProcessingInterfaceTest.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <utils/String8.h>
+
+#include <audio/AudioSignalFactory.h>
+#include <SignalProcessingInterface.h>
+#include <SignalProcessingImpl.h>
+#include <task/TaskAll.h>
+
+class SignalProcessingInterfaceTest : public testing::Test {
+protected:
+ SignalProcessingImpl* mSp;
+
+protected:
+ virtual void SetUp() {
+ mSp = new SignalProcessingImpl();
+ ASSERT_TRUE(mSp != NULL);
+ ASSERT_TRUE(mSp->init(SignalProcessingImpl::MAIN_PROCESSING_SCRIPT));
+ }
+
+ virtual void TearDown() {
+ delete mSp;
+ mSp = NULL;
+ }
+};
+
+TEST_F(SignalProcessingInterfaceTest, InitTest) {
+ // SetUp do all the work, nothing to do
+}
+
+TEST_F(SignalProcessingInterfaceTest, EchoTest) {
+ android::String8 functionName("echo");
+ int nInputs = 4;
+ int nOutputs = 4;
+ bool inputTypes[4] = { true, true, false, false };
+ bool outputTypes[4] = { true, true, false, false };
+
+ android::sp<Buffer> in0(new Buffer(160000, 160000, true));
+ char* data0 = in0->getData();
+ for (size_t i = 0; i < in0->getSize(); i++) {
+ data0[i] = i;
+ }
+ android::sp<Buffer> in1(new Buffer(8, 8, false));
+ char* data1 = in1->getData();
+ for (size_t i = 0; i < in1->getSize(); i++) {
+ data1[i] = i;
+ }
+ TaskCase::Value in2(1.0f);
+ TaskCase::Value in3((int64_t)100);
+ void* inputs[4] = { &in0, &in1, &in2, &in3 };
+
+ android::sp<Buffer> out0(new Buffer(160000, 160000, true));
+ char* outdata0 = out0->getData();
+ for (size_t i = 0; i < out0->getSize(); i++) {
+ outdata0[i] = 0xaa;
+ }
+ android::sp<Buffer> out1(new Buffer(8, 8, false));
+ char* outdata1 = out1->getData();
+ for (size_t i = 0; i < out1->getSize(); i++) {
+ outdata1[i] = 0xbb;
+ }
+ TaskCase::Value out2(-1.0f);
+ TaskCase::Value out3((int64_t)1000);
+ void *outputs[4] = { &out0, &out1, &out2, &out3 };
+
+ ASSERT_TRUE(mSp->run( functionName,
+ nInputs, inputTypes, inputs,
+ nOutputs, outputTypes, outputs) == TaskGeneric::EResultOK);
+ ASSERT_TRUE(*(in0.get()) == *(out0.get()));
+ ASSERT_TRUE(*(in1.get()) == *(out1.get()));
+ ASSERT_TRUE(in2 == out2);
+ ASSERT_TRUE(in3 == out3);
+}
+
+TEST_F(SignalProcessingInterfaceTest, intsumTest) {
+ android::String8 functionName("intsum");
+ int nInputs = 2;
+ int nOutputs = 1;
+ bool inputTypes[2] = { false, false };
+ bool outputTypes[1] = { false };
+
+ TaskCase::Value in0((int64_t)10);
+ TaskCase::Value in1((int64_t)100);
+ void* inputs[2] = { &in0, &in1 };
+
+ TaskCase::Value out0((int64_t)0);
+ void *outputs[1] = { &out0 };
+
+ ASSERT_TRUE(mSp->run( functionName,
+ nInputs, inputTypes, inputs,
+ nOutputs, outputTypes, outputs) == TaskGeneric::EResultOK);
+ ASSERT_TRUE(out0.getInt64() == (in0.getInt64() + in1.getInt64()));
+}
+
+// two instances of python processing processes should work
+TEST_F(SignalProcessingInterfaceTest, TwoInstanceTest) {
+ SignalProcessingImpl* sp2 = new SignalProcessingImpl();
+ ASSERT_TRUE(sp2 != NULL);
+ ASSERT_TRUE(sp2->init(SignalProcessingImpl::MAIN_PROCESSING_SCRIPT));
+
+ android::String8 functionName("intsum");
+ int nInputs = 2;
+ int nOutputs = 1;
+ bool inputTypes[2] = { false, false };
+ bool outputTypes[1] = { false };
+
+ TaskCase::Value in0((int64_t)10);
+ TaskCase::Value in1((int64_t)100);
+ void* inputs[2] = { &in0, &in1 };
+
+ TaskCase::Value out0((int64_t)0);
+ void *outputs[1] = { &out0 };
+
+ ASSERT_TRUE(mSp->run( functionName,
+ nInputs, inputTypes, inputs,
+ nOutputs, outputTypes, outputs) == TaskGeneric::EResultOK);
+ ASSERT_TRUE(out0.getInt64() == (in0.getInt64() + in1.getInt64()));
+ out0.setInt64(0);
+ ASSERT_TRUE(sp2->run( functionName,
+ nInputs, inputTypes, inputs,
+ nOutputs, outputTypes, outputs) == TaskGeneric::EResultOK);
+ ASSERT_TRUE(out0.getInt64() == (in0.getInt64() + in1.getInt64()));
+ delete sp2;
+}
+
+// test to run processing/example.py
+TEST_F(SignalProcessingInterfaceTest, exampleTest) {
+ android::String8 functionName("example");
+ int nInputs = 8;
+ int nOutputs = 4;
+ bool inputTypes[8] = { true, true, true, true, false, false, false, false };
+ bool outputTypes[4] = { true, true, false, false };
+
+ android::sp<Buffer> in0(new Buffer(16, 16, true));
+ char* data0 = in0->getData();
+ for (size_t i = 0; i < in0->getSize(); i++) {
+ data0[i] = i;
+ }
+ android::sp<Buffer> in1(new Buffer(16, 16, true));
+ char* data1 = in1->getData();
+ for (size_t i = 0; i < in1->getSize(); i++) {
+ data1[i] = i;
+ }
+ android::sp<Buffer> in2(new Buffer(8, 8, false));
+ char* data2 = in2->getData();
+ for (size_t i = 0; i < in2->getSize(); i++) {
+ data2[i] = i;
+ }
+ android::sp<Buffer> in3(new Buffer(8, 8, false));
+ char* data3 = in3->getData();
+ for (size_t i = 0; i < in3->getSize(); i++) {
+ data3[i] = i;
+ }
+ TaskCase::Value in4((int64_t)100);
+ TaskCase::Value in5((int64_t)100);
+ TaskCase::Value in6(1.0f);
+ TaskCase::Value in7(1.0f);
+ void* inputs[8] = { &in0, &in1, &in2, &in3, &in4, &in5, &in6, &in7 };
+
+ android::sp<Buffer> out0(new Buffer(16, 16, true));
+ char* outdata0 = out0->getData();
+ for (size_t i = 0; i < out0->getSize(); i++) {
+ outdata0[i] = 0xaa;
+ }
+ android::sp<Buffer> out1(new Buffer(8, 8, false));
+ char* outdata1 = out1->getData();
+ for (size_t i = 0; i < out1->getSize(); i++) {
+ outdata1[i] = 0xbb;
+ }
+ TaskCase::Value out2((int64_t)1000);
+ TaskCase::Value out3(-1.0f);
+ void *outputs[4] = { &out0, &out1, &out2, &out3 };
+
+ ASSERT_TRUE(mSp->run( functionName,
+ nInputs, inputTypes, inputs,
+ nOutputs, outputTypes, outputs) == TaskGeneric::EResultOK);
+ ASSERT_TRUE(*(in0.get()) == *(out0.get()));
+ ASSERT_TRUE(*(in2.get()) == *(out1.get()));
+ ASSERT_TRUE(in4 == out2);
+ ASSERT_TRUE(in6 == out3);
+}
diff --git a/suite/audio_quality/test/SimpleScriptExecTest.cpp b/suite/audio_quality/test/SimpleScriptExecTest.cpp
new file mode 100644
index 0000000..7016ef9
--- /dev/null
+++ b/suite/audio_quality/test/SimpleScriptExecTest.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+
+#include <gtest/gtest.h>
+#include <SimpleScriptExec.h>
+
+
+class ScriptExecTest : public testing::Test {
+
+};
+
+TEST_F(ScriptExecTest, PythonVersionTest) {
+ ASSERT_TRUE(SimpleScriptExec::checkPythonEnv());
+}
+
+
+TEST_F(ScriptExecTest, checkIfPassedTest) {
+ android::String8 pass1("___CTS_AUDIO_PASS___");
+ android::String8 match1;
+ ASSERT_TRUE(SimpleScriptExec::checkIfPassed(pass1, match1));
+
+ android::String8 fail1;
+ ASSERT_TRUE(!SimpleScriptExec::checkIfPassed(fail1, match1));
+}
+
diff --git a/suite/audio_quality/test/StringUtilTest.cpp b/suite/audio_quality/test/StringUtilTest.cpp
new file mode 100644
index 0000000..1dbcea0
--- /dev/null
+++ b/suite/audio_quality/test/StringUtilTest.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <StringUtil.h>
+
+
+class StringUtilTest : public testing::Test {
+
+};
+
+TEST_F(StringUtilTest, compareTest) {
+ android::String8 str("hello");
+ ASSERT_TRUE(StringUtil::compare(str, "hello") == 0);
+ ASSERT_TRUE(StringUtil::compare(str, "hi") != 0);
+}
+
+TEST_F(StringUtilTest, substrTest) {
+ android::String8 str("hello there");
+
+ android::String8 sub1 = StringUtil::substr(str, 0, 5);
+ ASSERT_TRUE(StringUtil::compare(sub1, "hello") == 0);
+
+ android::String8 sub2 = StringUtil::substr(str, 10, 5);
+ ASSERT_TRUE(StringUtil::compare(sub2, "e") == 0);
+
+ android::String8 sub3 = StringUtil::substr(str, 6, 5);
+ ASSERT_TRUE(StringUtil::compare(sub3, "there") == 0);
+
+ android::String8 sub4 = StringUtil::substr(str, 100, 5);
+ ASSERT_TRUE(sub4.length() == 0);
+}
+
+TEST_F(StringUtilTest, endsWithTest) {
+ android::String8 str("hello there");
+ ASSERT_TRUE(StringUtil::endsWith(str, "there"));
+ ASSERT_TRUE(StringUtil::endsWith(str, "hello there"));
+ ASSERT_TRUE(!StringUtil::endsWith(str, "not there"));
+}
+
+TEST_F(StringUtilTest, splitTest) {
+ android::String8 str("hello:there:break:this:");
+ std::vector<android::String8>* tokens = StringUtil::split(str, ':');
+ ASSERT_TRUE(tokens != NULL);
+ ASSERT_TRUE(tokens->size() == 4);
+ ASSERT_TRUE(StringUtil::compare(tokens->at(0), "hello") == 0);
+ ASSERT_TRUE(StringUtil::compare(tokens->at(1), "there") == 0);
+ ASSERT_TRUE(StringUtil::compare(tokens->at(2), "break") == 0);
+ ASSERT_TRUE(StringUtil::compare(tokens->at(3), "this") == 0);
+ delete tokens;
+
+ android::String8 str2("::::");
+ std::vector<android::String8>* tokens2 = StringUtil::split(str2, ':');
+ ASSERT_TRUE(tokens2 != NULL);
+ ASSERT_TRUE(tokens2->size() == 0);
+ delete tokens2;
+}
+
+
+
diff --git a/suite/audio_quality/test/TaskCaseCommon.h b/suite/audio_quality/test/TaskCaseCommon.h
new file mode 100644
index 0000000..cf8d272
--- /dev/null
+++ b/suite/audio_quality/test/TaskCaseCommon.h
@@ -0,0 +1,43 @@
+/*
+ * 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 CTSAUDIO_TASKCASECOMMON_H
+#define CTSAUDIO_TASKCASECOMMON_H
+
+#include <gtest/gtest.h>
+
+#include <Log.h>
+#include <GenericFactory.h>
+#include <task/TaskAll.h>
+
+/**
+ * Create TaskCase with setup and action as children
+ * No need to destroy setup and action
+ */
+inline TaskCase* getTaskCase(TaskGeneric*& setup, TaskGeneric*& action)
+{
+ GenericFactory factory;
+ TaskCase* taskCase = new TaskCase();
+ setup = factory.createTask(TaskGeneric::ETaskSetup);
+ taskCase->addChild(setup);
+ action = factory.createTask(TaskGeneric::ETaskAction);
+ taskCase->addChild(action);
+ return taskCase;
+}
+
+
+#endif // CTSAUDIO_TASKCASECOMMON_H
diff --git a/suite/audio_quality/test/TaskCaseTest.cpp b/suite/audio_quality/test/TaskCaseTest.cpp
new file mode 100644
index 0000000..9cf74a7
--- /dev/null
+++ b/suite/audio_quality/test/TaskCaseTest.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include "Log.h"
+#include "StringUtil.h"
+#include "task/TaskAll.h"
+
+
+class TaskCaseTest : public testing::Test {
+public:
+ TaskCase* mTaskCase;
+ virtual void SetUp() {
+ mTaskCase = new TaskCase();
+ ASSERT_TRUE(mTaskCase != NULL);
+ }
+
+ virtual void TearDown() {
+ delete mTaskCase;
+ }
+};
+
+
+TEST_F(TaskCaseTest, DataMapTest) {
+ android::sp<Buffer> buffer1(new Buffer(4, 4, true));
+ android::sp<Buffer> buffer2(new Buffer(4, 4, true));
+ android::sp<Buffer> buffer3(new Buffer(4, 4, true));
+ android::sp<Buffer> buffer4(new Buffer(4, 4, true));
+
+ const android::String8 BUFFER1("buffer1");
+ const android::String8 BUFFER2("buffer2");
+ const android::String8 BUFFER3("buffer3");
+ const android::String8 BUFFER4("buffer4");
+ ASSERT_TRUE(mTaskCase->registerBuffer(BUFFER1, buffer1));
+ ASSERT_TRUE(mTaskCase->registerBuffer(BUFFER2, buffer2));
+ ASSERT_TRUE(mTaskCase->registerBuffer(BUFFER3, buffer3));
+ ASSERT_TRUE(mTaskCase->registerBuffer(BUFFER4, buffer4));
+
+ android::sp<Buffer> buffer1f = mTaskCase->findBuffer(BUFFER1);
+ //LOGI("buffer1 %x, buffer1f %x", &buffer1, buffer1f);
+ ASSERT_TRUE(buffer1.get() == buffer1f.get());
+ const android::String8 NO_SUCH_BUFFER("no_such_buffer");
+ buffer1f = mTaskCase->findBuffer(NO_SUCH_BUFFER);
+ ASSERT_TRUE(buffer1f.get() == NULL);
+ const android::String8 RE("buffer[1-2]");
+ std::list<TaskCase::BufferPair>* list = mTaskCase->findAllBuffers(RE);
+ ASSERT_TRUE(list != NULL);
+ ASSERT_TRUE(((list->front().second.get() == buffer1.get()) &&
+ (list->back().second.get() == buffer2.get())) ||
+ ((list->front().second.get() == buffer2.get()) &&
+ (list->back().second.get() == buffer1.get())));
+ delete list;
+}
+
+TEST_F(TaskCaseTest, ValueMapTest) {
+ TaskCase::Value val1(1.0f);
+ TaskCase::Value val2(2.0f);
+ TaskCase::Value val3((int64_t)1);
+ TaskCase::Value val4((int64_t)2);
+ TaskCase::Value val2_copy(2.0f);
+ ASSERT_TRUE(!(val1 == val2));
+ ASSERT_TRUE(!(val2 == val3));
+ ASSERT_TRUE(val2 == val2_copy);
+ ASSERT_TRUE(val1.getDouble() == 1.0f);
+ ASSERT_TRUE(val3.getInt64() == 1);
+ const android::String8 V1("v1");
+ const android::String8 V2("v2");
+ const android::String8 V3("v3");
+ const android::String8 V4("v4");
+ const android::String8 V5("v5");
+ ASSERT_TRUE(mTaskCase->registerValue(V1, val1));
+ ASSERT_TRUE(mTaskCase->registerValue(V2, val2));
+ ASSERT_TRUE(mTaskCase->registerValue(V3, val3));
+ ASSERT_TRUE(mTaskCase->registerValue(V4, val4));
+
+ TaskCase::Value valRead;
+ ASSERT_TRUE(mTaskCase->findValue(V4, valRead));
+ ASSERT_TRUE(valRead.getInt64() == 2);
+ TaskCase::Value val4_2((int64_t)3);
+ ASSERT_TRUE(mTaskCase->updateValue(V4, val4_2));
+ ASSERT_TRUE(mTaskCase->findValue(V4, valRead));
+ ASSERT_TRUE(valRead.getInt64() == 3);
+ ASSERT_TRUE(!mTaskCase->updateValue(V5, val4));
+ ASSERT_TRUE(!mTaskCase->findValue(V5, valRead));
+
+ const android::String8 RE("v[2-3]");
+ std::list<TaskCase::ValuePair>* list = mTaskCase->findAllValues(RE);
+ ASSERT_TRUE(list != NULL);
+ ASSERT_TRUE(((list->front().second == val2) && (list->back().second == val3)) ||
+ ((list->front().second == val3) && (list->back().second == val4)));
+ delete list;
+}
+
+TEST_F(TaskCaseTest, IndexMapTest) {
+ Buffer buffer1(4, 4, true);
+ Buffer buffer2(4, 4, true);
+ Buffer buffer3(4, 4, true);
+ Buffer buffer4(4, 4, true);
+
+ int i = 0;
+ int j = 1;
+ const android::String8 I("i");
+ const android::String8 J("j");
+ const android::String8 K("k");
+ ASSERT_TRUE(mTaskCase->registerIndex(I));
+ ASSERT_TRUE(mTaskCase->registerIndex(J));
+ ASSERT_TRUE(mTaskCase->updateIndex(I, i));
+ ASSERT_TRUE(mTaskCase->updateIndex(J, j));
+ int i_read, j_read, k_read;
+ ASSERT_TRUE(mTaskCase->findIndex(I, i_read));
+ ASSERT_TRUE(mTaskCase->findIndex(J, j_read));
+ ASSERT_TRUE(!mTaskCase->findIndex(K, k_read));
+ ASSERT_TRUE(i == i_read);
+ ASSERT_TRUE(j == j_read);
+ //TODO add findAll test
+}
+
+TEST_F(TaskCaseTest, VarTranslateTest) {
+ const android::String8 I("i");
+ const android::String8 J("j");
+ const android::String8 K("k");
+ ASSERT_TRUE(mTaskCase->registerIndex(I, 1));
+ ASSERT_TRUE(mTaskCase->registerIndex(J, 2));
+ ASSERT_TRUE(mTaskCase->registerIndex(K, 3));
+
+ android::String8 orig1("hello_$i_$j");
+ android::String8 result1;
+ ASSERT_TRUE(mTaskCase->translateVarName(orig1, result1));
+ ASSERT_TRUE(StringUtil::compare(result1, "hello_1_2") == 0);
+
+ android::String8 orig2("hello_$i_$j_$k_there");
+ android::String8 result2;
+ ASSERT_TRUE(mTaskCase->translateVarName(orig2, result2));
+ ASSERT_TRUE(StringUtil::compare(result2, "hello_1_2_3_there") == 0);
+
+ // should fail as there is no such var
+ android::String8 orig3("$n");
+ android::String8 result3;
+ ASSERT_TRUE(!mTaskCase->translateVarName(orig3, result3));
+
+ android::String8 orig4("hello_there");
+ android::String8 result4;
+ ASSERT_TRUE(mTaskCase->translateVarName(orig4, result4));
+ ASSERT_TRUE(StringUtil::compare(result4, "hello_there") == 0);
+}
diff --git a/suite/audio_quality/test/TaskProcessTest.cpp b/suite/audio_quality/test/TaskProcessTest.cpp
new file mode 100644
index 0000000..05c7f1d
--- /dev/null
+++ b/suite/audio_quality/test/TaskProcessTest.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+
+#include "TaskCaseCommon.h"
+
+class TaskProcessTest : public testing::Test {
+public:
+ TaskCase* mTestCase;
+ TaskSequential* mSequential;
+ TaskProcess* mProcess;
+
+
+ virtual void SetUp() {
+ TaskGeneric* setup = NULL;
+ TaskGeneric* action = NULL;
+ mTestCase = getTaskCase(setup, action);
+ ASSERT_TRUE(mTestCase != NULL);
+ ASSERT_TRUE(setup != NULL);
+ ASSERT_TRUE(action != NULL);
+ mSequential = new TaskSequential();
+ const android::String8 REPEAT("repeat");
+ const android::String8 N_10("10");
+ const android::String8 INDEX("index");
+ const android::String8 I("i");
+ ASSERT_TRUE(mSequential->parseAttribute(REPEAT, N_10));
+ ASSERT_TRUE(mSequential->parseAttribute(INDEX, I));
+ ASSERT_TRUE(action->addChild(mSequential));
+ mProcess = new TaskProcess();
+ ASSERT_TRUE(mSequential->addChild(mProcess));
+
+ }
+
+ virtual void TearDown() {
+ delete mTestCase;
+ }
+};
+
+
+TEST_F(TaskProcessTest, AttributeTest) {
+
+}
+
+
diff --git a/suite/audio_quality/test/TaskSequentialTest.cpp b/suite/audio_quality/test/TaskSequentialTest.cpp
new file mode 100644
index 0000000..289dafe
--- /dev/null
+++ b/suite/audio_quality/test/TaskSequentialTest.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#include "TaskCaseCommon.h"
+class TaskSequentialTest : public testing::Test {
+public:
+ TaskCase* mTestCase;
+ TaskSequential* mSequential;
+
+
+ virtual void SetUp() {
+ TaskGeneric* setup = NULL;
+ TaskGeneric* action = NULL;
+ mTestCase = getTaskCase(setup, action);
+ ASSERT_TRUE(mTestCase != NULL);
+ ASSERT_TRUE(setup != NULL);
+ ASSERT_TRUE(action != NULL);
+ mSequential = new TaskSequential();
+ action->addChild(mSequential);
+ }
+
+ virtual void TearDown() {
+ delete mTestCase;
+ }
+};
+
+
+TEST_F(TaskSequentialTest, AttributeTest) {
+ const android::String8 REPEAT("repeat");
+ const android::String8 N_10("10");
+ const android::String8 INDEX("index");
+ const android::String8 I("i");
+ const android::String8 NO_SUCH_THING("no_such_thing");
+ const android::String8 SHOULD_FAIL("should_fail");
+ ASSERT_TRUE(mSequential->parseAttribute(REPEAT, N_10));
+ ASSERT_TRUE(mSequential->parseAttribute(INDEX, I));
+ ASSERT_TRUE(!mSequential->parseAttribute(NO_SUCH_THING, SHOULD_FAIL));
+ mSequential->run();
+ const android::String8 RE(".*");
+ std::list<TaskCase::IndexPair>* indices = mTestCase->findAllIndices(RE);
+ ASSERT_TRUE(indices != NULL);
+ ASSERT_TRUE(indices->size() == 1);
+ int index = -10;
+
+ ASSERT_TRUE(mTestCase->findIndex(I, index));
+ ASSERT_TRUE(index == 10);
+ delete indices;
+}
+
+
+
+
diff --git a/suite/audio_quality/test/TaskTest.cpp b/suite/audio_quality/test/TaskTest.cpp
new file mode 100644
index 0000000..b003d99
--- /dev/null
+++ b/suite/audio_quality/test/TaskTest.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include "task/TaskAll.h"
+
+static const android::String8 AAA("aaa");
+static const android::String8 BBB("bbb");
+
+class TaskTest : public testing::Test {
+public:
+ TaskCase* mTestCase;
+ // should not delete
+ TaskGeneric* mTaskSetup;
+ TaskGeneric* mTaskAction;
+ TaskGeneric* mTaskSequential;
+ TaskGeneric* mTaskProcess;
+ TaskGeneric* mTaskInput;
+ TaskGeneric* mTaskOutput;
+ TaskGeneric* mTaskSound;
+
+ class TestTaskDummy: public TaskGeneric {
+ public:
+ static int mRunCounter;
+ static int mLiveInstanceCounter;
+
+ TestTaskDummy(TaskGeneric::TaskType type)
+ : TaskGeneric(type) {
+ mLiveInstanceCounter++;
+
+
+ const android::String8* list[] = {&AAA, &BBB, NULL};
+ registerSupportedStringAttributes(list);
+ };
+ virtual ~TestTaskDummy(){
+ mLiveInstanceCounter--;
+ };
+
+ virtual TaskGeneric::ExecutionResult run()
+ {
+ mRunCounter++;
+ return TaskGeneric::run();
+ };
+ bool addStringAttributePublic(const android::String8& key, android::String8& value){
+ return addStringAttribute(key, value);
+ }
+ bool findStringAttributePublic(const android::String8& key, android::String8& value){
+ return findStringAttribute(key, value);
+ }
+ };
+
+ virtual void SetUp() {
+ TestTaskDummy::mRunCounter = 0;
+ TestTaskDummy::mLiveInstanceCounter = 0;
+ mTestCase = new TaskCase();
+ mTaskSetup = new TestTaskDummy(TaskGeneric::ETaskSetup);
+ mTaskAction = new TestTaskDummy(TaskGeneric::ETaskAction);
+ ASSERT_TRUE(mTestCase->addChild(mTaskSetup));
+ ASSERT_TRUE(mTestCase->addChild(mTaskAction));
+ mTaskSequential = new TestTaskDummy(TaskGeneric::ETaskSequential);
+ ASSERT_TRUE(mTaskAction->addChild(mTaskSequential));
+ mTaskProcess = new TestTaskDummy(TaskGeneric::ETaskProcess);
+ mTaskInput = new TestTaskDummy(TaskGeneric::ETaskInput);
+ mTaskOutput = new TestTaskDummy(TaskGeneric::ETaskOutput);
+ ASSERT_TRUE(mTaskSequential->addChild(mTaskOutput));
+ ASSERT_TRUE(mTaskSequential->addChild(mTaskInput));
+ ASSERT_TRUE(mTaskSequential->addChild(mTaskProcess));
+ mTaskSound = new TestTaskDummy(TaskGeneric::ETaskSound);
+ ASSERT_TRUE(mTaskSetup->addChild(mTaskSound));
+ ASSERT_TRUE(TestTaskDummy::mLiveInstanceCounter == 7);
+ }
+
+ virtual void TearDown() {
+ if(mTestCase != NULL) {
+ delete mTestCase;
+ }
+ ASSERT_TRUE(TestTaskDummy::mLiveInstanceCounter == 0);
+ }
+};
+
+int TaskTest::TestTaskDummy::mRunCounter = 0;
+int TaskTest::TestTaskDummy::mLiveInstanceCounter = 0;
+
+TEST_F(TaskTest, HierarchyTest) {
+ // verify hierarchy
+ ASSERT_TRUE(mTaskSetup->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskAction->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskSequential->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskProcess->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskInput->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskOutput->getTestCase() == mTestCase);
+ ASSERT_TRUE(mTaskSound->getTestCase() == mTestCase);
+}
+
+TEST_F(TaskTest, RunTest) {
+ ASSERT_TRUE(mTestCase->run() == TaskGeneric::EResultOK);
+ ASSERT_TRUE(TestTaskDummy::mRunCounter == 7);
+}
+
+TEST_F(TaskTest, StringAttributeTest) {
+ android::String8 aaaVal("aaa_val");
+ android::String8 bbbVal("bbb_val");
+ android::String8 read;
+ TestTaskDummy* task = reinterpret_cast<TestTaskDummy*>(mTaskSetup);
+ ASSERT_TRUE(task->addStringAttributePublic(AAA, aaaVal));
+ ASSERT_TRUE(task->addStringAttributePublic(BBB, bbbVal));
+ const android::String8 CCC("ccc");
+ ASSERT_TRUE(!task->addStringAttributePublic(CCC, bbbVal));
+ ASSERT_TRUE(task->findStringAttributePublic(AAA, read));
+ ASSERT_TRUE(read == aaaVal);
+ ASSERT_TRUE(task->findStringAttributePublic(BBB, read));
+ ASSERT_TRUE(read == bbbVal);
+ const android::String8 VERSION("version");
+ const android::String8 NAME("name");
+ ASSERT_TRUE(!task->findStringAttributePublic(VERSION, read));
+ ASSERT_TRUE(!task->findStringAttributePublic(NAME, read));
+}
+
+