brillo: Add binder interfaces for volume control.
Add binder interfaces for volume control to brilloaudioservice so the
client library can communicate to it.
BUG=27976764
TEST=none
Change-Id: I14dde5215ffb3116ea4d5cedc7110dec0c9fb173
diff --git a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl
index 01e8ba2..841c4ae 100644
--- a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl
+++ b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl
@@ -27,4 +27,9 @@
// 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);
}
diff --git a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl
index 745541e..209b651 100644
--- a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl
+++ b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl
@@ -21,13 +21,18 @@
/*
* Interface for BrilloAudioService that clients can use to get the list of
- * devices currently connected to the system as well as to register callbacks to
- * be notified when the device state changes.
+ * 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);
@@ -37,6 +42,30 @@
// 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);
diff --git a/brillo/audio/audioservice/audio_daemon.cpp b/brillo/audio/audioservice/audio_daemon.cpp
index e737790..08ff548 100644
--- a/brillo/audio/audioservice/audio_daemon.cpp
+++ b/brillo/audio/audioservice/audio_daemon.cpp
@@ -46,12 +46,15 @@
// Register a callback with the audio device handler to call when device state
// changes.
- base::Callback<void(AudioDeviceHandler::DeviceConnectionState,
- const std::vector<int>&)> device_callback = base::Bind(
- &AudioDaemon::DeviceCallback,
- weak_ptr_factory_.GetWeakPtr());
+ 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_);
@@ -85,8 +88,9 @@
void AudioDaemon::InitializeBrilloAudioService() {
brillo_audio_service_ = new BrilloAudioServiceImpl();
- brillo_audio_service_->RegisterDeviceHandler(
- std::weak_ptr<AudioDeviceHandler>(audio_device_handler_));
+ 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.";
@@ -170,4 +174,18 @@
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
diff --git a/brillo/audio/audioservice/audio_daemon.h b/brillo/audio/audioservice/audio_daemon.h
index 0d0bf20..5fc01fd 100644
--- a/brillo/audio/audioservice/audio_daemon.h
+++ b/brillo/audio/audioservice/audio_daemon.h
@@ -40,7 +40,7 @@
virtual ~AudioDaemon();
protected:
- // Initialize the audio device handler and start pollig the files in
+ // Initialize the audio daemon handlers and start pollig the files in
// /dev/input.
int OnInit() override;
@@ -62,6 +62,15 @@
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();
@@ -85,7 +94,7 @@
// Handler for audio device input events.
std::shared_ptr<AudioDeviceHandler> audio_device_handler_;
// Handler for volume key press input events.
- std::unique_ptr<AudioVolumeHandler> audio_volume_handler_;
+ 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.
diff --git a/brillo/audio/audioservice/audio_volume_handler.cpp b/brillo/audio/audioservice/audio_volume_handler.cpp
index 7fac388..d95b2c2 100644
--- a/brillo/audio/audioservice/audio_volume_handler.cpp
+++ b/brillo/audio/audioservice/audio_volume_handler.cpp
@@ -21,6 +21,7 @@
#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"
@@ -48,10 +49,38 @@
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_) {
- SetVolumeCurrentIndex(stream, device, kDefaultCurrentIndex_);
+ PersistVolumeConfiguration(stream, device, kDefaultCurrentIndex_);
}
}
if (!kv_store_->Save(volume_state_file_)) {
@@ -59,6 +88,18 @@
}
}
+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) + "." +
@@ -68,18 +109,32 @@
return std::stoi(value);
}
-int AudioVolumeHandler::GetVolumeForKey(const std::string& key) {
- 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));
}
-void AudioVolumeHandler::SetVolumeCurrentIndex(audio_stream_type_t stream,
- audio_devices_t device,
- int index) {
+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() {
@@ -114,13 +169,18 @@
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 + direction * step_sizes_.at(stream);
+ int current_index =
+ previous_index + ConvertToInternalIndex(stream, direction);
if (current_index < kMinIndex_) {
return kMinIndex_;
} else if (current_index > kMaxIndex_) {
@@ -139,7 +199,8 @@
VLOG(1) << "Current index is " << current_index << " for stream " << stream
<< " and device " << device;
aps_->setStreamVolumeIndex(stream, current_index, device);
- SetVolumeCurrentIndex(selected_stream_, device, current_index);
+ PersistVolumeConfiguration(selected_stream_, device, current_index);
+ TriggerCallback(stream, previous_index, current_index);
}
void AudioVolumeHandler::AdjustVolumeActiveStreams(int direction) {
diff --git a/brillo/audio/audioservice/audio_volume_handler.h b/brillo/audio/audioservice/audio_volume_handler.h
index da9f141..fb95c2f 100644
--- a/brillo/audio/audioservice/audio_volume_handler.h
+++ b/brillo/audio/audioservice/audio_volume_handler.h
@@ -19,6 +19,7 @@
#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>
@@ -58,30 +59,39 @@
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);
- 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);
-
- // Read the initial volume of audio streams.
+ // Register a callback to be triggered when keys are pressed.
//
- // |path| is the file that contains the initial volume state.
- void GetInitialVolumeState(const base::FilePath& path);
+ // |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.
//
@@ -91,20 +101,25 @@
// Returns an int which corresponds to the current index.
int GetVolumeCurrentIndex(audio_stream_type_t stream, audio_devices_t device);
- // Get the volume of a given key.
- //
- // |key| is a string representing key in the key-value file.
- //
- // Returns an int which corresponds to the index.
- int GetVolumeForKey(const std::string& key);
-
// 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.
- void SetVolumeCurrentIndex(audio_stream_type_t stream, audio_devices_t device,
- int index);
+ //
+ // 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.
//
@@ -120,12 +135,40 @@
// 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.
+ // 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.
@@ -144,6 +187,35 @@
// 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
@@ -158,7 +230,9 @@
// 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, int> step_sizes_;
+ 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.
diff --git a/brillo/audio/audioservice/brillo_audio_service.h b/brillo/audio/audioservice/brillo_audio_service.h
index c3cbc8c..87ca0d7 100644
--- a/brillo/audio/audioservice/brillo_audio_service.h
+++ b/brillo/audio/audioservice/brillo_audio_service.h
@@ -24,8 +24,9 @@
#include <binder/Status.h>
-#include "audio_device_handler.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;
@@ -40,16 +41,26 @@
// 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 a device handler.
+ // Register daemon handlers.
//
// |audio_device_handler| is a weak pointer to an audio device handler object.
- virtual void RegisterDeviceHandler(
- std::weak_ptr<AudioDeviceHandler> audio_device_handler) = 0;
+ // |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.
//
@@ -60,6 +71,15 @@
//
// |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
diff --git a/brillo/audio/audioservice/brillo_audio_service_impl.cpp b/brillo/audio/audioservice/brillo_audio_service_impl.cpp
index 9aa7c9b..d108a4a 100644
--- a/brillo/audio/audioservice/brillo_audio_service_impl.cpp
+++ b/brillo/audio/audioservice/brillo_audio_service_impl.cpp
@@ -64,9 +64,108 @@
return Status::ok();
}
-void BrilloAudioServiceImpl::RegisterDeviceHandler(
- std::weak_ptr<AudioDeviceHandler> audio_device_handler) {
+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(
@@ -83,4 +182,12 @@
}
}
+void BrilloAudioServiceImpl::OnVolumeChanged(audio_stream_type_t stream,
+ int previous_index,
+ int current_index) {
+ for (auto callback : callbacks_set_) {
+ callback->OnVolumeChanged(stream, previous_index, current_index);
+ }
+}
+
} // namespace brillo
diff --git a/brillo/audio/audioservice/brillo_audio_service_impl.h b/brillo/audio/audioservice/brillo_audio_service_impl.h
index d1e170b..af53b66 100644
--- a/brillo/audio/audioservice/brillo_audio_service_impl.h
+++ b/brillo/audio/audioservice/brillo_audio_service_impl.h
@@ -29,16 +29,26 @@
// 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 a device handler.
+ // Register daemon handlers.
//
// |audio_device_handler| is a weak pointer to an audio device handler object.
- void RegisterDeviceHandler(
- std::weak_ptr<AudioDeviceHandler> audio_device_handler) override;
+ // |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.
//
@@ -50,9 +60,20 @@
// |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_;
};
diff --git a/brillo/audio/audioservice/test/audio_volume_handler_mock.h b/brillo/audio/audioservice/test/audio_volume_handler_mock.h
index 19168f6..32028ca 100644
--- a/brillo/audio/audioservice/test/audio_volume_handler_mock.h
+++ b/brillo/audio/audioservice/test/audio_volume_handler_mock.h
@@ -43,7 +43,9 @@
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));
};
diff --git a/brillo/audio/audioservice/test/audio_volume_handler_test.cpp b/brillo/audio/audioservice/test/audio_volume_handler_test.cpp
index c4e2f0d..47ef236 100644
--- a/brillo/audio/audioservice/test/audio_volume_handler_test.cpp
+++ b/brillo/audio/audioservice/test/audio_volume_handler_test.cpp
@@ -47,6 +47,11 @@
handler_.SetVolumeFilePathForTesting(volume_file_path_);
}
+ void SetupHandlerVolumeFile() {
+ handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
+ handler_.GenerateVolumeFile();
+ }
+
AudioVolumeHandlerMock handler_;
FilePath volume_file_path_;
@@ -56,8 +61,7 @@
// Test that the volume file is formatted correctly.
TEST_F(AudioVolumeHandlerTest, FileGeneration) {
- handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
- handler_.GenerateVolumeFile();
+ SetupHandlerVolumeFile();
KeyValueStore kv_store;
kv_store.Load(volume_file_path_);
for (auto stream : handler_.kSupportedStreams_) {
@@ -74,13 +78,6 @@
}
}
-// Test accessing the key-value store works.
-TEST_F(AudioVolumeHandlerTest, GetVolumeForKey) {
- handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
- handler_.kv_store_->SetString("foo", "100");
- ASSERT_EQ(handler_.GetVolumeForKey("foo"), 100);
-}
-
// Test GetVolumeCurrentIndex.
TEST_F(AudioVolumeHandlerTest, GetVolumeForStreamDeviceTuple) {
handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
@@ -93,7 +90,8 @@
// Test SetVolumeCurrentIndex.
TEST_F(AudioVolumeHandlerTest, SetVolumeForStreamDeviceTuple) {
handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
- handler_.SetVolumeCurrentIndex(static_cast<audio_stream_type_t>(1), 2, 100);
+ 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);
@@ -148,9 +146,9 @@
}
TEST_F(AudioVolumeHandlerTest, SelectStream) {
- EXPECT_EQ(handler_.selected_stream_, AUDIO_STREAM_DEFAULT);
+ EXPECT_EQ(handler_.GetVolumeControlStream(), AUDIO_STREAM_DEFAULT);
handler_.SetVolumeControlStream(AUDIO_STREAM_MUSIC);
- EXPECT_EQ(handler_.selected_stream_, AUDIO_STREAM_MUSIC);
+ EXPECT_EQ(handler_.GetVolumeControlStream(), AUDIO_STREAM_MUSIC);
}
TEST_F(AudioVolumeHandlerTest, ComputeNewVolume) {
@@ -159,10 +157,56 @@
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);
- handler_.kv_store_ = std::unique_ptr<KeyValueStore>(new KeyValueStore);
- handler_.GenerateVolumeFile();
+ 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