roundup.c \
echo_reference.c
+LOCAL_CFLAGS := -Wno-unused-parameter
LOCAL_C_INCLUDES += $(call include-path-for, speex)
LOCAL_C_INCLUDES += \
$(call include-path-for, speex) \
primitives.c \
roundup.c
+LOCAL_CFLAGS := -Wno-unused-parameter
LOCAL_C_INCLUDES += \
$(call include-path-for, audio-utils)
// -----------------------------------------------------------------------------
// Scanner for AC3 byte streams.
-AC3FrameScanner::AC3FrameScanner()
+AC3FrameScanner::AC3FrameScanner(audio_format_t format)
: FrameScanner(SPDIF_DATA_TYPE_AC3,
AC3FrameScanner::kSyncBytes,
sizeof(AC3FrameScanner::kSyncBytes), 6)
, mStreamType(0)
, mSubstreamID(0)
+ , mFormat(format)
{
mAudioBlocksPerSyncFrame = 6;
memset(mSubstreamBlockCounts, 0, sizeof(mSubstreamBlockCounts));
* kAC3FrameSizeTable[frmsizcod][fscod];
}
mAudioBlocksPerSyncFrame = 6;
+ if (mFormat == AUDIO_FORMAT_E_AC3) {
+ ALOGV("Its a Ac3 substream in EAC3 stream");
+ mStreamType = 2;
+ mSubstreamID = 0;
+ mSubstreamBlockCounts[0] += mAudioBlocksPerSyncFrame;
+ mDataType = SPDIF_DATA_TYPE_E_AC3;
+ mRateMultiplier = EAC3_RATE_MULTIPLIER;
+ }
}
ALOGI_IF((mFormatDumpCount == 0),
"AC3 frame rate = %d * %d, size = %zu, audioBlocksPerSyncFrame = %d",
#define ANDROID_AUDIO_AC3_FRAME_SCANNER_H
#include <stdint.h>
+#include <hardware/audio.h>
#include <audio_utils/spdif/FrameScanner.h>
namespace android {
class AC3FrameScanner : public FrameScanner
{
public:
- AC3FrameScanner();
+ AC3FrameScanner(audio_format_t format);
virtual ~AC3FrameScanner();
virtual int getMaxChannels() const { return 5 + 1; } // 5.1 surround
uint32_t mStreamType;
// substream index
uint32_t mSubstreamID;
+ audio_format_t mFormat;
// used to recognize the start of an AC3 sync frame
static const uint8_t kSyncBytes[];
switch(format) {
case AUDIO_FORMAT_AC3:
case AUDIO_FORMAT_E_AC3:
- mFramer = new AC3FrameScanner();
+ mFramer = new AC3FrameScanner(format);
break;
case AUDIO_FORMAT_DTS:
case AUDIO_FORMAT_DTS_HD:
LOCAL_PATH := $(call my-dir)
audio_service_shared_libraries := \
+ libbinder \
libbinderwrapper \
libbrillo \
libbrillo-binder \
libmedia \
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 \
+ brillo_audio_service.cpp
+
# Audio service.
# =============================================================================
include $(CLEAR_VARS)
LOCAL_MODULE := brilloaudioservice
LOCAL_SRC_FILES := \
- audio_daemon.cpp \
- audio_device_handler.cpp \
+ $(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)
-# Unit tests for audio device handler.
+# 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 -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_device_handler.cpp \
+ $(audio_service_sources) \
+ test/audio_daemon_test.cpp \
test/audio_device_handler_test.cpp
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_C_INCLUDES := external/gtest/include
-LOCAL_SHARED_LIBRARIES := $(audio_service_shared_libraries)
+LOCAL_SHARED_LIBRARIES := \
+ $(audio_service_shared_libraries) \
+ libbinderwrapper_test_support
LOCAL_STATIC_LIBRARIES := \
libBionicGtestMain \
libchrome_test_helpers \
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_device_info_internal_test.cpp
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
+LOCAL_C_INCLUDES := external/gtest/include
+LOCAL_SHARED_LIBRARIES := \
+ $(audio_service_shared_libraries) \
+ libbinderwrapper_test_support
+LOCAL_STATIC_LIBRARIES := \
+ libBionicGtestMain \
+ libchrome_test_helpers \
+ libgmock
+LOCAL_CFLAGS := -Wno-sign-compare -Wall
+include $(BUILD_NATIVE_TEST)
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 register callbacks to
+ * be notified when the device state changes.
+ */
+interface IBrilloAudioService {
+ const int GET_DEVICES_INPUTS = 1;
+ const int GET_DEVICES_OUTPUTS = 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);
+
+ // Register a callback object with the service.
+ void RegisterServiceCallback(IAudioServiceCallback callback);
+
+ // Unregister a callback object.
+ void UnregisterServiceCallback(IAudioServiceCallback callback);
+}
#include <binderwrapper/binder_wrapper.h>
#include <linux/input.h>
+#include "brillo_audio_service.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::InitializeHandler() {
// Start and initialize the audio device handler.
audio_device_handler_ =
- std::unique_ptr<AudioDeviceHandler>(new AudioDeviceHandler());
+ std::shared_ptr<AudioDeviceHandler>(new AudioDeviceHandler());
+
+ // Register a callback with the 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());
+ audio_device_handler_->RegisterDeviceCallback(device_callback);
+
audio_device_handler_->Init(aps_);
// Poll on all files in kInputDeviceDir.
// 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 callback =
- base::Bind(&AudioDaemon::Callback, weak_ptr_factory_.GetWeakPtr(),
+ base::Closure file_callback =
+ base::Bind(&AudioDaemon::EventCallback, weak_ptr_factory_.GetWeakPtr(),
&files_.top());
message_loop->WatchFileDescriptor(fd, MessageLoop::kWatchRead,
- true /*persistent*/, callback);
+ true /*persistent*/, file_callback);
} else {
LOG(WARNING) << "Could not open " << name.value() << " for reading. ("
<< base::File::ErrorToString(file.error_details()) << ")";
}
}
+
handler_initialized_ = true;
+ // Once the handler has been initialized, we can register with service
+ // manager.
+ InitializeBrilloAudioService();
+}
+
+void AudioDaemon::InitializeBrilloAudioService() {
+ brillo_audio_service_ = new BrilloAudioService();
+ brillo_audio_service_->RegisterDeviceHandler(
+ std::weak_ptr<AudioDeviceHandler>(audio_device_handler_));
+ android::BinderWrapper::Get()->RegisterService(kServiceName,
+ brillo_audio_service_);
+ VLOG(1) << "Registered brilloaudioservice with the service manager.";
}
void AudioDaemon::ConnectToAPS() {
return EX_OK;
}
-void AudioDaemon::Callback(base::File* file) {
+void AudioDaemon::EventCallback(base::File* file) {
input_event event;
int bytes_read =
file->ReadAtCurrentPos(reinterpret_cast<char*>(&event), sizeof(event));
audio_device_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);
+}
+
} // namespace brillo
#include <memory>
#include <stack>
+#include <vector>
#include <base/files/file.h>
#include <base/memory/weak_ptr.h>
#include <media/IAudioPolicyService.h>
#include "audio_device_handler.h"
+#include "brillo_audio_service.h"
namespace brillo {
class AudioDaemon : public Daemon {
public:
AudioDaemon() {}
+ virtual ~AudioDaemon();
protected:
// Initialize the audio device handler and start pollig the files in
int OnInit() override;
private:
+ friend class AudioDaemonTest;
+ FRIEND_TEST(AudioDaemonTest, RegisterService);
+ FRIEND_TEST(AudioDaemonTest, TestAPSConnectInitializesHandlerOnlyOnce);
+ FRIEND_TEST(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL);
+
// Callback function for input events. Events are handled by the audio device
// handler.
- void Callback(base::File* file);
+ 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 for audio policy service death notification.
void OnAPSDisconnected();
// if the audio policy service dies.
void ConnectToAPS();
+ // Register the brillo audio service with the service manager.
+ void InitializeBrilloAudioService();
+
// Initialize the audio_device_handler_.
//
// Note: This can only occur after we have connected to the audio policy
// service.
- void InitializeHandler();
+ virtual void InitializeHandler();
// 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::unique_ptr<AudioDeviceHandler> audio_device_handler_;
+ std::shared_ptr<AudioDeviceHandler> audio_device_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.
// Flag to indicate whether the handler has been initialized.
bool handler_initialized_ = false;
// Binder watcher to watch for binder messages.
- brillo::BinderWatcher binder_watcher_;
+ BinderWatcher binder_watcher_;
+ // Brillo audio service. Used for scheduling callbacks to clients.
+ android::sp<BrilloAudioService> brillo_audio_service_;
};
} // namespace brillo
#include <base/files/file.h>
#include <base/logging.h>
+#include <brillo/message_loops/message_loop.h>
#include <media/AudioSystem.h>
namespace brillo {
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();
}
// 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.";
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()) << " ).";
+ << "open " << path.value() << " ("
+ << base::File::ErrorToString(file.error_details()) << ").";
return;
}
int state = 0;
connected_input_devices_.insert(device);
else
connected_output_devices_.insert(device);
+ changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAudioDevice(audio_devices_t device) {
connected_input_devices_.erase(device);
else
connected_output_devices_.erase(device);
+ changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAllSupportedDevices() {
// 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) {
#include <set>
#include <vector>
+#include <base/bind.h>
#include <base/files/file_path.h>
#include <gtest/gtest_prod.h>
#include <linux/input.h>
// |aps| is a pointer to the binder object.
void APSConnect(android::sp<android::IAudioPolicyService> aps);
+ // 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);
+
+ // 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_TEST(AudioDeviceHandlerTest,
// 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.
std::vector<audio_devices_t> kSupportedInputDevices_{
AUDIO_DEVICE_IN_WIRED_HEADSET};
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
--- /dev/null
+// 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_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);
+ 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();
+}
+
+bool AudioServiceCallback::Equals(AudioServiceCallback* callback) {
+ if (callback->connected_callback_.Equals(connected_callback_) &&
+ callback->disconnected_callback_.Equals(disconnected_callback_) &&
+ callback->user_data_ == user_data_)
+ return true;
+ return false;
+}
+
+} // namespace brillo
--- /dev/null
+// 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 with a device is disconnected.
+ //
+ // |devices| is a vector of audio_devices_t.
+ Status OnAudioDevicesDisconnected(const std::vector<int>& devices);
+
+ // Method to compare two AudioServiceCallback objects.
+ //
+ // |callback| is a pointer to a AudioServiceCallback object to be compared
+ // with this.
+ //
+ // Returns true if |callback| equals this.
+ bool Equals(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_;
+ // User data passed to the callbacks.
+ void* user_data_;
+};
+
+} // namespace brillo
+
+#endif // BRILLO_AUDIO_AUDIOSERVICE_AUDIO_SERVICE_CALLBACK_H_
--- /dev/null
+// 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_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";
+static const char kAudioPolicyServiceName[] = "media.audio_policy";
+
+std::shared_ptr<BrilloAudioClient> BrilloAudioClient::instance_ = nullptr;
+
+int BrilloAudioClient::callback_id_counter_ = 1;
+
+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(
+ 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();
+}
+
+void BrilloAudioClient::OnAPSDisconnect() {
+ LOG(ERROR) << "The audio policy 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);
+ service = ConnectToService(kAudioPolicyServiceName,
+ base::Bind(&BrilloAudioClient::OnAPSDisconnect,
+ weak_ptr_factory_.GetWeakPtr()));
+ if (!service.get()) {
+ LOG(ERROR) << "Could not connect to audio policy service.";
+ return false;
+ }
+ aps_ = android::interface_cast<android::IAudioPolicyService>(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);
+ if (!status.isOk()) {
+ return status.exceptionCode();
+ }
+ return 0;
+}
+
+int BrilloAudioClient::SetDevice(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config) {
+ if (!aps_.get()) {
+ OnAPSDisconnect();
+ return ECONNABORTED;
+ }
+ return aps_->setForceUse(usage, config);
+}
+
+int BrilloAudioClient::RegisterAudioCallback(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.";
+ return EINVAL;
+ }
+ }
+ *callback_id = callback_id_counter_++;
+ callback_map_.emplace(
+ *callback_id, std::unique_ptr<AudioServiceCallback>(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
--- /dev/null
+// 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 <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:
+
+ // 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 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(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);
+
+ private:
+ BrilloAudioClient() = default;
+
+ // 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.
+ void OnBASDisconnect();
+
+ // Callback to be triggered when the audio policy service dies. It attempts to
+ // reconnect to the service.
+ void OnAPSDisconnect();
+
+ // 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(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 audio policy service.
+ android::sp<android::IAudioPolicyService> aps_;
+ // 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, std::unique_ptr<AudioServiceCallback> > callback_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrilloAudioClient);
+};
+
+} // namespace brillo
+
+#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_H_
--- /dev/null
+// 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;
+}
+
+} // namespace brillo
--- /dev/null
+// 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);
+};
+
+} // namespace brillo
+
+#endif // BRILLO_AUDIO_AUDIOSERVICE_BRILLO_AUDIO_CLIENT_HELPERS_H_
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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_
--- /dev/null
+// 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;
+ }
+}
+
+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
--- /dev/null
+// 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.
+ 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();
+
+ 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_
--- /dev/null
+ // 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)
+ 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_registerAudioDeviceCallback(
+ const BAudioManager* brillo_audio_manager, const BAudioCallback* callback,
+ void* user_data, int* callback_id) {
+ if (!brillo_audio_manager || !callback || !callback_id)
+ return EINVAL;
+ // This copies the BAudioCallback into AudioServiceCallback so the
+ // BAudioCallback can be safely deleted.
+ auto client = brillo_audio_manager->client_.lock();
+ if (!client) {
+ *callback_id = 0;
+ return ECONNABORTED;
+ }
+ return client->RegisterAudioCallback(
+ new AudioServiceCallback(callback, user_data), callback_id);
+}
+
+int BAudioManager_unregisterAudioDeviceCallback(
+ 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;
+}
--- /dev/null
+// 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.h
+
+#include "brillo_audio_service.h"
+
+using android::binder::Status;
+
+namespace brillo {
+
+Status BrilloAudioService::GetDevices(int flag,
+ std::vector<int>* _aidl_return) {
+ auto device_handler = audio_device_handler_.lock();
+ if (device_handler) {
+ return Status::fromExceptionCode(
+ Status::EX_SERVICE_SPECIFIC,
+ 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::fromExceptionCode(Status::EX_SERVICE_SPECIFIC,
+ android::String8("Invalid flag."));
+ }
+ return Status::ok();
+}
+
+Status BrilloAudioService::RegisterServiceCallback(
+ const android::sp<IAudioServiceCallback>& callback) {
+ callbacks_set_.insert(callback);
+ return Status::ok();
+}
+
+Status BrilloAudioService::UnregisterServiceCallback(
+ const android::sp<IAudioServiceCallback>& callback) {
+ callbacks_set_.erase(callback);
+ return Status::ok();
+}
+
+void BrilloAudioService::RegisterDeviceHandler(
+ std::weak_ptr<AudioDeviceHandler> audio_device_handler) {
+ audio_device_handler_ = audio_device_handler;
+}
+
+void BrilloAudioService::OnDevicesConnected(const std::vector<int>& devices) {
+ for (auto callback : callbacks_set_) {
+ callback->OnAudioDevicesConnected(devices);
+ }
+}
+
+void BrilloAudioService::OnDevicesDisconnected(const std::vector<int>& devices) {
+ for (auto callback : callbacks_set_) {
+ callback->OnAudioDevicesDisconnected(devices);
+ }
+}
+
+} // namespace brillo
--- /dev/null
+// 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 "audio_device_handler.h"
+#include "android/brillo/brilloaudioservice/IAudioServiceCallback.h"
+
+using android::binder::Status;
+using android::brillo::brilloaudioservice::BnBrilloAudioService;
+using android::brillo::brilloaudioservice::IAudioServiceCallback;
+
+namespace brillo {
+
+class BrilloAudioService : public BnBrilloAudioService {
+ public:
+ // From AIDL.
+ Status GetDevices(int flag, std::vector<int>* _aidl_return);
+
+ Status RegisterServiceCallback(
+ const android::sp<IAudioServiceCallback>& callback);
+ Status UnregisterServiceCallback(
+ const android::sp<IAudioServiceCallback>& callback);
+
+ // Register a device handler.
+ //
+ // |audio_device_handler| is a weak pointer to an audio device handler object.
+ void RegisterDeviceHandler(
+ std::weak_ptr<AudioDeviceHandler> audio_device_handler);
+
+ // 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);
+
+ // 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);
+
+ private:
+ // A weak pointer to the audio device handler.
+ std::weak_ptr<AudioDeviceHandler> audio_device_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_H_
service brilloaudioserv /system/bin/brilloaudioservice
class late_start
- user system
+ user audioserver
group input
--- /dev/null
+// 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_
--- /dev/null
+// 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();
+
+// 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
+};
+
+// 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);
+
+// 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);
+};
+
+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_registerAudioDeviceCallback(
+ 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_unregisterAudioDeviceCallback(
+ 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_
--- /dev/null
+// 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, TestAPSConnectInitializesHandlerOnlyOnce);
+ FRIEND_TEST(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL);
+
+ MOCK_METHOD0(InitializeHandler, void());
+};
+
+} // namespace brillo
+
+#endif // BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
--- /dev/null
+// 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, TestAPSConnectInitializesHandlerOnlyOnce) {
+ binder_wrapper()->SetBinderForService("media.audio_policy",
+ binder_wrapper()->CreateLocalBinder());
+ daemon_.handler_initialized_ = false;
+ EXPECT_CALL(daemon_, InitializeHandler()).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
MOCK_METHOD2(NotifyAudioPolicyService,
void(audio_devices_t device, audio_policy_dev_state_t state));
+ MOCK_METHOD1(TriggerCallback, void(DeviceConnectionState));
};
} // namespace brillo
using brillo::AudioDeviceHandlerMock;
using testing::_;
using testing::AnyNumber;
+using testing::AtLeast;
namespace brillo {
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)).Times(3);
handler_.DisconnectAllSupportedDevices();
+ EXPECT_EQ(handler_.changed_devices_.size(), 3);
}
// Test that Init() calls DisconnectAllSupportedDevices().
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);
}
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.
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_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
// 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
event.type = 0;
event.code = 0;
event.value = 0;
+ EXPECT_CALL(handler_, TriggerCallback(_));
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
--- /dev/null
+// 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
--- /dev/null
+// 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
size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
data_capacity);
void *buffer = malloc(memory_needed);
- return place_camera_metadata(buffer, memory_needed,
- entry_capacity,
- data_capacity);
+ camera_metadata_t *metadata = place_camera_metadata(
+ buffer, memory_needed, entry_capacity, data_capacity);
+ if (!metadata) {
+ /* This should not happen when memory_needed is the same
+ * calculated in this function and in place_camera_metadata.
+ */
+ free(buffer);
+ }
+ return metadata;
}
camera_metadata_t *place_camera_metadata(void *dst,