audio: Implement audio HAL V7.1

Split PrimaryDevice into parts which implement
IDevice and IPrimaryDevice.

Implement new methods from V7.1.

Bug: 214426419
Test: atest VtsHalAudioV7_0TargetTest
Test: atest VtsHalAudioV7_1TargetTest
Change-Id: I11cce585a80bd2ded3709bf467c7e5f0dc1e9831
(cherry picked from commit c9b2d3e4a15259089398c2c15bfb25532c1661a6)
Merged-In: I11cce585a80bd2ded3709bf467c7e5f0dc1e9831
diff --git a/audio/Android.bp b/audio/Android.bp
index cc60168..f12f1c4 100644
--- a/audio/Android.bp
+++ b/audio/Android.bp
@@ -102,3 +102,34 @@
         "audio.r_submix.default",
     ],
 }
+
+cc_library_shared {
+    name: "android.hardware.audio.legacy@7.1-impl.ranchu",
+    defaults: ["android.hardware.audio@7.1-impl_default"],
+    relative_install_path: "hw",
+    vendor: true,
+}
+
+cc_library_shared {
+    name: "android.hardware.audio@7.1-impl.ranchu",
+    defaults: ["android.hardware.audio@7.x-impl.ranchu_default"],
+    vintf_fragments: ["android.hardware.audio@7.1-impl.ranchu.xml"],
+    shared_libs: [
+        "android.hardware.audio@7.1",
+        "android.hardware.audio.common@7.1-enums",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"android.hardware.audio@7.1-impl.ranchu\"",
+        "-DMAJOR_VERSION=7",
+        "-DMINOR_VERSION=1",
+        "-DCOMMON_TYPES_MINOR_VERSION=0",
+        "-DCORE_TYPES_MINOR_VERSION=0",
+    ],
+    // a.h.audio@X.0-impl.ranchu (see above) loads a.h.audio.legacy@X.0-impl
+    // which loads audio.r_submix.default which provides the r_submix device,
+    // see b/161485545. Should be retired once a better r_submix is available.
+    required: [
+        "android.hardware.audio.legacy@7.1-impl.ranchu",
+        "audio.r_submix.default",
+    ],
+}
diff --git a/audio/android.hardware.audio@7.1-impl.ranchu.xml b/audio/android.hardware.audio@7.1-impl.ranchu.xml
new file mode 100644
index 0000000..57ccd0d
--- /dev/null
+++ b/audio/android.hardware.audio@7.1-impl.ranchu.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.audio</name>
+        <transport>hwbinder</transport>
+        <version>7.1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/audio/device_factory.cpp b/audio/device_factory.cpp
index 084e9b1..788893b 100644
--- a/audio/device_factory.cpp
+++ b/audio/device_factory.cpp
@@ -67,6 +67,28 @@
     return Void();
 }
 
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> DevicesFactory::openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) {
+    if (device == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+        auto primary = sp<PrimaryDevice>::make();
+        auto getDeviceRet = primary->getDevice();
+        if (getDeviceRet.isOk()) {
+            _hidl_cb(Result::OK, getDeviceRet);
+        } else {
+            _hidl_cb(Result::NOT_INITIALIZED, nullptr);
+        }
+    } else {
+        mLegacyFactory->openDevice_7_1(device, _hidl_cb);
+    }
+    return Void();
+}
+
+Return<void> DevicesFactory::openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) {
+    _hidl_cb(Result::OK, new PrimaryDevice);
+    return Void();
+}
+#endif
+
 }  // namespace implementation
 }  // namespace CPP_VERSION
 }  // namespace audio
diff --git a/audio/device_factory.h b/audio/device_factory.h
index cb2881d..1bc06b2 100644
--- a/audio/device_factory.h
+++ b/audio/device_factory.h
@@ -34,6 +34,10 @@
 
     Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override;
     Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override;
