upload android base code part6

This commit is contained in:
August 2018-08-08 17:48:24 +08:00
parent 421e214c7d
commit 4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions

View file

@ -0,0 +1,109 @@
# 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.
LOCAL_PATH := $(call my-dir)
audio_service_shared_libraries := \
libbinder \
libbinderwrapper \
libbrillo \
libbrillo-binder \
libc \
libchrome \
libaudioclient \
libutils
audio_client_sources := \
aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl \
aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl \
audio_service_callback.cpp \
brillo_audio_client.cpp \
brillo_audio_client_helpers.cpp \
brillo_audio_device_info.cpp \
brillo_audio_device_info_internal.cpp \
brillo_audio_manager.cpp
audio_service_sources := \
aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl \
aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl \
audio_daemon.cpp \
audio_device_handler.cpp \
audio_volume_handler.cpp \
brillo_audio_service_impl.cpp
# Audio service.
# =============================================================================
include $(CLEAR_VARS)
LOCAL_MODULE := brilloaudioservice
LOCAL_SRC_FILES := \
$(audio_service_sources) \
main_audio_service.cpp
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_SHARED_LIBRARIES := $(audio_service_shared_libraries)
LOCAL_CFLAGS := -Werror -Wall
LOCAL_INIT_RC := brilloaudioserv.rc
include $(BUILD_EXECUTABLE)
# Audio client library.
# =============================================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libbrilloaudio
LOCAL_SRC_FILES := \
$(audio_client_sources)
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_SHARED_LIBRARIES := $(audio_service_shared_libraries)
LOCAL_CFLAGS := -Wall -Werror -std=c++14
include $(BUILD_SHARED_LIBRARY)
# Unit tests for the Brillo audio service.
# =============================================================================
include $(CLEAR_VARS)
LOCAL_MODULE := brilloaudioservice_test
LOCAL_SRC_FILES := \
$(audio_service_sources) \
test/audio_daemon_test.cpp \
test/audio_device_handler_test.cpp \
test/audio_volume_handler_test.cpp
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_SHARED_LIBRARIES := \
$(audio_service_shared_libraries)
LOCAL_STATIC_LIBRARIES := \
libBionicGtestMain \
libbinderwrapper_test_support \
libchrome_test_helpers \
libgmock
LOCAL_CFLAGS := -Werror -Wall
LOCAL_CFLAGS += -Wno-sign-compare
include $(BUILD_NATIVE_TEST)
# Unit tests for the Brillo audio client.
# =============================================================================
include $(CLEAR_VARS)
LOCAL_MODULE := brilloaudioclient_test
LOCAL_SRC_FILES := \
$(audio_client_sources) \
test/audio_service_callback_test.cpp \
test/brillo_audio_client_test.cpp \
test/brillo_audio_device_info_internal_test.cpp \
test/brillo_audio_manager_test.cpp
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_SHARED_LIBRARIES := \
$(audio_service_shared_libraries)
LOCAL_STATIC_LIBRARIES := \
libBionicGtestMain \
libbinderwrapper_test_support \
libchrome_test_helpers \
libgmock
LOCAL_CFLAGS := -Wno-sign-compare -Wall -Werror
include $(BUILD_NATIVE_TEST)

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 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.
*/
package android.brillo.brilloaudioservice;
/*
* Interface for the callback object registered with IBrilloAudioService. Used
* to notify clients about changes to the audio system.
*/
interface IAudioServiceCallback {
// Oneway call triggered when audio devices are connected to the system.
oneway void OnAudioDevicesConnected(in int[] added_devices);
// Oneway call triggered when audio devices are disconnected from the system.
oneway void OnAudioDevicesDisconnected(in int[] removed_devices);
// Oneway call triggered when the volume is changed. If there are
// multiple active streams, this call will be called multiple times.
oneway void OnVolumeChanged(
int stream_type, int old_volume_index, int new_volume_index);
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 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.
*/
package android.brillo.brilloaudioservice;
import android.brillo.brilloaudioservice.IAudioServiceCallback;
/*
* Interface for BrilloAudioService that clients can use to get the list of
* devices currently connected to the system as well as to control volume.
* Clients can also register callbacks to be notified about changes.
*/
interface IBrilloAudioService {
// Constants for device enumeration.
const int GET_DEVICES_INPUTS = 1;
const int GET_DEVICES_OUTPUTS = 2;
// Constants for volume control.
const int VOLUME_BUTTON_PRESS_DOWN = 1;
const int VOLUME_BUTTON_PRESS_UP = 2;
// Get the list of devices connected. If flag is GET_DEVICES_INPUTS, then
// return input devices. Otherwise, return output devices.
int[] GetDevices(int flag);
// Set device for a given usage.
// usage is an int of type audio_policy_force_use_t.
// config is an int of type audio_policy_forced_cfg_t.
void SetDevice(int usage, int config);
// Get the maximum number of steps used for a given stream.
int GetMaxVolumeSteps(int stream);
// Set the maximum number of steps to use for a given stream.
void SetMaxVolumeSteps(int stream, int max_steps);
// Set the volume for a given (stream, device) tuple.
void SetVolumeIndex(int stream, int device, int index);
// Get the current volume for a given (stream, device) tuple.
int GetVolumeIndex(int stream, int device);
// Get stream used when volume buttons are pressed.
int GetVolumeControlStream();
// Set default stream to use when volume buttons are pressed.
void SetVolumeControlStream(int stream);
// Increment volume.
void IncrementVolume();
// Decrement volume.
void DecrementVolume();
// Register a callback object with the service.
void RegisterServiceCallback(IAudioServiceCallback callback);
// Unregister a callback object.
void UnregisterServiceCallback(IAudioServiceCallback callback);
}

View file

@ -0,0 +1,191 @@
// 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.
//
// Implementation of audio_daemon.h.
#include "audio_daemon.h"
#include <sysexits.h>
#include <base/bind.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/time/time.h>
#include <binderwrapper/binder_wrapper.h>
#include <linux/input.h>
#include "brillo_audio_service_impl.h"
namespace brillo {
static const char kAPSServiceName[] = "media.audio_policy";
static const char kInputDeviceDir[] = "/dev/input";
static const char kServiceName[] =
"android.brillo.brilloaudioservice.BrilloAudioService";
AudioDaemon::~AudioDaemon() {}
void AudioDaemon::InitializeHandlers() {
// Start and initialize the audio daemon handlers.
audio_device_handler_ =
std::shared_ptr<AudioDeviceHandler>(new AudioDeviceHandler());
audio_volume_handler_ =
std::unique_ptr<AudioVolumeHandler>(new AudioVolumeHandler());
// Register a callback with the audio device handler to call when device state
// changes.
auto device_callback =
base::Bind(&AudioDaemon::DeviceCallback, weak_ptr_factory_.GetWeakPtr());
audio_device_handler_->RegisterDeviceCallback(device_callback);
// Register a callback with the audio volume handler.
auto volume_callback =
base::Bind(&AudioDaemon::VolumeCallback, weak_ptr_factory_.GetWeakPtr());
audio_volume_handler_->RegisterCallback(volume_callback);
audio_device_handler_->Init(aps_);
audio_volume_handler_->Init(aps_);
// Poll on all files in kInputDeviceDir.
base::FileEnumerator fenum(base::FilePath(kInputDeviceDir),
false /*recursive*/, base::FileEnumerator::FILES);
for (base::FilePath name = fenum.Next(); !name.empty(); name = fenum.Next()) {
base::File file(name, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (file.IsValid()) {
MessageLoop* message_loop = MessageLoop::current();
int fd = file.GetPlatformFile();
// Move file to files_ and ensure that when binding we get a pointer from
// the object in files_.
files_.emplace(std::move(file));
base::Closure file_callback =
base::Bind(&AudioDaemon::EventCallback, weak_ptr_factory_.GetWeakPtr(),
&files_.top());
message_loop->WatchFileDescriptor(fd, MessageLoop::kWatchRead,
true /*persistent*/, file_callback);
} else {
LOG(WARNING) << "Could not open " << name.value() << " for reading. ("
<< base::File::ErrorToString(file.error_details()) << ")";
}
}
handlers_initialized_ = true;
// Once the handlers have been initialized, we can register with service
// manager.
InitializeBrilloAudioService();
}
void AudioDaemon::InitializeBrilloAudioService() {
brillo_audio_service_ = new BrilloAudioServiceImpl();
brillo_audio_service_->RegisterHandlers(
std::weak_ptr<AudioDeviceHandler>(audio_device_handler_),
std::weak_ptr<AudioVolumeHandler>(audio_volume_handler_));
android::BinderWrapper::Get()->RegisterService(kServiceName,
brillo_audio_service_);
VLOG(1) << "Registered brilloaudioservice with the service manager.";
}
void AudioDaemon::ConnectToAPS() {
android::BinderWrapper* binder_wrapper = android::BinderWrapper::Get();
auto binder = binder_wrapper->GetService(kAPSServiceName);
// If we didn't get the audio policy service, try again in 500 ms.
if (!binder.get()) {
LOG(INFO) << "Could not connect to audio policy service. Trying again...";
brillo::MessageLoop::current()->PostDelayedTask(
base::Bind(&AudioDaemon::ConnectToAPS, weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(500));
return;
}
LOG(INFO) << "Connected to audio policy service.";
binder_wrapper->RegisterForDeathNotifications(
binder,
base::Bind(&AudioDaemon::OnAPSDisconnected,
weak_ptr_factory_.GetWeakPtr()));
VLOG(1) << "Registered death notification.";
aps_ = android::interface_cast<android::IAudioPolicyService>(binder);
if (!handlers_initialized_) {
InitializeHandlers();
} else {
audio_device_handler_->APSConnect(aps_);
audio_volume_handler_->APSConnect(aps_);
}
}
void AudioDaemon::OnAPSDisconnected() {
LOG(INFO) << "Audio policy service died. Will try to reconnect.";
audio_device_handler_->APSDisconnect();
audio_volume_handler_->APSDisconnect();
aps_ = nullptr;
ConnectToAPS();
}
// OnInit, we want to do the following:
// - Get a binder to the audio policy service.
// - Initialize the audio device and volume handlers.
// - Set up polling on files in /dev/input.
int AudioDaemon::OnInit() {
int exit_code = Daemon::OnInit();
if (exit_code != EX_OK) return exit_code;
// Initialize a binder wrapper.
android::BinderWrapper::Create();
// Initialize a binder watcher.
binder_watcher_.Init();
ConnectToAPS();
return EX_OK;
}
void AudioDaemon::EventCallback(base::File* file) {
input_event event;
int bytes_read =
file->ReadAtCurrentPos(reinterpret_cast<char*>(&event), sizeof(event));
if (bytes_read != sizeof(event)) {
LOG(WARNING) << "Couldn't read an input event.";
return;
}
audio_device_handler_->ProcessEvent(event);
audio_volume_handler_->ProcessEvent(event);
}
void AudioDaemon::DeviceCallback(
AudioDeviceHandler::DeviceConnectionState state,
const std::vector<int>& devices) {
VLOG(1) << "Triggering device callback.";
if (!brillo_audio_service_.get()) {
LOG(ERROR) << "The Brillo audio service object is unavailble. Will try to "
<< "call the clients again once the service is up.";
InitializeBrilloAudioService();
DeviceCallback(state, devices);
return;
}
if (state == AudioDeviceHandler::DeviceConnectionState::kDevicesConnected)
brillo_audio_service_->OnDevicesConnected(devices);
else
brillo_audio_service_->OnDevicesDisconnected(devices);
}
void AudioDaemon::VolumeCallback(audio_stream_type_t stream,
int previous_index,
int current_index) {
VLOG(1) << "Triggering volume button press callback.";
if (!brillo_audio_service_.get()) {
LOG(ERROR) << "The Brillo audio service object is unavailble. Will try to "
<< "call the clients again once the service is up.";
InitializeBrilloAudioService();
VolumeCallback(stream, previous_index, current_index);
return;
}
brillo_audio_service_->OnVolumeChanged(stream, previous_index, current_index);
}
} // namespace brillo

View file

@ -0,0 +1,112 @@
// 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.
//
// Main loop of the brillo audio service.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_H_
#define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_H_
#include <memory>
#include <stack>
#include <vector>
#include <base/files/file.h>
#include <base/memory/weak_ptr.h>
#include <brillo/binder_watcher.h>
#include <brillo/daemons/daemon.h>
#include <media/IAudioPolicyService.h>
#include "audio_device_handler.h"
#include "audio_volume_handler.h"
#include "brillo_audio_service.h"
namespace brillo {
class AudioDaemon : public Daemon {
public:
AudioDaemon() {}
virtual ~AudioDaemon();
protected:
// Initialize the audio daemon handlers and start pollig the files in
// /dev/input.
int OnInit() override;
private:
friend class AudioDaemonTest;
FRIEND_TEST(AudioDaemonTest, RegisterService);
FRIEND_TEST(AudioDaemonTest, TestAPSConnectInitializesHandlersOnlyOnce);
FRIEND_TEST(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL);
// Callback function for input events. Events are handled by the audio device
// handler.
void EventCallback(base::File* file);
// Callback function for device state changes. Events are handler by the
// audio service.
//
// |mode| is kDevicesConnected when |devices| are connected.
// |devices| is a vector of integers representing audio_devices_t.
void DeviceCallback(AudioDeviceHandler::DeviceConnectionState,
const std::vector<int>& devices);
// Callback function when volume changes.
//
// |stream| is an audio_stream_type_t representing the stream.
// |previous_index| is the volume index before the key press.
// |current_index| is the volume index after the key press.
void VolumeCallback(audio_stream_type_t stream,
int previous_index,
int current_index);
// Callback function for audio policy service death notification.
void OnAPSDisconnected();
// Connect to the audio policy service and register a callback to be invoked
// if the audio policy service dies.
void ConnectToAPS();
// Register the brillo audio service with the service manager.
void InitializeBrilloAudioService();
// Initialize all audio daemon handlers.
//
// Note: This can only occur after we have connected to the audio policy
// service.
virtual void InitializeHandlers();
// Store the file objects that are created during initialization for the files
// being polled. This is done so these objects can be freed when the
// AudioDaemon object is destroyed.
std::stack<base::File> files_;
// Handler for audio device input events.
std::shared_ptr<AudioDeviceHandler> audio_device_handler_;
// Handler for volume key press input events.
std::shared_ptr<AudioVolumeHandler> audio_volume_handler_;
// Used to generate weak_ptr to AudioDaemon for use in base::Bind.
base::WeakPtrFactory<AudioDaemon> weak_ptr_factory_{this};
// Pointer to the audio policy service.
android::sp<android::IAudioPolicyService> aps_;
// Flag to indicate whether the handlers have been initialized.
bool handlers_initialized_ = false;
// Binder watcher to watch for binder messages.
BinderWatcher binder_watcher_;
// Brillo audio service. Used for scheduling callbacks to clients.
android::sp<BrilloAudioService> brillo_audio_service_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_H_

View file

@ -0,0 +1,58 @@
// 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.
//
// Handler for input events in /dev/input. AudioDaemonHandler is the base class
// that other handlers inherit.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_HANDLER_H_
#define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_HANDLER_H_
#include <linux/input.h>
#include <media/IAudioPolicyService.h>
namespace brillo {
class AudioDaemonHandler {
public:
virtual ~AudioDaemonHandler(){};
// Initialize the handler.
//
// |aps| is a pointer to the binder object.
virtual void Init(android::sp<android::IAudioPolicyService> aps) = 0;
// Process input events from the kernel.
//
// |event| is a pointer to an input_event. This function should be able to
// gracefully handle input events that are not relevant to the functionality
// provided by this class.
virtual void ProcessEvent(const struct input_event& event) = 0;
// Inform the handler that the audio policy service has been disconnected.
virtual void APSDisconnect() = 0;
// Inform the handler that the audio policy service is reconnected.
//
// |aps| is a pointer to the binder object.
virtual void APSConnect(android::sp<android::IAudioPolicyService> aps) = 0;
protected:
// Pointer to the audio policy service.
android::sp<android::IAudioPolicyService> aps_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DAEMON_HANDLER_H_

View file

@ -0,0 +1,233 @@
// 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.
//
// Implementation of audio_device_handler.h
#include "audio_device_handler.h"
#include <base/files/file.h>
#include <base/logging.h>
#include <brillo/message_loops/message_loop.h>
#include <media/AudioSystem.h>
namespace brillo {
// All input devices currently supported by AudioDeviceHandler.
const std::vector<audio_devices_t> AudioDeviceHandler::kSupportedInputDevices_ =
{AUDIO_DEVICE_IN_WIRED_HEADSET};
const std::vector<audio_devices_t>
AudioDeviceHandler::kSupportedOutputDevices_ = {
AUDIO_DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADPHONE};
static const char kH2WStateFile[] = "/sys/class/switch/h2w/state";
AudioDeviceHandler::AudioDeviceHandler() {
headphone_ = false;
microphone_ = false;
}
AudioDeviceHandler::~AudioDeviceHandler() {}
void AudioDeviceHandler::GetInputDevices(std::vector<int>* devices_list) {
std::copy(connected_input_devices_.begin(),
connected_input_devices_.end(),
std::back_inserter(*devices_list));
}
void AudioDeviceHandler::GetOutputDevices(std::vector<int>* devices_list) {
std::copy(connected_output_devices_.begin(),
connected_output_devices_.end(),
std::back_inserter(*devices_list));
}
void AudioDeviceHandler::RegisterDeviceCallback(
base::Callback<void(DeviceConnectionState,
const std::vector<int>& )>& callback) {
callback_ = callback;
}
void AudioDeviceHandler::TriggerCallback(DeviceConnectionState state) {
// If no devices have changed, don't bother triggering a callback.
if (changed_devices_.size() == 0)
return;
base::Closure closure = base::Bind(callback_, state, changed_devices_);
MessageLoop::current()->PostTask(closure);
// We can clear changed_devices_ here since base::Bind makes a copy of
// changed_devices_.
changed_devices_.clear();
}
void AudioDeviceHandler::APSDisconnect() {
aps_.clear();
}
void AudioDeviceHandler::APSConnect(
android::sp<android::IAudioPolicyService> aps) {
aps_ = aps;
// Reset the state
connected_input_devices_.clear();
connected_output_devices_.clear();
// Inform audio policy service about the currently connected devices.
VLOG(1) << "Calling GetInitialAudioDeviceState on APSConnect.";
GetInitialAudioDeviceState(base::FilePath(kH2WStateFile));
}
void AudioDeviceHandler::Init(android::sp<android::IAudioPolicyService> aps) {
aps_ = aps;
// Reset audio policy service state in case this service crashed and there is
// a mismatch between the current system state and what audio policy service
// was previously told.
VLOG(1) << "Calling DisconnectAllSupportedDevices.";
DisconnectAllSupportedDevices();
TriggerCallback(kDevicesDisconnected);
// Get headphone jack state and update audio policy service with new state.
VLOG(1) << "Calling ReadInitialAudioDeviceState.";
GetInitialAudioDeviceState(base::FilePath(kH2WStateFile));
}
void AudioDeviceHandler::GetInitialAudioDeviceState(
const base::FilePath& path) {
base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
LOG(WARNING) << "Kernel does not have wired headset support. Could not "
<< "open " << path.value() << " ("
<< base::File::ErrorToString(file.error_details()) << ").";
return;
}
int state = 0;
int bytes_read = file.ReadAtCurrentPos(reinterpret_cast<char*>(&state), 1);
state -= '0';
if (bytes_read == 0) {
LOG(WARNING) << "Could not read from " << path.value();
return;
}
VLOG(1) << "Initial audio jack state is " << state;
static const int kHeadPhoneMask = 0x1;
bool headphone = state & kHeadPhoneMask;
static const int kMicrophoneMask = 0x2;
bool microphone = (state & kMicrophoneMask) >> 1;
UpdateAudioSystem(headphone, microphone);
}
void AudioDeviceHandler::NotifyAudioPolicyService(
audio_devices_t device, audio_policy_dev_state_t state) {
if (aps_ == nullptr) {
LOG(INFO) << "Audio device handler cannot call audio policy service. Will "
<< "try again later.";
return;
}
VLOG(1) << "Calling Audio Policy Service to change " << device << " to state "
<< state;
aps_->setDeviceConnectionState(device, state, "", "");
}
int AudioDeviceHandler::SetDevice(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) {
if (aps_ == nullptr) {
LOG(WARNING) << "Audio policy service cannot be reached. Please try again.";
return EAGAIN;
}
VLOG(1) << "Calling audio policy service to set " << usage << " to "
<< config;
return aps_->setForceUse(usage, config);
}
void AudioDeviceHandler::ConnectAudioDevice(audio_devices_t device) {
audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
NotifyAudioPolicyService(device, state);
if (audio_is_input_device(device))
connected_input_devices_.insert(device);
else
connected_output_devices_.insert(device);
changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAudioDevice(audio_devices_t device) {
audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
NotifyAudioPolicyService(device, state);
if (audio_is_input_device(device))
connected_input_devices_.erase(device);
else
connected_output_devices_.erase(device);
changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAllSupportedDevices() {
for (auto device : kSupportedInputDevices_) {
DisconnectAudioDevice(device);
}
for (auto device : kSupportedOutputDevices_) {
DisconnectAudioDevice(device);
}
}
void AudioDeviceHandler::DisconnectAllConnectedDevices() {
while (!connected_input_devices_.empty()) {
audio_devices_t device = *(connected_input_devices_.begin());
DisconnectAudioDevice(device);
}
while (!connected_output_devices_.empty()) {
audio_devices_t device = *(connected_output_devices_.begin());
DisconnectAudioDevice(device);
}
}
void AudioDeviceHandler::UpdateAudioSystem(bool headphone, bool microphone) {
if (microphone) {
ConnectAudioDevice(AUDIO_DEVICE_IN_WIRED_HEADSET);
}
if (headphone && microphone) {
ConnectAudioDevice(AUDIO_DEVICE_OUT_WIRED_HEADSET);
} else if (headphone) {
ConnectAudioDevice(AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
} else if (!microphone) {
// No devices are connected. Inform the audio policy service that all
// connected devices have been disconnected.
DisconnectAllConnectedDevices();
TriggerCallback(kDevicesDisconnected);
return;
}
TriggerCallback(kDevicesConnected);
return;
}
void AudioDeviceHandler::ProcessEvent(const struct input_event& event) {
VLOG(1) << event.type << " " << event.code << " " << event.value;
if (event.type == EV_SW) {
switch (event.code) {
case SW_HEADPHONE_INSERT:
headphone_ = event.value;
break;
case SW_MICROPHONE_INSERT:
microphone_ = event.value;
break;
default:
// This event code is not supported by this handler.
break;
}
} else if (event.type == EV_SYN) {
// We have received all input events. Update the audio system.
UpdateAudioSystem(headphone_, microphone_);
// Reset the headphone and microphone flags that are used to track
// information across multiple calls to ProcessEvent.
headphone_ = false;
microphone_ = false;
}
}
} // namespace brillo

View file

@ -0,0 +1,201 @@
// 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.
//
// Handler for input events in /dev/input. AudioDeviceHandler handles events
// only for audio devices being plugged in/removed from the system. Implements
// some of the functionality present in WiredAccessoryManager.java.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_
#define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_
#include <set>
#include <vector>
#include <base/bind.h>
#include <base/files/file_path.h>
#include <gtest/gtest_prod.h>
#include <linux/input.h>
#include <media/IAudioPolicyService.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include "audio_daemon_handler.h"
namespace brillo {
class AudioDeviceHandler : public AudioDaemonHandler {
public:
AudioDeviceHandler();
virtual ~AudioDeviceHandler();
// Get the current state of the headset jack and update AudioSystem based on
// the initial state.
//
// |aps| is a pointer to the binder object.
virtual void Init(android::sp<android::IAudioPolicyService> aps) override;
// Process input events from the kernel. Connecting/disconnecting an audio
// device will result in multiple calls to this method.
//
// |event| is a pointer to an input_event. This function should be able to
// gracefully handle input events that are not relevant to the functionality
// provided by this class.
virtual void ProcessEvent(const struct input_event& event) override;
// Inform the handler that the audio policy service has been disconnected.
void APSDisconnect();
// Inform the handler that the audio policy service is reconnected.
//
// |aps| is a pointer to the binder object.
virtual void APSConnect(
android::sp<android::IAudioPolicyService> aps) override;
// Get the list of connected devices.
//
// |devices_list| is the vector to copy list of connected input devices to.
void GetInputDevices(std::vector<int>* devices_list);
// Get the list of connected output devices.
//
// |devices_list| is the vector to copy the list of connected output devices
// to.
void GetOutputDevices(std::vector<int>* devices_list);
// Set device.
//
// |usage| is an int of type audio_policy_force_use_t
// |config| is an int of type audio_policy_forced_cfg_t.
//
// Returns 0 on sucess and errno on failure.
int SetDevice(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
// Enum used to represent whether devices are being connected or not. This is
// used when triggering callbacks.
enum DeviceConnectionState {
kDevicesConnected,
kDevicesDisconnected
};
// Register a callback function to call when device state changes.
//
// |callback| is an object of type base::Callback that accepts a
// DeviceConnectionState and a vector of ints. See DeviceCallback() in
// audio_daemon.h.
void RegisterDeviceCallback(
base::Callback<void(DeviceConnectionState,
const std::vector<int>& )>& callback);
private:
friend class AudioDeviceHandlerTest;
friend class AudioVolumeHandler;
friend class AudioVolumeHandlerTest;
FRIEND_TEST(AudioDeviceHandlerTest,
DisconnectAllSupportedDevicesCallsDisconnect);
FRIEND_TEST(AudioDeviceHandlerTest, InitCallsDisconnectAllSupportedDevices);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateMic);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateNone);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateInvalid);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventEmpty);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophonePresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphonePresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophoneNotPresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphoneNotPresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventInvalid);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemNone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectMic);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectMic);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceInput);
FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceOutput);
FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceInput);
FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceOutput);
FRIEND_TEST(AudioVolumeHandlerTest, FileGeneration);
// Read the initial state of audio devices in /sys/class/* and update
// the audio policy service.
//
// |path| is the file that contains the initial audio jack state.
void GetInitialAudioDeviceState(const base::FilePath& path);
// Update the audio policy service once an input_event has completed.
//
// |headphone| is true is headphones are connected.
// |microphone| is true is microphones are connected.
void UpdateAudioSystem(bool headphone, bool microphone);
// Notify the audio policy service that this device has been removed.
//
// |device| is the audio device whose state is to be changed.
// |state| is the current state of |device|.
virtual void NotifyAudioPolicyService(audio_devices_t device,
audio_policy_dev_state_t state);
// Connect an audio device by calling aps and add it to the appropriate set
// (either connected_input_devices_ or connected_output_devices_).
//
// |device| is the audio device that has been added.
void ConnectAudioDevice(audio_devices_t device);
// Disconnect an audio device by calling aps and remove it from the
// appropriate set (either connected_input_devices_ or
// connected_output_devices_).
//
// |device| is the audio device that has been disconnected.
void DisconnectAudioDevice(audio_devices_t device);
// Disconnected all connected audio devices.
void DisconnectAllConnectedDevices();
// Disconnect all supported audio devices.
void DisconnectAllSupportedDevices();
// Trigger a callback when a device is either connected or disconnected.
//
// |state| is kDevicesConnected when |devices| are being connected.
virtual void TriggerCallback(DeviceConnectionState state);
// All input devices currently supported by AudioDeviceHandler.
static const std::vector<audio_devices_t> kSupportedInputDevices_;
// All output devices currently supported by AudioDeviceHandler.
static const std::vector<audio_devices_t> kSupportedOutputDevices_;
protected:
// Set of connected input devices.
std::set<audio_devices_t> connected_input_devices_;
// Set of connected output devices.
std::set<audio_devices_t> connected_output_devices_;
// Vector of devices changed (used for callbacks to clients).
std::vector<int> changed_devices_;
// Keeps track of whether a headphone has been connected. Used by ProcessEvent
// and UpdateAudioSystem.
bool headphone_;
// Keeps track of whether a microphone has been connected. Used by
// ProcessEvent and UpdateAudioSystem.
bool microphone_;
// Callback object to call when device state changes.
base::Callback<void(DeviceConnectionState,
const std::vector<int>& )> callback_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_DEVICE_HANDLER_H_

View file

@ -0,0 +1,78 @@
// 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.
//
// Implementation of audio_service_callback.
#include "audio_service_callback.h"
#include <base/bind.h>
#include <base/logging.h>
#include "brillo_audio_client_helpers.h"
#include "brillo_audio_device_info_def.h"
using android::binder::Status;
namespace brillo {
AudioServiceCallback::AudioServiceCallback(const BAudioCallback* callback,
void* user_data) {
connected_callback_ = base::Bind(callback->OnAudioDeviceAdded);
disconnected_callback_ = base::Bind(callback->OnAudioDeviceRemoved);
volume_callback_ = base::Bind(callback->OnVolumeChanged);
user_data_ = user_data;
}
Status AudioServiceCallback::OnAudioDevicesConnected(
const std::vector<int>& devices) {
for (auto device : devices) {
BAudioDeviceInfo device_info;
device_info.internal_ = std::unique_ptr<BAudioDeviceInfoInternal>(
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(device));
connected_callback_.Run(&device_info, user_data_);
}
return Status::ok();
}
Status AudioServiceCallback::OnAudioDevicesDisconnected(
const std::vector<int>& devices) {
for (auto device : devices) {
BAudioDeviceInfo device_info;
device_info.internal_ = std::unique_ptr<BAudioDeviceInfoInternal>(
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(device));
disconnected_callback_.Run(&device_info, user_data_);
}
return Status::ok();
}
Status AudioServiceCallback::OnVolumeChanged(int stream,
int previous_index,
int current_index) {
auto usage = BrilloAudioClientHelpers::GetBAudioUsage(
static_cast<audio_stream_type_t>(stream));
volume_callback_.Run(usage, previous_index, current_index, user_data_);
return Status::ok();
}
bool AudioServiceCallback::Equals(const android::sp<AudioServiceCallback>& callback) {
if (callback->connected_callback_.Equals(connected_callback_) &&
callback->disconnected_callback_.Equals(disconnected_callback_) &&
callback->volume_callback_.Equals(volume_callback_) &&
callback->user_data_ == user_data_)
return true;
return false;
}
} // namespace brillo

View file

@ -0,0 +1,80 @@
// 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.
//
// Callback object to be passed to brilloaudioservice.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_SERVICE_CALLBACK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_SERVICE_CALLBACK_H_
#include <vector>
#include <base/callback.h>
#include <binder/Status.h>
#include "android/brillo/brilloaudioservice/BnAudioServiceCallback.h"
#include "include/brillo_audio_manager.h"
using android::binder::Status;
using android::brillo::brilloaudioservice::BnAudioServiceCallback;
namespace brillo {
class AudioServiceCallback : public BnAudioServiceCallback {
public:
// Constructor for AudioServiceCallback.
//
// |callback| is an object of type BAudioCallback.
// |user_data| is an object to be passed to the callbacks.
AudioServiceCallback(const BAudioCallback* callback, void* user_data);
// Callback function triggered when a device is connected.
//
// |devices| is a vector of audio_devices_t.
Status OnAudioDevicesConnected(const std::vector<int>& devices);
// Callback function triggered when a device is disconnected.
//
// |devices| is a vector of audio_devices_t.
Status OnAudioDevicesDisconnected(const std::vector<int>& devices);
// Callback function triggered when volume is changed.
//
// |stream| is an int representing the stream.
// |previous_index| is the volume index before the key press.
// |current_index| is the volume index after the key press.
Status OnVolumeChanged(int stream, int previous_index, int current_index);
// Method to compare two AudioServiceCallback objects.
//
// |callback| is a ref counted pointer to a AudioServiceCallback object to be
// compared with this.
//
// Returns true if |callback| equals this.
bool Equals(const android::sp<AudioServiceCallback>& callback);
private:
// Callback when devices are connected.
base::Callback<void(const BAudioDeviceInfo*, void*)> connected_callback_;
// Callback when devices are disconnected.
base::Callback<void(const BAudioDeviceInfo*, void*)> disconnected_callback_;
// Callback when the volume button is pressed.
base::Callback<void(BAudioUsage, int, int, void*)> volume_callback_;
// User data passed to the callbacks.
void* user_data_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_SERVICE_CALLBACK_H_

View file

@ -0,0 +1,236 @@
// 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.
//
// Implementation of audio_volume_handler.h
#include "audio_volume_handler.h"
#include <base/files/file.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/map_utils.h>
#include <brillo/message_loops/message_loop.h>
#include <brillo/strings/string_utils.h>
#include "audio_device_handler.h"
namespace brillo {
static const char kVolumeStateFilePath[] =
"/data/misc/brilloaudioservice/volume.dat";
AudioVolumeHandler::AudioVolumeHandler() {
for (auto stream : kSupportedStreams_) {
step_sizes_.emplace(stream, kDefaultStepSize_);
}
selected_stream_ = AUDIO_STREAM_DEFAULT;
volume_state_file_ = base::FilePath(kVolumeStateFilePath);
}
AudioVolumeHandler::~AudioVolumeHandler() {}
void AudioVolumeHandler::APSDisconnect() { aps_.clear(); }
void AudioVolumeHandler::APSConnect(
android::sp<android::IAudioPolicyService> aps) {
aps_ = aps;
InitAPSAllStreams();
}
void AudioVolumeHandler::RegisterCallback(
base::Callback<void(audio_stream_type_t, int, int)>& callback) {
callback_ = callback;
}
int AudioVolumeHandler::ConvertToUserDefinedIndex(audio_stream_type_t stream,
int index) {
return index / step_sizes_[stream];
}
int AudioVolumeHandler::ConvertToInternalIndex(audio_stream_type_t stream,
int index) {
return index * step_sizes_[stream];
}
void AudioVolumeHandler::TriggerCallback(audio_stream_type_t stream,
int previous_index,
int current_index) {
int user_defined_previous_index =
ConvertToUserDefinedIndex(stream, previous_index);
int user_defined_current_index =
ConvertToUserDefinedIndex(stream, current_index);
MessageLoop::current()->PostTask(base::Bind(callback_,
stream,
user_defined_previous_index,
user_defined_current_index));
}
void AudioVolumeHandler::GenerateVolumeFile() {
for (auto stream : kSupportedStreams_) {
for (auto device : AudioDeviceHandler::kSupportedOutputDevices_) {
PersistVolumeConfiguration(stream, device, kDefaultCurrentIndex_);
}
}
if (!kv_store_->Save(volume_state_file_)) {
LOG(ERROR) << "Could not save volume data file!";
}
}
int AudioVolumeHandler::GetVolumeMaxSteps(audio_stream_type_t stream) {
return ConvertToUserDefinedIndex(stream, kMaxIndex_);
}
int AudioVolumeHandler::SetVolumeMaxSteps(audio_stream_type_t stream,
int max_steps) {
if (max_steps <= kMinIndex_ || max_steps > kMaxIndex_)
return EINVAL;
step_sizes_[stream] = kMaxIndex_ / max_steps;
return 0;
}
int AudioVolumeHandler::GetVolumeCurrentIndex(audio_stream_type_t stream,
audio_devices_t device) {
auto key = kCurrentIndexKey_ + "." + string_utils::ToString(stream) + "." +
string_utils::ToString(device);
std::string value;
kv_store_->GetString(key, &value);
return std::stoi(value);
}
int AudioVolumeHandler::GetVolumeIndex(audio_stream_type_t stream,
audio_devices_t device) {
return ConvertToUserDefinedIndex(stream,
GetVolumeCurrentIndex(stream, device));
}
int AudioVolumeHandler::SetVolumeIndex(audio_stream_type_t stream,
audio_devices_t device,
int index) {
if (index < kMinIndex_ ||
index > ConvertToUserDefinedIndex(stream, kMaxIndex_))
return EINVAL;
int previous_index = GetVolumeCurrentIndex(stream, device);
int current_absolute_index = ConvertToInternalIndex(stream, index);
PersistVolumeConfiguration(stream, device, current_absolute_index);
TriggerCallback(stream, previous_index, current_absolute_index);
return 0;
}
void AudioVolumeHandler::PersistVolumeConfiguration(audio_stream_type_t stream,
audio_devices_t device,
int index) {
auto key = kCurrentIndexKey_ + "." + string_utils::ToString(stream) + "." +
string_utils::ToString(device);
kv_store_->SetString(key, string_utils::ToString(index));
kv_store_->Save(volume_state_file_);
}
void AudioVolumeHandler::InitAPSAllStreams() {
for (auto stream : kSupportedStreams_) {
aps_->initStreamVolume(stream, kMinIndex_, kMaxIndex_);
for (auto device : AudioDeviceHandler::kSupportedOutputDevices_) {
int current_index = GetVolumeCurrentIndex(stream, device);
aps_->setStreamVolumeIndex(stream, current_index, device);
}
}
}
void AudioVolumeHandler::SetVolumeFilePathForTesting(
const base::FilePath& path) {
volume_state_file_ = path;
}
void AudioVolumeHandler::Init(android::sp<android::IAudioPolicyService> aps) {
aps_ = aps;
kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore());
if (!base::PathExists(volume_state_file_)) {
// Generate key-value store and save it to a file.
GenerateVolumeFile();
} else {
// Load the file. If loading fails, generate the file.
if (!kv_store_->Load(volume_state_file_)) {
LOG(ERROR) << "Could not load volume data file!";
GenerateVolumeFile();
}
}
// Inform APS.
InitAPSAllStreams();
}
audio_stream_type_t AudioVolumeHandler::GetVolumeControlStream() {
return selected_stream_;
}
void AudioVolumeHandler::SetVolumeControlStream(audio_stream_type_t stream) {
selected_stream_ = stream;
}
int AudioVolumeHandler::GetNewVolumeIndex(int previous_index, int direction,
audio_stream_type_t stream) {
int current_index =
previous_index + ConvertToInternalIndex(stream, direction);
if (current_index < kMinIndex_) {
return kMinIndex_;
} else if (current_index > kMaxIndex_) {
return kMaxIndex_;
} else
return current_index;
}
void AudioVolumeHandler::AdjustStreamVolume(audio_stream_type_t stream,
int direction) {
VLOG(1) << "Adjusting volume of stream " << selected_stream_
<< " in direction " << direction;
auto device = aps_->getDevicesForStream(stream);
int previous_index = GetVolumeCurrentIndex(stream, device);
int current_index = GetNewVolumeIndex(previous_index, direction, stream);
VLOG(1) << "Current index is " << current_index << " for stream " << stream
<< " and device " << device;
aps_->setStreamVolumeIndex(stream, current_index, device);
PersistVolumeConfiguration(selected_stream_, device, current_index);
TriggerCallback(stream, previous_index, current_index);
}
void AudioVolumeHandler::AdjustVolumeActiveStreams(int direction) {
if (selected_stream_ != AUDIO_STREAM_DEFAULT) {
AdjustStreamVolume(selected_stream_, direction);
return;
}
for (auto stream : kSupportedStreams_) {
if (aps_->isStreamActive(stream)) {
AdjustStreamVolume(stream, direction);
return;
}
}
}
void AudioVolumeHandler::ProcessEvent(const struct input_event& event) {
VLOG(1) << event.type << " " << event.code << " " << event.value;
if (event.type == EV_KEY) {
switch (event.code) {
case KEY_VOLUMEDOWN:
AdjustVolumeActiveStreams(-1);
break;
case KEY_VOLUMEUP:
AdjustVolumeActiveStreams(1);
break;
default:
// This event code is not supported by this handler.
break;
}
}
}
} // namespace brillo

View file

@ -0,0 +1,248 @@
// 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.
//
// Handler for input events in /dev/input. AudioVolumeHandler handles events
// only for volume key presses.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_
#define BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_
#include <base/bind.h>
#include <base/files/file_path.h>
#include <brillo/key_value_store.h>
#include <gtest/gtest_prod.h>
#include <linux/input.h>
#include <media/IAudioPolicyService.h>
#include <system/audio.h>
#include "audio_daemon_handler.h"
namespace brillo {
class AudioVolumeHandler : public AudioDaemonHandler {
public:
AudioVolumeHandler();
virtual ~AudioVolumeHandler();
// Get the current state of the headset jack and update AudioSystem based on
// the initial state.
//
// |aps| is a pointer to the binder object.
virtual void Init(android::sp<android::IAudioPolicyService> aps) override;
// Process input events from the kernel. Connecting/disconnecting an audio
// device will result in multiple calls to this method.
//
// |event| is a pointer to an input_event. This function should be able to
// gracefully handle input events that are not relevant to the functionality
// provided by this class.
virtual void ProcessEvent(const struct input_event& event) override;
// Inform the handler that the audio policy service has been disconnected.
virtual void APSDisconnect() override;
// Inform the handler that the audio policy service is reconnected.
//
// |aps| is a pointer to the binder object.
virtual void APSConnect(
android::sp<android::IAudioPolicyService> aps) override;
// Get the stream used when volume buttons are pressed.
//
// Returns an audio_stream_t representing the stream. If
// SetVolumeControlStream isn't called before calling this method,
// STREAM_DEFAULT is returned.
audio_stream_type_t GetVolumeControlStream();
// Set the stream to use when volume buttons are pressed.
//
// |stream| is an int representing the stream. Passing STREAM_DEFAULT to this
// method can be used to reset selected_stream_.
void SetVolumeControlStream(audio_stream_type_t stream);
// Register a callback to be triggered when keys are pressed.
//
// |callback| is an object of type base::Callback.
void RegisterCallback(
base::Callback<void(audio_stream_type_t, int, int)>& callback);
// Set the max steps for an audio stream.
//
// |stream| is an int representing the stream.
// |max_index| is an int representing the maximum index to set for |stream|.
//
// Returns 0 on success and errno on failure.
int SetVolumeMaxSteps(audio_stream_type_t stream, int max_steps);
// Get the max steps for an audio stream.
//
// |stream| is an int representing the stream.
//
// Returns the maximum possible index for |stream|.
int GetVolumeMaxSteps(audio_stream_type_t stream);
// Get the volume of a given key.
//
// |stream| is an int representing the stream.
// |device| is an int representing the device.
//
// Returns an int which corresponds to the current index.
int GetVolumeCurrentIndex(audio_stream_type_t stream, audio_devices_t device);
// Set the volume for a given (stream, device) tuple.
//
// |stream| is an int representing the stream.
// |device| is an int representing the device.
// |index| is an int representing the volume.
//
// Returns 0 on success and errno on failure.
int SetVolumeIndex(audio_stream_type_t stream,
audio_devices_t device,
int index);
// Get the volume for a given (stream, device) tuple.
//
// |stream| is an int representing the stream.
// |device| is an int representing the device.
//
// Returns the index for the (stream, device) tuple. This index is between 0
// and the user defined maximum value.
int GetVolumeIndex(audio_stream_type_t stream, audio_devices_t device);
// Update the volume index for a given stream.
//
// |previous_index| is the current index of the stream/device tuple before the
// volume button is pressed.
// |direction| is an int which is multiplied to step_. +1 for volume up and -1
// for volume down.
// |stream| is an int representing the stream.
//
// Returns the new volume index.
int GetNewVolumeIndex(int previous_index, int direction,
audio_stream_type_t stream);
// Adjust the volume of the active streams in the direction indicated. If
// SetDefaultStream() is called, then only the volume for that stream will be
// changed. Calling this method always triggers a callback.
//
// |direction| is an int which is multiplied to step_. +1 for volume up and -1
// for volume down.
virtual void AdjustVolumeActiveStreams(int direction);
private:
friend class AudioVolumeHandlerTest;
FRIEND_TEST(AudioVolumeHandlerTest, FileGeneration);
FRIEND_TEST(AudioVolumeHandlerTest, GetVolumeForStreamDeviceTuple);
FRIEND_TEST(AudioVolumeHandlerTest, SetVolumeForStreamDeviceTuple);
FRIEND_TEST(AudioVolumeHandlerTest, InitNoFile);
FRIEND_TEST(AudioVolumeHandlerTest, InitFilePresent);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventEmpty);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyUp);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyDown);
FRIEND_TEST(AudioVolumeHandlerTest, SelectStream);
FRIEND_TEST(AudioVolumeHandlerTest, ComputeNewVolume);
FRIEND_TEST(AudioVolumeHandlerTest, GetSetVolumeIndex);
// Save the volume for a given (stream, device) tuple.
//
// |stream| is an int representing the stream.
// |device| is an int representing the device.
// |index| is an int representing the volume.
void PersistVolumeConfiguration(audio_stream_type_t stream,
audio_devices_t device,
int index);
// Read the initial volume of audio streams.
//
// |path| is the file that contains the initial volume state.
void GetInitialVolumeState(const base::FilePath& path);
// Adjust the volume of a given stream in the direction specified.
//
// |stream| is an int representing the stream.
// |direction| is an int which is multiplied to step_. +1 for volume up and -1
// for volume down.
void AdjustStreamVolume(audio_stream_type_t stream, int direction);
// Set the file path for testing.
//
// |path| to use while running tests.
void SetVolumeFilePathForTesting(const base::FilePath& path);
// Initialize all the streams in the audio policy service.
virtual void InitAPSAllStreams();
// Generate the volume config file.
void GenerateVolumeFile();
// Trigger a callback when a volume button is pressed.
//
// |stream| is an audio_stream_t representing the stream.
// |previous_index| is the volume index before the key press. This is an
// absolute index from 0 - 100.
// |current_index| is the volume index after the key press. This is an
// absolute index from 0 - 100.
virtual void TriggerCallback(audio_stream_type_t stream,
int previous_index,
int current_index);
// Convert internal index to user defined index scale.
//
// |stream| is an audio_stream_t representing the stream.
// |index| is the volume index before the key press. This is an absolute
// index from 0 - 100.
//
// Returns an int between 0 and the user defined max.
int ConvertToUserDefinedIndex(audio_stream_type_t stream, int index);
// Convert user defined index to internal index scale.
//
// |stream| is an audio_stream_t representing the stream.
// |index| is the volume index before the key press. This is an index from 0
// and the user defined max.
//
// Returns an int between 0 and 100.
int ConvertToInternalIndex(audio_stream_type_t stream, int index);
// Stream to use for volume control.
audio_stream_type_t selected_stream_;
// File backed key-value store of the current index (as seen by the audio
// policy service).
std::unique_ptr<KeyValueStore> kv_store_;
// Supported stream names. The order of this vector defines the priority from
// high to low.
std::vector<audio_stream_type_t> kSupportedStreams_{
AUDIO_STREAM_ALARM, AUDIO_STREAM_NOTIFICATION, AUDIO_STREAM_SYSTEM,
AUDIO_STREAM_MUSIC};
// Step size for each stream. This is used to translate between user defined
// stream ranges and the range as seen by audio policy service. This value is
// not file-backed and is intended to be re-applied by the user on reboots and
// brilloaudioservice crashes.
std::map<audio_stream_type_t, double> step_sizes_;
// Callback to call when volume buttons are pressed.
base::Callback<void(audio_stream_type_t, int, int)> callback_;
// Key indicies.
const std::string kCurrentIndexKey_ = "current_index";
// Default values.
const int kMinIndex_ = 0;
const int kDefaultCurrentIndex_ = 30;
const int kMaxIndex_ = 100;
const int kDefaultStepSize_ = 1;
base::FilePath volume_state_file_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_VOLUME_HANDLER_H_

View file

@ -0,0 +1,224 @@
// 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.
//
// Implementation of brillo_audio_client.h
#include "brillo_audio_client.h"
#include <base/logging.h>
#include <binder/Status.h>
#include <binderwrapper/binder_wrapper.h>
#include "brillo_audio_client_helpers.h"
#include "brillo_audio_device_info_def.h"
#include "brillo_audio_device_info_internal.h"
using android::binder::Status;
namespace brillo {
static const char kBrilloAudioServiceName[] =
"android.brillo.brilloaudioservice.BrilloAudioService";
std::shared_ptr<BrilloAudioClient> BrilloAudioClient::instance_ = nullptr;
int BrilloAudioClient::callback_id_counter_ = 1;
BrilloAudioClient::~BrilloAudioClient() {}
std::weak_ptr<BrilloAudioClient> BrilloAudioClient::GetClientInstance() {
if (!instance_) {
instance_ = std::shared_ptr<BrilloAudioClient>(new BrilloAudioClient());
if (!instance_->Initialize()) {
LOG(ERROR) << "Could not Initialize the brillo audio client.";
instance_.reset();
return instance_;
}
}
return instance_;
}
android::sp<android::IBinder> BrilloAudioClient::ConnectToService(
const std::string& service_name, const base::Closure& callback) {
android::BinderWrapper* binder_wrapper =
android::BinderWrapper::GetOrCreateInstance();
auto service = binder_wrapper->GetService(service_name);
if (!service.get()) {
return service;
}
binder_wrapper->RegisterForDeathNotifications(service, callback);
return service;
}
void BrilloAudioClient::OnBASDisconnect() {
LOG(WARNING) << "The brillo audio service died! Please reset the "
<< "BAudioManager.";
instance_.reset();
}
bool BrilloAudioClient::Initialize() {
auto service = ConnectToService(
kBrilloAudioServiceName, base::Bind(&BrilloAudioClient::OnBASDisconnect,
weak_ptr_factory_.GetWeakPtr()));
if (!service.get()) {
LOG(ERROR) << "Could not connect to brillo audio service.";
return false;
}
brillo_audio_service_ = android::interface_cast<IBrilloAudioService>(service);
return true;
}
int BrilloAudioClient::GetDevices(int flag, std::vector<int>& devices) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->GetDevices(flag, &devices);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::SetDevice(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->SetDevice(usage, config);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::GetMaxVolumeSteps(BAudioUsage usage, int* max_steps) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->GetMaxVolumeSteps(
BrilloAudioClientHelpers::GetStreamType(usage), max_steps);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::SetMaxVolumeSteps(BAudioUsage usage, int max_steps) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->SetMaxVolumeSteps(
BrilloAudioClientHelpers::GetStreamType(usage), max_steps);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::SetVolumeIndex(BAudioUsage usage,
audio_devices_t device,
int index) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->SetVolumeIndex(
BrilloAudioClientHelpers::GetStreamType(usage), device, index);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::GetVolumeIndex(BAudioUsage usage,
audio_devices_t device,
int* index) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->GetVolumeIndex(
BrilloAudioClientHelpers::GetStreamType(usage), device, index);
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::GetVolumeControlStream(BAudioUsage* usage) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
int stream;
auto status = brillo_audio_service_->GetVolumeControlStream(&stream);
*usage = BrilloAudioClientHelpers::GetBAudioUsage(
static_cast<audio_stream_type_t>(stream));
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::SetVolumeControlStream(BAudioUsage usage) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->SetVolumeControlStream(
BrilloAudioClientHelpers::GetStreamType(usage));
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::IncrementVolume() {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->IncrementVolume();
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::DecrementVolume() {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto status = brillo_audio_service_->DecrementVolume();
return status.serviceSpecificErrorCode();
}
int BrilloAudioClient::RegisterAudioCallback(
android::sp<AudioServiceCallback> callback, int* callback_id) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
if (!brillo_audio_service_->RegisterServiceCallback(callback).isOk()) {
*callback_id = 0;
return ECONNABORTED;
}
for (auto& entry : callback_map_) {
if (entry.second->Equals(callback)) {
LOG(ERROR) << "Callback has already been registered.";
*callback_id = 0;
return EINVAL;
}
}
*callback_id = callback_id_counter_++;
callback_map_.emplace(*callback_id, callback);
return 0;
}
int BrilloAudioClient::UnregisterAudioCallback(int callback_id) {
if (!brillo_audio_service_.get()) {
OnBASDisconnect();
return ECONNABORTED;
}
auto callback_elem = callback_map_.find(callback_id);
if (callback_elem == callback_map_.end()) {
// If we were passed an invalid callback_id, do nothing.
LOG(ERROR) << "Unregister called with invalid callback ID.";
return EINVAL;
}
brillo_audio_service_->UnregisterServiceCallback(callback_elem->second.get());
callback_map_.erase(callback_elem);
return 0;
}
} // namespace brillo

View file

@ -0,0 +1,183 @@
// 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.
//
// Client for the brilloaudioservice.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_H_
#include <map>
#include <memory>
#include <vector>
#include <base/bind.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>
#include <media/IAudioPolicyService.h>
#include "android/brillo/brilloaudioservice/IBrilloAudioService.h"
#include "audio_service_callback.h"
using android::brillo::brilloaudioservice::IBrilloAudioService;
namespace brillo {
class BrilloAudioClient {
public:
virtual ~BrilloAudioClient();
// Get or create a pointer to the client instance.
//
// Returns a weak_ptr to a BrilloAudioClient object.
static std::weak_ptr<BrilloAudioClient> GetClientInstance();
// Query brillo audio service to get list of connected audio devices.
//
// |flag| is an int which is either GET_DEVICES_INPUTS or GET_DEVICES_OUTPUTS.
// |devices| is a reference to a vector of audio_devices_t.
//
// Returns 0 on success and errno on failure.
int GetDevices(int flag, std::vector<int>& devices);
// Register a callback object with the service.
//
// |callback| is a ref pointer to a callback object to be register with the
// brillo audio service.
// |callback_id| is a pointer to an int that represents a callback id token on
// success and 0 on failure.
//
// Returns 0 on success and errno on failure.
int RegisterAudioCallback(android::sp<AudioServiceCallback> callback,
int* callback_id);
// Unregister a callback object with the service.
//
// |callback_id| is an int referring to the callback object.
//
// Returns 0 on success and errno on failure.
int UnregisterAudioCallback(int callback_id);
// Set a device to be the default. This does not communicate with the brillo
// audio service but instead communicates directly with the audio policy
// service.
//
// Please see system/audio_policy.h for details on these arguments.
//
// Returns 0 on success and errno on failure.
int SetDevice(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
// Get the maximum number of steps for a given BAudioUsage.
//
// |usage| is an enum of type BAudioUsage.
// |max_steps| is a pointer to the maximum number of steps.
//
// Returns 0 on success and errno on failure.
int GetMaxVolumeSteps(BAudioUsage usage, int* max_steps);
// Set the maximum number of steps to use for a given BAudioUsage.
//
// |usage| is an enum of type BAudioUsage.
// |max_steps| is an int between 0 and 100.
//
// Returns 0 on success and errno on failure.
int SetMaxVolumeSteps(BAudioUsage usage, int max_steps);
// Set the volume index for a given BAudioUsage and device.
//
// |usage| is an enum of type BAudioUsage.
// |device| is of type audio_devices_t.
// |index| is an int representing the current index.
//
// Returns 0 on success and errno on failure.
int SetVolumeIndex(BAudioUsage usage, audio_devices_t device, int index);
// Get the volume index for a given BAudioUsage and device.
//
// |usage| is an enum of type BAudioUsage.
// |device| is of type audio_devices_t.
// |index| is a pointer to an int representing the current index.
//
// Returns 0 on success and errno on failure.
int GetVolumeIndex(BAudioUsage usage, audio_devices_t device, int* index);
// Get default stream to use for volume buttons.
//
// |usage| is a pointer to a BAudioUsage.
//
// Returns 0 on success and errno on failure.
int GetVolumeControlStream(BAudioUsage* usage);
// Set default stream to use for volume buttons.
//
// |usage| is an enum of type BAudioUsage.
//
// Returns 0 on success and errno on failure.
int SetVolumeControlStream(BAudioUsage usage);
// Increment the volume.
//
// Returns 0 on success and errno on failure.
int IncrementVolume();
// Decrement the volume.
//
// Returns 0 on success and errno on failure.
int DecrementVolume();
protected:
BrilloAudioClient() = default;
private:
friend class BrilloAudioClientTest;
FRIEND_TEST(BrilloAudioClientTest, InitializeNoService);
FRIEND_TEST(BrilloAudioClientTest,
CheckInitializeRegistersForDeathNotifications);
// Initialize the BrilloAudioClient object and connects to the brillo audio
// service and the audio policy service. It also registers for death
// notifications.
bool Initialize();
// Callback to be triggered when the brillo audio service dies. It attempts to
// reconnect to the service.
virtual void OnBASDisconnect();
// Helper method to connect to a service and register a callback to receive
// death notifications.
//
// |service_name| is a string representing the name of the service.
// |callback| is a base::Closure which will be called if the service dies.
android::sp<android::IBinder> ConnectToService(const std::string& service_name,
const base::Closure& callback);
// Pointer to the BrilloAudioClient object.
static std::shared_ptr<BrilloAudioClient> instance_;
// Used to generate weak_ptr to BrilloAudioClient for use in base::Bind.
base::WeakPtrFactory<BrilloAudioClient> weak_ptr_factory_{this};
// Pointer to the brillo audio service.
android::sp<IBrilloAudioService> brillo_audio_service_;
// Counter for callback IDs.
static int callback_id_counter_;
// Map of callback ids to callback objects.
std::map<int, android::sp<AudioServiceCallback> > callback_map_;
DISALLOW_COPY_AND_ASSIGN(BrilloAudioClient);
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_H_

View file

@ -0,0 +1,59 @@
// 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.
//
#include "brillo_audio_client_helpers.h"
namespace brillo {
audio_policy_force_use_t BrilloAudioClientHelpers::GetForceUse(
BAudioUsage usage) {
if (usage == kUsageMedia)
return AUDIO_POLICY_FORCE_FOR_MEDIA;
else
return AUDIO_POLICY_FORCE_FOR_SYSTEM;
}
audio_stream_type_t BrilloAudioClientHelpers::GetStreamType(BAudioUsage usage) {
switch (usage) {
case kUsageAlarm:
return AUDIO_STREAM_ALARM;
case kUsageMedia:
return AUDIO_STREAM_MUSIC;
case kUsageNotifications:
return AUDIO_STREAM_NOTIFICATION;
case kUsageSystem:
return AUDIO_STREAM_SYSTEM;
default:
return AUDIO_STREAM_DEFAULT;
}
}
BAudioUsage BrilloAudioClientHelpers::GetBAudioUsage(
audio_stream_type_t stream) {
switch (stream) {
case AUDIO_STREAM_ALARM:
return kUsageAlarm;
case AUDIO_STREAM_MUSIC:
return kUsageMedia;
case AUDIO_STREAM_NOTIFICATION:
return kUsageNotifications;
case AUDIO_STREAM_SYSTEM:
return kUsageSystem;
default:
return kUsageInvalid;
}
}
} // namespace brillo

View file

@ -0,0 +1,38 @@
// 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.
//
// Helpers for the brillo audio client.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_HELPERS_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_HELPERS_H_
#include <gtest/gtest_prod.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include "include/brillo_audio_manager.h"
namespace brillo {
class BrilloAudioClientHelpers {
public:
static audio_policy_force_use_t GetForceUse(BAudioUsage usage);
static audio_stream_type_t GetStreamType(BAudioUsage usage);
static BAudioUsage GetBAudioUsage(audio_stream_type_t stream);
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_HELPERS_H_

View file

@ -0,0 +1,38 @@
// 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.
//
// Implementation of brillo_audio_device_info.h.
#include "include/brillo_audio_device_info.h"
#include "brillo_audio_device_info_def.h"
#include "brillo_audio_device_info_internal.h"
using brillo::BAudioDeviceInfoInternal;
BAudioDeviceInfo* BAudioDeviceInfo_new(int device) {
BAudioDeviceInfo* audio_device_info = new BAudioDeviceInfo;
audio_device_info->internal_ =
std::make_unique<BAudioDeviceInfoInternal>(device);
return audio_device_info;
}
int BAudioDeviceInfo_getType(BAudioDeviceInfo* device) {
return device->internal_->GetDeviceId();
}
void BAudioDeviceInfo_delete(BAudioDeviceInfo* device) {
delete device;
}

View file

@ -0,0 +1,33 @@
// 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.
//
// Definition of BAudioDeviceInfo.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_DEF_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_DEF_H_
#include <memory>
#include "brillo_audio_device_info_internal.h"
#include "include/brillo_audio_device_info.h"
using brillo::BAudioDeviceInfoInternal;
struct BAudioDeviceInfo {
std::unique_ptr<BAudioDeviceInfoInternal> internal_;
};
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_DEF_H_

View file

@ -0,0 +1,89 @@
// 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.
//
// Internal helpers for BAudioDeviceInfo.
#include "brillo_audio_device_info_internal.h"
#include <base/logging.h>
#include "brillo_audio_device_info_def.h"
namespace brillo {
BAudioDeviceInfoInternal::BAudioDeviceInfoInternal(int device_id) {
device_id_ = device_id;
}
int BAudioDeviceInfoInternal::GetDeviceId() {
return device_id_;
}
audio_policy_forced_cfg_t BAudioDeviceInfoInternal::GetConfig() {
switch (device_id_) {
case TYPE_BUILTIN_SPEAKER:
return AUDIO_POLICY_FORCE_SPEAKER;
case TYPE_WIRED_HEADSET:
return AUDIO_POLICY_FORCE_HEADPHONES;
case TYPE_WIRED_HEADSET_MIC:
return AUDIO_POLICY_FORCE_HEADPHONES;
case TYPE_WIRED_HEADPHONES:
return AUDIO_POLICY_FORCE_HEADPHONES;
case TYPE_BUILTIN_MIC:
return AUDIO_POLICY_FORCE_NONE;
default:
return AUDIO_POLICY_FORCE_NONE;
}
}
audio_devices_t BAudioDeviceInfoInternal::GetAudioDevicesT() {
switch (device_id_) {
case TYPE_BUILTIN_SPEAKER:
return AUDIO_DEVICE_OUT_SPEAKER;
case TYPE_WIRED_HEADSET:
return AUDIO_DEVICE_OUT_WIRED_HEADSET;
case TYPE_WIRED_HEADSET_MIC:
return AUDIO_DEVICE_IN_WIRED_HEADSET;
case TYPE_WIRED_HEADPHONES:
return AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
case TYPE_BUILTIN_MIC:
return AUDIO_DEVICE_IN_BUILTIN_MIC;
default:
return AUDIO_DEVICE_NONE;
}
}
BAudioDeviceInfoInternal* BAudioDeviceInfoInternal::CreateFromAudioDevicesT(
unsigned int device) {
int device_id = TYPE_UNKNOWN;
switch (device) {
case AUDIO_DEVICE_OUT_WIRED_HEADSET:
device_id = TYPE_WIRED_HEADSET;
break;
case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
device_id = TYPE_WIRED_HEADPHONES;
break;
case AUDIO_DEVICE_IN_WIRED_HEADSET:
device_id = TYPE_WIRED_HEADSET_MIC;
break;
}
if (device_id == TYPE_UNKNOWN) {
LOG(ERROR) << "Unsupported device.";
return nullptr;
}
return new BAudioDeviceInfoInternal(device_id);
}
} // namespace brillo

View file

@ -0,0 +1,74 @@
// 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.
//
// Internal class to represent BAudioDeviceInfo.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_INTERNAL_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_INTERNAL_H_
#include <vector>
#include <gtest/gtest_prod.h>
#include <hardware/audio_policy.h>
#include "include/brillo_audio_device_info.h"
namespace brillo {
class BAudioDeviceInfoInternal {
public:
// Constructor for BAudioDeviceInfoInternal.
//
// |device_id| is an integer representing an audio device type as defined in
// brillo_audio_device_info.h.
explicit BAudioDeviceInfoInternal(int device_id);
// Get audio policy config.
//
// Returns an audio_policy_forced_cfg_t.
audio_policy_forced_cfg_t GetConfig();
// Create a BAudioDeviceInfoInternal object from a audio_devices_t device
// type.
//
// |devices_t| is an audio device of type audio_devices_t which is represented
// using an int.
//
// Returns a pointer to a BAudioDeviceInfoInternal that has been created.
static BAudioDeviceInfoInternal* CreateFromAudioDevicesT(unsigned int device);
// Get the device id.
//
// Returns an int which is the device_id.
int GetDeviceId();
// Get audio_devices_t that corresponds to device_id;
//
// Returns an audio_devices_t.
audio_devices_t GetAudioDevicesT();
private:
FRIEND_TEST(BrilloAudioDeviceInfoInternalTest, InWiredHeadset);
FRIEND_TEST(BrilloAudioDeviceInfoInternalTest, OutWiredHeadset);
FRIEND_TEST(BrilloAudioDeviceInfoInternalTest, OutWiredHeadphone);
// An int representing the underlying audio device. The int is one of the
// constants defined in brillo_audio_device_info.h.
int device_id_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_INTERNAL_H_

View file

@ -0,0 +1,227 @@
// 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.
//
// Implementation of brillo_audio_manager.h.
#include "include/brillo_audio_manager.h"
#include <memory>
#include <stdlib.h>
#include "audio_service_callback.h"
#include "brillo_audio_client.h"
#include "brillo_audio_client_helpers.h"
#include "brillo_audio_device_info_def.h"
#include "brillo_audio_device_info_internal.h"
using brillo::AudioServiceCallback;
using brillo::BrilloAudioClient;
using brillo::BrilloAudioClientHelpers;
struct BAudioManager {
std::weak_ptr<BrilloAudioClient> client_;
};
BAudioManager* BAudioManager_new() {
auto client = BrilloAudioClient::GetClientInstance();
if (!client.lock())
return nullptr;
BAudioManager* bam = new BAudioManager;
bam->client_ = client;
return bam;
}
int BAudioManager_getDevices(
const BAudioManager* brillo_audio_manager, int flag,
BAudioDeviceInfo* device_array[], unsigned int size,
unsigned int* num_devices) {
if (!brillo_audio_manager || !num_devices ||
(flag != GET_DEVICES_INPUTS && flag != GET_DEVICES_OUTPUTS))
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client) {
*num_devices = 0;
return ECONNABORTED;
}
std::vector<int> devices;
auto rc = client->GetDevices(flag, devices);
if (rc) {
*num_devices = 0;
return rc;
}
unsigned int num_elems = (devices.size() < size) ? devices.size() : size;
for (size_t i = 0; i < num_elems; i++) {
device_array[i] = new BAudioDeviceInfo;
device_array[i]->internal_ = std::unique_ptr<BAudioDeviceInfoInternal>(
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(devices[i]));
}
*num_devices = devices.size();
return 0;
}
int BAudioManager_setInputDevice(const BAudioManager* brillo_audio_manager,
const BAudioDeviceInfo* device) {
if (!brillo_audio_manager || !device)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->SetDevice(AUDIO_POLICY_FORCE_FOR_RECORD,
device->internal_->GetConfig());
}
int BAudioManager_setOutputDevice(
const BAudioManager* brillo_audio_manager, const BAudioDeviceInfo* device,
BAudioUsage usage) {
if (!brillo_audio_manager || !device)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client)
return ECONNABORTED;
return client->SetDevice(BrilloAudioClientHelpers::GetForceUse(usage),
device->internal_->GetConfig());
}
int BAudioManager_getMaxVolumeSteps(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
int* max_steps) {
if (!brillo_audio_manager || !max_steps)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client)
return ECONNABORTED;
return client->GetMaxVolumeSteps(usage, max_steps);
}
int BAudioManager_setMaxVolumeSteps(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
int max_steps) {
if (!brillo_audio_manager || max_steps < 0 || max_steps > 100)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client)
return ECONNABORTED;
return client->SetMaxVolumeSteps(usage, max_steps);
}
int BAudioManager_setVolumeIndex(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
const BAudioDeviceInfo* device,
int index) {
if (!brillo_audio_manager || !device) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->SetVolumeIndex(
usage, device->internal_->GetAudioDevicesT(), index);
}
int BAudioManager_getVolumeIndex(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
const BAudioDeviceInfo* device,
int* index) {
if (!brillo_audio_manager || !device || !index) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->GetVolumeIndex(
usage, device->internal_->GetAudioDevicesT(), index);
}
int BAudioManager_getVolumeControlUsage(
const BAudioManager* brillo_audio_manager, BAudioUsage* usage) {
if (!brillo_audio_manager || !usage) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->GetVolumeControlStream(usage);
}
int BAudioManager_setVolumeControlUsage(
const BAudioManager* brillo_audio_manager, BAudioUsage usage) {
if (!brillo_audio_manager) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->SetVolumeControlStream(usage);
}
int BAudioManager_incrementVolume(const BAudioManager* brillo_audio_manager) {
if (!brillo_audio_manager) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->IncrementVolume();
}
int BAudioManager_decrementVolume(const BAudioManager* brillo_audio_manager) {
if (!brillo_audio_manager) {
return EINVAL;
}
auto client = brillo_audio_manager->client_.lock();
if (!client) {
return ECONNABORTED;
}
return client->DecrementVolume();
}
int BAudioManager_registerAudioCallback(
const BAudioManager* brillo_audio_manager, const BAudioCallback* callback,
void* user_data, int* callback_id) {
if (!brillo_audio_manager || !callback || !callback_id)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client) {
*callback_id = 0;
return ECONNABORTED;
}
// This copies the BAudioCallback into AudioServiceCallback so the
// BAudioCallback can be safely deleted.
return client->RegisterAudioCallback(
new AudioServiceCallback(callback, user_data), callback_id);
}
int BAudioManager_unregisterAudioCallback(
const BAudioManager* brillo_audio_manager, int callback_id) {
if (!brillo_audio_manager)
return EINVAL;
auto client = brillo_audio_manager->client_.lock();
if (!client)
return ECONNABORTED;
return client->UnregisterAudioCallback(callback_id);
}
int BAudioManager_delete(BAudioManager* brillo_audio_manager) {
if (!brillo_audio_manager)
return EINVAL;
delete brillo_audio_manager;
return 0;
}

View file

@ -0,0 +1,87 @@
// 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.
//
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_H_
#include "android/brillo/brilloaudioservice/BnBrilloAudioService.h"
#include <memory>
#include <set>
#include <vector>
#include <binder/Status.h>
#include "android/brillo/brilloaudioservice/IAudioServiceCallback.h"
#include "audio_device_handler.h"
#include "audio_volume_handler.h"
using android::binder::Status;
using android::brillo::brilloaudioservice::BnBrilloAudioService;
using android::brillo::brilloaudioservice::IAudioServiceCallback;
namespace brillo {
class BrilloAudioService : public BnBrilloAudioService {
public:
virtual ~BrilloAudioService() {}
// From AIDL.
virtual Status GetDevices(int flag, std::vector<int>* _aidl_return) = 0;
virtual Status SetDevice(int usage, int config) = 0;
virtual Status GetMaxVolumeSteps(int stream, int* _aidl_return) = 0;
virtual Status SetMaxVolumeSteps(int stream, int max_steps) = 0;
virtual Status SetVolumeIndex(int stream, int device, int index) = 0;
virtual Status GetVolumeIndex(int stream, int device, int* _aidl_return) = 0;
virtual Status GetVolumeControlStream(int* _aidl_return) = 0;
virtual Status SetVolumeControlStream(int stream) = 0;
virtual Status IncrementVolume() = 0;
virtual Status DecrementVolume() = 0;
virtual Status RegisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) = 0;
virtual Status UnregisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) = 0;
// Register daemon handlers.
//
// |audio_device_handler| is a weak pointer to an audio device handler object.
// |audio_volume_handler| is a weak pointer to an audio volume handler object.
virtual void RegisterHandlers(
std::weak_ptr<AudioDeviceHandler> audio_device_handler,
std::weak_ptr<AudioVolumeHandler> audio_volume_handler) = 0;
// Callback to be called when a device is connected.
//
// |devices| is a vector of ints representing the audio_devices_t.
virtual void OnDevicesConnected(const std::vector<int>& device) = 0;
// Callback to be called when a device is disconnected.
//
// |devices| is a vector of ints representing the audio_devices_t.
virtual void OnDevicesDisconnected(const std::vector<int>& device) = 0;
// Callback to be called when the volume is changed.
//
// |stream| is an audio_stream_type_t representing the stream.
// |previous_index| is the volume index before the key press.
// |current_index| is the volume index after the key press.
virtual void OnVolumeChanged(audio_stream_type_t stream,
int previous_index,
int current_index) = 0;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_H_

View file

@ -0,0 +1,193 @@
// 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.
//
// Implementation of brillo_audio_service_impl.h
#include "brillo_audio_service_impl.h"
using android::binder::Status;
namespace brillo {
Status BrilloAudioServiceImpl::GetDevices(int flag,
std::vector<int>* _aidl_return) {
auto device_handler = audio_device_handler_.lock();
if (!device_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio device handler died."));
}
if (flag == BrilloAudioService::GET_DEVICES_INPUTS) {
device_handler->GetInputDevices(_aidl_return);
} else if (flag == BrilloAudioService::GET_DEVICES_OUTPUTS) {
device_handler->GetOutputDevices(_aidl_return);
} else {
return Status::fromServiceSpecificError(EINVAL,
android::String8("Invalid flag."));
}
return Status::ok();
}
Status BrilloAudioServiceImpl::SetDevice(int usage, int config) {
auto device_handler = audio_device_handler_.lock();
if (!device_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio device handler died."));
}
int rc =
device_handler->SetDevice(static_cast<audio_policy_force_use_t>(usage),
static_cast<audio_policy_forced_cfg_t>(config));
if (rc) return Status::fromServiceSpecificError(rc);
return Status::ok();
}
Status BrilloAudioServiceImpl::RegisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) {
callbacks_set_.insert(callback);
return Status::ok();
}
Status BrilloAudioServiceImpl::UnregisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) {
callbacks_set_.erase(callback);
return Status::ok();
}
void BrilloAudioServiceImpl::RegisterHandlers(
std::weak_ptr<AudioDeviceHandler> audio_device_handler,
std::weak_ptr<AudioVolumeHandler> audio_volume_handler) {
audio_device_handler_ = audio_device_handler;
audio_volume_handler_ = audio_volume_handler;
}
Status BrilloAudioServiceImpl::GetMaxVolumeSteps(int stream,
int* _aidl_return) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
*_aidl_return = volume_handler->GetVolumeMaxSteps(
static_cast<audio_stream_type_t>(stream));
return Status::ok();
}
Status BrilloAudioServiceImpl::SetMaxVolumeSteps(int stream, int max_steps) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
int rc = volume_handler->SetVolumeMaxSteps(
static_cast<audio_stream_type_t>(stream), max_steps);
if (rc)
return Status::fromServiceSpecificError(rc);
return Status::ok();
}
Status BrilloAudioServiceImpl::SetVolumeIndex(int stream,
int device,
int index) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
int rc =
volume_handler->SetVolumeIndex(static_cast<audio_stream_type_t>(stream),
static_cast<audio_devices_t>(device),
index);
if (rc)
return Status::fromServiceSpecificError(rc);
return Status::ok();
}
Status BrilloAudioServiceImpl::GetVolumeIndex(int stream,
int device,
int* _aidl_return) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
*_aidl_return =
volume_handler->GetVolumeIndex(static_cast<audio_stream_type_t>(stream),
static_cast<audio_devices_t>(device));
return Status::ok();
}
Status BrilloAudioServiceImpl::IncrementVolume() {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
volume_handler->AdjustVolumeActiveStreams(1);
return Status::ok();
}
Status BrilloAudioServiceImpl::GetVolumeControlStream(int* _aidl_return) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
*_aidl_return = volume_handler->GetVolumeControlStream();
return Status::ok();
}
Status BrilloAudioServiceImpl::SetVolumeControlStream(int stream) {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
volume_handler->SetVolumeControlStream(
static_cast<audio_stream_type_t>(stream));
return Status::ok();
}
Status BrilloAudioServiceImpl::DecrementVolume() {
auto volume_handler = audio_volume_handler_.lock();
if (!volume_handler) {
return Status::fromServiceSpecificError(
EREMOTEIO, android::String8("The audio volume handler died."));
}
volume_handler->AdjustVolumeActiveStreams(-1);
return Status::ok();
}
void BrilloAudioServiceImpl::OnDevicesConnected(
const std::vector<int>& devices) {
for (const auto& callback : callbacks_set_) {
callback->OnAudioDevicesConnected(devices);
}
}
void BrilloAudioServiceImpl::OnDevicesDisconnected(
const std::vector<int>& devices) {
for (const auto& callback : callbacks_set_) {
callback->OnAudioDevicesDisconnected(devices);
}
}
void BrilloAudioServiceImpl::OnVolumeChanged(audio_stream_type_t stream,
int previous_index,
int current_index) {
for (const auto& callback : callbacks_set_) {
callback->OnVolumeChanged(stream, previous_index, current_index);
}
}
} // namespace brillo

