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 17namespace { 18const int kTestComponentID = 0; 19const char kTestDeviceID[] = "test-device-id"; 20} // namespace 21 22namespace content { 23 24class MediaInternalsTest 25 : public testing::TestWithParam<media::AudioLogFactory::AudioComponent> { 26 public: 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 48000, 34 16, 35 128, 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_); 41 } 42 43 virtual ~MediaInternalsTest() { 44 media_internals_->RemoveUpdateCallback(update_cb_); 45 } 46 47 protected: 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))); 57 CHECK(output_value); 58 59 base::DictionaryValue* output_dict = NULL; 60 CHECK(output_value->GetAsDictionary(&output_dict)); 61 update_data_.MergeDictionary(output_dict); 62 } 63 64 void ExpectInt(const std::string& key, int expected_value) { 65 int actual_value = 0; 66 ASSERT_TRUE(update_data_.GetInteger(key, &actual_value)); 67 EXPECT_EQ(expected_value, actual_value); 68 } 69 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); 74 } 75 76 void ExpectStatus(const std::string& expected_value) { 77 ExpectString("status", expected_value); 78 } 79 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_; 87}; 88 89TEST_P(MediaInternalsTest, AudioLogCreateStartStopErrorClose) { 90 audio_log_->OnCreated( 91 kTestComponentID, test_params_, kTestDeviceID); 92 base::RunLoop().RunUntilIdle(); 93 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"); 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 129TEST_P(MediaInternalsTest, AudioLogCreateClose) { 130 audio_log_->OnCreated( 131 kTestComponentID, test_params_, kTestDeviceID); 132 base::RunLoop().RunUntilIdle(); 133 ExpectStatus("created"); 134 135 audio_log_->OnClosed(kTestComponentID); 136 base::RunLoop().RunUntilIdle(); 137 ExpectStatus("closed"); 138} 139 140INSTANTIATE_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