[audio_core][test] Flesh out a few more audio integration tests

Flesh out more reporting-related integration tests.

Bug: 49807
Multiply: audio-core-api-tests
Change-Id: I3eb87235cb11091dc504bbc3b60aede05cb18c2b
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/404704
Commit-Queue: Tom Bergan <tombergan@google.com>
Reviewed-by: Tim Detwiler <tjdetwiler@google.com>
Testability-Review: Tim Detwiler <tjdetwiler@google.com>
diff --git a/src/media/audio/audio_core/test/api/usage_reporter_test.cc b/src/media/audio/audio_core/test/api/usage_reporter_test.cc
index cbec157..e3619e6 100644
--- a/src/media/audio/audio_core/test/api/usage_reporter_test.cc
+++ b/src/media/audio/audio_core/test/api/usage_reporter_test.cc
@@ -59,7 +59,7 @@
     FakeUsageWatcher fake_watcher;
   };
 
-  std::unique_ptr<Controller> CreateController(fuchsia::media::AudioRenderUsage u) {
+  std::unique_ptr<Controller> CreateController(AudioRenderUsage u) {
     fuchsia::media::Usage usage;
     usage.set_render_usage(u);
 
@@ -71,16 +71,36 @@
     return c;
   }
 
-  AudioRendererShim<AudioSampleFormat::SIGNED_16>* StartRendererWithUsage(AudioRenderUsage usage) {
+  std::unique_ptr<Controller> CreateController(AudioCaptureUsage u) {
+    fuchsia::media::Usage usage;
+    usage.set_capture_usage(u);
+
+    auto c = std::make_unique<Controller>(this);
+    environment()->ConnectToService(c->usage_reporter.NewRequest());
+    AddErrorHandler(c->usage_reporter, "UsageReporter");
+    c->usage_reporter->Watch(std::move(usage), c->fake_watcher.NewBinding());
+
+    return c;
+  }
+
+  void StartRendererWithUsage(AudioRenderUsage usage) {
     auto format = Format::Create<AudioSampleFormat::SIGNED_16>(1, 8000).value();  // arbitrary
     auto r = CreateAudioRenderer(format, 1024, usage);
     r->renderer()->PlayNoReply(0, 0);
-    return r;
+  }
+
+  void StartCapturerWithUsage(AudioCaptureUsage usage) {
+    auto format = Format::Create<AudioSampleFormat::SIGNED_16>(1, 8000).value();  // arbitrary
+    fuchsia::media::InputAudioCapturerConfiguration cfg;
+    cfg.set_usage(usage);
+    auto c = CreateAudioCapturer(
+        format, 1024, fuchsia::media::AudioCapturerConfiguration::WithInput(std::move(cfg)));
+    c->capturer()->StartAsyncCapture(1024);
   }
 };
 
 TEST_F(UsageReporterTest, RenderUsageInitialState) {
-  auto c = CreateController(fuchsia::media::AudioRenderUsage::MEDIA);
+  auto c = CreateController(AudioRenderUsage::MEDIA);
 
   fuchsia::media::Usage last_usage;
   fuchsia::media::UsageState last_state;
@@ -95,11 +115,11 @@
   ExpectCallback();
   EXPECT_TRUE(last_state.is_unadjusted());
   EXPECT_TRUE(last_usage.is_render_usage());
-  EXPECT_EQ(last_usage.render_usage(), fuchsia::media::AudioRenderUsage::MEDIA);
+  EXPECT_EQ(last_usage.render_usage(), AudioRenderUsage::MEDIA);
 }
 
 TEST_F(UsageReporterTest, RenderUsageDucked) {
-  auto c = CreateController(fuchsia::media::AudioRenderUsage::MEDIA);
+  auto c = CreateController(AudioRenderUsage::MEDIA);
 
   // The initial callback happens immediately.
   c->fake_watcher.SetNextHandler(AddCallback("OnStateChange InitialCall"));
@@ -114,24 +134,24 @@
         last_state = std::move(state);
       }));
 