View file

@ -0,0 +1,83 @@
// 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.
//
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_IMPL_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_IMPL_H_
// Server side implementation of brillo audio service.
#include "brillo_audio_service.h"
namespace brillo {
class BrilloAudioServiceImpl : public BrilloAudioService {
public:
~BrilloAudioServiceImpl() = default;
// From AIDL.
Status GetDevices(int flag, std::vector<int>* _aidl_return) override;
Status SetDevice(int usage, int config) override;
Status GetMaxVolumeSteps(int stream, int* _aidl_return) override;
Status SetMaxVolumeSteps(int stream, int max_steps) override;
Status SetVolumeIndex(int stream, int device, int index) override;
Status GetVolumeIndex(int stream, int device, int* _aidl_return) override;
Status GetVolumeControlStream(int* _aidl_return) override;
Status SetVolumeControlStream(int stream) override;
Status IncrementVolume() override;
Status DecrementVolume() override;
Status RegisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) override;
Status UnregisterServiceCallback(
const android::sp<IAudioServiceCallback>& callback) override;
// Register daemon handlers.
//
// |audio_device_handler| is a weak pointer to an audio device handler object.
// |audio_volume_handler| is a weak pointer to an audio volume handler object.
void RegisterHandlers(
std::weak_ptr<AudioDeviceHandler> audio_device_handler,
std::weak_ptr<AudioVolumeHandler> audio_volume_handler) override;
// Callback to be called when a device is connected.
//
// |devices| is a vector of ints representing the audio_devices_t.
void OnDevicesConnected(const std::vector<int>& device) override;
// Callback to be called when a device is disconnected.
//
// |devices| is a vector of ints representing the audio_devices_t.
void OnDevicesDisconnected(const std::vector<int>& device) override;
// Callback to be called when volume is changed.
//
// |stream| is an int representing the stream.
// |previous_index| is the volume index before the key press.
// |current_index| is the volume index after the key press.
void OnVolumeChanged(audio_stream_type_t stream,
int previous_index,
int current_index) override;
private:
// A weak pointer to the audio device handler.
std::weak_ptr<AudioDeviceHandler> audio_device_handler_;
// A weak pointer to the audio volume handler.
std::weak_ptr<AudioVolumeHandler> audio_volume_handler_;
// List of all callbacks objects registered with the service.
std::set<android::sp<IAudioServiceCallback> > callbacks_set_;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_IMPL_H_

View file

@ -0,0 +1,4 @@
service brilloaudioserv /system/bin/brilloaudioservice
class late_start
user audioserver
group input

View file

@ -0,0 +1,74 @@
// 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.
//
// Type to represent audio devices in a brillo system.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_H_
#include <sys/cdefs.h>
__BEGIN_DECLS
struct BAudioDeviceInfo;
typedef struct BAudioDeviceInfo BAudioDeviceInfo;
// A device type associated with an unknown or uninitialized device.
static const int TYPE_UNKNOWN = 0;
// A device type describing the speaker system (i.e. a mono speaker or stereo
// speakers) built in a device.
static const int TYPE_BUILTIN_SPEAKER = 1;
// A device type describing a headset, which is the combination of a headphones
// and microphone. This type represents just the transducer in the headset.
static const int TYPE_WIRED_HEADSET = 2;
// A device type describing a headset, which is the combination of a headphones
// and microphone. This type represents the microphone in the headset.
static const int TYPE_WIRED_HEADSET_MIC = 3;
// A device type describing a pair of wired headphones.
static const int TYPE_WIRED_HEADPHONES = 4;
// A device type describing the microphone(s) built in a device.
static const int TYPE_BUILTIN_MIC = 5;
// Create a BAudioDeviceInfo based on a type described above.
//
// Arg:
// device: An int representing an audio type as defined above.
//
// Returns a pointer to a BAudioDeviceInfo object.
BAudioDeviceInfo* BAudioDeviceInfo_new(int device);
// Get the type of the device.
//
// Arg:
// device: A pointer to a BAudioDeviceInfo object to be freed.
//
// Returns an int representing the type of the device.
int BAudioDeviceInfo_getType(BAudioDeviceInfo* device);
// Free a BAudioDeviceInfo.
//
// Arg:
// device: A pointer to a BAudioDeviceInfo object to be freed.
void BAudioDeviceInfo_delete(BAudioDeviceInfo* device);
__END_DECLS
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_DEVICE_INFO_H_

View file

@ -0,0 +1,258 @@
// 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.
//
// Class to manage audio devices in Brillo.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_MANAGER_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_MANAGER_H_
#include <sys/cdefs.h>
#include "brillo_audio_device_info.h"
__BEGIN_DECLS
struct BAudioManager;
typedef struct BAudioManager BAudioManager;
// Get a pointer to a BAudioManager. This object will refer to the same
// underlying client object no matter how many times it is called.
//
// Returns a pointer to a BAudioManager. Returns NULL on failure.
BAudioManager* BAudioManager_new();
// Flag to get input devices.
static const int GET_DEVICES_INPUTS = 1;
// Flag to get output devices.
static const int GET_DEVICES_OUTPUTS = 2;
// Returns the list of input/output devices connected to the system.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager.
// flag: Either GET_DEVICES_INPUTS or GET_DEVICES_OUTPUTS.
// device_array: An array of BAudioDeviceInfo pointers. The caller has to
// allocate this array.
// size: The size of device_array.
// num_devices: A pointer to an unsigned int which will represent the number
// of audio devices connected to the device.
//
// Returns 0 on success and errno on failure.
int BAudioManager_getDevices(
const BAudioManager* brillo_audio_manager, int flag,
BAudioDeviceInfo* device_array[], unsigned int size,
unsigned int* num_devices);
// Select the input device to be used for recording.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager.
// device: Device to set as the input device. Note that the device has to be
// an input device.
//
// Returns 0 on success and errno on failure.
int BAudioManager_setInputDevice(const BAudioManager* brillo_audio_manager,
const BAudioDeviceInfo* device);
// Usage types.
enum BAudioUsage {
kUsageAlarm,
kUsageMedia,
kUsageNotifications,
kUsageSystem,
kUsageInvalid
};
// Select the output device to be used for playback.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager.
// device: Device to set as the output device. Note that the device has to
// be an output device.
// usage: A BAudioUsage type representing a usage to route to |device|.
//
// Returns 0 on success and errno on failure.
int BAudioManager_setOutputDevice(
const BAudioManager* brillo_audio_manager, const BAudioDeviceInfo* device,
BAudioUsage usage);
// Get the number of steps for a given stream type.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A BAudioUsage representing the audio stream.
// max_steps: A pointer to an int representing the number of steps for a given
// usage.
//
// Returns 0 on success and errno on failure.
int BAudioManager_getMaxVolumeSteps(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
int* max_steps);
// Set the number of steps for a given stream type.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A BAudioUsage representing the audio stream.
// max_steps: An int representing the number of steps to use for a given
// usage.
//
// Returns 0 on success and errno on failure.
int BAudioManager_setMaxVolumeSteps(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
int max_steps);
// Set the volume for a given stream type.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A BAudioUsage representing the audio stream.
// device: A pointer to a BAudioDeviceInfo object.
// value: An int representing the index to set the volume to. The index must
// be less than max_steps if BAudioManager_setMaxVolumeSteps was
// called or 100 otherwise.
//
// Returns 0 on success and errno on failure.
int BAudioManager_setVolumeIndex(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
const BAudioDeviceInfo* device,
int index);
// Get the volume for a given stream type.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A BAudioUsage representing the audio stream.
// device: A pointer to a BAudioDeviceInfo object.
// value: A pointer to int. This will be set to an int representing the volume
// index for |usage|.
//
// Returns 0 on success and errno on failure.
int BAudioManager_getVolumeIndex(const BAudioManager* brillo_audio_manager,
BAudioUsage usage,
const BAudioDeviceInfo* device,
int* index);
// Get the default stream for volume buttons. If
// BAudioManager_setVolumeControlUsage has not been called, this will return
// kInvalidUsage.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A pointer to a BAudioUsage representing the audio stream.
//
// Returns 0 on success and errno on failure.
int BAudioManager_getVolumeControlUsage(
const BAudioManager* brillo_audio_manager, BAudioUsage* usage);
// Set the default stream to use for volume buttons. By default, streams will be
// ordered by priority:
// 1. kUsageAlarm
// 2. kUsageNotifications
// 3. kUsageSystem
// 4. kUsageMedia
//
// Calling BAudioMananager_setVolumeControlUsage with kInvalidUsage will reset
// the volume control stream to its default priorities and undo the effects of
// previous calls to BAudioManager_setVolumeControlUsage.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
// usage: A BAudioUsage representing the audio stream.
//
// Returns 0 on success and errno on failure.
int BAudioManager_setVolumeControlUsage(
const BAudioManager* brillo_audio_manager, BAudioUsage usage);
// Increment the volume of active streams or stream selected using
// BAudioManager_setVolumeControlUsage.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
//
// Returns 0 on success and errno on failure.
int BAudioManager_incrementVolume(const BAudioManager* brillo_audio_manager);
// Decrement the volume of active streams or stream selected using
// BAudioManager_setVolumeControlUsage.
//
// Args:
// brillo_audio_manager: A pointer to a BAudioManager object.
//
// Returns 0 on success and errno on failure.
int BAudioManager_decrementVolume(const BAudioManager* brillo_audio_manager);
// Object used for callbacks.
struct BAudioCallback {
// Function to be called when an audio device is added. If multiple audio
// devices are added, then this function will be called multiple times. The
// user is not responsible for freeing added_device.
void (*OnAudioDeviceAdded)(const BAudioDeviceInfo* added_device,
void* user_data);
// Function to be called when an audio device is removed. If multiple audio
// devices are removed, then this function will be called multiple times. The
// user is not responsible for freeing removed_device.
void (*OnAudioDeviceRemoved)(const BAudioDeviceInfo* removed_device,
void* user_data);
// Function to be called when the volume button is pressed.
void (*OnVolumeChanged)(BAudioUsage usage,
int old_volume_index,
int new_volume_index,
void* user_data);
};
typedef struct BAudioCallback BAudioCallback;
// Registers a callback object that lets clients know when audio devices have
// been added/removed from the system.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager.
// callback: An object of type BAudioCallback. The BAudioManager
// maintains ownership of this object.
// user_data : A pointer to user data. This is not used by BAudioManager and
// is passed as an arg to callbacks.
// callback_id: A pointer to an int. The int represents a token that can be
// used to de-register this callback. Contains 0 on failure.
//
// Returns 0 on success and errno on failure.
int BAudioManager_registerAudioCallback(
const BAudioManager* brillo_audio_manager, const BAudioCallback* callback,
void* user_data, int* callback_id);
// Unregisters a callback object.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager.
// callback_id: A token correspoding to the callback object.
//
// Returns 0 on success and errno on failure.
int BAudioManager_unregisterAudioCallback(
const BAudioManager* brillo_audio_manager, int callback_id);
// Free a Brillo audio manager object.
//
// Arg:
// brillo_audio_manager: A pointer to a BAudioManager to be freed.
//
// Returns 0 on success and errno on failure.
int BAudioManager_delete(BAudioManager* brillo_audio_manager);
__END_DECLS
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_MANAGER_H_

View file

@ -0,0 +1,27 @@
// 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.
//
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include "audio_daemon.h"
int main(int argc, char** argv) {
brillo::FlagHelper::Init(argc, argv, "Brillo audio service,");
brillo::InitLog(brillo::kLogToSyslog | brillo::kLogHeader);
LOG(INFO) << "Starting brilloaudioservice.";
brillo::AudioDaemon audio_daemon;
return audio_daemon.Run();
}

View file

@ -0,0 +1,44 @@
// 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.
//
// Mock of audio daemon.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
#include <gmock/gmock.h>
#include <gtest/gtest_prod.h>
#include "audio_daemon.h"
namespace brillo {
class AudioDaemonMock : public AudioDaemon {
public:
AudioDaemonMock() = default;
~AudioDaemonMock() {}
private:
friend class AudioDaemonTest;
FRIEND_TEST(AudioDaemonTest, RegisterService);
FRIEND_TEST(AudioDaemonTest, TestAPSConnectInitializesHandlersOnlyOnce);
FRIEND_TEST(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL);
MOCK_METHOD0(InitializeHandlers, void());
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_

View file

@ -0,0 +1,68 @@
// 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 daemon.
#include "audio_daemon_mock.h"
#include <memory>
#include <vector>
#include <binder/Binder.h>
#include <binderwrapper/binder_test_base.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <gmock/gmock.h>
#include "audio_device_handler_mock.h"
using android::BinderTestBase;
using android::IInterface;
using std::make_shared;
using testing::_;
using testing::AnyNumber;
namespace brillo {
class AudioDaemonTest : public BinderTestBase {
public:
AudioDaemonMock daemon_;
AudioDeviceHandlerMock device_handler_;
};
TEST_F(AudioDaemonTest, RegisterService) {
daemon_.InitializeBrilloAudioService();
EXPECT_EQ(daemon_.brillo_audio_service_,
binder_wrapper()->GetRegisteredService(
"android.brillo.brilloaudioservice.BrilloAudioService"));
}
TEST_F(AudioDaemonTest, TestAPSConnectInitializesHandlersOnlyOnce) {
binder_wrapper()->SetBinderForService("media.audio_policy",
binder_wrapper()->CreateLocalBinder());
daemon_.handlers_initialized_ = false;
EXPECT_CALL(daemon_, InitializeHandlers()).Times(1);
daemon_.ConnectToAPS();
}
TEST_F(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL) {
daemon_.DeviceCallback(
AudioDeviceHandlerMock::DeviceConnectionState::kDevicesConnected,
std::vector<int>());
EXPECT_EQ(daemon_.brillo_audio_service_,
binder_wrapper()->GetRegisteredService(
"android.brillo.brilloaudioservice.BrilloAudioService"));
}
} // namespace brillo

View file

@ -0,0 +1,80 @@
// 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.
//
// Mock of AudioDeviceHandler.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DEVICE_HANDLER_MOCK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DEVICE_HANDLER_MOCK_H_
#include <base/files/file_path.h>
#include <gmock/gmock.h>
#include <gtest/gtest_prod.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include "audio_device_handler.h"
namespace brillo {
class AudioDeviceHandlerMock : public AudioDeviceHandler {
public:
AudioDeviceHandlerMock() = default;
~AudioDeviceHandlerMock() {}
// Reset all local data.
void Reset() {
connected_input_devices_.clear();
connected_output_devices_.clear();
headphone_ = false;
microphone_ = false;
}
private:
friend class AudioDeviceHandlerTest;
FRIEND_TEST(AudioDeviceHandlerTest,
DisconnectAllSupportedDevicesCallsDisconnect);
FRIEND_TEST(AudioDeviceHandlerTest, InitCallsDisconnectAllSupportedDevices);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateMic);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateNone);
FRIEND_TEST(AudioDeviceHandlerTest, InitialAudioStateInvalid);
FRIEND_TEST(AudioDeviceHandlerTest, InitCallsDisconnect);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventEmpty);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophonePresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphonePresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventMicrophoneNotPresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventHeadphoneNotPresent);
FRIEND_TEST(AudioDeviceHandlerTest, ProcessEventInvalid);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemNone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectMic);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemConnectHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectMic);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadphone);
FRIEND_TEST(AudioDeviceHandlerTest, UpdateAudioSystemDisconnectHeadset);
FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceInput);
FRIEND_TEST(AudioDeviceHandlerTest, ConnectAudioDeviceOutput);
FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceInput);
FRIEND_TEST(AudioDeviceHandlerTest, DisconnectAudioDeviceOutput);
MOCK_METHOD2(NotifyAudioPolicyService,
void(audio_devices_t device, audio_policy_dev_state_t state));
MOCK_METHOD1(TriggerCallback, void(DeviceConnectionState));
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DEVICE_HANDLER_MOCK_H_

