From 46bc12867bc748eaccf9ea384a8b6cf9a6dfa642 Mon Sep 17 00:00:00 2001 From: Scott Randolph Date: Thu, 27 Jul 2017 18:26:27 -0700 Subject: [PATCH] Define new AudioControl HAL for automotive. This provides a mechanism for Android to interact with a car's audio subsystem. It is a partial replacement for the deprecated AUDIO_* properties in VehicleHal. It also provides control over fade/balance. Bug: 31623564 Test: build for bat_land. VTS tests in future CL. Change-Id: I4344cce3a6aa9a28d1327bf4d16bd080c7fd3f50 --- automotive/audiocontrol/1.0/Android.bp | 23 +++++ automotive/audiocontrol/1.0/IAudioControl.hal | 73 ++++++++++++++++ .../1.0/IAudioControlCallback.hal | 57 ++++++++++++ .../audiocontrol/1.0/default/Android.bp | 40 +++++++++ .../audiocontrol/1.0/default/AudioControl.cpp | 86 +++++++++++++++++++ .../audiocontrol/1.0/default/AudioControl.h | 45 ++++++++++ .../1.0/default/AudioControlCallback.cpp | 31 +++++++ .../1.0/default/AudioControlCallback.h | 41 +++++++++ ...are.automotive.audiocontrol@1.0-service.rc | 4 + .../audiocontrol/1.0/default/service.cpp | 54 ++++++++++++ automotive/audiocontrol/1.0/types.hal | 44 ++++++++++ automotive/evs/1.0/default/Android.bp | 2 +- 12 files changed, 499 insertions(+), 1 deletion(-) create mode 100644 automotive/audiocontrol/1.0/Android.bp create mode 100644 automotive/audiocontrol/1.0/IAudioControl.hal create mode 100644 automotive/audiocontrol/1.0/IAudioControlCallback.hal create mode 100644 automotive/audiocontrol/1.0/default/Android.bp create mode 100644 automotive/audiocontrol/1.0/default/AudioControl.cpp create mode 100644 automotive/audiocontrol/1.0/default/AudioControl.h create mode 100644 automotive/audiocontrol/1.0/default/AudioControlCallback.cpp create mode 100644 automotive/audiocontrol/1.0/default/AudioControlCallback.h create mode 100644 automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc create mode 100644 automotive/audiocontrol/1.0/default/service.cpp create mode 100644 automotive/audiocontrol/1.0/types.hal diff --git a/automotive/audiocontrol/1.0/Android.bp b/automotive/audiocontrol/1.0/Android.bp new file mode 100644 index 0000000000..a9670492cc --- /dev/null +++ b/automotive/audiocontrol/1.0/Android.bp @@ -0,0 +1,23 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.automotive.audiocontrol@1.0", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "types.hal", + "IAudioControl.hal", + "IAudioControlCallback.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + ], + types: [ + "AudioResult", + "ContextNumber", + ], + gen_java: true, +} + diff --git a/automotive/audiocontrol/1.0/IAudioControl.hal b/automotive/audiocontrol/1.0/IAudioControl.hal new file mode 100644 index 0000000000..fe9ea8e938 --- /dev/null +++ b/automotive/audiocontrol/1.0/IAudioControl.hal @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 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.hardware.automotive.audiocontrol@1.0; + +import IAudioControlCallback; + + +/** + * Interacts with the car's audio subsystem to manage audio sources and volumes + */ +interface IAudioControl { + + /** + * Registers the required callback object so that we can be notified when the state + * of the car's audio system changes. This call must be made when the interface is + * initialized. + */ + setCallback(IAudioControlCallback notificationObject) + generates (AudioResult result); + + + /** + * Called at startup once per context to get the mapping from ContextNumber to + * busAddress. This lets the car tell the framework to which physical output stream + * each context should be routed. + * + * For every context, a valid bus number (0 - num busses-1) must be returned. If an + * unrecognized contextNumber is encountered, then -1 shall be returned. + * + * Any context for which an invalid busNumber is returned must be routed to bus 0. + */ + getBusForContext(uint32_t contextNumber) + generates (int32_t busNumber); + + + /** + * Control the right/left balance setting of the car speakers. + * + * This is intended to shift the speaker volume toward the right (+) or left (-) side of + * the car. 0.0 means "centered". +1.0 means fully right. -1.0 means fully left. + * + * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1 + * range. + */ + oneway setBalanceTowardRight(float value); + + + /** + * Control the fore/aft fade setting of the car speakers. + * + * This is intended to shift the speaker volume toward the front (+) or back (-) of the car. + * 0.0 means "centered". +1.0 means fully forward. -1.0 means fully rearward. + * + * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1 + * range. + */ + oneway setFadeTowardFront(float value); +}; + diff --git a/automotive/audiocontrol/1.0/IAudioControlCallback.hal b/automotive/audiocontrol/1.0/IAudioControlCallback.hal new file mode 100644 index 0000000000..f5c227e203 --- /dev/null +++ b/automotive/audiocontrol/1.0/IAudioControlCallback.hal @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 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.hardware.automotive.audiocontrol@1.0; + + +/** + * Implemented on client (framework) side to receive asynchronous updates from the car. + */ +interface IAudioControlCallback { + + /** + * When the HAL makes this call, any apps currently playing must be asked to + * temporarily suspend playback (via an AudioManager::AUDIOFOCUS_LOSS_TRANSIENT event). + * + * This is only a suggestion. Apps may be slow to react or even ignore this message + * entirely. Enforcement, if necessary, must be done at the AudioHAL level as the + * samples are delivered. In most instances, this is the way a car should ask for + * quiet if it needs it for some important situation, such as warning alarms or chimes. + */ + oneway suggestPausePlayers(); + + + /** + * When the HAL makes this case, any apps currently playing must be asked to stop + * playing (via an AudioManager::AUDIOFOCUS_LOSS event). Once stopped, the apps must + * not resume their playback. + * + * It should be noted that not all apps or sound sources honor this request, but this + * at least gives an app the chance to do the right thing. + * Because it premanently stops media, this call is expected to be used only rarely. + * Perhaps in the event of an E-call, where resuming music might be undesirable assuming + * the driver is now dealing with whatever the emergency is? + */ + oneway suggestStopPlayers(); + + + /** + * Receives calls from the HAL when Android should resume normal operations. If the previous + * action was a requestPausePlayers, then things that were paused must be told they may + * resume. + */ + oneway resumePlayers(); +}; diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp new file mode 100644 index 0000000000..614c58b0e0 --- /dev/null +++ b/automotive/audiocontrol/1.0/default/Android.bp @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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. + +cc_binary { + name: "android.hardware.automotive.audiocontrol@1.0-service", + defaults: ["hidl_defaults"], + vendor: true, + relative_install_path: "hw", + srcs: [ + "AudioControl.cpp", + "AudioControlCallback.cpp", + "service.cpp" + ], + init_rc: ["android.hardware.automotive.audiocontrol@1.0-service.rc"], + + shared_libs: [ + "android.hardware.automotive.audiocontrol@1.0", + "libhidlbase", + "libhidltransport", + "liblog", + "libutils", + ], + + cflags: [ + "-DLOG_TAG=\"AudCntrlDrv\"", + "-O0", + "-g", + ], +} diff --git a/automotive/audiocontrol/1.0/default/AudioControl.cpp b/automotive/audiocontrol/1.0/default/AudioControl.cpp new file mode 100644 index 0000000000..419225d201 --- /dev/null +++ b/automotive/audiocontrol/1.0/default/AudioControl.cpp @@ -0,0 +1,86 @@ +#include "AudioControl.h" + +#include +#include + + +namespace android { +namespace hardware { +namespace automotive { +namespace audiocontrol { +namespace V1_0 { +namespace implementation { + + +// This is the static map we're using to associate a ContextNumber with a +// bus number from the audio_policy_configuration.xml setup. Every valid context needs +// to be mapped to a bus address that actually exists in the platforms configuration. +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) // Would be nice if this were common... +static int sContextToBusMap[] = { + -1, // INVALID + 0, // MUSIC_CONTEXT + 1, // NAVIGATION_CONTEXT + 2, // VOICE_COMMAND_CONTEXT + 3, // CALL_RING_CONTEXT + 4, // CALL_CONTEXT + 5, // ALARM_CONTEXT + 6, // NOTIFICATION_CONTEXT + 7, // SYSTEM_SOUND_CONTEXT +}; +static const unsigned sContextMapSize = ARRAY_SIZE(sContextToBusMap); +static const unsigned sContextCount = sContextMapSize - 1; // Less one for the INVALID entry +static const unsigned sContextNumberMax = sContextCount; // contextNumber is counted from 1 + + +AudioControl::AudioControl() { +}; + + +// Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControl follow. +Return AudioControl::setCallback(const sp& notificationObject) { + // Hang onto the provided callback object for future use + callback = notificationObject; + + return AudioResult::OK; +} + + +Return AudioControl::getBusForContext(uint32_t contextNumber) { + if (contextNumber > sContextNumberMax) { + ALOGE("Unexpected context number %d (max expected is %d)", contextNumber, sContextCount); + return -1; + } else { + return sContextToBusMap[contextNumber]; + } +} + + +Return AudioControl::setBalanceTowardRight(float value) { + // For completeness, lets bounds check the input... + if ((value > 1.0f) || (value < -1.0f)) { + ALOGE("Balance value out of range -1 to 1 at %0.2f", value); + } else { + // Just log in this default mock implementation + ALOGI("Balance set to %0.2f", value); + } + return Void(); +} + + +Return AudioControl::setFadeTowardFront(float value) { + // For completeness, lets bounds check the input... + if ((value > 1.0f) || (value < -1.0f)) { + ALOGE("Fader value out of range -1 to 1 at %0.2f", value); + } else { + // Just log in this default mock implementation + ALOGI("Fader set to %0.2f", value); + } + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace audiocontrol +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/audiocontrol/1.0/default/AudioControl.h b/automotive/audiocontrol/1.0/default/AudioControl.h new file mode 100644 index 0000000000..33838755d4 --- /dev/null +++ b/automotive/audiocontrol/1.0/default/AudioControl.h @@ -0,0 +1,45 @@ +#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H +#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H + +#include +#include +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace audiocontrol { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +struct AudioControl : public IAudioControl { +public: + // Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControl follow. + Return setCallback(const sp& notificationObject) override; + Return getBusForContext(uint32_t contextNumber) override; + Return setBalanceTowardRight(float value) override; + Return setFadeTowardFront(float value) override; + + // Implementation details + AudioControl(); + +private: + sp callback; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace audiocontrol +} // namespace automotive +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H diff --git a/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp b/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp new file mode 100644 index 0000000000..ea79cada0c --- /dev/null +++ b/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp @@ -0,0 +1,31 @@ +#include "AudioControlCallback.h" + +namespace android { +namespace hardware { +namespace automotive { +namespace audiocontrol { +namespace V1_0 { +namespace implementation { + +// Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControlCallback follow. +Return AudioControlCallback::suggestPausePlayers() { + // TODO implement in framework (this is called by the HAL implementation when needed) + return Void(); +} + +Return AudioControlCallback::suggestStopPlayers() { + // TODO implement in framework (this is called by the HAL implementation when needed) + return Void(); +} + +Return AudioControlCallback::resumePlayers() { + // TODO implement in framework (this is called by the HAL implementation when needed) + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace audiocontrol +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/audiocontrol/1.0/default/AudioControlCallback.h b/automotive/audiocontrol/1.0/default/AudioControlCallback.h new file mode 100644 index 0000000000..10545485ed --- /dev/null +++ b/automotive/audiocontrol/1.0/default/AudioControlCallback.h @@ -0,0 +1,41 @@ +#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H +#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H + +#include +#include +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace audiocontrol { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +// TODO: Move this into packages/services/Car... +struct AudioControlCallback : public IAudioControlCallback { + // Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControlCallback follow. + Return suggestPausePlayers() override; + Return suggestStopPlayers() override; + Return resumePlayers() override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. + +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace audiocontrol +} // namespace automotive +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H diff --git a/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc b/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc new file mode 100644 index 0000000000..79edad69fd --- /dev/null +++ b/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc @@ -0,0 +1,4 @@ +service vendor.evs-hal-mock /vendor/bin/hw/android.hardware.automotive.audiocontrol@1.0-service + class hal + user audioserver + group system diff --git a/automotive/audiocontrol/1.0/default/service.cpp b/automotive/audiocontrol/1.0/default/service.cpp new file mode 100644 index 0000000000..a033fd909f --- /dev/null +++ b/automotive/audiocontrol/1.0/default/service.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 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 + +#include +#include +#include +#include + +#include "AudioControl.h" + + +// libhidl: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::automotive::audiocontrol::V1_0::IAudioControl; + +// The namespace in which all our implementation code lives +using namespace android::hardware::automotive::audiocontrol::V1_0::implementation; +using namespace android; + + +// Main service entry point +int main() { + // Create an instance of our service class + android::sp service = new AudioControl(); + configureRpcThreadpool(1, true /*callerWillJoin*/); + + if (service->registerAsService() != OK) { + ALOGE("registerAsService failed"); + return 1; + } + + // Join (forever) the thread pool we created for the service above + joinRpcThreadpool(); + + // We don't ever actually expect to return, so return an error if we do get here + return 2; +} \ No newline at end of file diff --git a/automotive/audiocontrol/1.0/types.hal b/automotive/audiocontrol/1.0/types.hal new file mode 100644 index 0000000000..6301d3a4e7 --- /dev/null +++ b/automotive/audiocontrol/1.0/types.hal @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2017 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.hardware.automotive.audiocontrol@1.0; + + +/** + * Predefined flags to identifying audio contexts + */ +enum ContextNumber : uint32_t { + INVALID = 0, /* Shouldn't be used */ + + // Sounds from Android (counting from 1 coincidentally lets us match AudioAttributes usages) + MUSIC, /* Music playback */ + NAVIGATION, /* Navigation directions */ + VOICE_COMMAND, /* Voice command session */ + CALL_RING, /* Voice call ringing */ + CALL, /* Voice call */ + ALARM, /* Alarm sound from Android */ + NOTIFICATION, /* Notifications */ + SYSTEM_SOUND, /* User interaction sounds (button clicks, etc) */ +}; + + +/** Error codes used in AudioControl HAL interface. */ +enum AudioResult : uint32_t { + OK = 0, + NOT_AVAILABLE, + INVALID_ARGUMENT, + UNDERLYING_SERVICE_ERROR, +}; diff --git a/automotive/evs/1.0/default/Android.bp b/automotive/evs/1.0/default/Android.bp index 2574e860b2..7286478a84 100644 --- a/automotive/evs/1.0/default/Android.bp +++ b/automotive/evs/1.0/default/Android.bp @@ -13,7 +13,6 @@ cc_binary { shared_libs: [ "android.hardware.automotive.evs@1.0", - "libui", "libbase", "libbinder", "libcutils", @@ -21,6 +20,7 @@ cc_binary { "libhidlbase", "libhidltransport", "liblog", + "libui", "libutils", ],