Home | History | Annotate | Download | only in test
      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