View file

@ -0,0 +1,408 @@
// 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

View file

@ -0,0 +1,62 @@
// 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 the audio service callback object.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hardware/audio.h>
#include "audio_service_callback.h"
namespace brillo {
class AudioServiceCallbackTest : public testing::Test {
public:
void SetUp() override {
connected_call_count_ = 0;
disconnected_call_count_ = 0;
callback_.OnAudioDeviceAdded = OnDeviceConnectedMock;
callback_.OnAudioDeviceRemoved = OnDeviceDisconnectedMock;
user_data_ = static_cast<void*>(this);
}
static void OnDeviceConnectedMock(const BAudioDeviceInfo*, void* user_data) {
static_cast<AudioServiceCallbackTest*>(user_data)->connected_call_count_++;
}
static void OnDeviceDisconnectedMock(const BAudioDeviceInfo*, void* user_data) {
static_cast<AudioServiceCallbackTest*>(
user_data)->disconnected_call_count_++;
}
BAudioCallback callback_;
void* user_data_;
int connected_call_count_;
int disconnected_call_count_;
};
TEST_F(AudioServiceCallbackTest, CallbackCallCount) {
std::vector<int> devices = {AUDIO_DEVICE_OUT_WIRED_HEADSET,
AUDIO_DEVICE_OUT_WIRED_HEADPHONE};
AudioServiceCallback service_callback(&callback_, user_data_);
service_callback.OnAudioDevicesConnected(devices);
EXPECT_EQ(connected_call_count_, devices.size());
service_callback.OnAudioDevicesDisconnected(devices);
EXPECT_EQ(disconnected_call_count_, devices.size());
}
} // namespace brillo

