// Copyright 2019 The Fuchsia 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 "src/media/audio/audio_core/audio_admin.h"

#include <unordered_map>

#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/media/audio/audio_core/stream_volume_manager.h"
#include "src/media/audio/lib/test/null_audio_capturer.h"
#include "src/media/audio/lib/test/null_audio_renderer.h"

namespace media::audio {
namespace {
// Note we purposely use some strange values here to ensure we're not falling back to any default
// or hard-coded logic for values.
static constexpr float kMuteGain = -3.0f;
static constexpr float kDuckGain = -2.0f;
static constexpr float kNoneGain = -1.0f;

static constexpr AudioAdmin::BehaviorGain kTestBehaviorGain{
    .none_gain_db = kNoneGain,
    .duck_gain_db = kDuckGain,
    .mute_gain_db = kMuteGain,
};

class MockPolicyActionReporter : public AudioAdmin::PolicyActionReporter {
 public:
  MockPolicyActionReporter(
      fit::function<void(fuchsia::media::Usage usage, fuchsia::media::Behavior policy_action)>
          receiver)
      : receiver_(std::move(receiver)) {}

  void ReportPolicyAction(fuchsia::media::Usage usage,
                          fuchsia::media::Behavior policy_action) override {
    receiver_(std::move(usage), policy_action);
  }

 private:
  fit::function<void(fuchsia::media::Usage usage, fuchsia::media::Behavior policy_action)>
      receiver_;
};

class MockActivityDispatcher : public AudioAdmin::ActivityDispatcher {
 public:
  void OnRenderActivityChanged(std::bitset<fuchsia::media::RENDER_USAGE_COUNT> activity) override {
    last_dispatched_render_activity_ = activity;
  }
  void OnCaptureActivityChanged(
      std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT> activity) override {
    last_dispatched_capture_activity_ = activity;
  }

  // Access last activity dispatched.
  std::bitset<fuchsia::media::RENDER_USAGE_COUNT> GetLastRenderActivity() {
    return last_dispatched_render_activity_;
  }
  std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT> GetLastCaptureActivity() {
    return last_dispatched_capture_activity_;
  }

 private:
  std::bitset<fuchsia::media::RENDER_USAGE_COUNT> last_dispatched_render_activity_;
  std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT> last_dispatched_capture_activity_;
};

class MockStreamVolume : public StreamVolume {
 public:
  explicit MockStreamVolume(fuchsia::media::AudioRenderUsage usage)
      : usage_(fuchsia::media::Usage::WithRenderUsage(std::move(usage))) {}
  explicit MockStreamVolume(fuchsia::media::AudioCaptureUsage usage)
      : usage_(fuchsia::media::Usage::WithCaptureUsage(std::move(usage))) {}

  // |StreamVolume|
  fuchsia::media::Usage GetStreamUsage() const final { return fidl::Clone(usage_); }
  bool GetStreamMute() const final { return false; }  // Not reflective of policy.
  void RealizeVolume(VolumeCommand volume_command) final { ++volume_update_count_; }

  size_t volume_update_count() { return volume_update_count_; }

 private:
  // Ignore volume update that occurs on renderer/capturer creation.
  size_t volume_update_count_ = -1;
  fuchsia::media::Usage usage_;
};

class AudioAdminTest : public gtest::TestLoopFixture {};

TEST_F(AudioAdminTest, OnlyUpdateVolumeOnPolicyChange) {
  StreamVolumeManager stream_volume_manager(dispatcher());
  MockStreamVolume stream(fuchsia::media::AudioRenderUsage::MEDIA);
  stream_volume_manager.AddStream(&stream);

  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1;
  test::NullAudioCapturer c1;
  test::NullAudioCapturer c2;

  // Media should duck when comms is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::COMMUNICATION),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA),
      fuchsia::media::Behavior::MUTE);

  // Create active media stream; activation triggers initial policy application (volume update).
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::MEDIA, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(stream.volume_update_count(), 1ul);