-  // Duck MEDIA when SYSTEM_AGENT is playing.
+  // Duck MEDIA when SYSTEM_AGENT is active.
   {
     fuchsia::media::Usage active, affected;
-    active.set_render_usage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT);
-    affected.set_render_usage(fuchsia::media::AudioRenderUsage::MEDIA);
+    active.set_render_usage(AudioRenderUsage::SYSTEM_AGENT);
+    affected.set_render_usage(AudioRenderUsage::MEDIA);
     audio_core_->SetInteraction(std::move(active), std::move(affected),
                                 fuchsia::media::Behavior::DUCK);
   }
 
-  StartRendererWithUsage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT);
+  StartRendererWithUsage(AudioRenderUsage::SYSTEM_AGENT);
   ExpectCallback();
   EXPECT_TRUE(last_state.is_ducked());
   EXPECT_TRUE(last_usage.is_render_usage());
-  EXPECT_EQ(last_usage.render_usage(), fuchsia::media::AudioRenderUsage::MEDIA);
+  EXPECT_EQ(last_usage.render_usage(), AudioRenderUsage::MEDIA);
 }
 
 TEST_F(UsageReporterTest, RenderUsageMuted) {
-  auto c = CreateController(fuchsia::media::AudioRenderUsage::MEDIA);
+  auto c = CreateController(AudioRenderUsage::MEDIA);
 
   // The initial callback happens immediately.
   c->fake_watcher.SetNextHandler(AddCallback("OnStateChange InitialCall"));
@@ -146,22 +166,103 @@
         last_state = std::move(state);
       }));
 
-  // Duck MEDIA when SYSTEM_AGENT is playing.
+  // Mute MEDIA when SYSTEM_AGENT is active.
   {
     fuchsia::media::Usage active, affected;
-    active.set_render_usage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT);
-    affected.set_render_usage(fuchsia::media::AudioRenderUsage::MEDIA);
+    active.set_render_usage(AudioRenderUsage::SYSTEM_AGENT);
+    affected.set_render_usage(AudioRenderUsage::MEDIA);
     audio_core_->SetInteraction(std::move(active), std::move(affected),
                                 fuchsia::media::Behavior::MUTE);
   }
 
-  StartRendererWithUsage(fuchsia::media::AudioRenderUsage::SYSTEM_AGENT);
+  StartRendererWithUsage(AudioRenderUsage::SYSTEM_AGENT);
   ExpectCallback();
   EXPECT_TRUE(last_state.is_muted());
   EXPECT_TRUE(last_usage.is_render_usage());
-  EXPECT_EQ(last_usage.render_usage(), fuchsia::media::AudioRenderUsage::MEDIA);
+  EXPECT_EQ(last_usage.render_usage(), AudioRenderUsage::MEDIA);
 }
 
