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
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
new file mode 100644
index 0000000..614c58b
--- /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 0000000..419225d
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/AudioControl.cpp
@@ -0,0 +1,86 @@
+#include "AudioControl.h"
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+
+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<AudioResult> AudioControl::setCallback(const sp<IAudioControlCallback>& notificationObject) {
+    // Hang onto the provided callback object for future use
+    callback = notificationObject;
+
+    return AudioResult::OK;
+}
+
+
+Return<int32_t> 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<void> 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<void> 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 0000000..3383875
--- /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 <android/hardware/automotive/audiocontrol/1.0/IAudioControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+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<AudioResult> setCallback(const sp<IAudioControlCallback>& notificationObject) override;
+    Return<int32_t> getBusForContext(uint32_t contextNumber) override;
+    Return<void> setBalanceTowardRight(float value) override;
+    Return<void> setFadeTowardFront(float value) override;
+
+    // Implementation details
+    AudioControl();
+
+private:
+    sp<IAudioControlCallback> 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 0000000..ea79cad
--- /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<void> AudioControlCallback::suggestPausePlayers() {
+    // TODO implement in framework (this is called by the HAL implementation when needed)
+    return Void();
+}
+
+Return<void> AudioControlCallback::suggestStopPlayers() {
+    // TODO implement in framework (this is called by the HAL implementation when needed)
+    return Void();
+}
+
+Return<void> 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 0000000..1054548
--- /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 <android/hardware/automotive/audiocontrol/1.0/IAudioControlCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+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<void> suggestPausePlayers() override;
+    Return<void> suggestStopPlayers() override;
+    Return<void> 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 0000000..79edad6
--- /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 0000000..a033fd9
--- /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 <unistd.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#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<IAudioControl> 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