  // Create active comms capturer; media volume should duck.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, true, &c1);
  RunLoopUntilIdle();
  EXPECT_EQ(stream.volume_update_count(), 2ul);

  // Create second active comms capturer; media volume should remain ducked (no update).
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, true, &c2);
  RunLoopUntilIdle();
  EXPECT_EQ(stream.volume_update_count(), 2ul);

  // All comms become inactive; media volume should un-duck.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, false, &c1);
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, false, &c2);
  RunLoopUntilIdle();
  EXPECT_EQ(stream.volume_update_count(), 3ul);
}

TEST_F(AudioAdminTest, TwoRenderersWithNoInteractions) {
  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  StreamVolumeManager stream_volume_manager(dispatcher());
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1, r2;

  // Set an inintial stream volume.
  const float kStreamGain = 1.0;
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA), kStreamGain);
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      kStreamGain);

  // Start playing a MEDIA stream and check for 'no gain adjustment'.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::MEDIA, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));

  // Now play a COMMUNICATIONS stream and also check for 'no gain adjustment'.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, true, &r2);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));
}

TEST_F(AudioAdminTest, TwoRenderersWithDuck) {
  StreamVolumeManager stream_volume_manager(dispatcher());
  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1, r2;

  // Media should duck when comms is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA),
      fuchsia::media::Behavior::DUCK);

  // Set an inintial stream volume.
  const float kStreamGain = 1.0;
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA), kStreamGain);
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      kStreamGain);

  // create media active stream.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::MEDIA, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));

  // communications renderer becomes active; media should duck.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, true, &r2);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kDuckGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));

  // comms becomes inactive; ducking should stop.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, false, &r2);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));
}

TEST_F(AudioAdminTest, CapturerDucksRenderer) {
  StreamVolumeManager stream_volume_manager(dispatcher());
  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1;
  test::NullAudioCapturer c1;

  // Set an inintial stream volume.
  const float kStreamGain = 1.0;
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA), kStreamGain);
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::COMMUNICATION),
      kStreamGain);

  // Media should duck when comms is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::COMMUNICATION),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA),
      fuchsia::media::Behavior::DUCK);

  // Create active media stream.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::MEDIA, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));

  // Create active comms capturer; media output should duck.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, true, &c1);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kDuckGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithCaptureUsage(
                    fuchsia::media::AudioCaptureUsage::COMMUNICATION)));

  // Comms becomes inactive; ducking should stop.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::COMMUNICATION, false, &c1);
  RunLoopUntilIdle();
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::MEDIA)));
  EXPECT_EQ(kStreamGain + kNoneGain,
            stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
                fuchsia::media::Usage::WithCaptureUsage(
                    fuchsia::media::AudioCaptureUsage::COMMUNICATION)));
}

TEST_F(AudioAdminTest, RendererDucksCapturer) {
  StreamVolumeManager stream_volume_manager(dispatcher());
  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1;
  test::NullAudioCapturer c1;

  const float kStreamGain = 1.0;
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      kStreamGain);
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND),
      kStreamGain);

  // Foreground capturer should duck when communication renderers are active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND),
      fuchsia::media::Behavior::DUCK);

  // Create active capturer stream.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::FOREGROUND, true, &c1);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND)));

  // Create active comms renderer; foreground capturer should duck.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kDuckGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND)));
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));

  // Comms becomes inactive; ducking should stop.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, false, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND)));
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));
}