View file

@ -0,0 +1,55 @@
// 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.
//
// Mock of AudioVolumeHandler.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_VOLUME_HANDLER_MOCK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_VOLUME_HANDLER_MOCK_H_
#include <gmock/gmock.h>
#include <gtest/gtest_prod.h>
#include "audio_volume_handler.h"
namespace brillo {
class AudioVolumeHandlerMock : public AudioVolumeHandler {
public:
AudioVolumeHandlerMock() = default;
~AudioVolumeHandlerMock() {}
private:
friend class AudioVolumeHandlerTest;
FRIEND_TEST(AudioVolumeHandlerTest, FileGeneration);
FRIEND_TEST(AudioVolumeHandlerTest, GetVolumeForKey);
FRIEND_TEST(AudioVolumeHandlerTest, GetVolumeForStreamDeviceTuple);
FRIEND_TEST(AudioVolumeHandlerTest, SetVolumeForStreamDeviceTuple);
FRIEND_TEST(AudioVolumeHandlerTest, InitNoFile);
FRIEND_TEST(AudioVolumeHandlerTest, InitFilePresent);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventEmpty);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyUp);
FRIEND_TEST(AudioVolumeHandlerTest, ProcessEventKeyDown);
FRIEND_TEST(AudioVolumeHandlerTest, SelectStream);
FRIEND_TEST(AudioVolumeHandlerTest, ComputeNewVolume);
FRIEND_TEST(AudioVolumeHandlerTest, GetSetVolumeIndex);
MOCK_METHOD3(TriggerCallback, void(audio_stream_type_t, int, int));
MOCK_METHOD0(InitAPSAllStreams, void());
MOCK_METHOD1(AdjustVolumeActiveStreams, void(int));
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_VOLUME_HANDLER_MOCK_H_