-// TODO(50645): Test the integration with capturers
+TEST_F(UsageReporterTest, CaptureUsageInitialState) {
+  auto c = CreateController(AudioCaptureUsage::COMMUNICATION);
+
+  fuchsia::media::Usage last_usage;
+  fuchsia::media::UsageState last_state;
+  c->fake_watcher.SetNextHandler(AddCallback(
+      "OnStateChange",
+      [&last_usage, &last_state](fuchsia::media::Usage usage, fuchsia::media::UsageState state) {
+        last_usage = std::move(usage);
+        last_state = std::move(state);
+      }));
+
+  // The initial callback happens immediately.
+  ExpectCallback();
+  EXPECT_TRUE(last_state.is_unadjusted());
+  EXPECT_TRUE(last_usage.is_capture_usage());
+  EXPECT_EQ(last_usage.capture_usage(), AudioCaptureUsage::COMMUNICATION);
+}
+
+TEST_F(UsageReporterTest, CaptureUsageDucked) {
+  auto c = CreateController(AudioCaptureUsage::COMMUNICATION);
+
+  // The initial callback happens immediately.
+  c->fake_watcher.SetNextHandler(AddCallback("OnStateChange InitialCall"));
+  ExpectCallback();
+
+  fuchsia::media::Usage last_usage;
+  fuchsia::media::UsageState last_state;
+  c->fake_watcher.SetNextHandler(AddCallback(
+      "OnStateChange",
+      [&last_usage, &last_state](fuchsia::media::Usage usage, fuchsia::media::UsageState state) {
+        last_usage = std::move(usage);
+        last_state = std::move(state);
+      }));
+
+  // Duck COMMUNICATION when SYSTEM_AGENT is active.
+  {
+    fuchsia::media::Usage active, affected;
+    active.set_capture_usage(AudioCaptureUsage::SYSTEM_AGENT);
+    affected.set_capture_usage(AudioCaptureUsage::COMMUNICATION);
+    audio_core_->SetInteraction(std::move(active), std::move(affected),
+                                fuchsia::media::Behavior::DUCK);
+  }
+
+  StartCapturerWithUsage(AudioCaptureUsage::SYSTEM_AGENT);
+  ExpectCallback();
+  EXPECT_TRUE(last_state.is_ducked());
+  EXPECT_TRUE(last_usage.is_capture_usage());
+  EXPECT_EQ(last_usage.capture_usage(), AudioCaptureUsage::COMMUNICATION);
+}
+
+TEST_F(UsageReporterTest, CaptureUsageMuted) {
+  auto c = CreateController(AudioCaptureUsage::COMMUNICATION);
+
+  // The initial callback happens immediately.
+  c->fake_watcher.SetNextHandler(AddCallback("OnStateChange InitialCall"));
+  ExpectCallback();
+
+  fuchsia::media::Usage last_usage;
+  fuchsia::media::UsageState last_state;
+  c->fake_watcher.SetNextHandler(AddCallback(
+      "OnStateChange",
+      [&last_usage, &last_state](fuchsia::media::Usage usage, fuchsia::media::UsageState state) {
+        last_usage = std::move(usage);
+        last_state = std::move(state);
+      }));
+
+  // Mute COMMUNICATION when SYSTEM_AGENT is active.
+  {
+    fuchsia::media::Usage active, affected;
+    active.set_capture_usage(AudioCaptureUsage::SYSTEM_AGENT);
+    affected.set_capture_usage(AudioCaptureUsage::COMMUNICATION);
+    audio_core_->SetInteraction(std::move(active), std::move(affected),
+                                fuchsia::media::Behavior::MUTE);
+  }
+
+  StartCapturerWithUsage(AudioCaptureUsage::SYSTEM_AGENT);
+  ExpectCallback();
+  EXPECT_TRUE(last_state.is_muted());
+  EXPECT_TRUE(last_usage.is_capture_usage());
+  EXPECT_EQ(last_usage.capture_usage(), AudioCaptureUsage::COMMUNICATION);
+}
 
 }  // namespace media::audio::test
diff --git a/src/media/audio/audio_core/test/api/volume_control.cc b/src/media/audio/audio_core/test/api/volume_control.cc
index 788fb0c..43113bd 100644
--- a/src/media/audio/audio_core/test/api/volume_control.cc
+++ b/src/media/audio/audio_core/test/api/volume_control.cc
@@ -10,24 +10,25 @@
 
 #include "src/media/audio/lib/test/hermetic_audio_test.h"
 