TEST_F(AudioAdminTest, PolicyActionsReported) {
  auto test_policy_action = [this](auto expected_action) {
    const auto target_usage =
        fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND);
    fuchsia::media::Behavior policy_action_taken;
    // Record any actions taken on our target_usage (AudioCaptureUsage::FOREGROUND)
    MockPolicyActionReporter policy_action_reporter(
        [&policy_action_taken, &target_usage](auto usage, auto action) {
          if (fidl::Equals(usage, target_usage)) {
            policy_action_taken = action;
          }
        });

    StreamVolumeManager stream_volume_manager(dispatcher());
    MockActivityDispatcher mock_activity_dispatcher;
    AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                     &mock_activity_dispatcher, dispatcher());
    test::NullAudioRenderer r1;
    test::NullAudioCapturer c1;

    const float kStreamGain = 1.0;
    stream_volume_manager.SetUsageGain(
        fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
        kStreamGain);
    stream_volume_manager.SetUsageGain(
        fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND),
        kStreamGain);

    // Foreground capturer should duck when communication renderers are active.
    admin.SetInteraction(
        fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
        fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::FOREGROUND),
        expected_action);

    // Create active capturer stream.
    admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::FOREGROUND, true, &c1);
    // Create active comms renderer; foreground capturer should receive policy action.
    admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, true, &r1);
    RunLoopUntilIdle();
    EXPECT_EQ(policy_action_taken, expected_action);

    // Comms becomes inactive; action should stop.
    admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, false, &r1);
    RunLoopUntilIdle();
    EXPECT_EQ(policy_action_taken, fuchsia::media::Behavior::NONE);
  };

  test_policy_action(fuchsia::media::Behavior::DUCK);
  test_policy_action(fuchsia::media::Behavior::MUTE);
}

TEST_F(AudioAdminTest, RenderActivityDispatched) {
  // Test that a change of usage given an initial activity is correctly dispatched.
  auto test_dispatch_action = [this](
                                  std::bitset<fuchsia::media::RENDER_USAGE_COUNT> initial_activity,
                                  fuchsia::media::AudioRenderUsage changed_usage) {
    StreamVolumeManager stream_volume_manager(dispatcher());
    MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
    MockActivityDispatcher mock_activity_dispatcher;
    AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                     &mock_activity_dispatcher, dispatcher());

    // Trigger the initial activity by registering AudioRenderers.
    std::array<test::NullAudioRenderer, fuchsia::media::RENDER_USAGE_COUNT> rs;
    for (int i = 0; i < fuchsia::media::RENDER_USAGE_COUNT; i++) {
      if (initial_activity[i]) {
        admin.UpdateRendererState(static_cast<fuchsia::media::AudioRenderUsage>(i), true, &rs[i]);
      }
    }

    RunLoopUntilIdle();
    EXPECT_EQ(initial_activity, mock_activity_dispatcher.GetLastRenderActivity());

    int changed_usage_index = static_cast<int>(changed_usage);
    std::bitset<fuchsia::media::RENDER_USAGE_COUNT> final_activity = initial_activity;
    final_activity.flip(changed_usage_index);

    // Modify the initial activity to reflect the changed usage.
    admin.UpdateRendererState(changed_usage, final_activity[changed_usage_index],
                              &rs[changed_usage_index]);

    RunLoopUntilIdle();
    EXPECT_EQ(final_activity, mock_activity_dispatcher.GetLastRenderActivity());
  };

  // Check all of the possible state transitions from each possible activity.
  int possible_activities_count = std::pow(2, fuchsia::media::RENDER_USAGE_COUNT);
  for (int i = 0; i < possible_activities_count; i++) {
    for (int j = 0; j < fuchsia::media::RENDER_USAGE_COUNT; j++) {
      auto initial_activity = static_cast<std::bitset<fuchsia::media::RENDER_USAGE_COUNT>>(i);
      auto changed_usage = static_cast<fuchsia::media::AudioRenderUsage>(j);
      test_dispatch_action(initial_activity, changed_usage);
    }
  }
}