+    Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override;
+#endif
 
 private:
     struct DLDeleter {
diff --git a/audio/primary_device.cpp b/audio/primary_device.cpp
index 941e398..1273337 100644
--- a/audio/primary_device.cpp
+++ b/audio/primary_device.cpp
@@ -38,13 +38,13 @@
 
 using ::android::hardware::Void;
 
-PrimaryDevice::PrimaryDevice() {}
+Device::Device() {}
 
-Return<Result> PrimaryDevice::initCheck() {
+Return<Result> Device::initCheck() {
     return Result::OK;
 }
 
-Return<Result> PrimaryDevice::setMasterVolume(float volume) {
+Return<Result> Device::setMasterVolume(float volume) {
     if (isnan(volume) || volume < 0 || volume > 1.0) {
         return FAILURE(Result::INVALID_ARGUMENTS);
     }
@@ -54,35 +54,34 @@
     return Result::OK;
 }
 
-Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
+Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
     _hidl_cb(Result::OK, mMasterVolume);
     return Void();
 }
 
-Return<Result> PrimaryDevice::PrimaryDevice::setMicMute(bool mute) {
+Return<Result> Device::setMicMute(bool mute) {
     mMicMute = mute;
     updateInputStreamMicMute(mute);
     return Result::OK;
 }
 
-Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
+Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
     _hidl_cb(Result::OK, mMicMute);
     return Void();
 }
 
-Return<Result> PrimaryDevice::setMasterMute(bool mute) {
+Return<Result> Device::setMasterMute(bool mute) {
     mMasterMute = mute;
     updateOutputStreamVolume(mute ? 0.0f : mMasterVolume);
     return Result::OK;
 }
 
-Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
+Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
     _hidl_cb(Result::OK, mMasterMute);
     return Void();
 }
 
-Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
-                                               getInputBufferSize_cb _hidl_cb) {
+Return<void> Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
     AudioConfig suggestedConfig;
     if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
         const size_t sz =
@@ -98,81 +97,37 @@
     return Void();
 }
 
-Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
-                                             const DeviceAddress& device,
-                                             const AudioConfig& config,
-                                             const hidl_vec<AudioInOutFlag>& flags,
-                                             const SourceMetadata& sourceMetadata,
-                                             openOutputStream_cb _hidl_cb) {
-    if (!StreamOut::validateDeviceAddress(device)
-            || !util::checkAudioConfig(config)
-            || !StreamOut::validateFlags(flags)
-            || !StreamOut::validateSourceMetadata(sourceMetadata)) {
-        _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), {}, {});
-        return Void();
-    }
-
-    AudioConfig suggestedConfig;
-    if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) {
-        auto stream = std::make_unique<StreamOut>(
-            this, ioHandle, device, suggestedConfig, flags, sourceMetadata);
-
-        stream->setMasterVolume(mMasterMute ? 0.0f : mMasterVolume);
-
-        {
-            std::lock_guard<std::mutex> guard(mMutex);
-            LOG_ALWAYS_FATAL_IF(!mOutputStreams.insert(stream.get()).second);
-        }
-
-        _hidl_cb(Result::OK, stream.release(), suggestedConfig);
-    } else {
-        _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), {}, suggestedConfig);
-    }
-
+Return<void> Device::openOutputStream(int32_t ioHandle,
+                                      const DeviceAddress& device,
+                                      const AudioConfig& config,
+                                      const hidl_vec<AudioInOutFlag>& flags,
+                                      const SourceMetadata& sourceMetadata,
+                                      openOutputStream_cb _hidl_cb) {
+    auto [result, stream, cfg] = openOutputStreamImpl(ioHandle, device,
+            config, flags, sourceMetadata);
+    _hidl_cb(result, stream, cfg);
     return Void();
 }
 
