blob: 7d77a9b80f3750a7e45e8aba23677c8e1c2a083a [file] [log] [blame]
Keun young Park5eba08f2012-03-26 18:31:29 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17// test RemoteAudio with fake TCP
18
19#include <unistd.h>
20
21#include <utils/String8.h>
22
23#include <gtest/gtest.h>
24
25#include <utils/StrongPointer.h>
26
27#include <Log.h>
28#include <audio/AudioHardware.h>
29#include <audio/AudioProtocol.h>
30#include <audio/AudioSignalFactory.h>
31#include <ClientSocket.h>
32#include <audio/RemoteAudio.h>
33
34
35
36void assertTrue(bool cond) {
37 ASSERT_TRUE(cond);
38}
39void assertData(const char* data1, const char* data2, int len) {
40 for (int i = 0; i < len; i++) {
41 //LOGD("0x%x vs 0x%x", data1[i], data2[i]);
42 ASSERT_TRUE(data1[i] == data2[i]);
43 }
44}
45
46class ClientSocketForTest: public ClientSocket {
47public:
48 ClientSocketForTest()
49 : mToRead(NULL),
50 mReadLength(0) {};
51
52 virtual ~ClientSocketForTest() {
53 close(mSocket);
54 close(mPipeWrFd);
55 }
56 virtual bool init(const char* hostIp, int port, bool enableTimeout = false) {
57 LOGD("ClientSocketForTest::init");
58 // use this fd to work with poll
59 int pipefd[2];
60 if (pipe(pipefd) == -1) {
61 LOGE("cannot create pipe");
62 return false;
63 }
64 LOGD("pipe %d %d", pipefd[0], pipefd[1]);
65 mSocket = pipefd[0];
66 mPipeWrFd = pipefd[1];
67 const char ipExpectation[] = "127.0.0.1";
68 assertTrue(memcmp(ipExpectation, hostIp, sizeof(ipExpectation)) == 0);
69 return true;
70 }
71 virtual bool readData(char* data, int len, int timeoutInMs = 0) {
72 read(mSocket, data, len);
73 return true;
74 }
75 virtual bool sendData(const char* data, int len) {
76 assertTrue((len + mSendPointer) <= mSendLength);
77 assertData(data, mToSend + mSendPointer, len);
78 mSendPointer += len;
79 if ((mToRead != NULL) && (mReadLength != 0)) {
80 LOGD("fake TCP copy reply %d", mReadLength);
81 write(mPipeWrFd, mToRead, mReadLength);
82 mToRead = NULL; // prevent writing the same data again
83 }
84 return true;
85 }
86
87 void setSendExpectation(const char* data, int len) {
88 mToSend = data;
89 mSendLength = len;
90 mSendPointer = 0;
91 }
92 void setReadExpectation(char* data, int len) {
93 mToRead = data;
94 mReadLength = len;
95 }
96public:
97 int mPipeWrFd; // for writing
98 const char* mToRead;
99 int mReadLength;
100 const char* mToSend;
101 int mSendLength;
102 int mSendPointer;
103};
104
105class RemoteAudioFakeTcpTest : public testing::Test {
106protected:
107 android::sp<RemoteAudio> mRemoteAudio;
108 ClientSocketForTest mTestSocket;
109
110protected:
111 virtual void SetUp() {
112 ASSERT_TRUE(U32_ENDIAN_SWAP(0x12345678) == 0x78563412);
113 mRemoteAudio = new RemoteAudio(mTestSocket);
114 ASSERT_TRUE(mRemoteAudio != NULL);
115 ASSERT_TRUE(mRemoteAudio->init(1234));
116 }
117
118 virtual void TearDown() {
119 mRemoteAudio->release();
120 mRemoteAudio.clear();
121 }
122
123 void doDownload() {
124 android::sp<Buffer> buffer = AudioSignalFactory::generateZeroSound(AudioHardware::E2BPS, 2,
125 false);
126 uint32_t prepareSend[] = {
127 U32_ENDIAN_SWAP(AudioProtocol::ECmdDownload),
128 U32_ENDIAN_SWAP(8),
129 U32_ENDIAN_SWAP(0), //id
130 U32_ENDIAN_SWAP(0)
131 };
132 uint32_t prepareReply[] = {
133 U32_ENDIAN_SWAP((AudioProtocol::ECmdDownload & 0xffff) | 0x43210000),
134 0,
135 0
136 };
137 LOGD("reply 0x%x", prepareReply[0]);
138
139 mTestSocket.setSendExpectation((char*)prepareSend, sizeof(prepareSend));
140 // this is reply, but set expectation for reply first as it is sent after send
141 mTestSocket.setReadExpectation((char*)prepareReply, sizeof(prepareReply));
142
143 int id = -1;
144 android::String8 name("1");
145 ASSERT_TRUE(mRemoteAudio->downloadData(name, buffer, id));
146 ASSERT_TRUE(id >= 0);
147 }
148};
149
150TEST_F(RemoteAudioFakeTcpTest, InitTest) {
151 // all done in SetUp
152}
153
154TEST_F(RemoteAudioFakeTcpTest, DownloadTest) {
155 doDownload();
156}
157
158TEST_F(RemoteAudioFakeTcpTest, PlayTest) {
159 doDownload();
160
161 bool stereo = false;
162 int id = 0;
163 int samplingF = 44100;
164 int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
165 int volume = 0;
166 int repeat = 1;
167
168 uint32_t prepareSend[] = {
169 U32_ENDIAN_SWAP(AudioProtocol::ECmdStartPlayback),
170 U32_ENDIAN_SWAP(20),
171 U32_ENDIAN_SWAP(id), //id
172 U32_ENDIAN_SWAP(samplingF),
173 U32_ENDIAN_SWAP(mode),
174 U32_ENDIAN_SWAP(volume),
175 U32_ENDIAN_SWAP(repeat)
176 };
177 uint32_t prepareReply[] = {
178 U32_ENDIAN_SWAP((AudioProtocol::ECmdStartPlayback & 0xffff) | 0x43210000),
179 0,
180 0
181 };
182
183 mTestSocket.setSendExpectation((char*)prepareSend, sizeof(prepareSend));
184 // this is reply, but set expectation for reply first as it is sent after send
185 mTestSocket.setReadExpectation((char*)prepareReply, sizeof(prepareReply));
186
187 ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
188 ASSERT_TRUE(mRemoteAudio->waitForPlaybackCompletion());
189}
190
191TEST_F(RemoteAudioFakeTcpTest, PlayStopTest) {
192 doDownload();
193
194 bool stereo = false;
195 int id = 0;
196 int samplingF = 44100;
197 int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
198 int volume = 0;
199 int repeat = 1;
200
201 uint32_t startPlaybackSend[] = {
202 U32_ENDIAN_SWAP(AudioProtocol::ECmdStartPlayback),
203 U32_ENDIAN_SWAP(20),
204 U32_ENDIAN_SWAP(id),
205 U32_ENDIAN_SWAP(samplingF),
206 U32_ENDIAN_SWAP(mode),
207 U32_ENDIAN_SWAP(volume),
208 U32_ENDIAN_SWAP(repeat)
209 };
210 uint32_t startReply[] = {
211 U32_ENDIAN_SWAP((AudioProtocol::ECmdStartPlayback & 0xffff) | 0x43210000),
212 0,
213 0
214 };
215
216 uint32_t stopPlaybackSend[] = {
217 U32_ENDIAN_SWAP(AudioProtocol::ECmdStopPlayback),
218 U32_ENDIAN_SWAP(0)
219 };
220
221 uint32_t stopReply[] = {
222 U32_ENDIAN_SWAP((AudioProtocol::ECmdStopPlayback & 0xffff) | 0x43210000),
223 0,
224 0
225 };
226
227 mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
228 // this is reply, but set expectation for reply first as it is sent after send
229 mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
230
231 ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
232 sleep(1);
233 mTestSocket.setSendExpectation((char*)stopPlaybackSend, sizeof(stopPlaybackSend));
234 // this is reply, but set expectation for reply first as it is sent after send
235 mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
236 mRemoteAudio->stopPlayback();
237
238 mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
239 // this is reply, but set expectation for reply first as it is sent after send
240 mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
241 ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
242 sleep(1);
243 mTestSocket.setSendExpectation((char*)stopPlaybackSend, sizeof(stopPlaybackSend));
244 // this is reply, but set expectation for reply first as it is sent after send
245 mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
246 mRemoteAudio->stopPlayback();
247
248 mTestSocket.setSendExpectation((char*)startPlaybackSend, sizeof(startPlaybackSend));
249 // this is reply, but set expectation for reply first as it is sent after send
250 mTestSocket.setReadExpectation((char*)startReply, sizeof(startReply));
251 ASSERT_TRUE(mRemoteAudio->startPlayback(stereo, samplingF, mode, volume, id, repeat));
252 ASSERT_TRUE(mRemoteAudio->waitForPlaybackCompletion());
253}
254
255TEST_F(RemoteAudioFakeTcpTest, RecordingTest) {
256 bool stereo = false;
257 int id = 0;
258 int samplingF = 44100;
259 int mode = AudioHardware::EModeVoice | (stereo ? 0x80000000 : 0);
260 int volume = 0;
261 int noSamples = 44; // 1ms worth
262
263 android::sp<Buffer> buffer(new Buffer(100, noSamples*2, false));
264
265 uint32_t startSend[] = {
266 U32_ENDIAN_SWAP(AudioProtocol::ECmdStartRecording),
267 U32_ENDIAN_SWAP(16),
268 U32_ENDIAN_SWAP(samplingF),
269 U32_ENDIAN_SWAP(mode),
270 U32_ENDIAN_SWAP(volume),
271 U32_ENDIAN_SWAP(noSamples)
272 };
273
274 // 2bytes per sample, +2 for last samples rounded off
275 uint32_t startReply[noSamples/2 + 2 + 3];
276 memset(startReply, 0, sizeof(startReply));
277 startReply[0] = U32_ENDIAN_SWAP((AudioProtocol::ECmdStartRecording & 0xffff) | 0x43210000);
278 startReply[1] = 0;
279 startReply[2] = U32_ENDIAN_SWAP(noSamples * 2);
280
281 uint32_t stopSend[] = {
282 U32_ENDIAN_SWAP(AudioProtocol::ECmdStopRecording),
283 U32_ENDIAN_SWAP(0)
284 };
285
286 uint32_t stopReply[] = {
287 U32_ENDIAN_SWAP((AudioProtocol::ECmdStopRecording & 0xffff) | 0x43210000),
288 0,
289 0
290 };
291
292
293 mTestSocket.setSendExpectation((char*)startSend, sizeof(startSend));
294 // this is reply, but set expectation for reply first as it is sent after send
295 mTestSocket.setReadExpectation((char*)startReply, 12 + noSamples*2);
296
297 ASSERT_TRUE(mRemoteAudio->startRecording(stereo, samplingF, mode, volume, buffer));
298 ASSERT_TRUE(mRemoteAudio->waitForRecordingCompletion());
299 ASSERT_TRUE(buffer->amountHandled() == (size_t)(noSamples * 2));
300 mTestSocket.setSendExpectation((char*)startSend, sizeof(startSend));
301 // this is reply, but set expectation for reply first as it is sent after send
302 mTestSocket.setReadExpectation((char*)startReply, 12 + noSamples*2);
303 ASSERT_TRUE(mRemoteAudio->startRecording(stereo, samplingF, mode, volume, buffer));
304 sleep(1);
305 mTestSocket.setSendExpectation((char*)stopSend, sizeof(stopSend));
306 // this is reply, but set expectation for reply first as it is sent after send
307 mTestSocket.setReadExpectation((char*)stopReply, sizeof(stopReply));
308 mRemoteAudio->stopRecording();
309}