blob: 678e064abb9d402a0e56184b0d75dd18f4483c94 [file] [log] [blame]
// Copyright 2020 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.
#ifndef MEDIA_FUCHSIA_AUDIO_FAKE_AUDIO_CONSUMER_H_
#define MEDIA_FUCHSIA_AUDIO_FAKE_AUDIO_CONSUMER_H_
#include <fuchsia/media/audio/cpp/fidl.h>
#include <fuchsia/media/audio/cpp/fidl_test_base.h>
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/media/cpp/fidl_test_base.h>
#include <lib/fidl/cpp/binding.h>
#include <list>
#include <vector>
#include "base/fuchsia/scoped_service_binding.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
namespace vfs {
class PseudoDir;
} // namespace vfs
namespace media {
// Fake implementation of fuchsia::media::AudioConsumer interface. Used for
// tests.
class FakeAudioConsumer final
: public fuchsia::media::testing::AudioConsumer_TestBase,
public fuchsia::media::testing::StreamSink_TestBase,
public fuchsia::media::audio::testing::VolumeControl_TestBase {
public:
// Lead time range returned from WatchStatus().
static const base::TimeDelta kMinLeadTime;
static const base::TimeDelta kMaxLeadTime;
FakeAudioConsumer(
uint64_t session_id,
fidl::InterfaceRequest<fuchsia::media::AudioConsumer> request);
~FakeAudioConsumer() override;
FakeAudioConsumer(const FakeAudioConsumer&) = delete;
FakeAudioConsumer& operator=(const FakeAudioConsumer&) = delete;
uint64_t session_id() { return session_id_; }
float volume() const { return volume_; }
bool is_muted() const { return is_muted_; }
base::TimeDelta GetMediaPosition();
private:
enum class State {
kStopped,
kPlaying,
kEndOfStream,
};
struct Packet {
base::TimeDelta pts;
bool is_eos = false;
};
// fuchsia::media::AudioConsumer interface;
void CreateStreamSink(
std::vector<zx::vmo> buffers,
fuchsia::media::AudioStreamType stream_type,
std::unique_ptr<fuchsia::media::Compression> compression,
fidl::InterfaceRequest<fuchsia::media::StreamSink> stream_sink_request)
final;
void Start(fuchsia::media::AudioConsumerStartFlags flags,
int64_t reference_time,
int64_t media_time) override;
void Stop() override;
void WatchStatus(WatchStatusCallback callback) override;
void SetRate(float rate) override;
void BindVolumeControl(
fidl::InterfaceRequest<fuchsia::media::audio::VolumeControl>
volume_control_request) override;
// fuchsia::media::StreamSink interface.
void SendPacket(fuchsia::media::StreamPacket packet,
SendPacketCallback callback) override;
void SendPacketNoReply(fuchsia::media::StreamPacket packet) override;
void EndOfStream() override;
void DiscardAllPackets(DiscardAllPacketsCallback callback) override;
void DiscardAllPacketsNoReply() override;
// fuchsia::media::audio::VolumeControl interface.
void SetVolume(float volume) override;
void SetMute(bool mute) override;
// Not-implemented handler for _TestBase parents.
void NotImplemented_(const std::string& name) override;
void ScheduleNextStreamPosUpdate();
// Updates stream position and drops old packets from the stream.
void UpdateStreamPos();
void OnStatusUpdate();
void CallStatusCallback();
const uint64_t session_id_;
fidl::Binding<fuchsia::media::AudioConsumer> audio_consumer_binding_;
fidl::Binding<fuchsia::media::StreamSink> stream_sink_binding_;
fidl::Binding<fuchsia::media::audio::VolumeControl> volume_control_binding_;
size_t num_buffers_ = 0;
State state_ = State::kStopped;
bool have_status_update_ = true;
WatchStatusCallback status_callback_;
base::TimeTicks reference_time_;
// Numerator and denumerator for current playback rate.
uint32_t media_delta_ = 1;
uint32_t reference_delta_ = 1;
// Last known media position. Min value indicates that the stream position
// hasn't been set. If stream is playing then value corresponds to
// |reference_time_|.
base::TimeDelta media_pos_ = base::TimeDelta::Min();
std::list<Packet> pending_packets_;
// Timer to call UpdateStreamPos() for the next packet.
base::OneShotTimer update_timer_;
float volume_ = 1.0;
bool is_muted_ = false;
};
class FakeAudioConsumerService final
: public fuchsia::media::testing::SessionAudioConsumerFactory_TestBase {
public:
explicit FakeAudioConsumerService(vfs::PseudoDir* pseudo_dir);
~FakeAudioConsumerService() override;
FakeAudioConsumerService(const FakeAudioConsumerService&) = delete;
FakeAudioConsumerService& operator=(const FakeAudioConsumerService&) = delete;
size_t num_instances() { return audio_consumers_.size(); }
FakeAudioConsumer* instance(size_t index) {
return audio_consumers_[index].get();
}
private:
// fuchsia::media::SessionAudioConsumerFactory implementation.
void CreateAudioConsumer(uint64_t session_id,
fidl::InterfaceRequest<fuchsia::media::AudioConsumer>
audio_consumer_request) override;
// Not-implemented handler for SessionAudioConsumerFactory_TestBase.
void NotImplemented_(const std::string& name) override;
base::ScopedServiceBinding<fuchsia::media::SessionAudioConsumerFactory>
binding_;
std::vector<std::unique_ptr<FakeAudioConsumer>> audio_consumers_;
};
} // namespace media
#endif // MEDIA_FUCHSIA_AUDIO_FAKE_AUDIO_CONSUMER_H_