View file

@ -0,0 +1,212 @@
// 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 volume handler.
#include "audio_volume_handler_mock.h"
#include <memory>
#include <string>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <brillo/key_value_store.h>
#include <brillo/strings/string_utils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "audio_device_handler.h"
using base::FilePath;
using base::PathExists;
using base::ScopedTempDir;
using brillo::string_utils::ToString;
using std::stoi;
using testing::_;
namespace brillo {
class AudioVolumeHandlerTest : public testing::Test {
public:
void SetUp() override {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
volume_file_path_ = temp_dir_.path().Append("vol_file");
handler_.SetVolumeFilePathForTesting(volume_file_path_);
}
void SetupHandlerVolumeFile() {
handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
handler_.GenerateVolumeFile();
}
AudioVolumeHandlerMock handler_;
FilePath volume_file_path_;
private:
ScopedTempDir temp_dir_;
};
// Test that the volume file is formatted correctly.
TEST_F(AudioVolumeHandlerTest, FileGeneration) {
SetupHandlerVolumeFile();
KeyValueStore kv_store;
kv_store.Load(volume_file_path_);
for (auto stream : handler_.kSupportedStreams_) {
std::string value;
ASSERT_EQ(handler_.kMinIndex_, 0);
ASSERT_EQ(handler_.kMaxIndex_, 100);
for (auto device : AudioDeviceHandler::kSupportedOutputDevices_) {
ASSERT_TRUE(kv_store.GetString(handler_.kCurrentIndexKey_ + "." +
ToString(stream) + "." +
ToString(device),
&value));
ASSERT_EQ(handler_.kDefaultCurrentIndex_, stoi(value));
}
}
}
// Test GetVolumeCurrentIndex.
TEST_F(AudioVolumeHandlerTest, GetVolumeForStreamDeviceTuple) {
handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
handler_.kv_store_->SetString(handler_.kCurrentIndexKey_ + ".1.2", "100");
ASSERT_EQ(
handler_.GetVolumeCurrentIndex(static_cast<audio_stream_type_t>(1), 2),
100);
}
// Test SetVolumeCurrentIndex.
TEST_F(AudioVolumeHandlerTest, SetVolumeForStreamDeviceTuple) {
handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
handler_.PersistVolumeConfiguration(
static_cast<audio_stream_type_t>(1), 2, 100);
std::string value;
auto key = handler_.kCurrentIndexKey_ + ".1.2";
handler_.kv_store_->GetString(key, &value);
ASSERT_EQ(stoi(value), 100);
}
// Test that a new volume file is generated if it doesn't exist.
TEST_F(AudioVolumeHandlerTest, InitNoFile) {
EXPECT_CALL(handler_, InitAPSAllStreams());
handler_.Init(nullptr);
EXPECT_TRUE(PathExists(volume_file_path_));
}
// Test that a new volume file isn't generated it already exists.
TEST_F(AudioVolumeHandlerTest, InitFilePresent) {
KeyValueStore kv_store;
kv_store.SetString("foo", "100");
kv_store.Save(volume_file_path_);
EXPECT_CALL(handler_, InitAPSAllStreams());
handler_.Init(nullptr);
EXPECT_TRUE(PathExists(volume_file_path_));
std::string value;
handler_.kv_store_->GetString("foo", &value);
EXPECT_EQ(stoi(value), 100);
}
TEST_F(AudioVolumeHandlerTest, ProcessEventEmpty) {
struct input_event event;
event.type = 0;
event.code = 0;
event.value = 0;
EXPECT_CALL(handler_, AdjustVolumeActiveStreams(_)).Times(0);
handler_.ProcessEvent(event);
}
TEST_F(AudioVolumeHandlerTest, ProcessEventKeyUp) {
struct input_event event;
event.type = EV_KEY;
event.code = KEY_VOLUMEUP;
event.value = 1;
EXPECT_CALL(handler_, AdjustVolumeActiveStreams(1));
handler_.ProcessEvent(event);
}
TEST_F(AudioVolumeHandlerTest, ProcessEventKeyDown) {
struct input_event event;
event.type = EV_KEY;
event.code = KEY_VOLUMEDOWN;
event.value = 1;
EXPECT_CALL(handler_, AdjustVolumeActiveStreams(-1));
handler_.ProcessEvent(event);
}
TEST_F(AudioVolumeHandlerTest, SelectStream) {
EXPECT_EQ(handler_.GetVolumeControlStream(), AUDIO_STREAM_DEFAULT);
handler_.SetVolumeControlStream(AUDIO_STREAM_MUSIC);
EXPECT_EQ(handler_.GetVolumeControlStream(), AUDIO_STREAM_MUSIC);
}
TEST_F(AudioVolumeHandlerTest, ComputeNewVolume) {
EXPECT_EQ(handler_.GetNewVolumeIndex(50, 1, AUDIO_STREAM_MUSIC), 51);
EXPECT_EQ(handler_.GetNewVolumeIndex(50, -1, AUDIO_STREAM_MUSIC), 49);
handler_.step_sizes_[AUDIO_STREAM_MUSIC] = 10;
EXPECT_EQ(handler_.GetNewVolumeIndex(50, 1, AUDIO_STREAM_MUSIC), 60);
EXPECT_EQ(handler_.GetNewVolumeIndex(50, -1, AUDIO_STREAM_MUSIC), 40);
SetupHandlerVolumeFile();
EXPECT_EQ(handler_.GetNewVolumeIndex(100, 1, AUDIO_STREAM_MUSIC), 100);
EXPECT_EQ(handler_.GetNewVolumeIndex(0, -1, AUDIO_STREAM_MUSIC), 0);
}
TEST_F(AudioVolumeHandlerTest, GetSetMaxSteps) {
EXPECT_EQ(handler_.GetVolumeMaxSteps(AUDIO_STREAM_MUSIC), 100);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, 0), EINVAL);
EXPECT_EQ(handler_.GetVolumeMaxSteps(AUDIO_STREAM_MUSIC), 100);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, 100), 0);
EXPECT_EQ(handler_.GetVolumeMaxSteps(AUDIO_STREAM_MUSIC), 100);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, -1), EINVAL);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, 101), EINVAL);
}
TEST_F(AudioVolumeHandlerTest, GetSetVolumeIndex) {
SetupHandlerVolumeFile();
EXPECT_CALL(handler_, TriggerCallback(AUDIO_STREAM_MUSIC, _, 0));
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 0),
0);
EXPECT_CALL(handler_, TriggerCallback(AUDIO_STREAM_MUSIC, 0, 50));
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 50),
0);
EXPECT_CALL(handler_, TriggerCallback(AUDIO_STREAM_MUSIC, 50, 100));
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 100),
0);
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, -1),
EINVAL);
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 101),
EINVAL);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, 10), 0);
EXPECT_EQ(handler_.GetVolumeIndex(AUDIO_STREAM_MUSIC,
AUDIO_DEVICE_OUT_WIRED_HEADSET),
10);
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 11),
EINVAL);
EXPECT_CALL(handler_, TriggerCallback(AUDIO_STREAM_MUSIC, 100, 50));
EXPECT_EQ(handler_.SetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADSET, 5),
0);
EXPECT_EQ(handler_.SetVolumeMaxSteps(AUDIO_STREAM_MUSIC, 20), 0);
EXPECT_EQ(handler_.GetVolumeIndex(AUDIO_STREAM_MUSIC,
AUDIO_DEVICE_OUT_WIRED_HEADSET),
10);
}
} // namespace brillo

