// Copyright 2018 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 "content/browser/media/audio_output_stream_broker.h"

#include <utility>

#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/media/media_internals.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/media_observer.h"
#include "content/public/common/content_client.h"
#include "media/audio/audio_logging.h"

namespace content {

namespace {

// Used in Media.Audio.Render.StreamBrokerDisconnectReason2 histogram, matches
// StreamBrokerDisconnectReason2 enum.
enum class StreamBrokerDisconnectReason {
  kDefault = 0,
  kPlatformError,
  kTerminatedByClient,
  kTerminatedByClientAwaitingCreated,
  kStreamCreationFailed,
  kDocumentDestroyed,
  kDocumentDestroyedAwaitingCreated,
  kMaxValue = kDocumentDestroyedAwaitingCreated
};

using DisconnectReason =
    media::mojom::AudioOutputStreamObserver::DisconnectReason;

StreamBrokerDisconnectReason GetDisconnectReason(DisconnectReason reason,
                                                 bool awaiting_created) {
  switch (reason) {
    case DisconnectReason::kPlatformError:
      return StreamBrokerDisconnectReason::kPlatformError;
    case DisconnectReason::kTerminatedByClient:
      return awaiting_created
                 ? StreamBrokerDisconnectReason::
                       kTerminatedByClientAwaitingCreated
                 : StreamBrokerDisconnectReason::kTerminatedByClient;
    case DisconnectReason::kStreamCreationFailed:
      return StreamBrokerDisconnectReason::kStreamCreationFailed;
    case DisconnectReason::kDocumentDestroyed:
      return awaiting_created
                 ? StreamBrokerDisconnectReason::
                       kDocumentDestroyedAwaitingCreated
                 : StreamBrokerDisconnectReason::kDocumentDestroyed;
    case DisconnectReason::kDefault:
      return StreamBrokerDisconnectReason::kDefault;
  }
}

}  // namespace

AudioOutputStreamBroker::AudioOutputStreamBroker(
    int render_process_id,
    int render_frame_id,
    int stream_id,
    const std::string& output_device_id,
    const media::AudioParameters& params,
    const base::UnguessableToken& group_id,
    const base::Optional<base::UnguessableToken>& processing_id,
    DeleterCallback deleter,
    media::mojom::AudioOutputStreamProviderClientPtr client)
    : AudioStreamBroker(render_process_id, render_frame_id),
      output_device_id_(output_device_id),
      params_(params),
      group_id_(group_id),
      processing_id_(processing_id),
      deleter_(std::move(deleter)),
      client_(std::move(client)),
      observer_(render_process_id, render_frame_id, stream_id),
      observer_binding_(&observer_),
      weak_ptr_factory_(this) {
  DCHECK(client_);
  DCHECK(deleter_);
  DCHECK(group_id_);
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("audio", "AudioOutputStreamBroker", this);

  MediaObserver* media_observer =
      GetContentClient()->browser()->GetMediaObserver();

  // May be null in unit tests.
  if (media_observer)
    media_observer->OnCreatingAudioStream(render_process_id, render_frame_id);

  // Unretained is safe because |this| owns |client_|
  client_.set_connection_error_handler(
      base::BindOnce(&AudioOutputStreamBroker::Cleanup, base::Unretained(this),
                     DisconnectReason::kTerminatedByClient));
}

AudioOutputStreamBroker::~AudioOutputStreamBroker() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);

  const StreamBrokerDisconnectReason reason =
      GetDisconnectReason(disconnect_reason_, AwaitingCreated());

  if (AwaitingCreated()) {
    TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
                                    "failed or cancelled");
  }

  TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "AudioOutputStreamBroker", this,
                                  "disconnect reason",
                                  static_cast<uint32_t>(reason));

  UMA_HISTOGRAM_ENUMERATION("Media.Audio.Render.StreamBrokerDisconnectReason2",
                            reason);

  if (AwaitingCreated()) {
    UMA_HISTOGRAM_TIMES(
        "Media.Audio.Render.StreamBrokerDocumentDestroyedAwaitingCreatedTime",
        base::TimeTicks::Now() - stream_creation_start_time_);
  }
}

