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 kTestInputDeviceID[] = "test-input-id"; 20 const char kTestOutputDeviceID[] = "test-output-id"; 21 } // namespace 22 23 namespace content { 24 25 class MediaInternalsTest 26 : public testing::TestWithParam<media::AudioLogFactory::AudioComponent> { 27 public: 28 MediaInternalsTest() 29 : media_internals_(MediaInternals::GetInstance()), 30 update_cb_(base::Bind(&MediaInternalsTest::UpdateCallbackImpl, 31 base::Unretained(this))), 32 test_params_(media::AudioParameters::AUDIO_PCM_LINEAR, 33 media::CHANNEL_LAYOUT_MONO, 34 48000, 35 16, 36 128), 37 test_component_(GetParam()), 38 audio_log_(media_internals_->CreateAudioLog(test_component_)) { 39 media_internals_->AddUpdateCallback(update_cb_); 40 } 41 42 virtual ~MediaInternalsTest() { 43 media_internals_->RemoveUpdateCallback(update_cb_); 44 } 45 46 protected: 47 // Extracts and deserializes the JSON update data; merges into |update_data_|. 48 void UpdateCallbackImpl(const base::string16& update) { 49 // Each update string looks like "<JavaScript Function Name>({<JSON>});", to 50 // use the JSON reader we need to strip out the JavaScript code. 51 std::string utf8_update = base::UTF16ToUTF8(update); 52 const std::string::size_type first_brace = utf8_update.find('{'); 53 const std::string::size_type last_brace = utf8_update.rfind('}'); 54 scoped_ptr<base::Value> output_value(base::JSONReader::Read( 55 utf8_update.substr(first_brace, last_brace - first_brace + 1))); 56 CHECK(output_value); 57 58 base::DictionaryValue* output_dict = NULL; 59 CHECK(output_value->GetAsDictionary(&output_dict)); 60 update_data_.MergeDictionary(output_dict); 61 } 62 63 void ExpectInt(const std::string& key, int expected_value) { 64 int actual_value = 0; 65 ASSERT_TRUE(update_data_.GetInteger(key, &actual_value)); 66 EXPECT_EQ(expected_value, actual_value); 67 } 68 69 void ExpectString(const std::string& key, const std::string& expected_value) { 70 std::string actual_value; 71 ASSERT_TRUE(update_data_.GetString(key, &actual_value)); 72 EXPECT_EQ(expected_value, actual_value); 73 } 74 75 void ExpectStatus(const std::string& expected_value) { 76 ExpectString("status", expected_value); 77 } 78 79 TestBrowserThreadBundle thread_bundle_; 80 MediaInternals* const media_internals_; 81 MediaInternals::UpdateCallback update_cb_; 82 base::DictionaryValue update_data_; 83 const media::AudioParameters test_params_; 84 const media::AudioLogFactory::AudioComponent test_component_; 85 scoped_ptr<media::AudioLog> audio_log_; 86 }; 87 88 TEST_P(MediaInternalsTest, AudioLogCreateStartStopErrorClose) { 89 audio_log_->OnCreated( 90 kTestComponentID, test_params_, kTestInputDeviceID, kTestOutputDeviceID); 91 base::RunLoop().RunUntilIdle(); 92 93 ExpectString("channel_layout", 94 media::ChannelLayoutToString(test_params_.channel_layout())); 95 ExpectInt("sample_rate", test_params_.sample_rate()); 96 ExpectInt("frames_per_buffer", test_params_.frames_per_buffer()); 97 ExpectInt("channels", test_params_.channels()); 98 ExpectInt("input_channels", test_params_.input_channels()); 99 ExpectString("output_device_id", kTestOutputDeviceID); 100 ExpectString("input_device_id", kTestInputDeviceID); 101 ExpectInt("component_id", kTestComponentID); 102 ExpectInt("component_type", test_component_); 103 ExpectStatus("created"); 104 105 // Verify OnStarted(). 106 audio_log_->OnStarted(kTestComponentID); 107 base::RunLoop().RunUntilIdle(); 108 ExpectStatus("started"); 109 110 // Verify OnStopped(). 111 audio_log_->OnStopped(kTestComponentID); 112 base::RunLoop().RunUntilIdle(); 113 ExpectStatus("stopped"); 114 115 // Verify OnError(). 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"); 122 123 // Verify OnClosed(). 124 audio_log_->OnClosed(kTestComponentID); 125 base::RunLoop().RunUntilIdle(); 126 ExpectStatus("closed"); 127 } 128 129 TEST_P(MediaInternalsTest, AudioLogCreateClose) { 130 audio_log_->OnCreated( 131 kTestComponentID, test_params_, kTestInputDeviceID, kTestOutputDeviceID); 132 base::RunLoop().RunUntilIdle(); 133 ExpectStatus("created"); 134 135 audio_log_->OnClosed(kTestComponentID); 136 base::RunLoop().RunUntilIdle(); 137 ExpectStatus("closed"); 138 } 139 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)); 145 146 } // namespace content 147