• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/media/media_internals.h"
6 
7 #include "base/bind.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"
16 
17 namespace {
18 const int kTestComponentID = 0;
19 const char kTestDeviceID[] = "test-device-id";
20 }  // namespace
21 
22 namespace content {
23 
24 class MediaInternalsTest
25     : public testing::TestWithParam<media::AudioLogFactory::AudioComponent> {
26  public:
MediaInternalsTest()27   MediaInternalsTest()
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,
33                      0,
34                      48000,
35                      16,
36                      128,
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_);
42   }
43 
~MediaInternalsTest()44   virtual ~MediaInternalsTest() {
45     media_internals_->RemoveUpdateCallback(update_cb_);
46   }
47 
48  protected:
49   // Extracts and deserializes the JSON update data; merges into |update_data_|.
UpdateCallbackImpl(const base::string16 & update)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)));
58     CHECK(output_value);
59 
60     base::DictionaryValue* output_dict = NULL;
61     CHECK(output_value->GetAsDictionary(&output_dict));
62     update_data_.MergeDictionary(output_dict);
63   }
64 
ExpectInt(const std::string & key,int expected_value)65   void ExpectInt(const std::string& key, int expected_value) {
66     int actual_value = 0;
67     ASSERT_TRUE(update_data_.GetInteger(key, &actual_value));
68     EXPECT_EQ(expected_value, actual_value);
69   }
70 
ExpectString(const std::string & key,const std::string & expected_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);
75   }
76 
ExpectStatus(const std::string & expected_value)77   void ExpectStatus(const std::string& expected_value) {
78     ExpectString("status", expected_value);
79   }
80 
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_;
88 };
89 
TEST_P(MediaInternalsTest,AudioLogCreateStartStopErrorClose)90 TEST_P(MediaInternalsTest, AudioLogCreateStartStopErrorClose) {
91   audio_log_->OnCreated(
92       kTestComponentID, test_params_, kTestDeviceID);
93   base::RunLoop().RunUntilIdle();
94 
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");
106 
107   // Verify OnStarted().
108   audio_log_->OnStarted(kTestComponentID);
109   base::RunLoop().RunUntilIdle();
110   ExpectStatus("started");
111 
112   // Verify OnStopped().
113   audio_log_->OnStopped(kTestComponentID);
114   base::RunLoop().RunUntilIdle();
115   ExpectStatus("stopped");
116 
117   // Verify OnError().
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");
124 
125   // Verify OnClosed().
126   audio_log_->OnClosed(kTestComponentID);
127   base::RunLoop().RunUntilIdle();
128   ExpectStatus("closed");
129 }
130 
TEST_P(MediaInternalsTest,AudioLogCreateClose)131 TEST_P(MediaInternalsTest, AudioLogCreateClose) {
132   audio_log_->OnCreated(
133       kTestComponentID, test_params_, kTestDeviceID);
134   base::RunLoop().RunUntilIdle();
135   ExpectStatus("created");
136 
137   audio_log_->OnClosed(kTestComponentID);
138   base::RunLoop().RunUntilIdle();
139   ExpectStatus("closed");
140 }
141 
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));
147 
148 }  // namespace content
149