-Return<void> PrimaryDevice::openInputStream(int32_t ioHandle,
-                                            const DeviceAddress& device,
-                                            const AudioConfig& config,
-                                            const hidl_vec<AudioInOutFlag>& flags,
-                                            const SinkMetadata& sinkMetadata,
-                                            openInputStream_cb _hidl_cb) {
-    if (!StreamIn::validateDeviceAddress(device)
-            || !util::checkAudioConfig(config)
-            || !StreamIn::validateFlags(flags)
-            || !StreamIn::validateSinkMetadata(sinkMetadata)) {
-        _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), {}, {});
-        return Void();
-    }
-
-    AudioConfig suggestedConfig;
-    if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
-        auto stream = std::make_unique<StreamIn>(
-            this, ioHandle, device, suggestedConfig, flags, sinkMetadata);
-
-        stream->setMicMute(mMicMute);
-
-        {
-            std::lock_guard<std::mutex> guard(mMutex);
-            LOG_ALWAYS_FATAL_IF(!mInputStreams.insert(stream.get()).second);
-        }
-
-        _hidl_cb(Result::OK, stream.release(), suggestedConfig);
-    } else {
-        _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), {}, suggestedConfig);
-    }
-
+Return<void> Device::openInputStream(int32_t ioHandle,
+                                     const DeviceAddress& device,
+                                     const AudioConfig& config,
+                                     const hidl_vec<AudioInOutFlag>& flags,
+                                     const SinkMetadata& sinkMetadata,
+                                     openInputStream_cb _hidl_cb) {
+    auto [result, stream, cfg] = openInputStreamImpl(ioHandle, device,
+            config, flags, sinkMetadata);
+    _hidl_cb(result, stream, cfg);
     return Void();
 }
 
-Return<bool> PrimaryDevice::supportsAudioPatches() {
+Return<bool> Device::supportsAudioPatches() {
     return true;
 }
 
-Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
-                                             const hidl_vec<AudioPortConfig>& sinks,
-                                             createAudioPatch_cb _hidl_cb) {
+Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
+                                      const hidl_vec<AudioPortConfig>& sinks,
+                                      createAudioPatch_cb _hidl_cb) {
     if (sources.size() == 1 && sinks.size() == 1) {
         AudioPatch patch;
         if (!util::checkAudioPortConfig(sources[0]) || !util::checkAudioPortConfig(sinks[0])) {
@@ -199,10 +154,10 @@
     return Void();
 }
 
-Return<void> PrimaryDevice::updateAudioPatch(AudioPatchHandle previousPatchHandle,
-                                             const hidl_vec<AudioPortConfig>& sources,
-                                             const hidl_vec<AudioPortConfig>& sinks,
-                                             updateAudioPatch_cb _hidl_cb) {
+Return<void> Device::updateAudioPatch(AudioPatchHandle previousPatchHandle,
+                                      const hidl_vec<AudioPortConfig>& sources,
+                                      const hidl_vec<AudioPortConfig>& sinks,
+                                      updateAudioPatch_cb _hidl_cb) {
     const auto i = mAudioPatches.find(previousPatchHandle);
     if (i == mAudioPatches.end()) {
         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), previousPatchHandle);
@@ -222,33 +177,33 @@
     return Void();
 }
 
-Return<Result> PrimaryDevice::releaseAudioPatch(AudioPatchHandle patchHandle) {
+Return<Result> Device::releaseAudioPatch(AudioPatchHandle patchHandle) {
     return (mAudioPatches.erase(patchHandle) == 1) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
 }
 
-Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
+Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), port);
     return Void();
 }
 
-Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
+Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
     (void)config;
     return FAILURE(Result::NOT_SUPPORTED);
 }
 
-Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
+Return<Result> Device::setScreenState(bool turnedOn) {
     (void)turnedOn;
     return Result::OK;
 }
 
-Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+Return<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) {
     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
     return Void();
 }
 
-Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
-                                          const hidl_vec<hidl_string>& keys,
-                                          getParameters_cb _hidl_cb) {
+Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context,
+                                   const hidl_vec<hidl_string>& keys,
+                                   getParameters_cb _hidl_cb) {
     (void)context;
     if (keys.size() == 0) {
         _hidl_cb(Result::OK, {});
@@ -258,43 +213,267 @@
     return Void();
 }
 
-Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
-                                            const hidl_vec<ParameterValue>& parameters) {
+Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context,
+                                     const hidl_vec<ParameterValue>& parameters) {
     (void)context;
     (void)parameters;
     return Result::OK;
 }
 
-Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
+Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) {
     _hidl_cb(Result::OK, {util::getMicrophoneInfo()});
     return Void();
 }
 
-Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
+Return<Result> Device::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
     (void)dev_addr;
     (void)connected;
     return FAILURE(Result::NOT_SUPPORTED);
 }
 
-Return<Result> PrimaryDevice::close() {
+Return<Result> Device::close() {
     std::lock_guard<std::mutex> guard(mMutex);
 
     return (mInputStreams.empty() && mOutputStreams.empty())
         ? Result::OK : FAILURE(Result::INVALID_STATE);
 }
 
-Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+Return<Result> Device::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
     (void)device;
     (void)effectId;
     return FAILURE(Result::NOT_SUPPORTED);
 }
 
-Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+Return<Result> Device::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
     (void)device;
     (void)effectId;
     return FAILURE(Result::NOT_SUPPORTED);
 }
 
+void Device::unrefDevice(StreamIn *sin) {
+    std::lock_guard<std::mutex> guard(mMutex);
+    LOG_ALWAYS_FATAL_IF(mInputStreams.erase(sin) < 1);
+}
+
+void Device::unrefDevice(StreamOut *sout) {
+    std::lock_guard<std::mutex> guard(mMutex);
+    LOG_ALWAYS_FATAL_IF(mOutputStreams.erase(sout) < 1);
+}
+
+void Device::updateOutputStreamVolume(float masterVolume) const {
+    std::lock_guard<std::mutex> guard(mMutex);
+    for (StreamOut *stream : mOutputStreams) {
+        stream->setMasterVolume(masterVolume);
+    }
+}
+
+void Device::updateInputStreamMicMute(bool micMute) const {
+    std::lock_guard<std::mutex> guard(mMutex);
+    for (StreamIn *stream : mInputStreams) {
+        stream->setMicMute(micMute);
+    }
+}
+
+std::tuple<Result, sp<IStreamOut>, AudioConfig> Device::openOutputStreamImpl(
+        int32_t ioHandle, const DeviceAddress& device,
+        const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+        const SourceMetadata& sourceMetadata) {
+    if (!StreamOut::validateDeviceAddress(device)
+            || !util::checkAudioConfig(config)
+            || !StreamOut::validateFlags(flags)
+            || !StreamOut::validateSourceMetadata(sourceMetadata)) {
+        return {FAILURE(Result::INVALID_ARGUMENTS), {}, {}};
+    }
+
+    AudioConfig suggestedConfig;
+    if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) {
+        auto stream = std::make_unique<StreamOut>(
+            this, ioHandle, device, suggestedConfig, flags, sourceMetadata);
+
+        stream->setMasterVolume(mMasterMute ? 0.0f : mMasterVolume);
+
+        {
+            std::lock_guard<std::mutex> guard(mMutex);
+            LOG_ALWAYS_FATAL_IF(!mOutputStreams.insert(stream.get()).second);
+        }
+
+        return {Result::OK, stream.release(), suggestedConfig};
+    }
+    return {FAILURE(Result::INVALID_ARGUMENTS), {}, suggestedConfig};
+}
+
+std::tuple<Result, sp<IStreamIn>, AudioConfig> Device::openInputStreamImpl(
+        int32_t ioHandle, const DeviceAddress& device,
+        const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+        const SinkMetadata& sinkMetadata) {
+    if (!StreamIn::validateDeviceAddress(device)
+            || !util::checkAudioConfig(config)
+            || !StreamIn::validateFlags(flags)
+            || !StreamIn::validateSinkMetadata(sinkMetadata)) {
+        return {FAILURE(Result::INVALID_ARGUMENTS), {}, {}};
+    }
+
+    AudioConfig suggestedConfig;
+    if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
+        auto stream = std::make_unique<StreamIn>(
+            this, ioHandle, device, suggestedConfig, flags, sinkMetadata);
+
+        stream->setMicMute(mMicMute);
+
+        {
+            std::lock_guard<std::mutex> guard(mMutex);
+            LOG_ALWAYS_FATAL_IF(!mInputStreams.insert(stream.get()).second);
+        }
+
+        return {Result::OK, stream.release(), suggestedConfig};
+    }
+    return {FAILURE(Result::INVALID_ARGUMENTS), {}, suggestedConfig};
+}
+
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<void> Device::openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+        const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+        const SourceMetadata& sourceMetadata, openOutputStream_7_1_cb _hidl_cb) {
+    auto [result, stream, cfg] = openOutputStreamImpl(ioHandle, device,
+            config, flags, sourceMetadata);
+    _hidl_cb(result, stream, cfg);
+    return Void();
+}
+
+Return<void> Device::openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+        const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+        const SinkMetadata& sinkMetadata, openInputStream_7_1_cb _hidl_cb) {
+    auto [result, stream, cfg] = openInputStreamImpl(ioHandle, device,
+            config, flags, sinkMetadata);
+    _hidl_cb(result, stream, cfg);
+    return Void();
+}
+#endif
+
+// ==================
+
+PrimaryDevice::PrimaryDevice() : mDevice(sp<Device>::make()) {
+}
+
+Return<Result> PrimaryDevice::initCheck() {
+    return mDevice->initCheck();
+}
+
+Return<Result> PrimaryDevice::setMasterVolume(float volume) {
+    return mDevice->setMasterVolume(volume);
+}
+
+Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
+    return mDevice->getMasterVolume(_hidl_cb);
+}
+
+Return<Result> PrimaryDevice::setMicMute(bool mute) {
+    return mDevice->setMicMute(mute);
+}
+
+Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
+    return mDevice->getMicMute(_hidl_cb);
+}
+
+Return<Result> PrimaryDevice::setMasterMute(bool mute) {
+    return mDevice->setMasterMute(mute);
+}
+
+Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
+    return mDevice->getMasterMute(_hidl_cb);
+}
+
+Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
+                                               getInputBufferSize_cb _hidl_cb) {
+    return mDevice->getInputBufferSize(config, _hidl_cb);
+}
+
+Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
+                                             const DeviceAddress& device,
+                                             const AudioConfig& config,
+                                             const hidl_vec<AudioInOutFlag>& flags,
+                                             const SourceMetadata& sourceMetadata,
+                                             openOutputStream_cb _hidl_cb) {
+    return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb);
+}
+
+Return<void> PrimaryDevice::openInputStream(int32_t ioHandle,
+                                            const DeviceAddress& device,
+                                            const AudioConfig& config,
+                                            const hidl_vec<AudioInOutFlag>& flags,
+                                            const SinkMetadata& sinkMetadata,
+                                            openInputStream_cb _hidl_cb) {
+    return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb);
+}
+
+Return<bool> PrimaryDevice::supportsAudioPatches() {
+    return mDevice->supportsAudioPatches();
+}
+
+Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
+                                             const hidl_vec<AudioPortConfig>& sinks,
+                                             createAudioPatch_cb _hidl_cb) {
+    return mDevice->createAudioPatch(sources, sinks, _hidl_cb);
+}
+
+Return<void> PrimaryDevice::updateAudioPatch(int32_t previousPatch,
+                                             const hidl_vec<AudioPortConfig>& sources,
+                                             const hidl_vec<AudioPortConfig>& sinks,
+                                             updateAudioPatch_cb _hidl_cb) {
+    return mDevice->updateAudioPatch(previousPatch, sources, sinks, _hidl_cb);
+}
+
+Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch) {
+    return mDevice->releaseAudioPatch(patch);
+}
+
+Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
+    return mDevice->getAudioPort(port, _hidl_cb);
+}
+
+Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
+    return mDevice->setAudioPortConfig(config);
+}
+
+Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
+    return mDevice->setScreenState(turnedOn);
+}
+
+Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+    return mDevice->getHwAvSync(_hidl_cb);
+}
+
+Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
+                                          const hidl_vec<hidl_string>& keys,
+                                          getParameters_cb _hidl_cb) {
+    return mDevice->getParameters(context, keys, _hidl_cb);
+}
+
+Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
+                                            const hidl_vec<ParameterValue>& parameters) {
+    return mDevice->setParameters(context, parameters);
+}
+
+Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
+    return mDevice->getMicrophones(_hidl_cb);
+}
+
+Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
+    return mDevice->setConnectedState(dev_addr, connected);
+}
+
+Return<Result> PrimaryDevice::close() {
+    return mDevice->close();
+}
+
+Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+    return mDevice->addDeviceEffect(device, effectId);
+}
+
+Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
+    return mDevice->removeDeviceEffect(device, effectId);
+}
+
 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
     return (volume >= 0 && volume <= 1.0) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
 }
