// 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.

#ifndef SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
#define SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_

#include <list>
#include <string>
#include <unordered_map>

#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/media_session/media_controller.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h"
#include "services/media_session/public/mojom/media_controller.mojom.h"

namespace base {
class UnguessableToken;
}  // namespace base

namespace media_session {

namespace test {
class MockMediaSession;
}  // namespace test

class MediaController;

class AudioFocusManager : public mojom::AudioFocusManager,
                          public mojom::AudioFocusManagerDebug,
                          public mojom::MediaControllerManager {
 public:
  AudioFocusManager();
  ~AudioFocusManager() override;

  // TODO(beccahughes): Remove this.
  using RequestId = base::UnguessableToken;

  // mojom::AudioFocusManager.
  void RequestAudioFocus(mojom::AudioFocusRequestClientRequest request,
                         mojom::MediaSessionPtr media_session,
                         mojom::MediaSessionInfoPtr session_info,
                         mojom::AudioFocusType type,
                         RequestAudioFocusCallback callback) override;
  void RequestGroupedAudioFocus(mojom::AudioFocusRequestClientRequest request,
                                mojom::MediaSessionPtr media_session,
                                mojom::MediaSessionInfoPtr session_info,
                                mojom::AudioFocusType type,
                                const base::UnguessableToken& group_id,
                                RequestAudioFocusCallback callback) override;
  void GetFocusRequests(GetFocusRequestsCallback callback) override;
  void AddObserver(mojom::AudioFocusObserverPtr observer) override;
  void SetSourceName(const std::string& name) override;
  void SetEnforcementMode(mojom::EnforcementMode mode) override;

  // mojom::AudioFocusManagerDebug.
  void GetDebugInfoForRequest(const RequestId& request_id,
                              GetDebugInfoForRequestCallback callback) override;

  // mojom::MediaControllerManager.
  void CreateActiveMediaController(
      mojom::MediaControllerRequest request) override;
  void CreateMediaControllerForSession(
      mojom::MediaControllerRequest request,
      const base::UnguessableToken& request_id) override;

  // Bind to a mojom::AudioFocusManagerRequest.
  void BindToInterface(mojom::AudioFocusManagerRequest request);

  // Bind to a mojom::AudioFocusManagerDebugRequest.
  void BindToDebugInterface(mojom::AudioFocusManagerDebugRequest request);

  // Bind to a mojom::MediaControllerManagerRequest.
  void BindToControllerManagerInterface(
      mojom::MediaControllerManagerRequest request);

 private:
  friend class AudioFocusManagerTest;
  friend class MediaControllerTest;
  friend class test::MockMediaSession;

  // StackRow is an AudioFocusRequestClient and allows a media session to
  // control its audio focus.
  class StackRow;

  // BindingContext stores associated metadata for mojo binding.
  struct BindingContext {
    // The source name is associated with a binding when a client calls
    // |SetSourceName|. It is used to provide more granularity than a
    // service_manager::Identity for metrics and for identifying where an audio
    // focus request originated from.
    std::string source_name;
  };

  struct EnforcementState {
    bool should_duck = false;
    bool should_stop = false;
    bool should_suspend = false;
  };

  void RequestAudioFocusInternal(std::unique_ptr<StackRow>,
                                 mojom::AudioFocusType,
                                 base::OnceCallback<void()>);
  void AbandonAudioFocusInternal(RequestId);

  void EnforceAudioFocus();

  void MaybeUpdateActiveSession();

  std::unique_ptr<StackRow> RemoveFocusEntryIfPresent(RequestId id);

  // Returns the source name of the binding currently accessing the Audio
  // Focus Manager API over mojo.
  const std::string& GetBindingSourceName() const;

  bool IsSessionOnTopOfAudioFocusStack(RequestId id,
                                       mojom::AudioFocusType type) const;

  bool ShouldSessionBeSuspended(const StackRow* session,
                                const EnforcementState& state) const;
  bool ShouldSessionBeDucked(const StackRow* session,
                             const EnforcementState& state) const;

  void EnforceSingleSession(StackRow* session, const EnforcementState& state);

  // This |MediaController| acts as a proxy for controlling the active
  // |MediaSession| over mojo.
  MediaController active_media_controller_;

  // Holds mojo bindings for the Audio Focus Manager API.
  mojo::BindingSet<mojom::AudioFocusManager, std::unique_ptr<BindingContext>>
      bindings_;

  // Holds mojo bindings for the Audio Focus Manager Debug API.
  mojo::BindingSet<mojom::AudioFocusManagerDebug> debug_bindings_;

  // Holds mojo bindings for the Media Controller Manager API.
  mojo::BindingSet<mojom::MediaControllerManager> controller_bindings_;

  // Weak reference of managed observers. Observers are expected to remove
  // themselves before being destroyed.
  mojo::InterfacePtrSet<mojom::AudioFocusObserver> observers_;

  // A stack of Mojo interface pointers and their requested audio focus type.
  // A MediaSession must abandon audio focus before its destruction.
  std::list<std::unique_ptr<StackRow>> audio_focus_stack_;

  mojom::EnforcementMode enforcement_mode_;

  // Adding observers should happen on the same thread that the service is
  // running on.
  THREAD_CHECKER(thread_checker_);

  DISALLOW_COPY_AND_ASSIGN(AudioFocusManager);
};

}  // namespace media_session

#endif  // SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
