| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "media/remoting/fake_remoter.h" |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/callback.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "media/remoting/proto_utils.h" |
| #include "media/remoting/shared_session.h" |
| #include "mojo/public/cpp/bindings/strong_binding.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace media { |
| namespace remoting { |
| |
| FakeRemotingDataStreamSender::FakeRemotingDataStreamSender( |
| mojom::RemotingDataStreamSenderRequest request, |
| mojo::ScopedDataPipeConsumerHandle consumer_handle) |
| : binding_(this, std::move(request)), |
| consumer_handle_(std::move(consumer_handle)), |
| consume_data_chunk_count_(0), |
| send_frame_count_(0), |
| cancel_in_flight_count_(0) {} |
| |
| FakeRemotingDataStreamSender::~FakeRemotingDataStreamSender() = default; |
| |
| void FakeRemotingDataStreamSender::ResetHistory() { |
| consume_data_chunk_count_ = 0; |
| send_frame_count_ = 0; |
| cancel_in_flight_count_ = 0; |
| next_frame_data_.resize(0); |
| received_frame_list.clear(); |
| } |
| |
| bool FakeRemotingDataStreamSender::ValidateFrameBuffer(size_t index, |
| size_t size, |
| bool key_frame, |
| int pts_ms) { |
| if (index >= received_frame_list.size()) { |
| VLOG(1) << "There is no such frame"; |
| return false; |
| } |
| |
| const std::vector<uint8_t>& data = received_frame_list[index]; |
| scoped_refptr<DecoderBuffer> media_buffer = |
| ByteArrayToDecoderBuffer(data.data(), data.size()); |
| |
| // Checks if pts is correct or not |
| if (media_buffer->timestamp().InMilliseconds() != pts_ms) { |
| VLOG(1) << "Pts should be:" << pts_ms << "(" |
| << media_buffer->timestamp().InMilliseconds() << ")"; |
| return false; |
| } |
| |
| // Checks if key frame is set correct or not |
| if (media_buffer->is_key_frame() != key_frame) { |
| VLOG(1) << "Key frame should be:" << key_frame << "(" |
| << media_buffer->is_key_frame() << ")"; |
| return false; |
| } |
| |
| // Checks if frame buffer size is correct or not |
| if (media_buffer->data_size() != size) { |
| VLOG(1) << "Buffer size should be:" << size << "(" |
| << media_buffer->data_size() << ")"; |
| return false; |
| } |
| |
| // Checks if frame buffer is correct or not. |
| bool return_value = true; |
| const uint8_t* buffer = media_buffer->data(); |
| for (size_t i = 0; i < media_buffer->data_size(); ++i) { |
| uint32_t value = static_cast<uint32_t>(i & 0xFF); |
| if (value != static_cast<uint32_t>(buffer[i])) { |
| VLOG(1) << "buffer index: " << i << " should be " |
| << static_cast<uint32_t>(value) << " (" |
| << static_cast<uint32_t>(buffer[i]) << ")"; |
| return_value = false; |
| } |
| } |
| return return_value; |
| } |
| |
| void FakeRemotingDataStreamSender::ConsumeDataChunk( |
| uint32_t offset, |
| uint32_t size, |
| uint32_t total_payload_size) { |
| next_frame_data_.resize(total_payload_size); |
| MojoResult result = mojo::ReadDataRaw(consumer_handle_.get(), |
| next_frame_data_.data() + offset, &size, |
| MOJO_READ_DATA_FLAG_ALL_OR_NONE); |
| CHECK(result == MOJO_RESULT_OK); |
| ++consume_data_chunk_count_; |
| } |
| |
| void FakeRemotingDataStreamSender::SendFrame() { |
| ++send_frame_count_; |
| received_frame_list.push_back(std::move(next_frame_data_)); |
| EXPECT_EQ(send_frame_count_, received_frame_list.size()); |
| } |
| |
| void FakeRemotingDataStreamSender::CancelInFlightData() { |
| ++cancel_in_flight_count_; |
| } |
| |
| FakeRemoter::FakeRemoter(mojom::RemotingSourcePtr source, bool start_will_fail) |
| : source_(std::move(source)), |
| start_will_fail_(start_will_fail), |
| weak_factory_(this) {} |
| |
| FakeRemoter::~FakeRemoter() {} |
| |
| void FakeRemoter::Start() { |
| if (start_will_fail_) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| base::Bind(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr())); |
| } else { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| base::Bind(&FakeRemoter::Started, weak_factory_.GetWeakPtr())); |
| } |
| } |
| |
| void FakeRemoter::StartDataStreams( |
| mojo::ScopedDataPipeConsumerHandle audio_pipe, |
| mojo::ScopedDataPipeConsumerHandle video_pipe, |
| mojom::RemotingDataStreamSenderRequest audio_sender_request, |
| mojom::RemotingDataStreamSenderRequest video_sender_request) { |
| if (audio_pipe.is_valid()) { |
| VLOG(2) << "Has audio"; |
| audio_stream_sender_.reset(new FakeRemotingDataStreamSender( |
| std::move(audio_sender_request), std::move(audio_pipe))); |
| } |
| |
| if (video_pipe.is_valid()) { |
| VLOG(2) << "Has video"; |
| video_stream_sender_.reset(new FakeRemotingDataStreamSender( |
| std::move(video_sender_request), std::move(video_pipe))); |
| } |
| } |
| |
| void FakeRemoter::Stop(mojom::RemotingStopReason reason) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| base::Bind(&FakeRemoter::Stopped, weak_factory_.GetWeakPtr(), reason)); |
| } |
| |
| void FakeRemoter::SendMessageToSink(const std::vector<uint8_t>& message) {} |
| |
| void FakeRemoter::Started() { |
| source_->OnStarted(); |
| } |
| |
| void FakeRemoter::StartFailed() { |
| source_->OnStartFailed(mojom::RemotingStartFailReason::ROUTE_TERMINATED); |
| } |
| |
| void FakeRemoter::Stopped(mojom::RemotingStopReason reason) { |
| source_->OnStopped(reason); |
| } |
| |
| FakeRemoterFactory::FakeRemoterFactory(bool start_will_fail) |
| : start_will_fail_(start_will_fail) {} |
| |
| FakeRemoterFactory::~FakeRemoterFactory() {} |
| |
| void FakeRemoterFactory::Create(mojom::RemotingSourcePtr source, |
| mojom::RemoterRequest request) { |
| mojo::MakeStrongBinding( |
| base::MakeUnique<FakeRemoter>(std::move(source), start_will_fail_), |
| std::move(request)); |
| } |
| |
| // static |
| scoped_refptr<SharedSession> FakeRemoterFactory::CreateSharedSession( |
| bool start_will_fail) { |
| mojom::RemotingSourcePtr remoting_source; |
| mojom::RemotingSourceRequest remoting_source_request(&remoting_source); |
| mojom::RemoterPtr remoter; |
| FakeRemoterFactory remoter_factory(start_will_fail); |
| remoter_factory.Create(std::move(remoting_source), |
| mojo::MakeRequest(&remoter)); |
| return new SharedSession(std::move(remoting_source_request), |
| std::move(remoter)); |
| } |
| |
| } // namespace remoting |
| } // namespace media |