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
,
37 media::AudioParameters::ECHO_CANCELLER
|
38 media::AudioParameters::DUCKING
),
39 test_component_(GetParam()),
40 audio_log_(media_internals_
->CreateAudioLog(test_component_
)) {
41 media_internals_
->AddUpdateCallback(update_cb_
);
44 virtual ~MediaInternalsTest() {
45 media_internals_
->RemoveUpdateCallback(update_cb_
);
49 // Extracts and deserializes the JSON update data; merges into |update_data_|.
50 void UpdateCallbackImpl(const base::string16
& update
) {
51 // Each update string looks like "<JavaScript Function Name>({<JSON>});", to
52 // use the JSON reader we need to strip out the JavaScript code.
53 std::string utf8_update
= base::UTF16ToUTF8(update
);
54 const std::string::size_type first_brace
= utf8_update
.find('{');
55 const std::string::size_type last_brace
= utf8_update
.rfind('}');
56 scoped_ptr
<base::Value
> output_value(base::JSONReader::Read(
57 utf8_update
.substr(first_brace
, last_brace
- first_brace
+ 1)));
60 base::DictionaryValue
* output_dict
= NULL
;
61 CHECK(output_value
->GetAsDictionary(&output_dict
));
62 update_data_
.MergeDictionary(output_dict
);
65 void ExpectInt(const std::string
& key
, int expected_value
) {
67 ASSERT_TRUE(update_data_
.GetInteger(key
, &actual_value
));
68 EXPECT_EQ(expected_value
, actual_value
);
71 void ExpectString(const std::string
& key
, const std::string
& expected_value
) {
72 std::string actual_value
;
73 ASSERT_TRUE(update_data_
.GetString(key
, &actual_value
));
74 EXPECT_EQ(expected_value
, actual_value
);
77 void ExpectStatus(const std::string
& expected_value
) {
78 ExpectString("status", expected_value
);
81 TestBrowserThreadBundle thread_bundle_
;
82 MediaInternals
* const media_internals_
;
83 MediaInternals::UpdateCallback update_cb_
;
84 base::DictionaryValue update_data_
;
85 const media::AudioParameters test_params_
;
86 const media::AudioLogFactory::AudioComponent test_component_
;
87 scoped_ptr
<media::AudioLog
> audio_log_
;
90 TEST_P(MediaInternalsTest
, AudioLogCreateStartStopErrorClose
) {
91 audio_log_
->OnCreated(
92 kTestComponentID
, test_params_
, kTestDeviceID
);
93 base::RunLoop().RunUntilIdle();
95 ExpectString("channel_layout",
96 media::ChannelLayoutToString(test_params_
.channel_layout()));
97 ExpectInt("sample_rate", test_params_
.sample_rate());
98 ExpectInt("frames_per_buffer", test_params_
.frames_per_buffer());
99 ExpectInt("channels", test_params_
.channels());
100 ExpectInt("input_channels", test_params_
.input_channels());
101 ExpectString("effects", "ECHO_CANCELLER | DUCKING");
102 ExpectString("device_id", kTestDeviceID
);
103 ExpectInt("component_id", kTestComponentID
);
104 ExpectInt("component_type", test_component_
);
105 ExpectStatus("created");
107 // Verify OnStarted().
108 audio_log_
->OnStarted(kTestComponentID
);
109 base::RunLoop().RunUntilIdle();
110 ExpectStatus("started");
112 // Verify OnStopped().
113 audio_log_
->OnStopped(kTestComponentID
);
114 base::RunLoop().RunUntilIdle();
115 ExpectStatus("stopped");
118 const char kErrorKey
[] = "error_occurred";
119 std::string no_value
;
120 ASSERT_FALSE(update_data_
.GetString(kErrorKey
, &no_value
));
121 audio_log_
->OnError(kTestComponentID
);
122 base::RunLoop().RunUntilIdle();
123 ExpectString(kErrorKey
, "true");
125 // Verify OnClosed().
126 audio_log_
->OnClosed(kTestComponentID
);
127 base::RunLoop().RunUntilIdle();
128 ExpectStatus("closed");
131 TEST_P(MediaInternalsTest
, AudioLogCreateClose
) {
132 audio_log_
->OnCreated(
133 kTestComponentID
, test_params_
, kTestDeviceID
);
134 base::RunLoop().RunUntilIdle();
135 ExpectStatus("created");
137 audio_log_
->OnClosed(kTestComponentID
);
138 base::RunLoop().RunUntilIdle();
139 ExpectStatus("closed");
142 INSTANTIATE_TEST_CASE_P(
143 MediaInternalsTest
, MediaInternalsTest
, testing::Values(
144 media::AudioLogFactory::AUDIO_INPUT_CONTROLLER
,
145 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER
,
146 media::AudioLogFactory::AUDIO_OUTPUT_STREAM
));
148 } // namespace content