upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
109
android/system/media/brillo/audio/audioservice/Android.mk
Normal file
109
android/system/media/brillo/audio/audioservice/Android.mk
Normal 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)
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
191
android/system/media/brillo/audio/audioservice/audio_daemon.cpp
Normal file
191
android/system/media/brillo/audio/audioservice/audio_daemon.cpp
Normal 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
|
112
android/system/media/brillo/audio/audioservice/audio_daemon.h
Normal file
112
android/system/media/brillo/audio/audioservice/audio_daemon.h
Normal 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_
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -0,0 +1,4 @@
|
|||
service brilloaudioserv /system/bin/brilloaudioservice
|
||||
class late_start
|
||||
user audioserver
|
||||
group input
|
|
@ -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_
|
|
@ -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_
|
|
@ -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();
|
||||
}
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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_
|
Loading…
Add table
Add a link
Reference in a new issue