@@ -382,30 +561,6 @@
     return FAILURE(Result::NOT_SUPPORTED);
 }
 
-void PrimaryDevice::unrefDevice(StreamIn *sin) {
-    std::lock_guard<std::mutex> guard(mMutex);
-    LOG_ALWAYS_FATAL_IF(mInputStreams.erase(sin) < 1);
-}
-
-void PrimaryDevice::unrefDevice(StreamOut *sout) {
-    std::lock_guard<std::mutex> guard(mMutex);
-    LOG_ALWAYS_FATAL_IF(mOutputStreams.erase(sout) < 1);
-}
-
-void PrimaryDevice::updateOutputStreamVolume(float masterVolume) const {
-    std::lock_guard<std::mutex> guard(mMutex);
-    for (StreamOut *stream : mOutputStreams) {
-        stream->setMasterVolume(masterVolume);
-    }
-}
-
-void PrimaryDevice::updateInputStreamMicMute(bool micMute) const {
-    std::lock_guard<std::mutex> guard(mMutex);
-    for (StreamIn *stream : mInputStreams) {
-        stream->setMicMute(micMute);
-    }
-}
-
 }  // namespace implementation
 }  // namespace CPP_VERSION
 }  // namespace audio
diff --git a/audio/primary_device.h b/audio/primary_device.h
index 85bf0d6..ec85251 100644
--- a/audio/primary_device.h
+++ b/audio/primary_device.h
@@ -41,9 +41,8 @@
 struct StreamIn;
 struct StreamOut;
 