void AudioOutputStreamBroker::CreateStream(
    audio::mojom::StreamFactory* factory) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
  DCHECK(!observer_binding_.is_bound());
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("audio", "CreateStream", this, "device id",
                                    output_device_id_);
  stream_creation_start_time_ = base::TimeTicks::Now();

  // Set up observer ptr. Unretained is safe because |this| owns
  // |observer_binding_|.
  media::mojom::AudioOutputStreamObserverAssociatedPtrInfo ptr_info;
  observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
  observer_binding_.set_connection_error_with_reason_handler(base::BindOnce(
      &AudioOutputStreamBroker::ObserverBindingLost, base::Unretained(this)));

  media::mojom::AudioOutputStreamPtr stream;
  media::mojom::AudioOutputStreamRequest stream_request =
      mojo::MakeRequest(&stream);

  // Note that the component id for AudioLog is used to differentiate between
  // several users of the same audio log. Since this audio log is for a single
  // stream, the component id used doesn't matter.
  constexpr int log_component_id = 0;
  factory->CreateOutputStream(
      std::move(stream_request), std::move(ptr_info),
      MediaInternals::GetInstance()->CreateMojoAudioLog(
          media::AudioLogFactory::AudioComponent::AUDIO_OUTPUT_CONTROLLER,
          log_component_id, render_process_id(), render_frame_id()),
      output_device_id_, params_, group_id_, processing_id_,
      base::BindOnce(&AudioOutputStreamBroker::StreamCreated,
                     weak_ptr_factory_.GetWeakPtr(), std::move(stream)));
}

void AudioOutputStreamBroker::StreamCreated(
    media::mojom::AudioOutputStreamPtr stream,
    media::mojom::ReadWriteAudioDataPipePtr data_pipe) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
  TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
                                  !!data_pipe);
  UMA_HISTOGRAM_TIMES("Media.Audio.Render.StreamBrokerStreamCreationTime",
                      base::TimeTicks::Now() - stream_creation_start_time_);
  stream_creation_start_time_ = base::TimeTicks();

  if (!data_pipe) {
    // Stream creation failed. Signal error.
    client_.ResetWithReason(
        static_cast<uint32_t>(DisconnectReason::kPlatformError), std::string());
    Cleanup(DisconnectReason::kStreamCreationFailed);
    return;
  }

  client_->Created(std::move(stream), std::move(data_pipe));
}

void AudioOutputStreamBroker::ObserverBindingLost(
    uint32_t reason,
    const std::string& description) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
  TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("audio", "ObserverBindingLost", this,
                                      "reset reason", reason);
  if (reason > static_cast<uint32_t>(DisconnectReason::kMaxValue))
    NOTREACHED() << "Invalid reason: " << reason;

  DisconnectReason reason_enum = static_cast<DisconnectReason>(reason);

  // TODO(https://crbug.com/787806): Don't propagate errors if we can retry
  // instead.
  client_.ResetWithReason(
      static_cast<uint32_t>(DisconnectReason::kPlatformError), std::string());
  Cleanup((reason_enum == DisconnectReason::kPlatformError && AwaitingCreated())
              ? DisconnectReason::kStreamCreationFailed
              : reason_enum);
}

void AudioOutputStreamBroker::Cleanup(DisconnectReason reason) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
  DCHECK_EQ(DisconnectReason::kDocumentDestroyed, disconnect_reason_);
  disconnect_reason_ = reason;
  std::move(deleter_).Run(this);
}

bool AudioOutputStreamBroker::AwaitingCreated() const {
  return stream_creation_start_time_ != base::TimeTicks();
}

}  // namespace content