View file

@ -0,0 +1,45 @@
// 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.
//
// Mock for the brillo audio client.
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_MOCK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_MOCK_H_
#include <gmock/gmock.h>
#include <gtest/gtest_prod.h>
#include "brillo_audio_client.h"
namespace brillo {
class BrilloAudioClientMock : public BrilloAudioClient {
public:
virtual ~BrilloAudioClientMock() = default;
MOCK_METHOD0(OnBASDisconnect, void());
private:
friend class BrilloAudioClientTest;
FRIEND_TEST(BrilloAudioClientTest,
CheckInitializeRegistersForDeathNotifications);
FRIEND_TEST(BrilloAudioClientTest, InitializeNoService);
BrilloAudioClientMock() = default;
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_MOCK_H_

View file

@ -0,0 +1,287 @@
// 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 the brillo audio client.
#include <binderwrapper/binder_test_base.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "audio_service_callback.h"
#include "brillo_audio_client.h"
#include "include/brillo_audio_manager.h"
#include "test/brillo_audio_client_mock.h"
#include "test/brillo_audio_service_mock.h"
using android::sp;
using android::String8;
using testing::Return;
using testing::_;
namespace brillo {
static const char kBrilloAudioServiceName[] =
"android.brillo.brilloaudioservice.BrilloAudioService";
class BrilloAudioClientTest : public android::BinderTestBase {
public:
bool ConnectClientToBAS() {
bas_ = new BrilloAudioServiceMock();
binder_wrapper()->SetBinderForService(kBrilloAudioServiceName, bas_);
return client_.Initialize();
}
BrilloAudioClientMock client_;
sp<BrilloAudioServiceMock> bas_;
};
TEST_F(BrilloAudioClientTest, SetDeviceNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(
client_.SetDevice(AUDIO_POLICY_FORCE_USE_MAX, AUDIO_POLICY_FORCE_NONE),
ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, GetDevicesNoService) {
std::vector<int> foo;
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.GetDevices(0, foo), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, RegisterCallbackNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.RegisterAudioCallback(nullptr, nullptr), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, UnregisterAudioCallbackNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.UnregisterAudioCallback(0), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, InitializeNoService) {
EXPECT_FALSE(client_.Initialize());
}
TEST_F(BrilloAudioClientTest, CheckInitializeRegistersForDeathNotifications) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(client_, OnBASDisconnect());
binder_wrapper()->NotifyAboutBinderDeath(bas_);
}
TEST_F(BrilloAudioClientTest, GetDevicesWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
std::vector<int> foo;
EXPECT_CALL(*bas_.get(), GetDevices(0, &foo)).WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.GetDevices(0, foo), 0);
}
TEST_F(BrilloAudioClientTest, SetDeviceWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
std::vector<int> foo;
EXPECT_CALL(*bas_.get(),
SetDevice(AUDIO_POLICY_FORCE_USE_MAX, AUDIO_POLICY_FORCE_NONE))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(
client_.SetDevice(AUDIO_POLICY_FORCE_USE_MAX, AUDIO_POLICY_FORCE_NONE),
0);
}
TEST_F(BrilloAudioClientTest, RegisterCallbackWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
BAudioCallback bcallback;
AudioServiceCallback* callback =
new AudioServiceCallback(&bcallback, nullptr);
int id = 0;
EXPECT_CALL(*bas_.get(),
RegisterServiceCallback(sp<IAudioServiceCallback>(callback)))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.RegisterAudioCallback(callback, &id), 0);
EXPECT_NE(id, 0);
}
TEST_F(BrilloAudioClientTest, RegisterSameCallbackTwiceWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
BAudioCallback bcallback;
AudioServiceCallback* callback =
new AudioServiceCallback(&bcallback, nullptr);
int id = -1;
EXPECT_CALL(*bas_.get(),
RegisterServiceCallback(sp<IAudioServiceCallback>(callback)))
.Times(2)
.WillRepeatedly(Return(Status::ok()));
EXPECT_EQ(client_.RegisterAudioCallback(callback, &id), 0);
EXPECT_NE(id, 0);
id = -1;
EXPECT_EQ(client_.RegisterAudioCallback(callback, &id), EINVAL);
EXPECT_EQ(id, 0);
}
TEST_F(BrilloAudioClientTest, UnregisterAudioCallbackValidWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
BAudioCallback bcallback;
AudioServiceCallback* callback =
new AudioServiceCallback(&bcallback, nullptr);
int id = 0;
EXPECT_CALL(*bas_.get(),
RegisterServiceCallback(sp<IAudioServiceCallback>(callback)))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.RegisterAudioCallback(callback, &id), 0);
EXPECT_NE(id, 0);
EXPECT_CALL(*bas_.get(),
UnregisterServiceCallback(sp<IAudioServiceCallback>(callback)))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.UnregisterAudioCallback(id), 0);
}
TEST_F(BrilloAudioClientTest, UnregisterInvalidCallbackWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_EQ(client_.UnregisterAudioCallback(1), EINVAL);
}
TEST_F(BrilloAudioClientTest, RegisterAndUnregisterAudioTwoCallbacks) {
EXPECT_TRUE(ConnectClientToBAS());
BAudioCallback bcallback1, bcallback2;
AudioServiceCallback* callback1 =
new AudioServiceCallback(&bcallback1, nullptr);
AudioServiceCallback* callback2 =
new AudioServiceCallback(&bcallback2, nullptr);
int id1 = 0, id2 = 0;
EXPECT_CALL(*bas_.get(), RegisterServiceCallback(_))
.WillRepeatedly(Return(Status::ok()));
EXPECT_EQ(client_.RegisterAudioCallback(callback1, &id1), 0);
EXPECT_NE(id1, 0);
EXPECT_EQ(client_.RegisterAudioCallback(callback2, &id2), 0);
EXPECT_NE(id2, 0);
EXPECT_CALL(*bas_.get(), UnregisterServiceCallback(_))
.WillRepeatedly(Return(Status::ok()));
EXPECT_EQ(client_.UnregisterAudioCallback(id1), 0);
EXPECT_EQ(client_.UnregisterAudioCallback(id2), 0);
}
TEST_F(BrilloAudioClientTest, GetMaxVolStepsNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
int foo;
EXPECT_EQ(client_.GetMaxVolumeSteps(BAudioUsage::kUsageInvalid, &foo),
ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, GetMaxVolStepsWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
int foo;
EXPECT_CALL(*bas_.get(), GetMaxVolumeSteps(AUDIO_STREAM_MUSIC, &foo))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.GetMaxVolumeSteps(BAudioUsage::kUsageMedia, &foo), 0);
}
TEST_F(BrilloAudioClientTest, SetMaxVolStepsNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.SetMaxVolumeSteps(BAudioUsage::kUsageInvalid, 100),
ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, SetMaxVolStepsWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(), SetMaxVolumeSteps(AUDIO_STREAM_MUSIC, 100))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.SetMaxVolumeSteps(BAudioUsage::kUsageMedia, 100), 0);
}
TEST_F(BrilloAudioClientTest, SetVolIndexNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.SetVolumeIndex(
BAudioUsage::kUsageInvalid, AUDIO_DEVICE_NONE, 100),
ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, SetVolIndexWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(),
SetVolumeIndex(AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_SPEAKER, 100))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.SetVolumeIndex(
BAudioUsage::kUsageMedia, AUDIO_DEVICE_OUT_SPEAKER, 100),
0);
}
TEST_F(BrilloAudioClientTest, GetVolIndexNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
int foo;
EXPECT_EQ(client_.GetVolumeIndex(
BAudioUsage::kUsageInvalid, AUDIO_DEVICE_NONE, &foo),
ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, GetVolIndexWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
int foo;
EXPECT_CALL(
*bas_.get(),
GetVolumeIndex(AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_SPEAKER, &foo))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.GetVolumeIndex(
BAudioUsage::kUsageMedia, AUDIO_DEVICE_OUT_SPEAKER, &foo),
0);
}
TEST_F(BrilloAudioClientTest, GetVolumeControlStreamNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
BAudioUsage foo;
EXPECT_EQ(client_.GetVolumeControlStream(&foo), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, GetVolumeControlStreamWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(), GetVolumeControlStream(_))
.WillOnce(Return(Status::ok()));
BAudioUsage foo;
EXPECT_EQ(client_.GetVolumeControlStream(&foo), 0);
}
TEST_F(BrilloAudioClientTest, SetVolumeControlStreamNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.SetVolumeControlStream(kUsageMedia), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, SetVolumeControlStreamWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(), SetVolumeControlStream(AUDIO_STREAM_MUSIC))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.SetVolumeControlStream(kUsageMedia), 0);
}
TEST_F(BrilloAudioClientTest, IncrementVolNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.IncrementVolume(), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, IncrementVolWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(), IncrementVolume()).WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.IncrementVolume(), 0);
}
TEST_F(BrilloAudioClientTest, DecrementVolNoService) {
EXPECT_CALL(client_, OnBASDisconnect());
EXPECT_EQ(client_.DecrementVolume(), ECONNABORTED);
}
TEST_F(BrilloAudioClientTest, DecrementVolWithBAS) {
EXPECT_TRUE(ConnectClientToBAS());
EXPECT_CALL(*bas_.get(), DecrementVolume()).WillOnce(Return(Status::ok()));
EXPECT_EQ(client_.DecrementVolume(), 0);
}
} // namespace brillo