-struct PrimaryDevice : public IPrimaryDevice {
-    PrimaryDevice();
-
+struct Device : public IDevice {
+    Device();
     Return<Result> initCheck() override;
     Return<Result> setMasterVolume(float volume) override;
     Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override;
@@ -88,27 +87,32 @@
     Return<Result> close() override;
     Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
     Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
-    Return<Result> setVoiceVolume(float volume) override;
-    Return<Result> setMode(AudioMode mode) override;
-    Return<Result> setBtScoHeadsetDebugName(const hidl_string& name) override;
-    Return<void> getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) override;
-    Return<Result> setBtScoNrecEnabled(bool enabled) override;
-    Return<void> getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) override;
-    Return<Result> setBtScoWidebandEnabled(bool enabled) override;
-    Return<void> getTtyMode(getTtyMode_cb _hidl_cb) override;
-    Return<Result> setTtyMode(IPrimaryDevice::TtyMode mode) override;
-    Return<void> getHacEnabled(getHacEnabled_cb _hidl_cb) override;
-    Return<Result> setHacEnabled(bool enabled) override;
-    Return<void> getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) override;
-    Return<Result> setBtHfpEnabled(bool enabled) override;
-    Return<Result> setBtHfpSampleRate(uint32_t sampleRateHz) override;
-    Return<Result> setBtHfpVolume(float volume) override;
-    Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override;
 