TEST_F(AudioAdminTest, CaptureActivityDispatched) {
  // Test that a change of usage given an initial activity is correctly dispatched.
  auto test_dispatch_action = [this](
                                  std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT> initial_activity,
                                  fuchsia::media::AudioCaptureUsage changed_usage) {
    StreamVolumeManager stream_volume_manager(dispatcher());
    MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
    MockActivityDispatcher mock_activity_dispatcher;
    AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                     &mock_activity_dispatcher, dispatcher());

    // Trigger the initial activity by registering AudioCapturers.
    std::array<test::NullAudioCapturer, fuchsia::media::CAPTURE_USAGE_COUNT> rs;
    for (int i = 0; i < fuchsia::media::CAPTURE_USAGE_COUNT; i++) {
      if (initial_activity[i]) {
        admin.UpdateCapturerState(static_cast<fuchsia::media::AudioCaptureUsage>(i), true, &rs[i]);
      }
    }

    RunLoopUntilIdle();
    EXPECT_EQ(initial_activity, mock_activity_dispatcher.GetLastCaptureActivity());

    int changed_usage_index = static_cast<int>(changed_usage);
    std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT> final_activity = initial_activity;
    final_activity.flip(changed_usage_index);

    // Modify the initial activity to reflect the changed usage.
    admin.UpdateCapturerState(changed_usage, final_activity[changed_usage_index],
                              &rs[changed_usage_index]);

    RunLoopUntilIdle();
    EXPECT_EQ(final_activity, mock_activity_dispatcher.GetLastCaptureActivity());
  };

  // Check all of the possible state transitions from each possible activity.
  int possible_activities_count = std::pow(2, fuchsia::media::CAPTURE_USAGE_COUNT);
  for (int i = 0; i < possible_activities_count; i++) {
    for (int j = 0; j < fuchsia::media::CAPTURE_USAGE_COUNT; j++) {
      auto initial_activity = static_cast<std::bitset<fuchsia::media::CAPTURE_USAGE_COUNT>>(i);
      auto changed_usage = static_cast<fuchsia::media::AudioCaptureUsage>(j);
      test_dispatch_action(initial_activity, changed_usage);
    }
  }
}

// Test to verify that Mute overrides Duck, and both override None.
TEST_F(AudioAdminTest, PriorityActionsApplied) {
  StreamVolumeManager stream_volume_manager(dispatcher());
  MockPolicyActionReporter policy_action_reporter([](auto _usage, auto _policy_action) {});
  MockActivityDispatcher mock_activity_dispatcher;
  AudioAdmin admin(kTestBehaviorGain, &stream_volume_manager, &policy_action_reporter,
                   &mock_activity_dispatcher, dispatcher());
  test::NullAudioRenderer r1, r2, r3;
  test::NullAudioCapturer c1;

  // Interruption should duck when SystemAgent(render) is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::INTERRUPTION),
      fuchsia::media::Behavior::DUCK);

  // Communication(render) should duck when SystemAgent(render) is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      fuchsia::media::Behavior::DUCK);

  // Communication(render) should mute when SystemAgent(capture) is active.
  admin.SetInteraction(
      fuchsia::media::Usage::WithCaptureUsage(fuchsia::media::AudioCaptureUsage::SYSTEM_AGENT),
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      fuchsia::media::Behavior::MUTE);

  // Set an initial stream volume.
  const float kStreamGain = 1.0;
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::INTERRUPTION),
      kStreamGain);
  stream_volume_manager.SetUsageGain(
      fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION),
      kStreamGain);

  // Create Interruption active stream.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::INTERRUPTION, true, &r1);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::INTERRUPTION)));

  // Create Communication active stream.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::COMMUNICATION, true, &r2);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));

  // SystemAgent capturer becomes active; Interruption should not change, Communication should mute.
  admin.UpdateCapturerState(fuchsia::media::AudioCaptureUsage::SYSTEM_AGENT, true, &c1);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kNoneGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::INTERRUPTION)));
  EXPECT_EQ(
      kStreamGain + kMuteGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));

  // SystemAgent renderer becomes active; Interruption should duck, Communication should remain
  // muted.
  admin.UpdateRendererState(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT, true, &r3);
  RunLoopUntilIdle();
  EXPECT_EQ(
      kStreamGain + kDuckGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::INTERRUPTION)));
  EXPECT_EQ(
      kStreamGain + kMuteGain,
      stream_volume_manager.GetUsageGainSettings().GetAdjustedUsageGain(
          fuchsia::media::Usage::WithRenderUsage(fuchsia::media::AudioRenderUsage::COMMUNICATION)));
}

}  // namespace
}  // namespace media::audio