View file

@ -0,0 +1,51 @@
// 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 the BrilloAudioDeviceInfoInternal test.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hardware/audio.h>
#include "brillo_audio_device_info_internal.h"
namespace brillo {
TEST(BrilloAudioDeviceInfoInternalTest, OutWiredHeadset) {
BAudioDeviceInfoInternal* badi =
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(
AUDIO_DEVICE_OUT_WIRED_HEADSET);
EXPECT_EQ(badi->device_id_, TYPE_WIRED_HEADSET);
EXPECT_EQ(badi->GetConfig(), AUDIO_POLICY_FORCE_HEADPHONES);
}
TEST(BrilloAudioDeviceInfoInternalTest, OutWiredHeadphone) {
BAudioDeviceInfoInternal* badi =
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(
AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
EXPECT_EQ(badi->device_id_, TYPE_WIRED_HEADPHONES);
EXPECT_EQ(badi->GetConfig(), AUDIO_POLICY_FORCE_HEADPHONES);
}
TEST(BrilloAudioDeviceInfoInternalTest, InWiredHeadset) {
BAudioDeviceInfoInternal* badi =
BAudioDeviceInfoInternal::CreateFromAudioDevicesT(
AUDIO_DEVICE_IN_WIRED_HEADSET);
EXPECT_EQ(badi->device_id_, TYPE_WIRED_HEADSET_MIC);
EXPECT_EQ(badi->GetConfig(), AUDIO_POLICY_FORCE_HEADPHONES);
}
} // namespace brillo

View file

@ -0,0 +1,497 @@
// 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 the brillo audio manager interface.
#include <binderwrapper/binder_test_base.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "audio_service_callback.h"
#include "brillo_audio_client.h"
#include "include/brillo_audio_manager.h"
#include "test/brillo_audio_service_mock.h"
using android::sp;
using testing::Mock;
using testing::Return;
using testing::_;
namespace brillo {
static const char kBrilloAudioServiceName[] =
"android.brillo.brilloaudioservice.BrilloAudioService";
class BrilloAudioManagerTest : public android::BinderTestBase {
public:
void ConnectBAS() {
bas_ = new BrilloAudioServiceMock();
binder_wrapper()->SetBinderForService(kBrilloAudioServiceName, bas_);
}
BAudioManager* GetValidManager() {
ConnectBAS();
auto bam = BAudioManager_new();
EXPECT_NE(bam, nullptr);
return bam;
}
void TearDown() {
// Stopping the BAS will cause the client to delete itself.
binder_wrapper()->NotifyAboutBinderDeath(bas_);
bas_.clear();
}
sp<BrilloAudioServiceMock> bas_;
};
TEST_F(BrilloAudioManagerTest, NewNoService) {
EXPECT_EQ(BAudioManager_new(), nullptr);
}
TEST_F(BrilloAudioManagerTest, NewWithBAS) {
ConnectBAS();
auto bam = BAudioManager_new();
EXPECT_NE(bam, nullptr);
}
TEST_F(BrilloAudioManagerTest, GetDevicesInvalidParams) {
auto bam = GetValidManager();
unsigned int num_devices;
EXPECT_EQ(BAudioManager_getDevices(nullptr, 1, nullptr, 0, &num_devices),
EINVAL);
EXPECT_EQ(BAudioManager_getDevices(bam, 1, nullptr, 0, nullptr), EINVAL);
EXPECT_EQ(BAudioManager_getDevices(bam, -1, nullptr, 0, &num_devices),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, GetDevicesNullArrNoDevices) {
auto bam = GetValidManager();
unsigned int num_devices = -1;
EXPECT_CALL(*bas_.get(), GetDevices(1, _)).WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_getDevices(bam, 1, nullptr, 0, &num_devices), 0);
EXPECT_EQ(num_devices, 0);
}
TEST_F(BrilloAudioManagerTest, SetInputDeviceInvalidParams) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_UNKNOWN);
EXPECT_EQ(BAudioManager_setInputDevice(nullptr, nullptr), EINVAL);
EXPECT_EQ(BAudioManager_setInputDevice(bam, nullptr), EINVAL);
EXPECT_EQ(BAudioManager_setInputDevice(nullptr, device), EINVAL);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetInputDeviceHeadsetMic) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADSET_MIC);
EXPECT_CALL(*bas_.get(), SetDevice(AUDIO_POLICY_FORCE_FOR_RECORD,
AUDIO_POLICY_FORCE_HEADPHONES))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setInputDevice(bam, device), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetInputDeviceBuiltinMic) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_BUILTIN_MIC);
EXPECT_CALL(*bas_.get(),
SetDevice(AUDIO_POLICY_FORCE_FOR_RECORD, AUDIO_POLICY_FORCE_NONE))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setInputDevice(bam, device), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceInvalidParams) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_UNKNOWN);
EXPECT_EQ(BAudioManager_setOutputDevice(nullptr, nullptr, kUsageMedia),
EINVAL);
EXPECT_EQ(BAudioManager_setOutputDevice(bam, nullptr, kUsageMedia), EINVAL);
EXPECT_EQ(BAudioManager_setOutputDevice(nullptr, device, kUsageMedia),
EINVAL);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceWiredHeadset) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADSET);
EXPECT_CALL(*bas_.get(), SetDevice(AUDIO_POLICY_FORCE_FOR_MEDIA,
AUDIO_POLICY_FORCE_HEADPHONES))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setOutputDevice(bam, device, kUsageMedia), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceBuiltinSpeaker) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_BUILTIN_SPEAKER);
EXPECT_CALL(*bas_.get(), SetDevice(AUDIO_POLICY_FORCE_FOR_SYSTEM,
AUDIO_POLICY_FORCE_SPEAKER))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setOutputDevice(bam, device, kUsageSystem), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceWiredHeadphoneNotification) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
EXPECT_CALL(*bas_.get(), SetDevice(AUDIO_POLICY_FORCE_FOR_SYSTEM,
AUDIO_POLICY_FORCE_HEADPHONES))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setOutputDevice(bam, device, kUsageNotifications), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceWiredHeadphoneAlarm) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
EXPECT_CALL(*bas_.get(), SetDevice(AUDIO_POLICY_FORCE_FOR_SYSTEM,
AUDIO_POLICY_FORCE_HEADPHONES))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setOutputDevice(bam, device, kUsageAlarm), 0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, RegisterCallbackInvalidParams) {
auto bam = GetValidManager();
BAudioCallback callback;
int callback_id;
EXPECT_EQ(
BAudioManager_registerAudioCallback(nullptr, nullptr, nullptr, nullptr),
EINVAL);
EXPECT_EQ(BAudioManager_registerAudioCallback(bam, nullptr, nullptr, nullptr),
EINVAL);
EXPECT_EQ(
BAudioManager_registerAudioCallback(bam, &callback, nullptr, nullptr),
EINVAL);
EXPECT_EQ(
BAudioManager_registerAudioCallback(bam, nullptr, nullptr, &callback_id),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, RegisterCallbackOnStack) {
auto bam = GetValidManager();
BAudioCallback callback;
callback.OnAudioDeviceAdded = nullptr;
callback.OnAudioDeviceRemoved = nullptr;
int callback_id = 0;
EXPECT_CALL(*bas_.get(), RegisterServiceCallback(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_registerAudioCallback(bam, &callback, nullptr,
&callback_id),
0);
EXPECT_NE(callback_id, 0);
}
TEST_F(BrilloAudioManagerTest, RegisterCallbackOnHeap) {
auto bam = GetValidManager();
BAudioCallback* callback = new BAudioCallback;
callback->OnAudioDeviceAdded = nullptr;
callback->OnAudioDeviceRemoved = nullptr;
int callback_id = 0;
EXPECT_CALL(*bas_.get(), RegisterServiceCallback(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(
BAudioManager_registerAudioCallback(bam, callback, nullptr, &callback_id),
0);
EXPECT_NE(callback_id, 0);
delete callback;
}
TEST_F(BrilloAudioManagerTest, UnregisterCallbackInvalidParams) {
auto bam = GetValidManager();
EXPECT_EQ(BAudioManager_unregisterAudioCallback(nullptr, 1), EINVAL);
EXPECT_EQ(BAudioManager_unregisterAudioCallback(bam, 1), EINVAL);
}
TEST_F(BrilloAudioManagerTest, UnregisterCallback) {
auto bam = GetValidManager();
BAudioCallback callback;
callback.OnAudioDeviceAdded = nullptr;
callback.OnAudioDeviceRemoved = nullptr;
int callback_id = 0;
EXPECT_CALL(*bas_.get(), RegisterServiceCallback(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_registerAudioCallback(bam, &callback, nullptr,
&callback_id),
0);
EXPECT_NE(callback_id, 0);
EXPECT_CALL(*bas_.get(), UnregisterServiceCallback(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_unregisterAudioCallback(bam, callback_id), 0);
// 2nd call shouldn't result in a call to BAS.
EXPECT_EQ(BAudioManager_unregisterAudioCallback(bam, callback_id), EINVAL);
}
TEST_F(BrilloAudioManagerTest, GetDevicesBASDies) {
auto bam = GetValidManager();
unsigned int num_devices = -1;
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_getDevices(bam, 1, nullptr, 0, &num_devices),
ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, SetInputDeviceBASDies) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADSET_MIC);
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_setInputDevice(bam, device), ECONNABORTED);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetOutputDeviceBASDies) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_setOutputDevice(bam, device, kUsageNotifications),
ECONNABORTED);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, RegisterServiceCallbackBASDies) {
auto bam = GetValidManager();
BAudioCallback callback;
callback.OnAudioDeviceAdded = nullptr;
callback.OnAudioDeviceRemoved = nullptr;
int callback_id = 1;
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_registerAudioCallback(bam, &callback, nullptr,
&callback_id),
ECONNABORTED);
EXPECT_EQ(callback_id, 0);
}
TEST_F(BrilloAudioManagerTest, UnregisterCallbackBASDies) {
auto bam = GetValidManager();
BAudioCallback callback;
callback.OnAudioDeviceAdded = nullptr;
callback.OnAudioDeviceRemoved = nullptr;
int callback_id = 0;
EXPECT_CALL(*bas_.get(), RegisterServiceCallback(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_registerAudioCallback(bam, &callback, nullptr,
&callback_id),
0);
EXPECT_NE(callback_id, 0);
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_unregisterAudioCallback(bam, callback_id),
ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, GetMaxVolumeStepsInvalidParams) {
auto bam = GetValidManager();
int foo;
EXPECT_EQ(BAudioManager_getMaxVolumeSteps(
nullptr, BAudioUsage::kUsageMedia, nullptr),
EINVAL);
EXPECT_EQ(
BAudioManager_getMaxVolumeSteps(nullptr, BAudioUsage::kUsageMedia, &foo),
EINVAL);
EXPECT_EQ(
BAudioManager_getMaxVolumeSteps(bam, BAudioUsage::kUsageMedia, nullptr),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, GetMaxVolStepsWithBAS) {
auto bam = GetValidManager();
int foo;
EXPECT_CALL(*bas_.get(), GetMaxVolumeSteps(AUDIO_STREAM_MUSIC, &foo))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(
BAudioManager_getMaxVolumeSteps(bam, BAudioUsage::kUsageMedia, &foo), 0);
}
TEST_F(BrilloAudioManagerTest, GetMaxVolStepsBASDies) {
auto bam = GetValidManager();
int foo;
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(
BAudioManager_getMaxVolumeSteps(bam, BAudioUsage::kUsageMedia, &foo),
ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, SetMaxVolumeStepsInvalidParams) {
EXPECT_EQ(
BAudioManager_setMaxVolumeSteps(nullptr, BAudioUsage::kUsageMedia, 100),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, SetMaxVolStepsWithBAS) {
auto bam = GetValidManager();
EXPECT_CALL(*bas_.get(), SetMaxVolumeSteps(AUDIO_STREAM_MUSIC, 100))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setMaxVolumeSteps(bam, BAudioUsage::kUsageMedia, 100),
0);
}
TEST_F(BrilloAudioManagerTest, SetMaxVolStepsBASDies) {
auto bam = GetValidManager();
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_setMaxVolumeSteps(bam, BAudioUsage::kUsageMedia, 100),
ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, SetVolIndexInvalidParams) {
auto bam = GetValidManager();
EXPECT_EQ(BAudioManager_setVolumeIndex(
nullptr, BAudioUsage::kUsageMedia, nullptr, 100),
EINVAL);
EXPECT_EQ(
BAudioManager_setVolumeIndex(bam, BAudioUsage::kUsageMedia, nullptr, 100),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, SetVolIndexWithBAS) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
EXPECT_CALL(
*bas_.get(),
SetVolumeIndex(AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADPHONE, 100))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(
BAudioManager_setVolumeIndex(bam, BAudioUsage::kUsageMedia, device, 100),
0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, SetVolIndexBASDies) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(
BAudioManager_setVolumeIndex(bam, BAudioUsage::kUsageMedia, device, 100),
ECONNABORTED);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, GetVolIndexInvalidParams) {
auto bam = GetValidManager();
int foo;
EXPECT_EQ(BAudioManager_getVolumeIndex(
nullptr, BAudioUsage::kUsageMedia, nullptr, nullptr),
EINVAL);
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
EXPECT_EQ(BAudioManager_getVolumeIndex(
bam, BAudioUsage::kUsageMedia, device, nullptr),
EINVAL);
EXPECT_EQ(BAudioManager_getVolumeIndex(
nullptr, BAudioUsage::kUsageMedia, device, &foo),
EINVAL);
EXPECT_EQ(BAudioManager_getVolumeIndex(
bam, BAudioUsage::kUsageMedia, nullptr, &foo),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, GetVolIndexWithBAS) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
int foo;
EXPECT_CALL(*bas_.get(),
GetVolumeIndex(
AUDIO_STREAM_MUSIC, AUDIO_DEVICE_OUT_WIRED_HEADPHONE, &foo))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(
BAudioManager_getVolumeIndex(bam, BAudioUsage::kUsageMedia, device, &foo),
0);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, GetVolIndexBASDies) {
auto bam = GetValidManager();
auto device = BAudioDeviceInfo_new(TYPE_WIRED_HEADPHONES);
int foo;
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(
BAudioManager_getVolumeIndex(bam, BAudioUsage::kUsageMedia, device, &foo),
ECONNABORTED);
BAudioDeviceInfo_delete(device);
}
TEST_F(BrilloAudioManagerTest, GetVolumeControlUsageInvalidParams) {
auto bam = GetValidManager();
BAudioUsage foo;
EXPECT_EQ(BAudioManager_getVolumeControlUsage(nullptr, nullptr), EINVAL);
EXPECT_EQ(BAudioManager_getVolumeControlUsage(nullptr, &foo), EINVAL);
EXPECT_EQ(BAudioManager_getVolumeControlUsage(bam, nullptr), EINVAL);
}
TEST_F(BrilloAudioManagerTest, GetVolumeControlStreamWithBAS) {
auto bam = GetValidManager();
BAudioUsage foo;
EXPECT_CALL(*bas_.get(), GetVolumeControlStream(_))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_getVolumeControlUsage(bam, &foo), 0);
}
TEST_F(BrilloAudioManagerTest, GetVolumeControlStreamBASDies) {
auto bam = GetValidManager();
BAudioUsage foo;
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_getVolumeControlUsage(bam, &foo), ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, SetVolumeControlUsageInvalidParams) {
EXPECT_EQ(
BAudioManager_setVolumeControlUsage(nullptr, BAudioUsage::kUsageMedia),
EINVAL);
}
TEST_F(BrilloAudioManagerTest, SetVolumeControlStreamWithBAS) {
auto bam = GetValidManager();
EXPECT_CALL(*bas_.get(), SetVolumeControlStream(AUDIO_STREAM_MUSIC))
.WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_setVolumeControlUsage(bam, BAudioUsage::kUsageMedia),
0);
}
TEST_F(BrilloAudioManagerTest, SetVolumeControlStreamBASDies) {
auto bam = GetValidManager();
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_setVolumeControlUsage(bam, BAudioUsage::kUsageMedia),
ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, DecIncInvalidParams) {
EXPECT_EQ(BAudioManager_decrementVolume(nullptr), EINVAL);
EXPECT_EQ(BAudioManager_incrementVolume(nullptr), EINVAL);
}
TEST_F(BrilloAudioManagerTest, IncVolWithBAS) {
auto bam = GetValidManager();
EXPECT_CALL(*bas_.get(), IncrementVolume()).WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_incrementVolume(bam), 0);
}
TEST_F(BrilloAudioManagerTest, IncVolBASDies) {
auto bam = GetValidManager();
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_incrementVolume(bam), ECONNABORTED);
}
TEST_F(BrilloAudioManagerTest, DecVolWithBAS) {
auto bam = GetValidManager();
EXPECT_CALL(*bas_.get(), DecrementVolume()).WillOnce(Return(Status::ok()));
EXPECT_EQ(BAudioManager_decrementVolume(bam), 0);
}
TEST_F(BrilloAudioManagerTest, DecVolBASDies) {
auto bam = GetValidManager();
binder_wrapper()->NotifyAboutBinderDeath(bas_);
EXPECT_EQ(BAudioManager_decrementVolume(bam), ECONNABORTED);
}
} // namespace brillo

