Home | History | Annotate | Download | only in media
      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