1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/media/media_internals.h"
8 #include "base/bind_helpers.h"
9 #include "base/json/json_reader.h"
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "content/public/test/test_browser_thread_bundle.h"
13 #include "media/audio/audio_parameters.h"
14 #include "media/base/channel_layout.h"
15 #include "testing/gtest/include/gtest/gtest.h"
18 const int kTestComponentID = 0;
19 const char kTestDeviceID[] = "test-device-id";
24 class MediaInternalsTest
25 : public testing::TestWithParam<media::AudioLogFactory::AudioComponent> {
28 : media_internals_(MediaInternals::GetInstance()),
29 update_cb_(base::Bind(&MediaInternalsTest::UpdateCallbackImpl,
30 base::Unretained(this))),
31 test_params_(media::AudioParameters::AUDIO_PCM_LINEAR,
32 media::CHANNEL_LAYOUT_MONO,
36 media::AudioParameters::ECHO_CANCELLER |
37 media::AudioParameters::DUCKING),
38 test_component_(GetParam()),
39 audio_log_(media_internals_->CreateAudioLog(test_component_)) {
40 media_internals_->AddUpdateCallback(update_cb_);
43 virtual ~MediaInternalsTest() {
44 media_internals_->RemoveUpdateCallback(update_cb_);
48 // Extracts and deserializes the JSON update data; merges into |update_data_|.
49 void UpdateCallbackImpl(const base::string16& update) {
50 // Each update string looks like "<JavaScript Function Name>({<JSON>});", to
51 // use the JSON reader we need to strip out the JavaScript code.
52 std::string utf8_update = base::UTF16ToUTF8(update);
53 const std::string::size_type first_brace = utf8_update.find('{');
54 const std::string::size_type last_brace = utf8_update.rfind('}');
55 scoped_ptr<base::Value> output_value(base::JSONReader::Read(
56 utf8_update.substr(first_brace, last_brace - first_brace + 1)));
59 base::DictionaryValue* output_dict = NULL;
60 CHECK(output_value->GetAsDictionary(&output_dict));
61 update_data_.MergeDictionary(output_dict);
64 void ExpectInt(const std::string& key, int expected_value) {
66 ASSERT_TRUE(update_data_.GetInteger(key, &actual_value));
67 EXPECT_EQ(expected_value, actual_value);
70 void ExpectString(const std::string& key, const std::string& expected_value) {
71 std::string actual_value;
72 ASSERT_TRUE(update_data_.GetString(key, &actual_value));
73 EXPECT_EQ(expected_value, actual_value);
76 void ExpectStatus(const std::string& expected_value) {
77 ExpectString("status", expected_value);
80 TestBrowserThreadBundle thread_bundle_;
81 MediaInternals* const media_internals_;
82 MediaInternals::UpdateCallback update_cb_;
83 base::DictionaryValue update_data_;
84 const media::AudioParameters test_params_;
85 const media::AudioLogFactory::AudioComponent test_component_;
86 scoped_ptr<media::AudioLog> audio_log_;
89 TEST_P(MediaInternalsTest, AudioLogCreateStartStopErrorClose) {
90 audio_log_->OnCreated(
91 kTestComponentID, test_params_, kTestDeviceID);
92 base::RunLoop().RunUntilIdle();
94 ExpectString("channel_layout",
95 media::ChannelLayoutToString(test_params_.channel_layout()));
96 ExpectInt("sample_rate", test_params_.sample_rate());
97 ExpectInt("frames_per_buffer", test_params_.frames_per_buffer());
98 ExpectInt("channels", test_params_.channels());
99 ExpectString("effects", "ECHO_CANCELLER | DUCKING");
100 ExpectString("device_id", kTestDeviceID);
101 ExpectInt("component_id", kTestComponentID);
102 ExpectInt("component_type", test_component_);
103 ExpectStatus("created");
105 // Verify OnStarted().
106 audio_log_->OnStarted(kTestComponentID);
107 base::RunLoop().RunUntilIdle();
108 ExpectStatus("started");
110 // Verify OnStopped().
111 audio_log_->OnStopped(kTestComponentID);
112 base::RunLoop().RunUntilIdle();
113 ExpectStatus("stopped");
116 const char kErrorKey[] = "error_occurred";
117 std::string no_value;
118 ASSERT_FALSE(update_data_.GetString(kErrorKey, &no_value));
119 audio_log_->OnError(kTestComponentID);
120 base::RunLoop().RunUntilIdle();
121 ExpectString(kErrorKey, "true");
123 // Verify OnClosed().
124 audio_log_->OnClosed(kTestComponentID);
125 base::RunLoop().RunUntilIdle();
126 ExpectStatus("closed");
129 TEST_P(MediaInternalsTest, AudioLogCreateClose) {
130 audio_log_->OnCreated(
131 kTestComponentID, test_params_, kTestDeviceID);
132 base::RunLoop().RunUntilIdle();
133 ExpectStatus("created");
135 audio_log_->OnClosed(kTestComponentID);
136 base::RunLoop().RunUntilIdle();
137 ExpectStatus("closed");
140 INSTANTIATE_TEST_CASE_P(
141 MediaInternalsTest, MediaInternalsTest, testing::Values(
142 media::AudioLogFactory::AUDIO_INPUT_CONTROLLER,
143 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER,
144 media::AudioLogFactory::AUDIO_OUTPUT_STREAM));
146 } // namespace content