-private:
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<void> openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                      const AudioConfig& config,
+                                      const hidl_vec<AudioInOutFlag>& flags,
+                                      const SourceMetadata& sourceMetadata,
+                                      openOutputStream_7_1_cb _hidl_cb) override;
+    Return<void> openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
+                                     const AudioConfig& config,
+                                     const hidl_vec<AudioInOutFlag>& flags,
+                                     const SinkMetadata& sinkMetadata,
+                                     openInputStream_7_1_cb _hidl_cb) override;
+#endif
+
+  private:
     friend StreamIn;
     friend StreamOut;
 
+    std::tuple<Result, sp<IStreamOut>, AudioConfig> openOutputStreamImpl(
+            int32_t ioHandle, const DeviceAddress& device,
+            const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+            const SourceMetadata& sourceMetadata);
+    std::tuple<Result, sp<IStreamIn>, AudioConfig> openInputStreamImpl(
+            int32_t ioHandle, const DeviceAddress& device,
+            const AudioConfig& config, const hidl_vec<AudioInOutFlag>& flags,
+            const SinkMetadata& sinkMetadata);
     void unrefDevice(StreamIn *);
     void unrefDevice(StreamOut *);
     void updateOutputStreamVolume(float masterVolume) const;
@@ -131,6 +135,83 @@
     bool   mMicMute = false;
 };
 
+struct PrimaryDevice : public IPrimaryDevice {
+    PrimaryDevice();
+
+    // Implementation of IDevice.
+    Return<Result> initCheck() override;
+    Return<Result> setMasterVolume(float volume) override;
+    Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override;
+    Return<Result> setMicMute(bool mute) override;
+    Return<void> getMicMute(getMicMute_cb _hidl_cb) override;
+    Return<Result> setMasterMute(bool mute) override;
+    Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
+    Return<void> getInputBufferSize(const AudioConfig& config,
+                                    getInputBufferSize_cb _hidl_cb) override;
+    Return<void> openOutputStream(int32_t ioHandle,
+                                  const DeviceAddress& device,
+                                  const AudioConfig& config,
+                                  const hidl_vec<AudioInOutFlag>& flags,
+                                  const SourceMetadata& sourceMetadata,
+                                  openOutputStream_cb _hidl_cb) override;
+    Return<void> openInputStream(int32_t ioHandle,
+                                 const DeviceAddress& device,
+                                 const AudioConfig& config,
+                                 const hidl_vec<AudioInOutFlag>& flags,
+                                 const SinkMetadata& sinkMetadata,
+                                 openInputStream_cb _hidl_cb) override;
+    Return<bool> supportsAudioPatches() override;
+    Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
+                                  const hidl_vec<AudioPortConfig>& sinks,
+                                  createAudioPatch_cb _hidl_cb) override;
+    Return<void> updateAudioPatch(AudioPatchHandle previousPatch,
+                                  const hidl_vec<AudioPortConfig>& sources,
+                                  const hidl_vec<AudioPortConfig>& sinks,
+                                  updateAudioPatch_cb _hidl_cb) override;
+    Return<Result> releaseAudioPatch(AudioPatchHandle patch) override;
+    Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override;
+    Return<Result> setAudioPortConfig(const AudioPortConfig& config) override;
+    Return<Result> setScreenState(bool turnedOn) override;
+    Return<void> getHwAvSync(getHwAvSync_cb _hidl_cb) override;
+    Return<void> getParameters(const hidl_vec<ParameterValue>& context,
+                               const hidl_vec<hidl_string>& keys,
+                               getParameters_cb _hidl_cb) override;
+    Return<Result> setParameters(const hidl_vec<ParameterValue>& context,
+                                 const hidl_vec<ParameterValue>& parameters) override;
+    Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override;
+    Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
+    Return<Result> close() override;
+    Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+    Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override;
+
+    // Implementation of IPrimaryDevice.
+    Return<Result> setVoiceVolume(float volume) override;
+    Return<Result> setMode(AudioMode mode) override;
+    Return<Result> setBtScoHeadsetDebugName(const hidl_string& name) override;
+    Return<void> getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) override;
+    Return<Result> setBtScoNrecEnabled(bool enabled) override;
+    Return<void> getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) override;
+    Return<Result> setBtScoWidebandEnabled(bool enabled) override;
+    Return<void> getTtyMode(getTtyMode_cb _hidl_cb) override;
+    Return<Result> setTtyMode(IPrimaryDevice::TtyMode mode) override;
+    Return<void> getHacEnabled(getHacEnabled_cb _hidl_cb) override;
+    Return<Result> setHacEnabled(bool enabled) override;
+    Return<void> getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) override;
+    Return<Result> setBtHfpEnabled(bool enabled) override;
+    Return<Result> setBtHfpSampleRate(uint32_t sampleRateHz) override;
+    Return<Result> setBtHfpVolume(float volume) override;
+    Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override;
+
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+    Return<sp<::android::hardware::audio::V7_1::IDevice>> getDevice() override {
+        return mDevice;
+    }
+#endif
+
+private:
+    sp<Device> mDevice;
+};
+
 }  // namespace implementation
 }  // namespace CPP_VERSION
 }  // namespace audio
