// Copyright 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Tests for audio device handler.
#include "audio_device_handler_mock.h"
#include <string>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using base::FilePath;
using base::IntToString;
using base::ScopedTempDir;
using base::WriteFile;
using brillo::AudioDeviceHandlerMock;
using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
namespace brillo {
class AudioDeviceHandlerTest : public testing::Test {
public:
void SetUp() override {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
h2w_file_path_ = temp_dir_.path().Append("h2wstate");
}
void TearDown() override { handler_.Reset(); }
// Method to store the current state of the audio jack to a file.
//
// |value| - Value in the h2w file.
void WriteToH2WFile(int value) {
std::string value_string = IntToString(value);
WriteFile(h2w_file_path_, value_string.c_str(), value_string.length());
}
AudioDeviceHandlerMock handler_;
FilePath h2w_file_path_;
private:
ScopedTempDir temp_dir_;
};
// Test that DisconnectAllSupportedDevices() calls NotifyAudioPolicyService()
// the right number of times.
TEST_F(AudioDeviceHandlerTest, DisconnectAllSupportedDevicesCallsDisconnect) {
EXPECT_CALL(handler_,
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)).Times(3);
handler_.DisconnectAllSupportedDevices();
EXPECT_EQ(handler_.changed_devices_.size(), 3);
}
// Test that Init() calls DisconnectAllSupportedDevices().
TEST_F(AudioDeviceHandlerTest, InitCallsDisconnectAllSupportedDevices) {
EXPECT_CALL(handler_,
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)).Times(3);
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesDisconnected))
.Times(AtLeast(1));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_AVAILABLE)).Times(AnyNumber());
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected))
.Times(AnyNumber());
handler_.Init(nullptr);
}
// Test GetInitialAudioDeviceState() with just a microphone.
TEST_F(AudioDeviceHandlerTest, InitialAudioStateMic) {
WriteToH2WFile(2);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_IN_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
handler_.GetInitialAudioDeviceState(h2w_file_path_);
EXPECT_NE(
handler_.connected_input_devices_.find(AUDIO_DEVICE_IN_WIRED_HEADSET),
handler_.connected_input_devices_.end());
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], AUDIO_DEVICE_IN_WIRED_HEADSET);
}
// Test GetInitialAudioDeviceState() with a headphone.
TEST_F(AudioDeviceHandlerTest, InitialAudioStateHeadphone) {
WriteToH2WFile(1);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
handler_.GetInitialAudioDeviceState(h2w_file_path_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_NE(
handler_.connected_output_devices_.find(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
handler_.connected_output_devices_.end());
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
}
// Test GetInitialAudioDeviceState() with a headset.
TEST_F(AudioDeviceHandlerTest, InitialAudioStateHeadset) {
WriteToH2WFile(3);
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_IN_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
handler_.GetInitialAudioDeviceState(h2w_file_path_);
EXPECT_NE(
handler_.connected_input_devices_.find(AUDIO_DEVICE_IN_WIRED_HEADSET),
handler_.connected_input_devices_.end());
EXPECT_NE(
handler_.connected_output_devices_.find(AUDIO_DEVICE_OUT_WIRED_HEADSET),
handler_.connected_output_devices_.end());
EXPECT_EQ(handler_.changed_devices_.size(), 2);
}
// Test GetInitialAudioDeviceState() without any devices connected to the audio
// jack. No need to call NotifyAudioPolicyService() since that's already handled
// by Init().
TEST_F(AudioDeviceHandlerTest, InitialAudioStateNone) {
WriteToH2WFile(0);
EXPECT_CALL(handler_, TriggerCallback(_));
handler_.GetInitialAudioDeviceState(h2w_file_path_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 0);
}
// Test GetInitialAudioDeviceState() with an invalid file. The audio handler
// should not fail in this case because it should work on boards that don't
// support audio jacks.
TEST_F(AudioDeviceHandlerTest, InitialAudioStateInvalid) {
FilePath path = h2w_file_path_;
handler_.GetInitialAudioDeviceState(h2w_file_path_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
}
// Test ProcessEvent() with an empty input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventEmpty) {
struct input_event event;
event.type = 0;
event.code = 0;
event.value = 0;
EXPECT_CALL(handler_, TriggerCallback(_));
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
}
// Test ProcessEvent() with a microphone present input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventMicrophonePresent) {
struct input_event event;
event.type = EV_SW;
event.code = SW_MICROPHONE_INSERT;
event.value = 1;
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_TRUE(handler_.microphone_);
}
// Test ProcessEvent() with a headphone present input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventHeadphonePresent) {
struct input_event event;
event.type = EV_SW;
event.code = SW_HEADPHONE_INSERT;
event.value = 1;
handler_.ProcessEvent(event);
EXPECT_TRUE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
}
// Test ProcessEvent() with a microphone not present input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventMicrophoneNotPresent) {
struct input_event event;
event.type = EV_SW;
event.code = SW_MICROPHONE_INSERT;
event.value = 0;
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
}
// Test ProcessEvent() with a headphone not preset input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventHeadphoneNotPresent) {
struct input_event event;
event.type = EV_SW;
event.code = SW_HEADPHONE_INSERT;
event.value = 0;
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
}
// Test ProcessEvent() with an unsupported input_event arg.
TEST_F(AudioDeviceHandlerTest, ProcessEventInvalid) {
struct input_event event;
event.type = EV_SW;
event.code = SW_MAX;
event.value = 0;
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
}
// Test UpdateAudioSystem() without any devices connected.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemNone) {
EXPECT_CALL(handler_,
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)).Times(0);
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesDisconnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.changed_devices_.size(), 0);
}
// Test UpdateAudioSystem() when disconnecting a microphone.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectMic) {
audio_devices_t device = AUDIO_DEVICE_IN_WIRED_HEADSET;
handler_.connected_input_devices_.insert(device);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesDisconnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
// Test UpdateAudioSystem() when disconnecting a headphone.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadphone) {
audio_devices_t device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
handler_.connected_output_devices_.insert(device);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesDisconnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
// Test UpdateAudioSystem() when disconnecting a headset & headphones.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadset) {
handler_.connected_input_devices_.insert(AUDIO_DEVICE_IN_WIRED_HEADSET);
handler_.connected_output_devices_.insert(AUDIO_DEVICE_OUT_WIRED_HEADSET);
handler_.connected_output_devices_.insert(AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_IN_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesDisconnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 3);
}
// Test UpdateAudioSystem() when connecting a microphone.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemConnectMic) {
handler_.microphone_ = true;
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_IN_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 1);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], AUDIO_DEVICE_IN_WIRED_HEADSET);
}
// Test UpdateAudioSystem() when connecting a headphone.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadphone) {
handler_.headphone_ = true;
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
}
// Test UpdateAudioSystem() when connecting a headset.
TEST_F(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadset) {
handler_.headphone_ = true;
handler_.microphone_ = true;
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_IN_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_,
NotifyAudioPolicyService(AUDIO_DEVICE_OUT_WIRED_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
EXPECT_CALL(handler_, TriggerCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected));
handler_.UpdateAudioSystem(handler_.headphone_, handler_.microphone_);
EXPECT_EQ(handler_.connected_input_devices_.size(), 1);
EXPECT_EQ(handler_.connected_output_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_.size(), 2);
}
// Test ConnectAudioDevice() with an input device.
TEST_F(AudioDeviceHandlerTest, ConnectAudioDeviceInput) {
audio_devices_t device = AUDIO_DEVICE_IN_WIRED_HEADSET;
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
handler_.ConnectAudioDevice(device);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_NE(
handler_.connected_input_devices_.find(device),
handler_.connected_input_devices_.end());
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
// Test ConnectAudioDevice() with an output device.
TEST_F(AudioDeviceHandlerTest, ConnectAudioDeviceOutput) {
audio_devices_t device = AUDIO_DEVICE_OUT_WIRED_HEADSET;
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
handler_.ConnectAudioDevice(device);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_NE(
handler_.connected_output_devices_.find(device),
handler_.connected_output_devices_.end());
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
// Test DisconnectAudioDevice() with an input device.
TEST_F(AudioDeviceHandlerTest, DisconnectAudioDeviceInput) {
audio_devices_t device = AUDIO_DEVICE_IN_WIRED_HEADSET;
handler_.connected_input_devices_.insert(device);
handler_.connected_output_devices_.insert(device);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
handler_.DisconnectAudioDevice(device);
EXPECT_EQ(handler_.connected_input_devices_.size(), 0);
EXPECT_EQ(handler_.connected_output_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
// Test DisconnectAudioDevice() with an output device.
TEST_F(AudioDeviceHandlerTest, DisconnectAudioDeviceOutput) {
audio_devices_t device = AUDIO_DEVICE_OUT_WIRED_HEADSET;
handler_.connected_input_devices_.insert(device);
handler_.connected_output_devices_.insert(device);
EXPECT_CALL(handler_,
NotifyAudioPolicyService(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
handler_.DisconnectAudioDevice(device);
EXPECT_EQ(handler_.connected_input_devices_.size(), 1);
EXPECT_EQ(handler_.connected_output_devices_.size(), 0);
EXPECT_EQ(handler_.changed_devices_.size(), 1);
EXPECT_EQ(handler_.changed_devices_[0], device);
}
} // namespace brillo