View file

@ -0,0 +1,58 @@
// 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.
//
#ifndef BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_MOCK_H_
#define BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_MOCK_H_
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest_prod.h>
#include "brillo_audio_service.h"
namespace brillo {
class BrilloAudioServiceMock : public BrilloAudioService {
public:
BrilloAudioServiceMock() = default;
~BrilloAudioServiceMock() {}
MOCK_METHOD2(GetDevices, Status(int flag, std::vector<int>* _aidl_return));
MOCK_METHOD2(SetDevice, Status(int usage, int config));
MOCK_METHOD2(GetMaxVolumeSteps, Status(int stream, int* _aidl_return));
MOCK_METHOD2(SetMaxVolumeSteps, Status(int stream, int max_steps));
MOCK_METHOD3(SetVolumeIndex, Status(int stream, int device, int index));
MOCK_METHOD3(GetVolumeIndex,
Status(int stream, int device, int* _aidl_return));
MOCK_METHOD1(GetVolumeControlStream, Status(int* _aidl_return));
MOCK_METHOD1(SetVolumeControlStream, Status(int stream));
MOCK_METHOD0(IncrementVolume, Status());
MOCK_METHOD0(DecrementVolume, Status());
MOCK_METHOD1(RegisterServiceCallback,
Status(const android::sp<IAudioServiceCallback>& callback));
MOCK_METHOD1(UnregisterServiceCallback,
Status(const android::sp<IAudioServiceCallback>& callback));
void RegisterHandlers(std::weak_ptr<AudioDeviceHandler>,
std::weak_ptr<AudioVolumeHandler>){};
void OnDevicesConnected(const std::vector<int>&) {}
void OnDevicesDisconnected(const std::vector<int>&) {}
void OnVolumeChanged(audio_stream_type_t, int, int){};
};
} // namespace brillo
#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_SERVICE_MOCK_H_