diff --git a/audio/stream_in.cpp b/audio/stream_in.cpp
index 70a9bfe..88fcece 100644
--- a/audio/stream_in.cpp
+++ b/audio/stream_in.cpp
@@ -221,7 +221,7 @@
 
 } // namespace
 
-StreamIn::StreamIn(sp<PrimaryDevice> dev,
+StreamIn::StreamIn(sp<Device> dev,
                    int32_t ioHandle,
                    const DeviceAddress& device,
                    const AudioConfig& config,
diff --git a/audio/stream_in.h b/audio/stream_in.h
index 94248bf..2be11d2 100644
--- a/audio/stream_in.h
+++ b/audio/stream_in.h
@@ -37,7 +37,7 @@
 using ::android::hardware::audio::CPP_VERSION::IStreamIn;
 
 struct StreamIn : public IStreamIn {
-    StreamIn(sp<PrimaryDevice> dev,
+    StreamIn(sp<Device> dev,
              int32_t ioHandle,
              const DeviceAddress& device,
              const AudioConfig& config,
@@ -97,7 +97,7 @@
 private:
     Result closeImpl(bool fromDctor);
 
-    sp<PrimaryDevice> mDev;
+    sp<Device> mDev;
     const StreamCommon mCommon;
     const SinkMetadata mSinkMetadata;
     std::unique_ptr<IOThread> mReadThread;
diff --git a/audio/stream_out.cpp b/audio/stream_out.cpp
index fc80481..3ba1dd8 100644
--- a/audio/stream_out.cpp
+++ b/audio/stream_out.cpp
@@ -229,7 +229,7 @@
 
 } // namespace
 
-StreamOut::StreamOut(sp<PrimaryDevice> dev,
+StreamOut::StreamOut(sp<Device> dev,
                      int32_t ioHandle,
                      const DeviceAddress& device,
                      const AudioConfig& config,
diff --git a/audio/stream_out.h b/audio/stream_out.h
index e5a02f7..88e30e5 100644
--- a/audio/stream_out.h
+++ b/audio/stream_out.h
@@ -38,7 +38,7 @@
 using ::android::hardware::audio::CPP_VERSION::IStreamOut;
 
 struct StreamOut : public IStreamOut {
-    StreamOut(sp<PrimaryDevice> dev,
+    StreamOut(sp<Device> dev,
               int32_t ioHandle,
               const DeviceAddress& device,
               const AudioConfig& config,
@@ -112,7 +112,7 @@
     Result closeImpl(bool fromDctor);
     void updateEffectiveVolumeLocked();
 
-    sp<PrimaryDevice> mDev;
+    sp<Device> mDev;
     const StreamCommon mCommon;
     const SourceMetadata mSourceMetadata;
     std::unique_ptr<IOThread> mWriteThread;