11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/basictypes.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc/media_memory_chunk.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc/media_message.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast {
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ExternalMemoryBlock
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : public MediaMemoryChunk {
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExternalMemoryBlock(void* data, size_t size)
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : data_(data), size_(size) {}
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~ExternalMemoryBlock() {}
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MediaMemoryChunk implementation.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void* data() const OVERRIDE { return data_; }
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual size_t size() const OVERRIDE { return size_; }
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool valid() const OVERRIDE { return true; }
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void* const data_;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t size_;
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<MediaMemoryChunk> DummyAllocator(
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    void* data, size_t size, size_t alloc_size) {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK_LE(alloc_size, size);
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return scoped_ptr<MediaMemoryChunk>(
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new ExternalMemoryBlock(data, alloc_size));
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(MediaMessageTest, WriteRead) {
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int buffer_size = 1024;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage::MemoryAllocatorCB mem_alloc_cb(
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&DummyAllocator, buffer.get(), buffer_size));
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 type = 0x1;
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int msg_content_capacity = 512;
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Write a message.
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int count = 64;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg1(
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::CreateMessage(type, mem_alloc_cb, msg_content_capacity));
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (int k = 0; k < count; k++) {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int v1 = 2 * k + 1;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(msg1->WritePod(v1));
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint8 v2 = k;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(msg1->WritePod(v2));
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(msg1->content_size(), count * (sizeof(int) + sizeof(uint8)));
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify the integrity of the message.
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg2(
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::MapMessage(scoped_ptr<MediaMemoryChunk>(
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          new ExternalMemoryBlock(&buffer[0], buffer_size))));
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (int k = 0; k < count; k++) {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int v1;
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int expected_v1 = 2 * k + 1;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(msg2->ReadPod(&v1));
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(v1, expected_v1);
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint8 v2;
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint8 expected_v2 = k;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(msg2->ReadPod(&v2));
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(v2, expected_v2);
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(MediaMessageTest, WriteOverflow) {
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int buffer_size = 1024;
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage::MemoryAllocatorCB mem_alloc_cb(
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&DummyAllocator, buffer.get(), buffer_size));
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 type = 0x1;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int msg_content_capacity = 8;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg1(
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::CreateMessage(type, mem_alloc_cb, msg_content_capacity));
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 v1 = 0;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint8 v2 = 0;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(msg1->WritePod(v1));
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(msg1->WritePod(v2));
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(MediaMessageTest, ReadOverflow) {
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int buffer_size = 1024;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage::MemoryAllocatorCB mem_alloc_cb(
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&DummyAllocator, buffer.get(), buffer_size));
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 type = 0x1;
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int msg_content_capacity = 8;
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg1(
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::CreateMessage(type, mem_alloc_cb, msg_content_capacity));
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 v1 = 0xcd;
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg2(
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::MapMessage(scoped_ptr<MediaMemoryChunk>(
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          new ExternalMemoryBlock(&buffer[0], buffer_size))));
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 v2;
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg2->ReadPod(&v2));
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(v2, v1);
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg2->ReadPod(&v2));
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(v2, v1);
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(msg2->ReadPod(&v2));
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(MediaMessageTest, DummyMessage) {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int buffer_size = 1024;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<uint8[]> buffer(new uint8[buffer_size]);
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaMessage::MemoryAllocatorCB mem_alloc_cb(
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&DummyAllocator, buffer.get(), buffer_size));
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 type = 0x1;
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create first a dummy message to estimate the content size.
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg1(
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::CreateDummyMessage(type));
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 v1 = 0xcd;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg1->WritePod(v1));
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create the real message and write the actual content.
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg2(
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MediaMessage::CreateMessage(type, mem_alloc_cb, msg1->content_size()));
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg2->WritePod(v1));
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(msg2->WritePod(v1));
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(msg2->WritePod(v1));
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromecast
147