1 /* 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 36 void assertTrue(bool cond) { 37 ASSERT_TRUE(cond); 38 } 39 void 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 46 class ClientSocketForTest: public ClientSocket { 47 public: 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 } 96 public: 97 int mPipeWrFd; // for writing 98 const char* mToRead; 99 int mReadLength; 100 const char* mToSend; 101 int mSendLength; 102 int mSendPointer; 103 }; 104 105 class RemoteAudioFakeTcpTest : public testing::Test { 106 protected: 107 android::sp<RemoteAudio> mRemoteAudio; 108 ClientSocketForTest mTestSocket; 109 110 protected: 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 150 TEST_F(RemoteAudioFakeTcpTest, InitTest) { 151 // all done in SetUp 152 } 153 154 TEST_F(RemoteAudioFakeTcpTest, DownloadTest) { 155 doDownload(); 156 } 157 158 TEST_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 191 TEST_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 255 TEST_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 } 310 311 TEST_F(RemoteAudioFakeTcpTest, getDeviceInfoTest) { 312 uint32_t prepareSend[] = { 313 U32_ENDIAN_SWAP(AudioProtocol::ECmdGetDeviceInfo), 314 U32_ENDIAN_SWAP(0) 315 }; 316 uint32_t prepareReply[] = { 317 U32_ENDIAN_SWAP((AudioProtocol::ECmdGetDeviceInfo & 0xffff) | 0x43210000), 318 0, 319 U32_ENDIAN_SWAP(4), 320 U32_ENDIAN_SWAP(0x30313233) 321 }; 322 323 mTestSocket.setSendExpectation((char*)prepareSend, sizeof(prepareSend)); 324 // this is reply, but set expectation for reply first as it is sent after send 325 mTestSocket.setReadExpectation((char*)prepareReply, sizeof(prepareReply)); 326 327 android::String8 info; 328 ASSERT_TRUE(mRemoteAudio->getDeviceInfo(info)); 329 ASSERT_TRUE(info == "0123"); 330 } 331