+using AudioCaptureUsage = fuchsia::media::AudioCaptureUsage;
+using AudioRenderUsage = fuchsia::media::AudioRenderUsage;
+
 namespace media::audio::test {
 
-class VolumeControlTest : public HermeticAudioTest {};
+class VolumeControlTest : public HermeticAudioTest {
+ protected:
+  fuchsia::media::audio::VolumeControlPtr CreateRenderUsageControl(AudioRenderUsage u) {
+    fuchsia::media::audio::VolumeControlPtr c;
+    audio_core_->BindUsageVolumeControl(fuchsia::media::Usage::WithRenderUsage(std::move(u)),
+                                        c.NewRequest());
+    AddErrorHandler(c, "VolumeControl");
+    return c;
+  }
+};
 
-// TODO(52962): Flesh out
-TEST_F(VolumeControlTest, ConnectToRenderUsageVolume) {
-  fuchsia::media::AudioCorePtr audio_core;
-  environment()->ConnectToService(audio_core.NewRequest());
-  AddErrorHandler(audio_core, "AudioCore");
-
-  fuchsia::media::audio::VolumeControlPtr client1;
-  fuchsia::media::audio::VolumeControlPtr client2;
-
-  fuchsia::media::Usage usage;
-  usage.set_render_usage(fuchsia::media::AudioRenderUsage::MEDIA);
-
-  audio_core->BindUsageVolumeControl(fidl::Clone(usage), client1.NewRequest());
-  audio_core->BindUsageVolumeControl(fidl::Clone(usage), client2.NewRequest());
+TEST_F(VolumeControlTest, SetVolumeAndMute) {
+  auto client1 = CreateRenderUsageControl(AudioRenderUsage::MEDIA);
+  auto client2 = CreateRenderUsageControl(AudioRenderUsage::MEDIA);
 
   float volume = 0.0;
   bool muted = false;
@@ -39,10 +40,13 @@
         });
   };
 
+  // The initial callback happens immediately.
   add_callback();
   ExpectCallback();
   EXPECT_FLOAT_EQ(volume, 1.0);
+  EXPECT_EQ(muted, false);
 
+  // Further callbacks happen in response to events.
   add_callback();
   client1->SetVolume(0.5);
   ExpectCallback();
@@ -53,20 +57,46 @@
   client1->SetMute(true);
   ExpectCallback();
   EXPECT_EQ(muted, true);
+
+  // Unmute should restore the volume.
+  add_callback();
+  client1->SetMute(false);
+  ExpectCallback();
+  EXPECT_FLOAT_EQ(volume, 0.5);
+  EXPECT_EQ(muted, false);
+}
+
+TEST_F(VolumeControlTest, RoutedCorrectly) {
+  auto c1 = CreateRenderUsageControl(AudioRenderUsage::MEDIA);
+  auto c2 = CreateRenderUsageControl(AudioRenderUsage::BACKGROUND);
+
+  // The initial callbacks happen immediately.
+  c1.events().OnVolumeMuteChanged = AddCallback("OnVolumeMuteChanged1 InitialCall");
+  c2.events().OnVolumeMuteChanged = AddCallback("OnVolumeMuteChanged2 InitialCall");
+  ExpectCallback();
+
+  // Routing to c1.
+  c1.events().OnVolumeMuteChanged = AddCallback("OnVolumeMuteChanged1 RouteTo1");
+  c2.events().OnVolumeMuteChanged = AddUnexpectedCallback("OnVolumeMuteChanged2 RouteTo1");
+  c1->SetVolume(0);
+  ExpectCallback();
+
+  // Routing to c2.
+  c1.events().OnVolumeMuteChanged = AddUnexpectedCallback("OnVolumeMuteChanged1 RouteTo2");
+  c2.events().OnVolumeMuteChanged = AddCallback("OnVolumeMuteChanged2 RouteTo2");
+  c2->SetVolume(0);
+  ExpectCallback();
 }
 
 TEST_F(VolumeControlTest, FailToConnectToCaptureUsageVolume) {
   fuchsia::media::Usage usage;
   usage.set_capture_usage(fuchsia::media::AudioCaptureUsage::SYSTEM_AGENT);
 
-  std::optional<zx_status_t> client_error;
   fuchsia::media::audio::VolumeControlPtr client;
-  client.set_error_handler([&client_error](zx_status_t status) { client_error = status; });
-
   audio_core_->BindUsageVolumeControl(fidl::Clone(usage), client.NewRequest());
-  RunLoopUntil([&client_error] { return client_error != std::nullopt; });
+  AddErrorHandler(client, "VolumeControl");
 
-  EXPECT_EQ(ZX_ERR_NOT_SUPPORTED, *client_error);
+  ExpectError(client, ZX_ERR_NOT_SUPPORTED);
 }
 
 }  // namespace media::audio::test