Merge changes from topics \'cam-ndk-hidden-enum\', \'cam-ndk-enum-dco\', \'cam-ndk-hidden-keys\' into nyc-dev
am: b1379bd
* commit 'b1379bdb8fe4ddf1e052bff5e76703f70ec4afab':
Camera: hide some enum values in NDK
Camera: codegen NDK metadata enum value documents
Camera: modify metadata visibility attributes
Change-Id: Ife5a241f013a3f4bac5b41fc2b358005c8cb6a7b
diff --git a/audio_utils/Android.mk b/audio_utils/Android.mk
index e3b63f5..32c94e2 100644
--- a/audio_utils/Android.mk
+++ b/audio_utils/Android.mk
@@ -18,6 +18,7 @@
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) \
@@ -91,6 +92,7 @@
primitives.c \
roundup.c
+LOCAL_CFLAGS := -Wno-unused-parameter
LOCAL_C_INCLUDES += \
$(call include-path-for, audio-utils)
diff --git a/audio_utils/spdif/AC3FrameScanner.cpp b/audio_utils/spdif/AC3FrameScanner.cpp
index ab47274..4055bb0 100644
--- a/audio_utils/spdif/AC3FrameScanner.cpp
+++ b/audio_utils/spdif/AC3FrameScanner.cpp
@@ -92,12 +92,13 @@
// -----------------------------------------------------------------------------
// 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));
@@ -240,6 +241,14 @@
* 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",
diff --git a/audio_utils/spdif/AC3FrameScanner.h b/audio_utils/spdif/AC3FrameScanner.h
index 1ef5610..7cdba84 100644
--- a/audio_utils/spdif/AC3FrameScanner.h
+++ b/audio_utils/spdif/AC3FrameScanner.h
@@ -18,6 +18,7 @@
#define ANDROID_AUDIO_AC3_FRAME_SCANNER_H
#include <stdint.h>
+#include <hardware/audio.h>
#include <audio_utils/spdif/FrameScanner.h>
namespace android {
@@ -34,7 +35,7 @@
class AC3FrameScanner : public FrameScanner
{
public:
- AC3FrameScanner();
+ AC3FrameScanner(audio_format_t format);
virtual ~AC3FrameScanner();
virtual int getMaxChannels() const { return 5 + 1; } // 5.1 surround
@@ -58,6 +59,7 @@
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[];
diff --git a/audio_utils/spdif/SPDIFEncoder.cpp b/audio_utils/spdif/SPDIFEncoder.cpp
index 8e7e6cd..efcd556 100644
--- a/audio_utils/spdif/SPDIFEncoder.cpp
+++ b/audio_utils/spdif/SPDIFEncoder.cpp
@@ -48,7 +48,7 @@
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:
diff --git a/brillo/audio/audioservice/Android.mk b/brillo/audio/audioservice/Android.mk
index 8d4fb15..09da9f7 100644
--- a/brillo/audio/audioservice/Android.mk
+++ b/brillo/audio/audioservice/Android.mk
@@ -15,6 +15,7 @@
LOCAL_PATH := $(call my-dir)
audio_service_shared_libraries := \
+ libbinder \
libbinderwrapper \
libbrillo \
libbrillo-binder \
@@ -23,14 +24,21 @@
libmedia \
libutils
+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
@@ -41,10 +49,14 @@
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 \
diff --git a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl
new file mode 100644
index 0000000..01e8ba2
--- /dev/null
+++ b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IAudioServiceCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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);
+}
diff --git a/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl
new file mode 100644
index 0000000..dce7f81
--- /dev/null
+++ b/brillo/audio/audioservice/aidl/android/brillo/brilloaudioservice/IBrilloAudioService.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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);
+}
diff --git a/brillo/audio/audioservice/audio_daemon.cpp b/brillo/audio/audioservice/audio_daemon.cpp
index f764f1a..547b116 100644
--- a/brillo/audio/audioservice/audio_daemon.cpp
+++ b/brillo/audio/audioservice/audio_daemon.cpp
@@ -26,15 +26,29 @@
#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.
@@ -48,17 +62,30 @@
// 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() {
@@ -107,7 +134,7 @@
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));
@@ -118,4 +145,21 @@
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
diff --git a/brillo/audio/audioservice/audio_daemon.h b/brillo/audio/audioservice/audio_daemon.h
index 48aa35f..2358012 100644
--- a/brillo/audio/audioservice/audio_daemon.h
+++ b/brillo/audio/audioservice/audio_daemon.h
@@ -20,6 +20,7 @@
#include <memory>
#include <stack>
+#include <vector>
#include <base/files/file.h>
#include <base/memory/weak_ptr.h>
@@ -28,12 +29,14 @@
#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
@@ -41,9 +44,22 @@
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();
@@ -52,18 +68,21 @@
// 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.
@@ -71,7 +90,9 @@
// 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
diff --git a/brillo/audio/audioservice/audio_device_handler.cpp b/brillo/audio/audioservice/audio_device_handler.cpp
index af12c96..d4aac92 100644
--- a/brillo/audio/audioservice/audio_device_handler.cpp
+++ b/brillo/audio/audioservice/audio_device_handler.cpp
@@ -19,6 +19,7 @@
#include <base/files/file.h>
#include <base/logging.h>
+#include <brillo/message_loops/message_loop.h>
#include <media/AudioSystem.h>
namespace brillo {
@@ -32,6 +33,35 @@
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();
}
@@ -54,6 +84,7 @@
// 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.";
@@ -65,8 +96,8 @@
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;
@@ -104,6 +135,7 @@
connected_input_devices_.insert(device);
else
connected_output_devices_.insert(device);
+ changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAudioDevice(audio_devices_t device) {
@@ -113,6 +145,7 @@
connected_input_devices_.erase(device);
else
connected_output_devices_.erase(device);
+ changed_devices_.push_back(device);
}
void AudioDeviceHandler::DisconnectAllSupportedDevices() {
@@ -147,7 +180,11 @@
// 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) {
diff --git a/brillo/audio/audioservice/audio_device_handler.h b/brillo/audio/audioservice/audio_device_handler.h
index 335ae98..a5e0daa 100644
--- a/brillo/audio/audioservice/audio_device_handler.h
+++ b/brillo/audio/audioservice/audio_device_handler.h
@@ -23,6 +23,7 @@
#include <set>
#include <vector>
+#include <base/bind.h>
#include <base/files/file_path.h>
#include <gtest/gtest_prod.h>
#include <linux/input.h>
@@ -59,6 +60,33 @@
// |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,
@@ -125,6 +153,11 @@
// 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};
@@ -139,12 +172,17 @@
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
diff --git a/brillo/audio/audioservice/brillo_audio_service.cpp b/brillo/audio/audioservice/brillo_audio_service.cpp
new file mode 100644
index 0000000..b1c4fcb
--- /dev/null
+++ b/brillo/audio/audioservice/brillo_audio_service.cpp
@@ -0,0 +1,72 @@
+// 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
diff --git a/brillo/audio/audioservice/brillo_audio_service.h b/brillo/audio/audioservice/brillo_audio_service.h
new file mode 100644
index 0000000..d0dc18b
--- /dev/null
+++ b/brillo/audio/audioservice/brillo_audio_service.h
@@ -0,0 +1,71 @@
+// 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_
diff --git a/brillo/audio/audioservice/brilloaudioserv.rc b/brillo/audio/audioservice/brilloaudioserv.rc
index a9b3898..0595c33 100644
--- a/brillo/audio/audioservice/brilloaudioserv.rc
+++ b/brillo/audio/audioservice/brilloaudioserv.rc
@@ -1,4 +1,4 @@
service brilloaudioserv /system/bin/brilloaudioservice
class late_start
- user system
+ user audioserver
group input
diff --git a/brillo/audio/audioservice/test/audio_daemon_mock.h b/brillo/audio/audioservice/test/audio_daemon_mock.h
new file mode 100644
index 0000000..b01e947
--- /dev/null
+++ b/brillo/audio/audioservice/test/audio_daemon_mock.h
@@ -0,0 +1,44 @@
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Mock of audio daemon.
+
+#ifndef BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
+#define BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <gtest/gtest_prod.h>
+
+#include "audio_daemon.h"
+
+namespace brillo {
+
+class AudioDaemonMock : public AudioDaemon {
+ public:
+ AudioDaemonMock() = default;
+ ~AudioDaemonMock() {}
+
+ private:
+ friend class AudioDaemonTest;
+ FRIEND_TEST(AudioDaemonTest, RegisterService);
+ FRIEND_TEST(AudioDaemonTest, TestAPSConnectInitializesHandlerOnlyOnce);
+ FRIEND_TEST(AudioDaemonTest, TestDeviceCallbackInitializesBASIfNULL);
+
+ MOCK_METHOD0(InitializeHandler, void());
+};
+
+} // namespace brillo
+
+#endif // BRILLO_AUDIO_AUDIOSERVICE_TEST_AUDIO_DAEMON_MOCK_H_
diff --git a/brillo/audio/audioservice/test/audio_daemon_test.cpp b/brillo/audio/audioservice/test/audio_daemon_test.cpp
new file mode 100644
index 0000000..0ad7535
--- /dev/null
+++ b/brillo/audio/audioservice/test/audio_daemon_test.cpp
@@ -0,0 +1,68 @@
+// Copyright 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Tests for audio daemon.
+
+#include "audio_daemon_mock.h"
+
+#include <memory>
+#include <vector>
+
+#include <binder/Binder.h>
+#include <binderwrapper/binder_test_base.h>
+#include <binderwrapper/stub_binder_wrapper.h>
+#include <gmock/gmock.h>
+
+#include "audio_device_handler_mock.h"
+
+using android::BinderTestBase;
+using android::IInterface;
+using std::make_shared;
+using testing::_;
+using testing::AnyNumber;
+
+namespace brillo {
+
+class AudioDaemonTest : public BinderTestBase {
+ public:
+ AudioDaemonMock daemon_;
+ AudioDeviceHandlerMock device_handler_;
+};
+
+TEST_F(AudioDaemonTest, RegisterService) {
+ daemon_.InitializeBrilloAudioService();
+ EXPECT_EQ(daemon_.brillo_audio_service_,
+ binder_wrapper()->GetRegisteredService(
+ "android.brillo.brilloaudioservice.BrilloAudioService"));
+}
+
+TEST_F(AudioDaemonTest, 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
diff --git a/brillo/audio/audioservice/test/audio_device_handler_mock.h b/brillo/audio/audioservice/test/audio_device_handler_mock.h
index ce6dfd3..fcc711f 100644
--- a/brillo/audio/audioservice/test/audio_device_handler_mock.h
+++ b/brillo/audio/audioservice/test/audio_device_handler_mock.h
@@ -72,6 +72,7 @@
MOCK_METHOD2(NotifyAudioPolicyService,
void(audio_devices_t device, audio_policy_dev_state_t state));
+ MOCK_METHOD1(TriggerCallback, void(DeviceConnectionState));
};
} // namespace brillo
diff --git a/brillo/audio/audioservice/test/audio_device_handler_test.cpp b/brillo/audio/audioservice/test/audio_device_handler_test.cpp
index 5487469..d14faa0 100644
--- a/brillo/audio/audioservice/test/audio_device_handler_test.cpp
+++ b/brillo/audio/audioservice/test/audio_device_handler_test.cpp
@@ -33,6 +33,7 @@
using brillo::AudioDeviceHandlerMock;
using testing::_;
using testing::AnyNumber;
+using testing::AtLeast;
namespace brillo {
@@ -67,6 +68,7 @@
NotifyAudioPolicyService(
_, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)).Times(3);
handler_.DisconnectAllSupportedDevices();
+ EXPECT_EQ(handler_.changed_devices_.size(), 3);
}
// Test that Init() calls DisconnectAllSupportedDevices().
@@ -74,9 +76,15 @@
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);
}
@@ -86,11 +94,15 @@
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.
@@ -99,16 +111,22 @@
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));
@@ -122,6 +140,7 @@
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
@@ -129,9 +148,11 @@
// 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
@@ -150,6 +171,7 @@
event.type = 0;
event.code = 0;
event.value = 0;
+ EXPECT_CALL(handler_, TriggerCallback(_));
handler_.ProcessEvent(event);
EXPECT_FALSE(handler_.headphone_);
EXPECT_FALSE(handler_.microphone_);
@@ -215,7 +237,10 @@
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.
@@ -225,9 +250,13 @@
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.
@@ -237,9 +266,13 @@
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.
@@ -256,9 +289,12 @@
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.
@@ -267,9 +303,13 @@
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.
@@ -278,9 +318,13 @@
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.
@@ -293,9 +337,12 @@
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.
@@ -309,6 +356,8 @@
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.
@@ -322,6 +371,8 @@
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.
@@ -335,6 +386,8 @@
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.
@@ -348,6 +401,8 @@
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
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c
index c58a966..aa94e93 100644
--- a/camera/src/camera_metadata.c
+++ b/camera/src/camera_metadata.c
@@ -199,9 +199,15 @@
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,