Merge changes I42d7cbc5,I6eda8458

* changes:
  Add mp2 container and codec support
  Use header file for namespace functions
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index c1efa5f..69b9e7e 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -7608,6 +7608,13 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME                = 12,
 
+    /**
+     * <p>The camera device is capable of writing image data into a region of memory
+     * inaccessible to Android userspace or the Android kernel, and only accessible to
+     * trusted execution environments (TEE).</p>
+     */
+    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA         = 13,
+
 } acamera_metadata_enum_android_request_available_capabilities_t;
 
 
diff --git a/include/media/AudioAttributes.h b/include/media/AudioAttributes.h
new file mode 120000
index 0000000..27ba471
--- /dev/null
+++ b/include/media/AudioAttributes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioAttributes.h
\ No newline at end of file
diff --git a/include/media/AudioCommonTypes.h b/include/media/AudioCommonTypes.h
new file mode 120000
index 0000000..ae7c99a
--- /dev/null
+++ b/include/media/AudioCommonTypes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioCommonTypes.h
\ No newline at end of file
diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h
deleted file mode 120000
index 558657e..0000000
--- a/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioPolicyHelper.h
\ No newline at end of file
diff --git a/include/media/AudioProductStrategy.h b/include/media/AudioProductStrategy.h
new file mode 120000
index 0000000..6bfaf11
--- /dev/null
+++ b/include/media/AudioProductStrategy.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioProductStrategy.h
\ No newline at end of file
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index d02f541..78a444b 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -74,9 +74,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
@@ -90,9 +87,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 }
 
@@ -128,9 +122,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     ldflags: ["-Wl,-Bsymbolic"],
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 1417aaf..bd10d67 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -5,6 +5,28 @@
 }
 
 cc_library_shared {
+    name: "libaudiopolicy",
+    srcs: [
+        "AudioAttributes.cpp",
+        "AudioPolicy.cpp",
+        "AudioProductStrategy.cpp",
+    ],
+    shared_libs: [
+        "libaudioutils",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    include_dirs: ["system/media/audio_utils/include"],
+    export_include_dirs: ["include"],
+}
+
+cc_library_shared {
     name: "libaudioclient",
 
     aidl: {
@@ -23,7 +45,6 @@
         ":libaudioclient_aidl",
 
         "AudioEffect.cpp",
-        "AudioPolicy.cpp",
         "AudioRecord.cpp",
         "AudioSystem.cpp",
         "AudioTrack.cpp",
@@ -41,6 +62,7 @@
     ],
     shared_libs: [
         "libaudioutils",
+        "libaudiopolicy",
         "libaudiomanager",
         "libbinder",
         "libcutils",
diff --git a/media/libaudioclient/AudioAttributes.cpp b/media/libaudioclient/AudioAttributes.cpp
new file mode 100644
index 0000000..0f327cf
--- /dev/null
+++ b/media/libaudioclient/AudioAttributes.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "AudioAttributes"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+
+#include <media/AudioAttributes.h>
+
+namespace android {
+
+status_t AudioAttributes::readFromParcel(const Parcel *parcel)
+{
+    status_t ret = NO_ERROR;
+    mAttributes.content_type = static_cast<audio_content_type_t>(parcel->readInt32());
+    mAttributes.usage = static_cast<audio_usage_t>(parcel->readInt32());
+    mAttributes.source = static_cast<audio_source_t>(parcel->readInt32());
+    mAttributes.flags = static_cast<audio_flags_mask_t>(parcel->readInt32());
+    const bool hasFlattenedTag = (parcel->readInt32() == 1);
+    if (hasFlattenedTag) {
+        std::string tags;
+        ret = parcel->readUtf8FromUtf16(&tags);
+        if (ret != NO_ERROR) {
+            return ret;
+        }
+        std::strncpy(mAttributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+    } else {
+        strcpy(mAttributes.tags, "");
+    }
+    mStreamType = static_cast<audio_stream_type_t>(parcel->readInt32());
+    mGroupId = parcel->readUint32();
+    return NO_ERROR;
+}
+
+status_t AudioAttributes::writeToParcel(Parcel *parcel) const
+{
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.content_type));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.usage));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.source));
+    parcel->writeInt32(static_cast<int32_t>(mAttributes.flags));
+    if (strlen(mAttributes.tags) == 0) {
+        parcel->writeInt32(0);
+    } else {
+        parcel->writeInt32(1);
+        parcel->writeUtf8AsUtf16(mAttributes.tags);
+    }
+    parcel->writeInt32(static_cast<int32_t>(mStreamType));
+    parcel->writeUint32(mGroupId);
+    return NO_ERROR;
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioProductStrategy.cpp b/media/libaudioclient/AudioProductStrategy.cpp
new file mode 100644
index 0000000..1da1114
--- /dev/null
+++ b/media/libaudioclient/AudioProductStrategy.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "AudioProductStrategy"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <media/AudioProductStrategy.h>
+#include <media/AudioAttributes.h>
+#include <media/AudioSystem.h>
+
+namespace android {
+
+status_t AudioProductStrategy::readFromParcel(const Parcel *parcel)
+{
+    mId = static_cast<product_strategy_t>(parcel->readInt32());
+    status_t ret = parcel->readUtf8FromUtf16(&mName);
+    if (ret != NO_ERROR) {
+        return ret;
+    }
+    size_t size = static_cast<size_t>(parcel->readInt32());
+    for (size_t i = 0; i < size; i++) {
+        AudioAttributes attribute;
+        ret = attribute.readFromParcel(parcel);
+        if (ret != NO_ERROR) {
+            mAudioAttributes.clear();
+            return ret;
+        }
+        mAudioAttributes.push_back(attribute);
+    }
+    return NO_ERROR;
+}
+
+status_t AudioProductStrategy::writeToParcel(Parcel *parcel) const
+{
+    parcel->writeInt32(static_cast<int32_t>(mId));
+    parcel->writeUtf8AsUtf16(mName);
+    size_t size = mAudioAttributes.size();
+    size_t sizePosition = parcel->dataPosition();
+    parcel->writeInt32(size);
+    size_t finalSize = size;
+
+    for (size_t i = 0; i < size; i++) {
+        size_t position = parcel->dataPosition();
+        AudioAttributes attribute(mAudioAttributes[i]);
+        status_t ret = attribute.writeToParcel(parcel);
+        if (ret != NO_ERROR) {
+            parcel->setDataPosition(position);
+            finalSize--;
+        }
+    }
+    if (size != finalSize) {
+        size_t position = parcel->dataPosition();
+        parcel->setDataPosition(sizePosition);
+        parcel->writeInt32(finalSize);
+        parcel->setDataPosition(position);
+    }
+    return NO_ERROR;
+}
+
+bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
+                                        const audio_attributes_t clientAttritubes)
+{
+    if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
+        // The default product strategy is the strategy that holds default attributes by convention.
+        // All attributes that fail to match will follow the default strategy for routing.
+        // Choosing the default must be done as a fallback, the attributes match shall not
+        // select the default.
+        return false;
+    }
+    return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
+            (clientAttritubes.usage == refAttributes.usage)) &&
+            ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
+             (clientAttritubes.content_type == refAttributes.content_type)) &&
+            ((refAttributes.flags == AUDIO_FLAG_NONE) ||
+             (clientAttritubes.flags != AUDIO_FLAG_NONE &&
+            (clientAttritubes.flags & refAttributes.flags) == clientAttritubes.flags)) &&
+            ((strlen(refAttributes.tags) == 0) ||
+             (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 896198b..b83a441e 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -25,6 +25,7 @@
 #include <media/AudioSystem.h>
 #include <media/IAudioFlinger.h>
 #include <media/IAudioPolicyService.h>
+#include <media/TypeConverter.h>
 #include <math.h>
 
 #include <system/audio.h>
@@ -970,7 +971,7 @@
 uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
-    if (aps == 0) return 0;
+    if (aps == 0) return PRODUCT_STRATEGY_NONE;
     return aps->getStrategyForStream(stream);
 }
 
@@ -1327,7 +1328,6 @@
     return aps->setSurroundFormatEnabled(audioFormat, enabled);
 }
 
-
 status_t AudioSystem::setAssistantUid(uid_t uid)
 {
     const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1352,11 +1352,62 @@
 }
 
 status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
-                                std::vector<audio_format_t> *formats)
+                                std::vector<audio_format_t> *formats) {
+    const sp <IAudioPolicyService>
+        & aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
+status_t AudioSystem::listAudioProductStrategies(AudioProductStrategyVector &strategies)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
-    return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+    return aps->listAudioProductStrategies(strategies);
+}
+
+audio_attributes_t AudioSystem::streamTypeToAttributes(audio_stream_type_t stream)
+{
+    AudioProductStrategyVector strategies;
+    listAudioProductStrategies(strategies);
+    for (const auto &strategy : strategies) {
+        auto attrVect = strategy.getAudioAttributes();
+        auto iter = std::find_if(begin(attrVect), end(attrVect), [&stream](const auto &attributes) {
+                         return attributes.getStreamType() == stream; });
+        if (iter != end(attrVect)) {
+            return iter->getAttributes();
+        }
+    }
+    ALOGE("invalid stream type %s when converting to attributes",  toString(stream).c_str());
+    return AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t &attr)
+{
+    product_strategy_t strategyId =
+            AudioSystem::getProductStrategyFromAudioAttributes(AudioAttributes(attr));
+    AudioProductStrategyVector strategies;
+    listAudioProductStrategies(strategies);
+    for (const auto &strategy : strategies) {
+        if (strategy.getId() == strategyId) {
+            auto attrVect = strategy.getAudioAttributes();
+            auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto &refAttr) {
+                             return AudioProductStrategy::attributesMatches(
+                                 refAttr.getAttributes(), attr); });
+            if (iter != end(attrVect)) {
+                return iter->getStreamType();
+            }
+        }
+    }
+    ALOGE("invalid attributes %s when converting to stream",  toString(attr).c_str());
+    return AUDIO_STREAM_MUSIC;
+}
+
+product_strategy_t AudioSystem::getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PRODUCT_STRATEGY_NONE;
+    return aps->getProductStrategyFromAudioAttributes(aa);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index c2ee2ee..79abea0 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -33,7 +33,6 @@
 #include <media/IAudioFlinger.h>
 #include <media/IAudioPolicyService.h>
 #include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/MediaAnalyticsItem.h>
@@ -487,7 +486,7 @@
                 __func__,
                  mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
         mStreamType = AUDIO_STREAM_DEFAULT;
-        audio_attributes_flags_to_audio_output_flags(mAttributes.flags, flags);
+        audio_flags_to_audio_output_flags(mAttributes.flags, &flags);
     }
 
     // these below should probably come from the audioFlinger too...
@@ -1390,7 +1389,7 @@
 audio_stream_type_t AudioTrack::streamType() const
 {
     if (mStreamType == AUDIO_STREAM_DEFAULT) {
-        return audio_attributes_to_stream_type(&mAttributes);
+        return AudioSystem::attributesToStreamType(mAttributes);
     }
     return mStreamType;
 }
@@ -1473,7 +1472,7 @@
 
     IAudioFlinger::CreateTrackInput input;
     if (mStreamType != AUDIO_STREAM_DEFAULT) {
-        stream_type_to_audio_attributes(mStreamType, &input.attr);
+        input.attr = AudioSystem::streamTypeToAttributes(mStreamType);
     } else {
         input.attr = mAttributes;
     }
@@ -2891,7 +2890,8 @@
                         mPortId, mStatus, mState, mSessionId, mFlags);
     result.appendFormat("  stream type(%d), left - right volume(%f, %f)\n",
                         (mStreamType == AUDIO_STREAM_DEFAULT) ?
-                                audio_attributes_to_stream_type(&mAttributes) : mStreamType,
+                            AudioSystem::attributesToStreamType(mAttributes) :
+                            mStreamType,
                         mVolume[AUDIO_INTERLEAVE_LEFT], mVolume[AUDIO_INTERLEAVE_RIGHT]);
     result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u)\n",
                   mFormat, mChannelMask, mChannelCount);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 8c7fac5..0db56e8 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -92,7 +92,9 @@
     IS_HAPTIC_PLAYBACK_SUPPORTED,
     SET_UID_DEVICE_AFFINITY,
     REMOVE_UID_DEVICE_AFFINITY,
-    GET_OFFLOAD_FORMATS_A2DP
+    GET_OFFLOAD_FORMATS_A2DP,
+    LIST_AUDIO_PRODUCT_STRATEGIES,
+    GET_STRATEGY_FOR_ATTRIBUTES,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -412,7 +414,7 @@
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(static_cast <uint32_t>(stream));
         remote()->transact(GET_STRATEGY_FOR_STREAM, data, &reply);
-        return reply.readInt32();
+        return reply.readUint32();
     }
 
     virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream)
@@ -1051,19 +1053,61 @@
         return status;
     }
 
-    virtual status_t removeUidDeviceAffinities(uid_t uid)
-    {
+    virtual status_t removeUidDeviceAffinities(uid_t uid) {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
 
         data.writeInt32((int32_t) uid);
 
-        status_t status = remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
+        status_t status =
+            remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
         if (status == NO_ERROR) {
-            status = (status_t)reply.readInt32();
+            status = (status_t) reply.readInt32();
         }
         return status;
     }
+
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+        status_t status = remote()->transact(LIST_AUDIO_PRODUCT_STRATEGIES, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGE("%s: permission denied", __func__);
+            return status;
+        }
+        status = static_cast<status_t>(reply.readInt32());
+        if (status == NO_ERROR) {
+            uint32_t numStrategies = static_cast<uint32_t>(reply.readInt32());
+            for (size_t i = 0; i < numStrategies; i++) {
+                AudioProductStrategy strategy;
+                status = strategy.readFromParcel(&reply);
+                if (status != NO_ERROR) {
+                    ALOGE("%s: failed to read strategies", __FUNCTION__);
+                    strategies.clear();
+                    return status;
+                }
+                strategies.push_back(strategy);
+            }
+        }
+        return status;
+    }
+
+    virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        status_t status = aa.writeToParcel(&data);
+        if (status != NO_ERROR) {
+            return PRODUCT_STRATEGY_NONE;
+        }
+        status = remote()->transact(GET_STRATEGY_FOR_ATTRIBUTES, data, &reply);
+        if (status == NO_ERROR) {
+            return static_cast<product_strategy_t>(reply.readInt32());
+        }
+        return PRODUCT_STRATEGY_NONE;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1082,7 +1126,6 @@
         case START_INPUT:
         case STOP_INPUT:
         case RELEASE_INPUT:
-        case GET_STRATEGY_FOR_STREAM:
         case GET_OUTPUT_FOR_EFFECT:
         case REGISTER_EFFECT:
         case UNREGISTER_EFFECT:
@@ -1378,7 +1421,7 @@
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_stream_type_t stream =
                     static_cast <audio_stream_type_t>(data.readInt32());
-            reply->writeInt32(getStrategyForStream(stream));
+            reply->writeUint32(getStrategyForStream(stream));
             return NO_ERROR;
         } break;
 
@@ -1935,6 +1978,46 @@
             return NO_ERROR;
         }
 
+        case LIST_AUDIO_PRODUCT_STRATEGIES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioProductStrategyVector strategies;
+            status_t status = listAudioProductStrategies(strategies);
+            reply->writeInt32(status);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            size_t size = strategies.size();
+            size_t sizePosition = reply->dataPosition();
+            reply->writeInt32(size);
+            size_t finalSize = size;
+            for (size_t i = 0; i < size; i++) {
+                size_t position = reply->dataPosition();
+                if (strategies[i].writeToParcel(reply) != NO_ERROR) {
+                    reply->setDataPosition(position);
+                    finalSize--;
+                }
+            }
+            if (size != finalSize) {
+                size_t position = reply->dataPosition();
+                reply->setDataPosition(sizePosition);
+                reply->writeInt32(finalSize);
+                reply->setDataPosition(position);
+            }
+            return NO_ERROR;
+        }
+
+        case GET_STRATEGY_FOR_ATTRIBUTES: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            AudioAttributes attributes;
+            status_t status = attributes.readFromParcel(&data);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            product_strategy_t strategy = getProductStrategyFromAudioAttributes(attributes);
+            reply->writeUint32(static_cast<int>(strategy));
+            return NO_ERROR;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 5c5dbd6..536b00d 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -20,7 +20,6 @@
 #include <math.h>
 #include <utils/Log.h>
 #include <cutils/properties.h>
-#include <media/AudioPolicyHelper.h>
 #include "media/ToneGenerator.h"
 
 
@@ -1242,7 +1241,7 @@
     if (mStreamType == AUDIO_STREAM_VOICE_CALL) {
         streamType = AUDIO_STREAM_DTMF;
     }
-    stream_type_to_audio_attributes(streamType, &attr);
+    attr = AudioSystem::streamTypeToAttributes(streamType);
 
     const size_t frameCount = mProcessSize;
     status_t status = mpAudioTrack->set(
diff --git a/media/libaudioclient/include/media/AudioAttributes.h b/media/libaudioclient/include/media/AudioAttributes.h
new file mode 100644
index 0000000..edf26eb
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioAttributes.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+
+#pragma once
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioAttributes : public Parcelable
+{
+public:
+    AudioAttributes() = default;
+    AudioAttributes(const audio_attributes_t &attributes) : mAttributes(attributes) {}
+    AudioAttributes(uint32_t groupId,
+                    audio_stream_type_t stream,
+                    const audio_attributes_t &attributes) :
+         mAttributes(attributes), mStreamType(stream), mGroupId(groupId) {}
+
+    audio_attributes_t getAttributes() const { return mAttributes; }
+
+    status_t readFromParcel(const Parcel *parcel) override;
+    status_t writeToParcel(Parcel *parcel) const override;
+
+    audio_stream_type_t getStreamType() const { return mStreamType; }
+    uint32_t getGroupId() const { return mGroupId; }
+
+private:
+    audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+    /**
+     * @brief mStreamType: for legacy volume management, we need to be able to convert an attribute
+     * to a given stream type.
+     */
+    audio_stream_type_t mStreamType = AUDIO_STREAM_DEFAULT;
+
+    /**
+     * @brief mGroupId: for future volume management, define groups within a strategy that follows
+     * the same curves of volume (extension of stream types to manage volume)
+     */
+    uint32_t mGroupId = 0;
+};
+
+} // namespace android
diff --git a/media/libaudioclient/include/media/AudioCommonTypes.h b/media/libaudioclient/include/media/AudioCommonTypes.h
new file mode 100644
index 0000000..5188da1
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioCommonTypes.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+
+#pragma once
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+enum product_strategy_t : uint32_t;
+const product_strategy_t PRODUCT_STRATEGY_NONE = static_cast<product_strategy_t>(-1);
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamTypes = std::vector<audio_stream_type_t>;
+
+constexpr bool operator==(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+    return lhs.usage == rhs.usage && lhs.content_type == rhs.content_type &&
+            lhs.flags == rhs.flags && (std::strcmp(lhs.tags, rhs.tags) == 0);
+}
+constexpr bool operator!=(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+    return !(lhs==rhs);
+}
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioPolicyHelper.h b/media/libaudioclient/include/media/AudioPolicyHelper.h
deleted file mode 100644
index 46de6b3..0000000
--- a/media/libaudioclient/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2014 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 AUDIO_POLICY_HELPER_H_
-#define AUDIO_POLICY_HELPER_H_
-
-#include <android-base/macros.h>
-#include <system/audio.h>
-
-static inline
-audio_stream_type_t audio_usage_to_stream_type(const audio_usage_t usage)
-{
-    switch(usage) {
-        case AUDIO_USAGE_MEDIA:
-        case AUDIO_USAGE_GAME:
-        case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
-        case AUDIO_USAGE_ASSISTANT:
-            return AUDIO_STREAM_MUSIC;
-        case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-            return AUDIO_STREAM_ACCESSIBILITY;
-        case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
-            return AUDIO_STREAM_SYSTEM;
-        case AUDIO_USAGE_VOICE_COMMUNICATION:
-            return AUDIO_STREAM_VOICE_CALL;
-
-        case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
-            return AUDIO_STREAM_DTMF;
-
-        case AUDIO_USAGE_ALARM:
-            return AUDIO_STREAM_ALARM;
-        case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
-            return AUDIO_STREAM_RING;
-
-        case AUDIO_USAGE_NOTIFICATION:
-        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
-        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
-        case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
-        case AUDIO_USAGE_NOTIFICATION_EVENT:
-            return AUDIO_STREAM_NOTIFICATION;
-
-        case AUDIO_USAGE_UNKNOWN:
-        default:
-            return AUDIO_STREAM_MUSIC;
-    }
-}
-
-static inline
-audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
-{
-    // flags to stream type mapping
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return AUDIO_STREAM_ENFORCED_AUDIBLE;
-    }
-    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
-        return AUDIO_STREAM_BLUETOOTH_SCO;
-    }
-
-    // usage to stream type mapping
-    return audio_usage_to_stream_type(attr->usage);
-}
-
-static inline
-void stream_type_to_audio_attributes(audio_stream_type_t streamType,
-                                     audio_attributes_t *attr) {
-    memset(attr, 0, sizeof(audio_attributes_t));
-
-    switch (streamType) {
-    case AUDIO_STREAM_DEFAULT:
-    case AUDIO_STREAM_MUSIC:
-        attr->content_type = AUDIO_CONTENT_TYPE_MUSIC;
-        attr->usage = AUDIO_USAGE_MEDIA;
-        break;
-    case AUDIO_STREAM_VOICE_CALL:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
-        break;
-    case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        attr->flags  |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
-        FALLTHROUGH_INTENDED; // attributes in common with STREAM_SYSTEM
-    case AUDIO_STREAM_SYSTEM:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
-        break;
-    case AUDIO_STREAM_RING:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
-        break;
-    case AUDIO_STREAM_ALARM:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_ALARM;
-        break;
-    case AUDIO_STREAM_NOTIFICATION:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_NOTIFICATION;
-        break;
-    case AUDIO_STREAM_BLUETOOTH_SCO:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
-        attr->flags |= AUDIO_FLAG_SCO;
-        break;
-    case AUDIO_STREAM_DTMF:
-        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
-        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
-        break;
-    case AUDIO_STREAM_TTS:
-        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
-        attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
-        break;
-    default:
-        ALOGE("invalid stream type %d when converting to attributes", streamType);
-    }
-}
-
-// Convert flags sent from Java AudioAttributes.getFlags() method to audio_output_flags_t
-static inline
-void audio_attributes_flags_to_audio_output_flags(const audio_flags_mask_t audioAttributeFlags,
-            audio_output_flags_t &flags) {
-    if ((audioAttributeFlags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
-        flags = static_cast<audio_output_flags_t>(flags |
-            AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_DIRECT);
-    }
-    if ((audioAttributeFlags & AUDIO_FLAG_LOW_LATENCY) != 0) {
-        flags = static_cast<audio_output_flags_t>(flags | AUDIO_OUTPUT_FLAG_FAST);
-    }
-    // check deep buffer after flags have been modified above
-    if (flags == AUDIO_OUTPUT_FLAG_NONE && (audioAttributeFlags & AUDIO_FLAG_DEEP_BUFFER) != 0) {
-        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-    }
-}
-
-#endif //AUDIO_POLICY_HELPER_H_
diff --git a/media/libaudioclient/include/media/AudioProductStrategy.h b/media/libaudioclient/include/media/AudioProductStrategy.h
new file mode 100644
index 0000000..7441095
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioProductStrategy.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+
+#pragma once
+
+#include <media/AudioCommonTypes.h>
+#include <media/AudioAttributes.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioProductStrategy : public Parcelable
+{
+public:
+    AudioProductStrategy() {}
+    AudioProductStrategy(const std::string &name, const std::vector<AudioAttributes> &attributes,
+                         product_strategy_t id) :
+        mName(name), mAudioAttributes(attributes), mId(id) {}
+
+    const std::string &getName() const { return mName; }
+    std::vector<AudioAttributes> getAudioAttributes() const { return mAudioAttributes; }
+    product_strategy_t getId() const { return mId; }
+
+    status_t readFromParcel(const Parcel *parcel) override;
+    status_t writeToParcel(Parcel *parcel) const override;
+
+    /**
+     * @brief attributesMatches: checks if client attributes matches with a reference attributes
+     * "matching" means the usage shall match if reference attributes has a defined usage, AND
+     * content type shall match if reference attributes has a defined content type AND
+     * flags shall match if reference attributes has defined flags AND
+     * tags shall match if reference attributes has defined tags.
+     * Reference attributes "default" shall not be considered as a "true" case. This convention
+     * is used to identify the default strategy.
+     * @param refAttributes to be considered
+     * @param clientAttritubes to be considered
+     * @return true if matching, false otherwise
+     */
+    static bool attributesMatches(const audio_attributes_t refAttributes,
+                                  const audio_attributes_t clientAttritubes);
+private:
+    std::string mName;
+    std::vector<AudioAttributes> mAudioAttributes;
+    product_strategy_t mId;
+};
+
+using AudioProductStrategyVector = std::vector<AudioProductStrategy>;
+
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 1fb7add..87a9919 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 
 #include <media/AudioPolicy.h>
+#include <media/AudioProductStrategy.h>
 #include <media/AudioIoDescriptor.h>
 #include <media/IAudioFlingerClient.h>
 #include <media/IAudioPolicyServiceClient.h>
@@ -364,6 +365,12 @@
 
     static bool     isHapticPlaybackSupported();
 
+    static status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+    static product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa);
+
+    static audio_attributes_t streamTypeToAttributes(audio_stream_type_t stream);
+    static audio_stream_type_t attributesToStreamType(const audio_attributes_t &attr);
+
     // ----------------------------------------------------------------------------
 
     class AudioPortCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 177adc2..b2cda32 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -196,6 +196,8 @@
     virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) = 0;
 
     virtual bool     isHapticPlaybackSupported() = 0;
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+    virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa) = 0;
 };
 
 
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index e7da488..4dece96 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -107,6 +107,7 @@
         data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
         status_t ret = remote()->transact(GETFORMAT, data, &reply);
         if (ret == NO_ERROR) {
+            AutoMutex _l(mLock);
             mMetaData = MetaData::createFromParcel(reply);
             return mMetaData;
         }
@@ -222,6 +223,8 @@
     // NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
     // XXX: could we use this for caching, or does metadata change on the fly?
     sp<MetaData> mMetaData;
+    // ensure synchronize access to mMetaData
+    Mutex mLock;
 
     // Cache all IMemory objects received from MediaExtractor.
     // We gc IMemory objects that are no longer active (referenced by a MediaBuffer).
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
index 6dbc9b8..cbd64bb 100644
--- a/media/libmedia/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -57,6 +57,7 @@
     AMEDIAFORMAT_KEY_COLOR_STANDARD,
     AMEDIAFORMAT_KEY_COLOR_TRANSFER,
     AMEDIAFORMAT_KEY_COMPLEXITY,
+    AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
     AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
     AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
     AMEDIAFORMAT_KEY_CRYPTO_MODE,
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 00f537d..08519cd 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -123,9 +123,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
 }
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 98a3e75..4de92ad 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -22,7 +22,6 @@
 #include <cutils/properties.h> // for property_get
 #include <utils/Log.h>
 
-#include <media/AudioPolicyHelper.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace {
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 96f79e0..da95817 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -45,7 +45,6 @@
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 
-#include <media/AudioPolicyHelper.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>
@@ -1627,7 +1626,7 @@
         mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
         if (mAttributes != NULL) {
             memcpy(mAttributes, attr, sizeof(audio_attributes_t));
-            mStreamType = audio_attributes_to_stream_type(attr);
+            mStreamType = AudioSystem::attributesToStreamType(*attr);
         }
     } else {
         mAttributes = NULL;
@@ -1816,7 +1815,7 @@
             mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
         }
         memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
-        mStreamType = audio_attributes_to_stream_type(attributes);
+        mStreamType = AudioSystem::attributesToStreamType(*attributes);
     }
 }
 
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index c06c288..2dca5c3 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -752,6 +752,7 @@
 constexpr char KEY_COLOR_STANDARD[] = "color-standard";
 constexpr char KEY_COLOR_TRANSFER[] = "color-transfer";
 constexpr char KEY_COMPLEXITY[] = "complexity";
+constexpr char KEY_CREATE_INPUT_SURFACE_SUSPENDED[] = "create-input-buffers-suspended";
 constexpr char KEY_DURATION[] = "durationUs";
 constexpr char KEY_FEATURE_[] = "feature-";
 constexpr char KEY_FLAC_COMPRESSION_LEVEL[] = "flac-compression-level";
@@ -772,8 +773,10 @@
 constexpr char KEY_LATENCY[] = "latency";
 constexpr char KEY_LEVEL[] = "level";
 constexpr char KEY_MAX_BIT_RATE[] = "max-bitrate";
+constexpr char KEY_MAX_FPS_TO_ENCODER[] = "max-fps-to-encoder";
 constexpr char KEY_MAX_HEIGHT[] = "max-height";
 constexpr char KEY_MAX_INPUT_SIZE[] = "max-input-size";
+constexpr char KEY_MAX_PTS_GAP_TO_ENCODER[] = "max-pts-gap-to-encoder";
 constexpr char KEY_MAX_WIDTH[] = "max-width";
 constexpr char KEY_MIME[] = "mime";
 constexpr char KEY_OPERATING_RATE[] = "operating-rate";
@@ -828,8 +831,10 @@
 constexpr int32_t INFO_TRY_AGAIN_LATER        = -1;
 constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;
 constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+constexpr char PARAMETER_KEY_OFFSET_TIME[] = "time-offset-us";
 constexpr char PARAMETER_KEY_REQUEST_SYNC_FRAME[] = "request-sync";
 constexpr char PARAMETER_KEY_SUSPEND[] = "drop-input-frames";
+constexpr char PARAMETER_KEY_SUSPEND_TIME[] = "drop-start-time-us";
 constexpr char PARAMETER_KEY_VIDEO_BITRATE[] = "video-bitrate";
 
 }
diff --git a/media/libstagefright/timedtext/Android.bp b/media/libstagefright/timedtext/Android.bp
index 97e1ec6..6935655 100644
--- a/media/libstagefright/timedtext/Android.bp
+++ b/media/libstagefright/timedtext/Android.bp
@@ -44,9 +44,6 @@
             "signed-integer-overflow",
         ],
         cfi: true,
-        diag: {
-            cfi: true,
-        },
     },
 
     include_dirs: [
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index fcb706d..cd8ecb5 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -292,6 +292,7 @@
 EXPORT const char* AMEDIAFORMAT_KEY_COMPILATION = "compilation";
 EXPORT const char* AMEDIAFORMAT_KEY_COMPLEXITY = "complexity";
 EXPORT const char* AMEDIAFORMAT_KEY_COMPOSER = "composer";
+EXPORT const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED = "create-input-buffers-suspended";
 EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE = "crypto-default-iv-size";
 EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK = "crypto-encrypted-byte-block";
 EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES = "crypto-encrypted-sizes";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 2551228..cc1d9ef 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -188,6 +188,7 @@
 extern const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_COMPILATION __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_COMPOSER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK __INTRODUCED_IN(29);
 extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES __INTRODUCED_IN(29);
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index c50084e..171167d 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -56,6 +56,7 @@
     AMEDIAFORMAT_KEY_COMPILATION; # var introduced=29
     AMEDIAFORMAT_KEY_COMPLEXITY; # var introduced=28
     AMEDIAFORMAT_KEY_COMPOSER; # var introduced=29
+    AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED; # var introduced=29
     AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE; # var introduced=29
     AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK; # var introduced=29
     AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES; # var introduced=29
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 2d9bd8e..612855f 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -81,13 +81,16 @@
     class Endpoint {
     public:
         Endpoint() = default;
-        Endpoint(Endpoint&& other) { *this = std::move(other); }
-        Endpoint& operator=(Endpoint&& other) {
+        Endpoint(const Endpoint&) = delete;
+        Endpoint& operator=(const Endpoint&) = delete;
+        Endpoint(Endpoint&& other) noexcept { swap(other); }
+        Endpoint& operator=(Endpoint&& other) noexcept {
+            swap(other);
+            return *this;
+        }
+        ~Endpoint() {
             ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
                     "A non empty Patch Endpoint leaked, handle %d", mHandle);
-            *this = other;
-            other.mHandle = AUDIO_PATCH_HANDLE_NONE;
-            return *this;
         }
 
         status_t checkTrack(TrackType *trackOrNull) const {
@@ -127,10 +130,19 @@
         }
         void stopTrack() { if (mTrack) mTrack->stop(); }
 
-    private:
-        Endpoint(const Endpoint&) = default;
-        Endpoint& operator=(const Endpoint&) = default;
+        void swap(Endpoint &other) noexcept {
+            using std::swap;
+            swap(mThread, other.mThread);
+            swap(mCloseThread, other.mCloseThread);
+            swap(mHandle, other.mHandle);
+            swap(mTrack, other.mTrack);
+        }
 
+        friend void swap(Endpoint &a, Endpoint &b) noexcept {
+            a.swap(b);
+        }
+
+    private:
         sp<ThreadType> mThread;
         bool mCloseThread = true;
         audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index ebb4f3b..f72f44a 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -11,8 +11,10 @@
 LOCAL_C_INCLUDES := \
     frameworks/av/services/audioflinger \
     $(call include-path-for, audio-utils) \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
@@ -51,7 +53,7 @@
     libcutils \
     libutils \
     liblog \
-    libaudioclient \
+    libaudiopolicy \
     libsoundtrigger
 
 ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
@@ -76,10 +78,12 @@
 endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
 
 LOCAL_C_INCLUDES += \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
     $(call include-path-for, audio-utils) \
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers
+
 LOCAL_STATIC_LIBRARIES := \
     libaudiopolicycomponents
 
@@ -114,10 +118,12 @@
     libaudiopolicycomponents
 
 LOCAL_C_INCLUDES += \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
     $(call include-path-for, audio-utils) \
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers
+
 LOCAL_CFLAGS := -Wall -Werror
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index cf2ce99..d7030f9 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -240,6 +240,10 @@
                 std::vector<audio_format_t> *formats) = 0;
 
     virtual void     setAppState(uid_t uid, app_state_t state);
+
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+
+    virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa) = 0;
 };
 
 
diff --git a/services/audiopolicy/common/include/RoutingStrategy.h b/services/audiopolicy/common/include/RoutingStrategy.h
deleted file mode 100644
index f8a1cd6..0000000
--- a/services/audiopolicy/common/include/RoutingStrategy.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-namespace android {
-
-// Time in milliseconds after media stopped playing during which we consider that the
-// sonification should be as unobtrusive as during the time media was playing.
-#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
-
-enum routing_strategy {
-    STRATEGY_NONE = -1,
-    STRATEGY_MEDIA,
-    STRATEGY_PHONE,
-    STRATEGY_SONIFICATION,
-    STRATEGY_SONIFICATION_RESPECTFUL,
-    STRATEGY_DTMF,
-    STRATEGY_ENFORCED_AUDIBLE,
-    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
-    STRATEGY_ACCESSIBILITY,
-    STRATEGY_REROUTING,
-    NUM_STRATEGIES
-};
-
-}; //namespace android
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 837ca47..605fc1c 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -17,9 +17,20 @@
 #pragma once
 
 #include <system/audio.h>
+#include <vector>
+
+namespace android {
+
+using StreamTypeVector = std::vector<audio_stream_type_t>;
+
+static const audio_attributes_t defaultAttr = AUDIO_ATTRIBUTES_INITIALIZER;
+
+} // namespace android
 
 static const audio_format_t gDynamicFormat = AUDIO_FORMAT_DEFAULT;
 
+static const uint32_t SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY = 5000;
+
 // For mixed output and inputs, the policy will use max mixer sampling rates.
 // Do not limit sampling rate otherwise
 #define SAMPLE_RATE_HZ_MAX 192000
@@ -151,3 +162,25 @@
     }
     return format1 == format2;
 }
+
+/**
+ * @brief hasStream checks if a given stream type is found in the list of streams
+ * @param streams collection of stream types to consider.
+ * @param streamType to consider
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasStream(const android::StreamTypeVector &streams,
+                             audio_stream_type_t streamType)
+{
+    return std::find(begin(streams), end(streams), streamType) != end(streams);
+}
+
+/**
+ * @brief hasVoiceStream checks if a voice stream is found in the list of streams
+ * @param streams collection to consider.
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasVoiceStream(const android::StreamTypeVector &streams)
+{
+    return hasStream(streams, AUDIO_STREAM_VOICE_CALL);
+}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 555412e..6e29632 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "DeviceDescriptor.h"
+
 namespace android {
 
 /**
@@ -34,4 +36,36 @@
     virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
 };
 
+template <class IoDescriptor, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+        IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
+{
+    auto activeClients = desc->clientsList(true /*activeOnly*/);
+    auto activeClientsWithRoute =
+        desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
+    active = activeClients.size() > 0;
+    if (active && activeClients.size() == activeClientsWithRoute.size()) {
+        return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
+    }
+    return nullptr;
+}
+
+template <class IoCollection, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+        IoCollection& ioCollection, Filter filter, const DeviceVector& devices)
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < ioCollection.size(); i++) {
+        auto desc = ioCollection.valueAt(i);
+        bool active;
+        sp<DeviceDescriptor> curDevice = findPreferredDevice(desc, filter, active, devices);
+        if (active && curDevice == nullptr) {
+            return nullptr;
+        } else if (curDevice != nullptr) {
+            device = curDevice;
+        }
+    }
+    return device;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index e1ecc61..6132bb4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -16,18 +16,20 @@
 
 #pragma once
 
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
+
 #include <sys/types.h>
 
 #include <utils/Errors.h>
 #include <utils/Timers.h>
 #include <utils/KeyedVector.h>
 #include <system/audio.h>
-#include <RoutingStrategy.h>
 #include "AudioIODescriptorInterface.h"
 #include "AudioPort.h"
 #include "ClientDescriptor.h"
 #include "DeviceDescriptor.h"
-#include <map>
+#include <vector>
 
 namespace android {
 
@@ -35,6 +37,70 @@
 class AudioMix;
 class AudioPolicyClientInterface;
 
+class ActivityTracking
+{
+public:
+    virtual ~ActivityTracking() = default;
+    bool isActive(uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+    {
+        if (mActivityCount > 0) {
+            return true;
+        }
+        if (inPastMs == 0) {
+            return false;
+        }
+        if (sysTime == 0) {
+            sysTime = systemTime();
+        }
+        if (ns2ms(sysTime - mStopTime) < inPastMs) {
+            return true;
+        }
+        return false;
+    }
+    void changeActivityCount(int delta)
+    {
+        if ((delta + (int)mActivityCount) < 0) {
+            LOG_ALWAYS_FATAL("%s: invalid delta %d, refCount %d", __func__, delta, mActivityCount);
+        }
+        mActivityCount += delta;
+        if (!mActivityCount) {
+            setStopTime(systemTime());
+        }
+    }
+    uint32_t getActivityCount() const { return mActivityCount; }
+    nsecs_t getStopTime() const { return mStopTime; }
+    void setStopTime(nsecs_t stopTime) { mStopTime = stopTime; }
+
+    virtual void dump(String8 *dst, int spaces) const
+    {
+        dst->appendFormat("%*s- ActivityCount: %d, StopTime: %" PRId64 " \n", spaces, "",
+                          getActivityCount(), getStopTime());
+    }
+private:
+    uint32_t mActivityCount = 0;
+    nsecs_t mStopTime = 0;
+};
+
+/**
+ * @brief The Activity class: it tracks the activity for volume policy (volume index, mute,
+ * memorize previous stop, and store mute if incompatible device with another strategy.
+ * Having this class prevents from looping on all attributes (legacy streams) of the strategy
+ */
+class RoutingActivity : public ActivityTracking
+{
+public:
+    void setMutedByDevice( bool isMuted) { mIsMutedByDevice = isMuted; }
+    bool isMutedByDevice() const { return mIsMutedByDevice; }
+
+private:
+    /**
+     * strategies muted because of incompatible device selection.
+     * See AudioPolicyManager::checkDeviceMuteStrategies()
+     */
+    bool mIsMutedByDevice = false;
+};
+using RoutingActivities = std::map<product_strategy_t, RoutingActivity>;
+
 // descriptor for audio outputs. Used to maintain current configuration of each opened audio output
 // and keep track of the usage of this output by each audio stream type.
 class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
@@ -71,6 +137,14 @@
                             { return mActiveCount[stream]; }
 
     /**
+     * @brief setStopTime set the stop time due to the client stoppage or a re routing of this
+     * client
+     * @param client to be considered
+     * @param sysTime when the client stopped/was rerouted
+     */
+    void setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime);
+
+    /**
      * Changes the client->active() state and the output descriptor's global active count,
      * along with the stream active count and mActiveClients.
      * The client must be previously added by the base class addClient().
@@ -82,6 +156,21 @@
                         uint32_t inPastMs = 0,
                         nsecs_t sysTime = 0) const;
 
+    bool isStrategyActive(product_strategy_t ps, uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+    {
+        return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+                    mRoutingActivities.at(ps).isActive(inPastMs, sysTime) : false;
+    }
+    bool isStrategyMutedByDevice(product_strategy_t ps) const
+    {
+        return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+                    mRoutingActivities.at(ps).isMutedByDevice() : false;
+    }
+    void setStrategyMutedByDevice(product_strategy_t ps, bool isMuted)
+    {
+        mRoutingActivities[ps].setMutedByDevice(isMuted);
+    }
+
     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                            const struct audio_port_config *srcConfig = NULL) const;
     virtual sp<AudioPort> getAudioPort() const { return mPort; }
@@ -95,7 +184,8 @@
     void setPatchHandle(audio_patch_handle_t handle) override;
 
     TrackClientVector clientsList(bool activeOnly = false,
-        routing_strategy strategy = STRATEGY_NONE, bool preferredDeviceOnly = false) const;
+                                  product_strategy_t strategy = PRODUCT_STRATEGY_NONE,
+                                  bool preferredDeviceOnly = false) const;
 
     // override ClientMapHandler to abort when removing a client when active.
     void removeClient(audio_port_handle_t portId) override {
@@ -121,8 +211,6 @@
     DeviceVector mDevices; /**< current devices this output is routed to */
     nsecs_t mStopTime[AUDIO_STREAM_CNT];
     int mMuteCount[AUDIO_STREAM_CNT];            // mute request counter
-    bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
-                                        // device selection. See checkDeviceMuteStrategies()
     AudioMix *mPolicyMix = nullptr;              // non NULL when used by a dynamic policy
 
 protected:
@@ -139,6 +227,8 @@
     // Compare with the ClientMap (mClients) which are external AudioTrack clients of the
     // output descriptor (and do not count internal PatchTracks).
     ActiveClientMap mActiveClients;
+
+    RoutingActivities mRoutingActivities; /**< track routing activity on this ouput.*/
 };
 
 // Audio output driven by a software mixer in audio flinger.
@@ -275,6 +365,21 @@
     bool isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
 
     /**
+     * @brief isStrategyActiveOnSameModule checks if the given strategy is active (or was active
+     * in the past) on the given output and all the outputs belonging to the same HW Module
+     * the same module than the given output
+     * @param outputDesc to be considered
+     * @param ps product strategy to be checked upon activity status
+     * @param inPastMs if 0, check currently, otherwise, check in the past
+     * @param sysTime shall be set if request is done for the past activity.
+     * @return true if an output following the strategy is active on the same module than desc,
+     * false otherwise
+     */
+    bool isStrategyActiveOnSameModule(product_strategy_t ps,
+                                      const sp<SwAudioOutputDescriptor>& desc,
+                                      uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
+
+    /**
      * returns the A2DP output handle if it is open or 0 otherwise
      */
     audio_io_handle_t getA2dpOutput() const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 2932296..7296c95 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -78,7 +78,7 @@
 
     sp<DeviceDescriptor> getDeviceAndMixForInputSource(audio_source_t inputSource,
                                                        const DeviceVector &availableDeviceTypes,
-                                                       AudioMix **policyMix);
+                                                       AudioMix **policyMix) const;
 
     /**
      * @brief try to find a matching mix for a given output descriptor and returns the associated
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index a187029..4c069e4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -22,14 +22,14 @@
 #include <sys/types.h>
 
 #include <system/audio.h>
-#include <system/audio_policy.h>
+#include <media/AudioProductStrategy.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/String8.h>
+#include <policy.h>
 #include "AudioPatch.h"
 #include "EffectDescriptor.h"
-#include "RoutingStrategy.h"
 
 namespace android {
 
@@ -41,10 +41,12 @@
 {
 public:
     ClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
-                   audio_attributes_t attributes, audio_config_base_t config,
-                   audio_port_handle_t preferredDeviceId) :
+                     audio_attributes_t attributes, audio_config_base_t config,
+                     audio_port_handle_t preferredDeviceId,
+                     bool isPreferredDeviceForExclusiveUse = false) :
         mPortId(portId), mUid(uid), mSessionId(sessionId), mAttributes(attributes),
-        mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false) {}
+        mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false),
+        mPreferredDeviceForExclusiveUse(isPreferredDeviceForExclusiveUse){}
     ~ClientDescriptor() override = default;
 
     virtual void dump(String8 *dst, int spaces, int index) const;
@@ -58,7 +60,8 @@
     audio_port_handle_t preferredDeviceId() const { return mPreferredDeviceId; };
     void setPreferredDeviceId(audio_port_handle_t preferredDeviceId) {
         mPreferredDeviceId = preferredDeviceId;
-    };
+    }
+    bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
     void setActive(bool active) { mActive = active; }
     bool active() const { return mActive; }
     bool hasPreferredDevice(bool activeOnly = false) const {
@@ -73,16 +76,19 @@
     const audio_config_base_t mConfig;
           audio_port_handle_t mPreferredDeviceId;  // selected input device port ID
           bool mActive;
+          bool mPreferredDeviceForExclusiveUse = false;
 };
 
 class TrackClientDescriptor: public ClientDescriptor
 {
 public:
     TrackClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
-                   audio_attributes_t attributes, audio_config_base_t config,
-                   audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
-                          routing_strategy strategy, audio_output_flags_t flags) :
-        ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+                          audio_attributes_t attributes, audio_config_base_t config,
+                          audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
+                          product_strategy_t strategy, audio_output_flags_t flags,
+                          bool isPreferredDeviceForExclusiveUse) :
+        ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId,
+                         isPreferredDeviceForExclusiveUse),
         mStream(stream), mStrategy(strategy), mFlags(flags) {}
     ~TrackClientDescriptor() override = default;
 
@@ -92,11 +98,11 @@
 
     audio_output_flags_t flags() const { return mFlags; }
     audio_stream_type_t stream() const { return mStream; }
-    routing_strategy strategy() const { return mStrategy; }
+    product_strategy_t strategy() const { return mStrategy; }
 
 private:
     const audio_stream_type_t mStream;
-    const routing_strategy mStrategy;
+    const product_strategy_t mStrategy;
     const audio_output_flags_t mFlags;
 };
 
@@ -136,7 +142,7 @@
 public:
     SourceClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_attributes_t attributes,
                            const sp<AudioPatch>& patchDesc, const sp<DeviceDescriptor>& srcDevice,
-                           audio_stream_type_t stream, routing_strategy strategy);
+                           audio_stream_type_t stream, product_strategy_t strategy);
     ~SourceClientDescriptor() override = default;
 
     sp<AudioPatch> patchDesc() const { return mPatchDesc; }
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 2dc33ab..7f01dc5 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <RoutingStrategy.h>
+#include <policy.h>
 #include <system/audio_effect.h>
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
@@ -28,14 +28,26 @@
 class EffectDescriptor : public RefBase
 {
 public:
+    EffectDescriptor(const effect_descriptor_t *desc, bool isMusicEffect,
+                     int id, int io, int session) :
+        mId(id), mIo(io), mSession(session), mEnabled(false),
+        mIsMusicEffect(isMusicEffect)
+    {
+        memcpy (&mDesc, desc, sizeof(effect_descriptor_t));
+    }
+
     void dump(String8 *dst, int spaces = 0) const;
 
     int mId;                // effect unique ID
     int mIo;                // io the effect is attached to
-    routing_strategy mStrategy; // routing strategy the effect is associated to
     int mSession;               // audio session the effect is on
     effect_descriptor_t mDesc;  // effect descriptor
     bool mEnabled;              // enabled state: CPU load being used or not
+
+    bool isMusicEffect() const { return mIsMusicEffect; }
+
+private:
+    bool mIsMusicEffect;
 };
 
 class EffectDescriptorCollection : public KeyedVector<int, sp<EffectDescriptor> >
@@ -44,7 +56,7 @@
     EffectDescriptorCollection();
 
     status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io,
-                            uint32_t strategy, int session, int id);
+                            int session, int id, bool isMusicEffect);
     status_t unregisterEffect(int id);
     sp<EffectDescriptor> getEffect(int id) const;
     status_t setEffectEnabled(int id, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 78b3f45..1dfd88a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -44,9 +44,6 @@
         mMuteCount[i] = 0;
         mStopTime[i] = 0;
     }
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mStrategyMutedByDevice[i] = false;
-    }
     if (mPort.get() != nullptr) {
         mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
         if (mPort->mGains.size() > 0) {
@@ -101,6 +98,7 @@
         // return;
     }
     mActiveCount[stream] += delta;
+    mRoutingActivities[client->strategy()].changeActivityCount(delta);
 
     if (delta > 0) {
         mActiveClients[client] += delta;
@@ -122,6 +120,12 @@
     ALOGV("%s stream %d, count %d", __FUNCTION__, stream, mActiveCount[stream]);
 }
 
+void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
+{
+    mStopTime[client->stream()] = sysTime;
+    mRoutingActivities[client->strategy()].setStopTime(sysTime);
+}
+
 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
 {
     LOG_ALWAYS_FATAL_IF(getClient(client->portId()) == nullptr,
@@ -247,14 +251,15 @@
     port->ext.mix.hw_module = getModuleHandle();
 }
 
-TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, routing_strategy strategy,
+TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
                                                      bool preferredDeviceOnly) const
 {
     TrackClientVector clients;
     for (const auto &client : getClientIterable()) {
         if ((!activeOnly || client->active())
-            && (strategy == STRATEGY_NONE || strategy == client->strategy())
-            && (!preferredDeviceOnly || client->hasPreferredDevice())) {
+            && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
+            && (!preferredDeviceOnly ||
+                (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
             clients.push_back(client);
         }
     }
@@ -698,6 +703,20 @@
     return false;
 }
 
+bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
+                                                           const sp<SwAudioOutputDescriptor>& desc,
+                                                           uint32_t inPastMs, nsecs_t sysTime) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
+        if (desc->sharesHwModuleWith(otherDesc) &&
+                otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
 {
     for (size_t i = 0; i < size(); i++) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index cd10c82..2489e76 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -302,7 +302,7 @@
 }
 
 sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
-        audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix)
+        audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix) const
 {
     for (size_t i = 0; i < size(); i++) {
         AudioMix *mix = valueAt(i)->getMix();
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 82d64c9..a6f6c3b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -82,10 +82,10 @@
 SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
          audio_attributes_t attributes, const sp<AudioPatch>& patchDesc,
          const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
-         routing_strategy strategy) :
+         product_strategy_t strategy) :
     TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
         AUDIO_CONFIG_BASE_INITIALIZER, AUDIO_PORT_HANDLE_NONE,
-        stream, strategy, AUDIO_OUTPUT_FLAG_NONE),
+        stream, strategy, AUDIO_OUTPUT_FLAG_NONE, false),
         mPatchDesc(patchDesc), mSrcDevice(srcDevice)
 {
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 4cb1e17..a3121d1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -215,11 +215,12 @@
     sp<DeviceDescriptor> device;
     for (size_t i = 0; i < size(); i++) {
         if (itemAt(i)->type() == type) {
-            // Assign device if address is empty or matches and
-            // format is default or matches
+            // If format is specified, match it and ignore address
+            // Otherwise if address is specified match it
+            // Otherwise always match
             if (((address == "" || itemAt(i)->address() == address) &&
                  format == AUDIO_FORMAT_DEFAULT) ||
-                itemAt(i)->supportsFormat(format)) {
+                (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
                 device = itemAt(i);
                 if (itemAt(i)->address() == address) {
                     break;
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 40c49e7..89f9899 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -24,8 +24,9 @@
 
 void EffectDescriptor::dump(String8 *dst, int spaces) const
 {
+    dst->appendFormat("%*sID: %d\n", spaces, "", mId);
     dst->appendFormat("%*sI/O: %d\n", spaces, "", mIo);
-    dst->appendFormat("%*sStrategy: %d\n", spaces, "", mStrategy);
+    dst->appendFormat("%*sMusic Effect: %s\n", spaces, "", isMusicEffect()? "yes" : "no");
     dst->appendFormat("%*sSession: %d\n", spaces, "", mSession);
     dst->appendFormat("%*sName: %s\n", spaces, "",  mDesc.name);
     dst->appendFormat("%*s%s\n", spaces, "",  mEnabled ? "Enabled" : "Disabled");
@@ -41,9 +42,8 @@
 
 status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *desc,
                                                     audio_io_handle_t io,
-                                                    uint32_t strategy,
                                                     int session,
-                                                    int id)
+                                                    int id, bool isMusicEffect)
 {
     if (getEffect(id) != nullptr) {
         ALOGW("%s effect %s already registered", __FUNCTION__, desc->name);
@@ -59,18 +59,11 @@
     if (mTotalEffectsMemory > mTotalEffectsMemoryMaxUsed) {
         mTotalEffectsMemoryMaxUsed = mTotalEffectsMemory;
     }
-    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
-            desc->name, io, strategy, session, id);
+    ALOGV("registerEffect() effect %s, io %d, session %d id %d",
+            desc->name, io, session, id);
     ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
 
-    sp<EffectDescriptor> effectDesc = new EffectDescriptor();
-    memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
-    effectDesc->mId = id;
-    effectDesc->mIo = io;
-    effectDesc->mStrategy = static_cast<routing_strategy>(strategy);
-    effectDesc->mSession = session;
-    effectDesc->mEnabled = false;
-
+    sp<EffectDescriptor> effectDesc = new EffectDescriptor(desc, isMusicEffect, id, io, session);
     add(id, effectDesc);
 
     return NO_ERROR;
@@ -161,7 +154,7 @@
 {
     for (size_t i = 0; i < size(); i++) {
         sp<EffectDescriptor> effectDesc = valueAt(i);
-        if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
+        if (effectDesc->mEnabled && (effectDesc->isMusicEffect()) &&
                 ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
             ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
                   effectDesc->mDesc.name, effectDesc->mSession);
diff --git a/services/audiopolicy/engine/Android.mk b/services/audiopolicy/engine/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/engine/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
new file mode 100644
index 0000000..e6ede07
--- /dev/null
+++ b/services/audiopolicy/engine/common/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 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_library_headers {
+    name: "libaudiopolicyengine_common_headers",
+    host_supported: true,
+    export_include_dirs: ["include"],
+}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
new file mode 100644
index 0000000..5c33fb3
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <EngineConfig.h>
+#include <AudioPolicyManagerInterface.h>
+#include <ProductStrategy.h>
+
+namespace android {
+namespace audio_policy {
+
+class EngineBase : public AudioPolicyManagerInterface
+{
+public:
+    ///
+    /// from AudioPolicyManagerInterface
+    ///
+    android::status_t initCheck() override;
+
+    void setObserver(AudioPolicyManagerObserver *observer) override;
+
+    status_t setPhoneState(audio_mode_t mode) override;
+
+    audio_mode_t getPhoneState() const override { return mPhoneState; }
+
+    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override
+    {
+        mForceUse[usage] = config;
+        return NO_ERROR;
+    }
+
+    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override
+    {
+        return mForceUse[usage];
+    }
+    android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
+                                               audio_policy_dev_state_t /*state*/) override
+    {
+        return NO_ERROR;
+    }
+    product_strategy_t getProductStrategyForAttributes(
+            const audio_attributes_t &attr) const override;
+
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const override;
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const override;
+
+    StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const override;
+
+    AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const override;
+
+    StrategyVector getOrderedProductStrategies() const override;
+
+    status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const override;
+
+    void dump(String8 *dst) const override;
+
+
+    engineConfig::ParsingResult loadAudioPolicyEngineConfig();
+
+    const ProductStrategyMap &getProductStrategies() const { return mProductStrategies; }
+
+    ProductStrategyMap &getProductStrategies() { return mProductStrategies; }
+
+    product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+    product_strategy_t getProductStrategyByName(const std::string &name) const;
+
+    AudioPolicyManagerObserver *getApmObserver() const { return mApmObserver; }
+
+    inline bool isInCall() const
+    {
+        return is_state_in_call(getPhoneState());
+    }
+
+private:
+    AudioPolicyManagerObserver *mApmObserver = nullptr;
+
+    ProductStrategyMap mProductStrategies;
+    audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
+
+    /** current forced use configuration. */
+    audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT] = {};
+};
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
new file mode 100644
index 0000000..72505b2
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+#include <AudioPolicyManagerInterface.h>
+#include <utils/RefBase.h>
+#include <HandleGenerator.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/**
+ * @brief The ProductStrategy class describes for each product_strategy_t identifier the
+ * associated audio attributes, the device types to use, the device address to use.
+ * The identifier is voluntarily not strongly typed in order to be extensible by OEM.
+ */
+class ProductStrategy : public virtual RefBase, private HandleGenerator<uint32_t>
+{
+private:
+    struct AudioAttributes {
+        audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
+        uint32_t mGroupId = 0;
+        audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+    };
+
+    using AudioAttributesVector = std::vector<AudioAttributes>;
+
+public:
+    ProductStrategy(const std::string &name);
+
+    void addAttributes(const AudioAttributes &audioAttributes);
+
+    std::vector<android::AudioAttributes> listAudioAttributes() const;
+
+    std::string getName() const { return mName; }
+    AttributesVector getAudioAttributes() const;
+    product_strategy_t getId() const { return mId; }
+    StreamTypeVector getSupportedStreams() const;
+
+    /**
+     * @brief matches checks if the given audio attributes shall follow the strategy.
+     *        Order of the attributes within a strategy matters.
+     *        If only the usage is available, the check is performed on the usages of the given
+     *        attributes, otherwise all fields must match.
+     * @param attributes to consider
+     * @return true if attributes matches with the strategy, false otherwise.
+     */
+    bool matches(const audio_attributes_t attributes) const;
+
+    bool supportStreamType(const audio_stream_type_t &streamType) const;
+
+    void setDeviceAddress(const std::string &address)
+    {
+        mDeviceAddress = address;
+    }
+
+    std::string getDeviceAddress() const { return mDeviceAddress; }
+
+    void setDeviceTypes(audio_devices_t devices)
+    {
+        mApplicableDevices = devices;
+    }
+
+    audio_devices_t getDeviceTypes() const { return mApplicableDevices; }
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+    bool isDefault() const;
+
+    void dump(String8 *dst, int spaces = 0) const;
+
+private:
+    std::string mName;
+
+    AudioAttributesVector mAttributesVector;
+
+    product_strategy_t mId;
+
+    std::string mDeviceAddress; /**< Device address applicable for this strategy, maybe empty */
+
+    /**
+     * Applicable device(s) type mask for this strategy.
+     */
+    audio_devices_t mApplicableDevices = AUDIO_DEVICE_NONE;
+};
+
+class ProductStrategyMap : public std::map<product_strategy_t, sp<ProductStrategy> >
+{
+public:
+    /**
+     * @brief getProductStrategyForAttribute. The order of the vector is dimensionning.
+     * @param attr
+     * @return applicable product strategy for the given attribute, default if none applicable.
+     */
+    product_strategy_t getProductStrategyForAttributes(const audio_attributes_t &attr) const;
+
+    product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+    audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+
+    audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+    /**
+     * @brief getAttributesForProductStrategy can be called from
+     *        AudioManager: in this case, the product strategy IS the former routing strategy
+     *        CarAudioManager: in this case, the product strategy IS the car usage
+     *                      [getAudioAttributesForCarUsage]
+     *        OemExtension: in this case, the product strategy IS the Oem usage
+     *
+     * @param strategy
+     * @return audio attributes (or at least one of the attributes) following the given strategy.
+     */
+    audio_attributes_t getAttributesForProductStrategy(product_strategy_t strategy) const;
+
+    audio_devices_t getDeviceTypesForProductStrategy(product_strategy_t strategy) const;
+
+    std::string getDeviceAddressForProductStrategy(product_strategy_t strategy) const;
+
+    product_strategy_t getDefault() const;
+
+    void dump(String8 *dst, int spaces = 0) const;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
new file mode 100644
index 0000000..755f2a8
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Base"
+#define LOG_NDEBUG 0
+
+#include "EngineBase.h"
+#include "EngineDefaultConfig.h"
+#include <TypeConverter.h>
+
+namespace android {
+namespace audio_policy {
+
+void EngineBase::setObserver(AudioPolicyManagerObserver *observer)
+{
+    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
+    mApmObserver = observer;
+}
+
+status_t EngineBase::initCheck()
+{
+    return (mApmObserver != nullptr)? NO_ERROR : NO_INIT;
+}
+
+status_t EngineBase::setPhoneState(audio_mode_t state)
+{
+    ALOGV("setPhoneState() state %d", state);
+
+    if (state < 0 || state >= AUDIO_MODE_CNT) {
+        ALOGW("setPhoneState() invalid state %d", state);
+        return BAD_VALUE;
+    }
+
+    if (state == mPhoneState ) {
+        ALOGW("setPhoneState() setting same state %d", state);
+        return BAD_VALUE;
+    }
+
+    // store previous phone state for management of sonification strategy below
+    int oldState = mPhoneState;
+    mPhoneState = state;
+
+    if (!is_state_in_call(oldState) && is_state_in_call(state)) {
+        ALOGV("  Entering call in setPhoneState()");
+    } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
+        ALOGV("  Exiting call in setPhoneState()");
+    }
+    return NO_ERROR;
+}
+
+product_strategy_t EngineBase::getProductStrategyForAttributes(const audio_attributes_t &attr) const
+{
+    return mProductStrategies.getProductStrategyForAttributes(attr);
+}
+
+audio_stream_type_t EngineBase::getStreamTypeForAttributes(const audio_attributes_t &attr) const
+{
+    return mProductStrategies.getStreamTypeForAttributes(attr);
+}
+
+audio_attributes_t EngineBase::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+    return mProductStrategies.getAttributesForStreamType(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+    return mProductStrategies.getProductStrategyForStream(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyByName(const std::string &name) const
+{
+    for (const auto &iter : mProductStrategies) {
+        if (iter.second->getName() == name) {
+            return iter.second->getId();
+        }
+    }
+    return PRODUCT_STRATEGY_NONE;
+}
+
+engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
+{
+    auto loadProductStrategies =
+            [](auto& strategyConfigs, auto& productStrategies) {
+        uint32_t groupid = 0;
+        for (auto& strategyConfig : strategyConfigs) {
+            sp<ProductStrategy> strategy = new ProductStrategy(strategyConfig.name);
+            for (const auto &group : strategyConfig.attributesGroups) {
+                for (const auto &attr : group.attributesVect) {
+                    strategy->addAttributes({group.stream, groupid, attr});
+                }
+                groupid += 1;
+            }
+            product_strategy_t strategyId = strategy->getId();
+            productStrategies[strategyId] = strategy;
+        }
+    };
+
+    auto result = engineConfig::parse();
+    if (result.parsedConfig == nullptr) {
+        ALOGW("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
+        result = {std::make_unique<engineConfig::Config>(gDefaultEngineConfig), 0};
+    }
+    ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+    loadProductStrategies(result.parsedConfig->productStrategies, mProductStrategies);
+    return result;
+}
+
+StrategyVector EngineBase::getOrderedProductStrategies() const
+{
+    auto findByFlag = [](const auto &productStrategies, auto flag) {
+        return std::find_if(begin(productStrategies), end(productStrategies),
+                            [&](const auto &strategy) {
+            for (const auto &attributes : strategy.second->getAudioAttributes()) {
+                if ((attributes.flags & flag) == flag) {
+                    return true;
+                }
+            }
+            return false;
+        });
+    };
+    auto strategies = mProductStrategies;
+    auto enforcedAudibleStrategyIter = findByFlag(strategies, AUDIO_FLAG_AUDIBILITY_ENFORCED);
+
+    if (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED &&
+            enforcedAudibleStrategyIter != strategies.end()) {
+        auto enforcedAudibleStrategy = *enforcedAudibleStrategyIter;
+        strategies.erase(enforcedAudibleStrategyIter);
+        strategies.insert(begin(strategies), enforcedAudibleStrategy);
+    }
+    StrategyVector orderedStrategies;
+    for (const auto &iter : strategies) {
+        orderedStrategies.push_back(iter.second->getId());
+    }
+    return orderedStrategies;
+}
+
+StreamTypeVector EngineBase::getStreamTypesForProductStrategy(product_strategy_t ps) const
+{
+    // @TODO default music stream to control volume if no group?
+    return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+                mProductStrategies.at(ps)->getSupportedStreams() :
+                StreamTypeVector(AUDIO_STREAM_MUSIC);
+}
+
+AttributesVector EngineBase::getAllAttributesForProductStrategy(product_strategy_t ps) const
+{
+    return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+                mProductStrategies.at(ps)->getAudioAttributes() : AttributesVector();
+}
+
+status_t EngineBase::listAudioProductStrategies(AudioProductStrategyVector &strategies) const
+{
+    for (const auto &iter : mProductStrategies) {
+        const auto &productStrategy = iter.second;
+        strategies.push_back(
+        {productStrategy->getName(), productStrategy->listAudioAttributes(),
+         productStrategy->getId()});
+    }
+    return NO_ERROR;
+}
+
+void EngineBase::dump(String8 *dst) const
+{
+    mProductStrategies.dump(dst, 2);
+}
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
new file mode 100644
index 0000000..3940c0c
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+
+namespace android {
+/**
+ * @brief AudioProductStrategies hard coded array of strategies to fill new engine API contract.
+ */
+const engineConfig::ProductStrategies gOrderedStrategies = {
+    {"STRATEGY_PHONE",
+     {
+         {"phone", AUDIO_STREAM_VOICE_CALL,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_SOURCE_DEFAULT, 0,
+            ""}},
+         },
+         {"sco", AUDIO_STREAM_BLUETOOTH_SCO,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_SCO,
+            ""}},
+         }
+     },
+    },
+    {"STRATEGY_SONIFICATION",
+     {
+         {"ring", AUDIO_STREAM_RING,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         },
+         {"alarm", AUDIO_STREAM_ALARM,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, 0, ""}},
+         }
+     },
+    },
+    {"STRATEGY_ENFORCED_AUDIBLE",
+     {
+         {"", AUDIO_STREAM_ENFORCED_AUDIBLE,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+            AUDIO_FLAG_AUDIBILITY_ENFORCED, ""}}
+         }
+     },
+    },
+    {"STRATEGY_ACCESSIBILITY",
+     {
+         {"", AUDIO_STREAM_ACCESSIBILITY,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_SONIFICATION_RESPECTFUL",
+     {
+         {"", AUDIO_STREAM_NOTIFICATION,
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_EVENT,
+               AUDIO_SOURCE_DEFAULT, 0, ""}
+          }
+         }
+     },
+    },
+    {"STRATEGY_MEDIA",
+     {
+         {"music", AUDIO_STREAM_MUSIC,
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_GAME, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANT, AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+               AUDIO_SOURCE_DEFAULT, 0, ""},
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}
+          },
+         },
+         {"system", AUDIO_STREAM_SYSTEM,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_SONIFICATION,
+            AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_DTMF",
+     {
+         {"", AUDIO_STREAM_DTMF,
+          {
+              {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
+               AUDIO_SOURCE_DEFAULT, 0, ""}
+          }
+         }
+     },
+    },
+    {"STRATEGY_TRANSMITTED_THROUGH_SPEAKER",
+     {
+         {"", AUDIO_STREAM_TTS,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+            AUDIO_FLAG_BEACON, ""}}
+         }
+     },
+    },
+    {"STRATEGY_REROUTING",
+     {
+         {"", AUDIO_STREAM_REROUTING,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    },
+    {"STRATEGY_PATCH",
+     {
+         {"", AUDIO_STREAM_PATCH,
+          {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+         }
+     },
+    }
+};
+
+const engineConfig::Config gDefaultEngineConfig = {
+    1.0,
+    gOrderedStrategies,
+    {},
+    {}
+};
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
new file mode 100644
index 0000000..71607d1
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/ProductStrategy"
+//#define LOG_NDEBUG 0
+
+#include "ProductStrategy.h"
+
+#include <media/TypeConverter.h>
+#include <utils/String8.h>
+#include <cstdint>
+#include <string>
+
+#include <log/log.h>
+
+
+namespace android {
+
+ProductStrategy::ProductStrategy(const std::string &name) :
+    mName(name),
+    mId(static_cast<product_strategy_t>(HandleGenerator<uint32_t>::getNextHandle()))
+{
+}
+
+void ProductStrategy::addAttributes(const AudioAttributes &audioAttributes)
+{
+    mAttributesVector.push_back(audioAttributes);
+}
+
+std::vector<android::AudioAttributes> ProductStrategy::listAudioAttributes() const
+{
+    std::vector<android::AudioAttributes> androidAa;
+    for (const auto &attr : mAttributesVector) {
+        androidAa.push_back({attr.mGroupId, attr.mStream, attr.mAttributes});
+    }
+    return androidAa;
+}
+
+AttributesVector ProductStrategy::getAudioAttributes() const
+{
+    AttributesVector attrVector;
+    for (const auto &attrGroup : mAttributesVector) {
+        attrVector.push_back(attrGroup.mAttributes);
+    }
+    if (not attrVector.empty()) {
+        return attrVector;
+    }
+    return { AUDIO_ATTRIBUTES_INITIALIZER };
+}
+
+bool ProductStrategy::matches(const audio_attributes_t attr) const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                        [&attr](const auto &supportedAttr) {
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr);
+    }) != end(mAttributesVector);
+}
+
+audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(const audio_attributes_t &attr) const
+{
+    const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                                   [&attr](const auto &supportedAttr) {
+        return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr); });
+    return iter != end(mAttributesVector) ? iter->mStream : AUDIO_STREAM_DEFAULT;
+}
+
+audio_attributes_t ProductStrategy::getAttributesForStreamType(audio_stream_type_t streamType) const
+{
+    const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                                   [&streamType](const auto &supportedAttr) {
+        return supportedAttr.mStream == streamType; });
+    return iter != end(mAttributesVector) ? iter->mAttributes : AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+bool ProductStrategy::isDefault() const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector), [](const auto &attr) {
+        return attr.mAttributes == defaultAttr; }) != end(mAttributesVector);
+}
+
+StreamTypeVector ProductStrategy::getSupportedStreams() const
+{
+    StreamTypeVector streams;
+    for (const auto &supportedAttr : mAttributesVector) {
+        if (std::find(begin(streams), end(streams), supportedAttr.mStream) == end(streams) &&
+                supportedAttr.mStream != AUDIO_STREAM_DEFAULT) {
+            streams.push_back(supportedAttr.mStream);
+        }
+    }
+    return streams;
+}
+
+bool ProductStrategy::supportStreamType(const audio_stream_type_t &streamType) const
+{
+    return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+                        [&streamType](const auto &supportedAttr) {
+        return supportedAttr.mStream == streamType; }) != end(mAttributesVector);
+}
+
+void ProductStrategy::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("\n%*s-%s (id: %d)\n", spaces, "", mName.c_str(), mId);
+    std::string deviceLiteral;
+    if (!OutputDeviceConverter::toString(mApplicableDevices, deviceLiteral)) {
+        ALOGE("%s: failed to convert device %d", __FUNCTION__, mApplicableDevices);
+    }
+    dst->appendFormat("%*sSelected Device: {type:%s, @:%s}\n", spaces + 2, "",
+                       deviceLiteral.c_str(), mDeviceAddress.c_str());
+
+    for (const auto &attr : mAttributesVector) {
+        dst->appendFormat("%*sGroup: %d stream: %s\n", spaces + 3, "", attr.mGroupId,
+                          android::toString(attr.mStream).c_str());
+        dst->appendFormat("%*s Attributes: ", spaces + 3, "");
+        std::string attStr =
+                attr.mAttributes == defaultAttr ? "{ Any }" : android::toString(attr.mAttributes);
+        dst->appendFormat("%s\n", attStr.c_str());
+    }
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForAttributes(
+        const audio_attributes_t &attr) const
+{
+    for (const auto &iter : *this) {
+        if (iter.second->matches(attr)) {
+            return iter.second->getId();
+        }
+    }
+    ALOGV("%s: No matching product strategy for attributes %s, return default", __FUNCTION__,
+          toString(attr).c_str());
+    return getDefault();
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+    for (const auto &iter : *this) {
+        const auto strategy = iter.second;
+        if (strategy->supportStreamType(stream)) {
+            return strategy->getAttributesForStreamType(stream);
+        }
+    }
+    ALOGV("%s: No product strategy for stream %s, using default", __FUNCTION__,
+          toString(stream).c_str());
+    return {};
+}
+
+audio_stream_type_t ProductStrategyMap::getStreamTypeForAttributes(
+        const audio_attributes_t &attr) const
+{
+    for (const auto &iter : *this) {
+        audio_stream_type_t stream = iter.second->getStreamTypeForAttributes(attr);
+        if (stream != AUDIO_STREAM_DEFAULT) {
+            return stream;
+        }
+    }
+    ALOGV("%s: No product strategy for attributes %s, using default (aka MUSIC)", __FUNCTION__,
+          toString(attr).c_str());
+    return  AUDIO_STREAM_MUSIC;
+}
+
+product_strategy_t ProductStrategyMap::getDefault() const
+{
+    for (const auto &iter : *this) {
+        if (iter.second->isDefault()) {
+            ALOGV("%s: using default %s", __FUNCTION__, iter.second->getName().c_str());
+            return iter.second->getId();
+        }
+    }
+    ALOGE("%s: No default product strategy defined", __FUNCTION__);
+    return PRODUCT_STRATEGY_NONE;
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForProductStrategy(
+        product_strategy_t strategy) const
+{
+    if (find(strategy) == end()) {
+        ALOGE("Invalid %d strategy requested", strategy);
+        return AUDIO_ATTRIBUTES_INITIALIZER;
+    }
+    return at(strategy)->getAudioAttributes()[0];
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+    for (const auto &iter : *this) {
+        if (iter.second->supportStreamType(stream)) {
+            return iter.second->getId();
+        }
+    }
+    ALOGV("%s: No product strategy for stream %d, using default", __FUNCTION__, stream);
+    return getDefault();
+}
+
+
+audio_devices_t ProductStrategyMap::getDeviceTypesForProductStrategy(
+        product_strategy_t strategy) const
+{
+    if (find(strategy) == end()) {
+        ALOGE("Invalid %d strategy requested, returning device for default strategy", strategy);
+        product_strategy_t defaultStrategy = getDefault();
+        if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+            return AUDIO_DEVICE_NONE;
+        }
+        return at(getDefault())->getDeviceTypes();
+    }
+    return at(strategy)->getDeviceTypes();
+}
+
+std::string ProductStrategyMap::getDeviceAddressForProductStrategy(product_strategy_t psId) const
+{
+    if (find(psId) == end()) {
+        ALOGE("Invalid %d strategy requested, returning device for default strategy", psId);
+        product_strategy_t defaultStrategy = getDefault();
+        if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+            return {};
+        }
+        return at(getDefault())->getDeviceAddress();
+    }
+    return at(psId)->getDeviceAddress();
+}
+
+void ProductStrategyMap::dump(String8 *dst, int spaces) const
+{
+    dst->appendFormat("%*sProduct Strategies dump:", spaces, "");
+    for (const auto &iter : *this) {
+        iter.second->dump(dst, spaces + 2);
+    }
+}
+
+}
+
diff --git a/services/audiopolicy/engine/config/Android.mk b/services/audiopolicy/engine/config/Android.mk
new file mode 100644
index 0000000..fe7d961
--- /dev/null
+++ b/services/audiopolicy/engine/config/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH := $(call my-dir)
+
+##################################################################
+# Component build
+##################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS :=  $(LOCAL_PATH)/include
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_EXPORT_C_INCLUDE_DIRS) \
+    external/libxml2/include \
+    external/icu/icu4c/source/common
+
+LOCAL_SRC_FILES := \
+    src/EngineConfig.cpp
+
+LOCAL_CFLAGS += -Wall -Werror -Wextra
+
+LOCAL_SHARED_LIBRARIES := \
+    libmedia_helper \
+    libandroidicu \
+    libxml2 \
+    libutils \
+    liblog
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE := libaudiopolicyengineconfig
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudio_system_headers \
+    libaudiopolicycommon
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
new file mode 100644
index 0000000..e18f687
--- /dev/null
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <system/audio.h>
+
+#include <string>
+#include <vector>
+#include <utils/Errors.h>
+
+struct _xmlNode;
+struct _xmlDoc;
+
+namespace android {
+namespace engineConfig {
+
+/** Default path of audio policy usages configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamVector = std::vector<audio_stream_type_t>;
+
+struct AttributesGroup {
+    std::string name;
+    audio_stream_type_t stream;
+    AttributesVector attributesVect;
+};
+
+using AttributesGroups = std::vector<AttributesGroup>;
+
+struct ProductStrategy {
+    std::string name;
+    AttributesGroups attributesGroups;
+};
+
+using ProductStrategies = std::vector<ProductStrategy>;
+
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
+struct CriterionType
+{
+    std::string name;
+    bool isInclusive;
+    ValuePairs valuePairs;
+};
+
+using CriterionTypes = std::vector<CriterionType>;
+
+struct Criterion
+{
+    std::string name;
+    std::string typeName;
+    std::string defaultLiteralValue;
+};
+
+using Criteria = std::vector<Criterion>;
+
+struct Config {
+    float version;
+    ProductStrategies productStrategies;
+    Criteria criteria;
+    CriterionTypes criterionTypes;
+};
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+    /** Parsed config, nullptr if the xml lib could not load the file */
+    std::unique_ptr<Config> parsedConfig;
+    size_t nbSkippedElement; //< Number of skipped invalid product strategies
+};
+
+/** Parses the provided audio policy usage configuration.
+ * @return audio policy usage @see Config
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
new file mode 100644
index 0000000..3aa38cf
--- /dev/null
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/Config"
+//#define LOG_NDEBUG 0
+
+#include "EngineConfig.h"
+#include <policy.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/Log.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <istream>
+
+#include <cstdint>
+#include <string>
+
+
+namespace android {
+
+using utilities::convertTo;
+
+namespace engineConfig {
+
+static constexpr const char *gVersionAttribute = "version";
+static const char *const gReferenceElementName = "reference";
+static const char *const gReferenceAttributeName = "name";
+
+template<typename E, typename C>
+struct BaseSerializerTraits {
+    typedef E Element;
+    typedef C Collection;
+    typedef void* PtrSerializingCtx;
+};
+
+struct AttributesGroupTraits : public BaseSerializerTraits<AttributesGroup, AttributesGroups> {
+    static constexpr const char *tag = "AttributesGroup";
+    static constexpr const char *collectionTag = "AttributesGroups";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *streamType = "streamType";
+    };
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+
+struct ProductStrategyTraits : public BaseSerializerTraits<ProductStrategy, ProductStrategies> {
+    static constexpr const char *tag = "ProductStrategy";
+    static constexpr const char *collectionTag = "ProductStrategies";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+    };
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+struct ValueTraits : public BaseSerializerTraits<ValuePair, ValuePairs> {
+    static constexpr const char *tag = "value";
+    static constexpr const char *collectionTag = "values";
+
+    struct Attributes {
+        static constexpr const char *literal = "literal";
+        static constexpr const char *numerical = "numerical";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct CriterionTypeTraits : public BaseSerializerTraits<CriterionType, CriterionTypes> {
+    static constexpr const char *tag = "criterion_type";
+    static constexpr const char *collectionTag = "criterion_types";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *type = "type";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+struct CriterionTraits : public BaseSerializerTraits<Criterion, Criteria> {
+    static constexpr const char *tag = "criterion";
+    static constexpr const char *collectionTag = "criteria";
+
+    struct Attributes {
+        static constexpr const char *name = "name";
+        static constexpr const char *type = "type";
+        static constexpr const char *defaultVal = "default";
+    };
+
+    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+                                         Collection &collection);
+};
+
+using xmlCharUnique = std::unique_ptr<xmlChar, decltype(xmlFree)>;
+
+std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
+{
+    xmlCharUnique charPtr(xmlGetProp(cur, reinterpret_cast<const xmlChar *>(attribute)), xmlFree);
+    if (charPtr == NULL) {
+        return "";
+    }
+    std::string value(reinterpret_cast<const char*>(charPtr.get()));
+    return value;
+}
+
+static void getReference(const _xmlNode *root, const _xmlNode *&refNode, const std::string &refName,
+                         const char *collectionTag)
+{
+    for (root = root->xmlChildrenNode; root != NULL; root = root->next) {
+        if (!xmlStrcmp(root->name, (const xmlChar *)collectionTag)) {
+            for (xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+                if ((!xmlStrcmp(cur->name, (const xmlChar *)gReferenceElementName))) {
+                    std::string name = getXmlAttribute(cur, gReferenceAttributeName);
+                    if (refName == name) {
+                        refNode = cur;
+                        return;
+                    }
+                }
+            }
+        }
+    }
+    return;
+}
+
+template <class Trait>
+static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
+                                      typename Trait::Collection &collection,
+                                      size_t &nbSkippedElement)
+{
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (xmlStrcmp(cur->name, (const xmlChar *)Trait::collectionTag) &&
+            xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+            continue;
+        }
+        const xmlNode *child = cur;
+        if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
+            child = child->xmlChildrenNode;
+        }
+        for (; child != NULL; child = child->next) {
+            if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
+                status_t status = Trait::deserialize(doc, child, collection);
+                if (status != NO_ERROR) {
+                    nbSkippedElement += 1;
+                }
+            }
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+            return NO_ERROR;
+        }
+    }
+    return NO_ERROR;
+}
+
+static constexpr const char *attributesAttributeRef = "attributesRef"; /**< for factorization. */
+
+static status_t parseAttributes(const _xmlNode *cur, audio_attributes_t &attributes)
+{
+    for (; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("ContentType"))) {
+            std::string contentTypeXml = getXmlAttribute(cur, "value");
+            audio_content_type_t contentType;
+            if (not AudioContentTypeConverter::fromString(contentTypeXml.c_str(), contentType)) {
+                ALOGE("Invalid content type %s", contentTypeXml.c_str());
+                return BAD_VALUE;
+            }
+            attributes.content_type = contentType;
+            ALOGV("%s content type %s",  __FUNCTION__, contentTypeXml.c_str());
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Usage"))) {
+            std::string usageXml = getXmlAttribute(cur, "value");
+            audio_usage_t usage;
+            if (not UsageTypeConverter::fromString(usageXml.c_str(), usage)) {
+                ALOGE("Invalid usage %s", usageXml.c_str());
+                return BAD_VALUE;
+            }
+            attributes.usage = usage;
+            ALOGV("%s usage %s",  __FUNCTION__, usageXml.c_str());
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Flags"))) {
+            std::string flags = getXmlAttribute(cur, "value");
+
+            ALOGV("%s flags %s",  __FUNCTION__, flags.c_str());
+            attributes.flags = AudioFlagConverter::maskFromString(flags, " ");
+        }
+        if (!xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            std::string bundleKey = getXmlAttribute(cur, "key");
+            std::string bundleValue = getXmlAttribute(cur, "value");
+
+            ALOGV("%s Bundle %s %s",  __FUNCTION__, bundleKey.c_str(), bundleValue.c_str());
+
+            std::string tags(bundleKey + "=" + bundleValue);
+            std::strncpy(attributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+        }
+    }
+    return NO_ERROR;
+}
+
+static status_t deserializeAttributes(_xmlDoc *doc, const _xmlNode *cur,
+                                      audio_attributes_t &attributes) {
+    // Retrieve content type, usage, flags, and bundle from xml
+    for (; cur != NULL; cur = cur->next) {
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+            const xmlNode *attrNode = cur;
+            std::string attrRef = getXmlAttribute(cur, attributesAttributeRef);
+            if (!attrRef.empty()) {
+                getReference(xmlDocGetRootElement(doc), attrNode, attrRef, attributesAttributeRef);
+                if (attrNode == NULL) {
+                    ALOGE("%s: No reference found for %s", __FUNCTION__, attrRef.c_str());
+                    return BAD_VALUE;
+                }
+                return deserializeAttributes(doc, attrNode->xmlChildrenNode, attributes);
+            }
+            return parseAttributes(attrNode->xmlChildrenNode, attributes);
+        }
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            return parseAttributes(cur, attributes);
+        }
+    }
+    return BAD_VALUE;
+}
+
+static status_t deserializeAttributesCollection(_xmlDoc *doc, const _xmlNode *cur,
+                                                AttributesVector &collection)
+{
+    status_t ret = BAD_VALUE;
+    // Either we do provide only one attributes or a collection of supported attributes
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+                not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+            audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+            ret = deserializeAttributes(doc, cur, attributes);
+            if (ret == NO_ERROR) {
+                collection.push_back(attributes);
+                // We are done if the "Attributes" balise is omitted, only one Attributes is allowed
+                if (xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+                    return ret;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+status_t AttributesGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                            Collection &attributesGroup)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGV("AttributesGroupTraits No attribute %s found", Attributes::name);
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
+    std::string streamTypeXml = getXmlAttribute(child, Attributes::streamType);
+    if (streamTypeXml.empty()) {
+        ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::streamType);
+    } else {
+        ALOGV("%s: %s = %s", __FUNCTION__, Attributes::streamType, streamTypeXml.c_str());
+        if (not StreamTypeConverter::fromString(streamTypeXml.c_str(), streamType)) {
+            ALOGE("Invalid stream type %s", streamTypeXml.c_str());
+            return BAD_VALUE;
+        }
+    }
+    AttributesVector attributesVect;
+    deserializeAttributesCollection(doc, child, attributesVect);
+
+    attributesGroup.push_back({name, streamType, attributesVect});
+    return NO_ERROR;
+}
+
+status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
+{
+    std::string literal = getXmlAttribute(child, Attributes::literal);
+    if (literal.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+        return BAD_VALUE;
+    }
+    uint32_t numerical = 0;
+    std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
+    if (numericalTag.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+        return BAD_VALUE;
+    }
+    if (!convertTo(numericalTag, numerical)) {
+        ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
+        return BAD_VALUE;
+    }
+    values.push_back({numerical, literal});
+    return NO_ERROR;
+}
+
+status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                          Collection &criterionTypes)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
+
+    std::string type = getXmlAttribute(child, Attributes::type);
+    if (type.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
+    bool isInclusive(type == "inclusive");
+
+    ValuePairs pairs;
+    size_t nbSkippedElements = 0;
+    deserializeCollection<ValueTraits>(doc, child, pairs, nbSkippedElements);
+    criterionTypes.push_back({name, isInclusive, pairs});
+    return NO_ERROR;
+}
+
+status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child,
+                                      Collection &criteria)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
+    if (defaultValue.empty()) {
+        // Not mandatory to provide a default value for a criterion, even it is recommanded...
+        ALOGV("%s: No attribute %s found (but recommanded)", __FUNCTION__, Attributes::defaultVal);
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
+
+    std::string typeName = getXmlAttribute(child, Attributes::type);
+    if (typeName.empty()) {
+        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
+
+    criteria.push_back({name, typeName, defaultValue});
+    return NO_ERROR;
+}
+
+status_t ProductStrategyTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+                                            Collection &strategies)
+{
+    std::string name = getXmlAttribute(child, Attributes::name);
+    if (name.empty()) {
+        ALOGE("ProductStrategyTraits No attribute %s found", Attributes::name);
+        return BAD_VALUE;
+    }
+    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+    size_t skipped = 0;
+    AttributesGroups attrGroups;
+    deserializeCollection<AttributesGroupTraits>(doc, child, attrGroups, skipped);
+
+    strategies.push_back({name, attrGroups});
+    return NO_ERROR;
+}
+
+ParsingResult parse(const char* path) {
+    xmlDocPtr doc;
+    doc = xmlParseFile(path);
+    if (doc == NULL) {
+        ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
+        return {nullptr, 0};
+    }
+    xmlNodePtr cur = xmlDocGetRootElement(doc);
+    if (cur == NULL) {
+        ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
+        xmlFreeDoc(doc);
+        return {nullptr, 0};
+    }
+    if (xmlXIncludeProcess(doc) < 0) {
+        ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
+        return {nullptr, 0};
+    }
+    std::string version = getXmlAttribute(cur, gVersionAttribute);
+    if (version.empty()) {
+        ALOGE("%s: No version found", __func__);
+        return {nullptr, 0};
+    }
+    size_t nbSkippedElements = 0;
+    auto config = std::make_unique<Config>();
+    config->version = std::stof(version);
+    deserializeCollection<ProductStrategyTraits>(
+                doc, cur, config->productStrategies, nbSkippedElements);
+    deserializeCollection<CriterionTraits>(
+                doc, cur, config->criteria, nbSkippedElements);
+    deserializeCollection<CriterionTypeTraits>(
+                doc, cur, config->criterionTypes, nbSkippedElements);
+    return {std::move(config), nbSkippedElements};
+}
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/interface/Android.bp b/services/audiopolicy/engine/interface/Android.bp
new file mode 100644
index 0000000..2ea42b6
--- /dev/null
+++ b/services/audiopolicy/engine/interface/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 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_library_headers {
+    name: "libaudiopolicyengine_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["."],
+}
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 04594f5..498cc3b 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -17,7 +17,8 @@
 #pragma once
 
 #include <AudioPolicyManagerObserver.h>
-#include <RoutingStrategy.h>
+#include <media/AudioProductStrategy.h>
+#include <policy.h>
 #include <Volume.h>
 #include <HwModule.h>
 #include <DeviceDescriptor.h>
@@ -28,6 +29,10 @@
 
 namespace android {
 
+using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
+using StrategyVector = std::vector<product_strategy_t>;
+
+
 /**
  * This interface is dedicated to the policy manager that a Policy Engine shall implement.
  */
@@ -50,42 +55,6 @@
     virtual void setObserver(AudioPolicyManagerObserver *observer) = 0;
 
     /**
-     * Get the input device selected for a given input source.
-     *
-     * @param[in] inputSource to get the selected input device associated to
-     *
-     * @return selected input device for the given input source, may be none if error.
-     */
-    virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const = 0;
-
-    /**
-     * Get the output device associated to a given strategy.
-     *
-     * @param[in] stream type for which the selected ouput device is requested.
-     *
-     * @return selected ouput device for the given strategy, may be none if error.
-     */
-    virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const = 0;
-
-    /**
-     * Get the strategy selected for a given stream type.
-     *
-     * @param[in] stream: for which the selected strategy followed by is requested.
-     *
-     * @return strategy to be followed.
-     */
-    virtual routing_strategy getStrategyForStream(audio_stream_type_t stream) = 0;
-
-    /**
-     * Get the strategy selected for a given usage.
-     *
-     * @param[in] usage to get the selected strategy followed by.
-     *
-     * @return strategy to be followed.
-     */
-    virtual routing_strategy getStrategyForUsage(audio_usage_t usage) = 0;
-
-    /**
      * Set the Telephony Mode.
      *
      * @param[in] mode: Android Phone state (normal, ringtone, csv, in communication)
@@ -133,6 +102,140 @@
     virtual status_t setDeviceConnectionState(const android::sp<android::DeviceDescriptor> devDesc,
                                               audio_policy_dev_state_t state) = 0;
 
+    /**
+     * Get the strategy selected for a given audio attributes.
+     *
+     * @param[in] audio attributes to get the selected @product_strategy_t followed by.
+     *
+     * @return @product_strategy_t to be followed.
+     */
+    virtual product_strategy_t getProductStrategyForAttributes(
+            const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getOutputDevicesForAttributes retrieves the devices to be used for given
+     * audio attributes.
+     * @param attributes of the output requesting Device(s) selection
+     * @param preferedDevice valid reference if a prefered device is requested, nullptr otherwise.
+     * @param fromCache if true, the device is returned from internal cache,
+     *                  otherwise it is determined by current state (device connected,phone state,
+     *                  force use, a2dp output...)
+     * @return vector of selected device descriptors.
+     *         Appropriate device for streams handled by the specified audio attributes according
+     *         to current phone state, forced states, connected devices...
+     *         if fromCache is true, the device is returned from internal cache,
+     *         otherwise it is determined by current state (device connected,phone state, force use,
+     *         a2dp output...)
+     * This allows to:
+     *      1 speed up process when the state is stable (when starting or stopping an output)
+     *      2 access to either current device selection (fromCache == true) or
+     *      "future" device selection (fromCache == false) when called from a context
+     *      where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+     *      before manager updates its outputs.
+     */
+    virtual DeviceVector getOutputDevicesForAttributes(
+            const audio_attributes_t &attributes,
+            const sp<DeviceDescriptor> &preferedDevice = nullptr,
+            bool fromCache = false) const = 0;
+
+    /**
+     * @brief getOutputDevicesForStream Legacy function retrieving devices from a stream type.
+     * @param stream type of the output requesting Device(s) selection
+     * @param fromCache if true, the device is returned from internal cache,
+     *                  otherwise it is determined by current state (device connected,phone state,
+     *                  force use, a2dp output...)
+     * @return appropriate device for streams handled by the specified audio attributes according
+     *         to current phone state, forced states, connected devices...
+     *         if fromCache is true, the device is returned from internal cache,
+     *         otherwise it is determined by current state (device connected,phone state, force use,
+     *         a2dp output...)
+     * This allows to:
+     *      1 speed up process when the state is stable (when starting or stopping an output)
+     *      2 access to either current device selection (fromCache == true) or
+     *      "future" device selection (fromCache == false) when called from a context
+     *      where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+     *      before manager updates its outputs.
+     */
+    virtual DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                                   bool fromCache = false) const = 0;
+
+    /**
+     * Get the input device selected for given audio attributes.
+     *
+     * @param[in] attr audio attributes to consider
+     * @param[out] mix to be used if a mix has been installed for the given audio attributes.
+     * @return selected input device for the audio attributes, may be null if error.
+     */
+    virtual sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, AudioMix **mix = nullptr) const = 0;
+
+    /**
+     * Get the legacy stream type for a given audio attributes.
+     *
+     * @param[in] audio attributes to get the associated audio_stream_type_t.
+     *
+     * @return audio_stream_type_t associated to the attributes.
+     */
+    virtual audio_stream_type_t getStreamTypeForAttributes(
+            const audio_attributes_t &attr) const = 0;
+
+    /**
+     * @brief getAttributesForStream get the audio attributes from legacy stream type
+     * @param stream to consider
+     * @return audio attributes matching the legacy stream type
+     */
+    virtual audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const = 0;
+
+    /**
+     * @brief getStreamTypesForProductStrategy retrieves the list of legacy stream type following
+     * the given product strategy
+     * @param ps product strategy to consider
+     * @return associated legacy Stream Types vector of the given product strategy
+     */
+    virtual StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const = 0;
+
+    /**
+     * @brief getAllAttributesForProductStrategy retrieves all the attributes following the given
+     * product strategy. Any attributes that "matches" with this one will follow the product
+     * strategy.
+     * "matching" means the usage shall match if reference attributes has a defined usage, AND
+     * content type shall match if reference attributes has a defined content type AND
+     * flags shall match if reference attributes has defined flags AND
+     * tags shall match if reference attributes has defined tags.
+     * @param ps product strategy to consider
+     * @return vector of product strategy ids, empty if unknown strategy.
+     */
+    virtual AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const = 0;
+
+    /**
+     * @brief getOrderedAudioProductStrategies
+     * @return priority ordered product strategies to help the AudioPolicyManager evaluating the
+     * device selection per output according to the prioritized strategies.
+     */
+    virtual StrategyVector getOrderedProductStrategies() const = 0;
+
+    /**
+     * @brief updateDeviceSelectionCache. Device selection for AudioAttribute / Streams is cached
+     * in the engine in order to speed up process when the audio system is stable.
+     * When a device is connected, the android mode is changed, engine is notified and can update
+     * the cache.
+     * When starting / stopping an output with a stream that can affect notification, the engine
+     * needs to update the cache upon this function call.
+     */
+    virtual void updateDeviceSelectionCache() = 0;
+
+    /**
+     * @brief listAudioProductStrategies. Introspection API to retrieve a collection of
+     * AudioProductStrategyVector that allows to build AudioAttributes according to a
+     * product_strategy which is just an index. It has also a human readable name to help the
+     * Car/Oem/AudioManager identiying the use case.
+     * @param strategies collection.
+     * @return OK if the list has been retrieved, error code otherwise
+     */
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const = 0;
+
+    virtual void dump(String8 *dst) const = 0;
+
 protected:
     virtual ~AudioPolicyManagerInterface() {}
 };
diff --git a/services/audiopolicy/engineconfigurable/Android.mk b/services/audiopolicy/engineconfigurable/Android.mk
index c2105e9..bbd9688 100644
--- a/services/audiopolicy/engineconfigurable/Android.mk
+++ b/services/audiopolicy/engineconfigurable/Android.mk
@@ -11,14 +11,13 @@
     src/Engine.cpp \
     src/EngineInstance.cpp \
     src/Stream.cpp \
-    src/Strategy.cpp \
-    src/Usage.cpp \
     src/InputSource.cpp \
+    ../engine/common/src/ProductStrategy.cpp \
+    ../engine/common/src/EngineBase.cpp
 
 audio_policy_engine_includes_common := \
     frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
-    frameworks/av/services/audiopolicy/engine/interface
+    frameworks/av/services/audiopolicy/engineconfigurable/interface
 
 LOCAL_CFLAGS += \
     -Wall \
@@ -32,8 +31,12 @@
     $(audio_policy_engine_includes_common) \
     $(TARGET_OUT_HEADERS)/hw \
     $(call include-path-for, frameworks-av) \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/services/audiopolicy/common/include
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_common_headers \
+    libaudiopolicyengine_interface_headers
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
@@ -45,13 +48,14 @@
     libaudiopolicycomponents
 
 LOCAL_SHARED_LIBRARIES := \
+    libaudiopolicyengineconfig \
     liblog \
-    libcutils \
     libutils \
     liblog \
     libaudioutils \
     libparameter \
     libmedia_helper \
+    libaudiopolicy \
     libxml2
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/engineconfigurable/config/Android.mk b/services/audiopolicy/engineconfigurable/config/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
new file mode 100644
index 0000000..95a2ecc
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -0,0 +1,99 @@
+LOCAL_PATH := $(call my-dir)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies_phone.xml  \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+##################################################################
+# AUTOMOTIVE CONFIGURATION TOP FILE
+##################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_automotive.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies_automotive.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml
+
+include $(BUILD_PREBUILT)
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_automotive.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criteria.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := common/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criterion_types.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+    $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+
+ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
+AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+CRITERION_TYPES_FILE := $(LOCAL_PATH)/common/$(LOCAL_MODULE).in
+
+include $(PROVISION_CRITERION_TYPES)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
similarity index 67%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
rename to services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
index 5d9193b..e2fb02b 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
@@ -12,14 +12,13 @@
      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.
--->
-<!--
-    These are the minimum required criteria to be used by Audio HAL to ensure a basic
-    user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+     -->
 
-    <xi:include href="policy_criterion_types.xml"/>
-    <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
+    <xi:include href="audio_policy_engine_criterion_types.xml"/>
+    <xi:include href="audio_policy_engine_criteria.xml"/>
 
 </configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..543a2f0
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,161 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<ProductStrategies>
+    <!-- OEM Usages -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is oem_traffic_anouncement if all the conditions are satisfied for
+    AudioAttributes aa
+
+    int type = 0;
+    if (bundle != null) {
+    type = bundle.getInt(KEY_OEM_TYPE, 0);
+    }
+    if(
+    ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+    ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+    ( type == 1 ) )
+    -->
+
+    <ProductStrategy name="oem_traffic_anouncement">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <!--  traffic_annoucement = 1 -->
+            <Bundle key="oem" value="1"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_1">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="oem_strategy_2">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <Bundle key="oem" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Car Usages -->
+    <!-- Keep those lines only for car -->
+    <!-- Check car conditions if any OEM conditions matched -->
+    <!-- As defined by CarAudioAttributesUtil.java -->
+    <!-- product_strategy will be defined according this order
+    product_strategy is radio if all the conditions are satisfied for AudioAttributes aa
+
+        int type = CAR_AUDIO_TYPE_DEFAULT;
+        if (bundle != null) {
+        type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
+        }
+        if(
+        ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+        ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+        ( type == CAR_AUDIO_TYPE_RADIO ) )
+        -->
+    <ProductStrategy name="radio">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="3"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ext_audio_source">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <Usage value="AUDIO_USAGE_MEDIA"/>
+            <Bundle key="car_audio_type" value="7"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_command">
+        <AttributesGroup>
+            <Attributes>
+                <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+                <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+                <!--  CAR_AUDIO_TYPE_VOICE_COMMAND = 1 -->
+                <Bundle key="car_audio_type" value="1"/>
+            </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="safety_alert">
+        <AttributesGroup>
+            <ContentType value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+            <Usage value="AUDIO_USAGE_NOTIFICATION"/>
+            <!--  CAR_AUDIO_TYPE_SAFETY_ALERT = 2 -->
+            <Bundle key="car_audio_type" value="2"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- To be checked
+    CAR_AUDIO_TYPE_CARSERVICE_BOTTOM
+    CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY
+    CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE
+    -->
+
+    <!-- Generic Usages -->
+    <ProductStrategy name="music">
+        <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <!-- Default product strategy has empty attributes -->
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="nav_guidance">
+        <AttributesGroup>
+            <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="voice_call">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="alarm">
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+            <Usage value="AUDIO_USAGE_ALARM"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="ring">
+        <AttributesGroup streamType="AUDIO_STREAM_RING">
+            <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="notification">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+    <ProductStrategy name="system">
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+            <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+        </AttributesGroup>
+    </ProductStrategy>
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
rename to services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
similarity index 100%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
rename to services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
similarity index 67%
copy from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
copy to services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
index 5d9193b..ab61d8a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
@@ -12,14 +12,11 @@
      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.
--->
-<!--
-    These are the minimum required criteria to be used by Audio HAL to ensure a basic
-    user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+     -->
 
-    <xi:include href="policy_criterion_types.xml"/>
-    <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
 
 </configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..f72e379
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 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.
+     -->
+
+<ProductStrategies>
+
+    <!-- "hidden strategies" like TTS, enforced audible:
+            Shall we expose them here or keep it hard coded -->
+
+    <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+         countries (e.g. camera in Japan)
+         This strategy will only have higher priority than phone if force for system is set to
+         enforced. -->
+
+    <ProductStrategy name="STRATEGY_PHONE">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION">
+        <AttributesGroup streamType="AUDIO_STREAM_RING">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+            <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+        <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE">
+            <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+        <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_MEDIA">
+         <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+            <Attributes></Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_DTMF">
+        <AttributesGroup streamType="AUDIO_STREAM_DTMF">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Used to identify the volume of audio streams exclusively transmitted through the  speaker
+         (TTS) of the device -->
+    <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+        <AttributesGroup streamType="AUDIO_STREAM_TTS">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="STRATEGY_REROUTING">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Default product strategy has empty attributes -->
+    <ProductStrategy name="STRATEGY_PATCH">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
index 2e29a9b..1fc2264 100644
--- a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
+++ b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
@@ -16,10 +16,11 @@
 
 #pragma once
 
-#include <RoutingStrategy.h>
+#include <policy.h>
 #include <EngineDefinition.h>
 #include <Volume.h>
 #include <system/audio.h>
+#include <media/AudioCommonTypes.h>
 #include <utils/Errors.h>
 #include <string>
 #include <vector>
@@ -36,19 +37,6 @@
 {
 public:
     /**
-     * Add a strategy to the engine
-     *
-     * @param[in] name of the strategy to add
-     * @param[in] identifier: the numerical value associated to this member. It MUST match either
-     *            system/audio.h or system/audio_policy.h enumration value in order to link the
-     *            parameter controled by the PFW and the policy manager component.
-     *
-     * @return NO_ERROR if the strategy has been added successfully, error code otherwise.
-     *
-     */
-    virtual android::status_t addStrategy(const std::string &name, routing_strategy id) = 0;
-
-    /**
      * Add a streams to the engine.
      *
      * @param[in] name of the stream to add
@@ -62,19 +50,6 @@
     virtual android::status_t addStream(const std::string &name, audio_stream_type_t id) = 0;
 
     /**
-     * Add a usage to the engine
-     *
-     * @param[in] name of the usage to add
-     * @param[in] identifier: the numerical value associated to this member. It MUST match either
-     *            system/audio.h or system/audio_policy.h enumration value in order to link the
-     *            parameter controled by the PFW and the policy manager component.
-     *
-     * @return NO_ERROR if the usage has been added successfully, error code otherwise.
-     *
-     */
-    virtual android::status_t addUsage(const std::string &name, audio_usage_t id) = 0;
-
-    /**
      * Add an input source to the engine
      *
      * @param[in] name of the input source to add
@@ -88,26 +63,6 @@
     virtual android::status_t addInputSource(const std::string &name, audio_source_t id) = 0;
 
     /**
-     * Set the device to be used by a strategy.
-     *
-     * @param[in] strategy: name of the strategy for which the device to use has to be set
-     * @param[in] devices; mask of devices to be used for the given strategy.
-     *
-     * @return true if the devices were set correclty for this strategy, false otherwise.
-     */
-    virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices) = 0;
-
-    /**
-     * Set the strategy to be followed by a stream.
-     *
-     * @param[in] stream: name of the stream for which the strategy to use has to be set
-     * @param[in] strategy to follow for the given stream.
-     *
-     * @return true if the strategy were set correclty for this stream, false otherwise.
-     */
-    virtual bool setStrategyForStream(const audio_stream_type_t &stream, routing_strategy strategy) = 0;
-
-    /**
      * Set the strategy to be followed by a stream.
      *
      * @param[in] stream: name of the stream for which the strategy to use has to be set
@@ -119,16 +74,6 @@
                                            const audio_stream_type_t &volumeProfile) = 0;
 
     /**
-     * Set the strategy to be followed by a usage.
-     *
-     * @param[in] usage: name of the usage for which the strategy to use has to be set
-     * @param[in] strategy to follow for the given usage.
-     *
-     * @return true if the strategy were set correclty for this usage, false otherwise.
-     */
-    virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy) = 0;
-
-    /**
      * Set the input device to be used by an input source.
      *
      * @param[in] inputSource: name of the input source for which the device to use has to be set
@@ -139,6 +84,22 @@
     virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
                                          audio_devices_t device) = 0;
 
+    virtual void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                    const std::string &address) = 0;
+
+    /**
+     * Set the device to be used by a product strategy.
+     *
+     * @param[in] strategy: name of the product strategy for which the device to use has to be set
+     * @param[in] devices; mask of devices to be used for the given strategy.
+     *
+     * @return true if the devices were set correclty for this strategy, false otherwise.
+     */
+    virtual bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+                                                  audio_devices_t devices) = 0;
+
+    virtual product_strategy_t getProductStrategyByName(const std::string &address) = 0;
+
 protected:
     virtual ~AudioPolicyPluginInterface() {}
 };
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index 7631976..060830b 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -9,7 +9,7 @@
 
 LOCAL_PATH := $(call my-dir)
 
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable no-output_configurable no-input_configurable))
 
 PFW_CORE := external/parameter-framework
 #@TODO: upstream new domain generator
@@ -20,116 +20,79 @@
 TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
 BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
 
+endif
+
 ##################################################################
 # CONFIGURATION FILES
 ##################################################################
 ######### Policy PFW top level file #########
 
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework
 LOCAL_SRC_FILES := $(LOCAL_MODULE).in
 
+# external/parameter-framework prevents from using debug interface
 AUDIO_PATTERN = @TUNING_ALLOWED@
-ifeq ($(TARGET_BUILD_VARIANT),user)
+#ifeq ($(TARGET_BUILD_VARIANT),user)
 AUDIO_VALUE = false
-else
-AUDIO_VALUE = true
-endif
+#else
+#AUDIO_VALUE = true
+#endif
 
-LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
+LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
 
 include $(BUILD_PREBUILT)
 
-
-########## Policy PFW Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicyClass.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem-CommonTypes.xml \
-    libpolicy-subsystem
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
+########## Policy PFW Common Structures #########
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
 LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
-######### Policy PFW Settings #########
 include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE := PolicyClass.xml
+LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_REQUIRED_MODULES := \
-    policy_criteria.xml \
-    policy_criterion_types.xml \
-    PolicySubsystem.xml \
-    PolicyClass.xml \
-    ParameterFrameworkConfigurationPolicy.xml
-
-ifeq ($(pfw_rebuild_settings),true)
-PFW_EDD_FILES := \
-        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
-        $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
-        $(LOCAL_PATH)/Settings/volumes.pfw
-
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-    $(PFW_EDD_FILES)
-
-
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
-
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-include $(BUILD_PFW_SETTINGS)
-else
-# Use the existing file
-LOCAL_SRC_FILES := Settings/$(LOCAL_MODULE_STEM)
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
-endif # pfw_rebuild_settings
 
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 0)
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
+########## Policy PFW Example Structures #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.common
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem-CommonTypes.xml \
+    PolicySubsystem-Volume.xml \
+    libpolicy-subsystem \
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
 
 ######### Policy PFW Settings - No Output #########
-ifeq (0, 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := parameter-framework.policy.no-output
@@ -138,26 +101,24 @@
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
 LOCAL_REQUIRED_MODULES := \
-    policy_criteria.xml \
-    policy_criterion_types.xml \
-    PolicySubsystem.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml \
+    PolicySubsystem.xml.common \
     PolicyClass.xml \
     ParameterFrameworkConfigurationPolicy.xml
 
 PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
 PFW_EDD_FILES := \
         $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
         $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
         $(LOCAL_PATH)/Settings/volumes.pfw
 
 include $(BUILD_PFW_SETTINGS)
-endif # ifeq (0, 1)
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
 ######### Policy PFW Settings - No Input #########
-ifeq (0, 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := parameter-framework.policy.no-input
@@ -166,36 +127,26 @@
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
 LOCAL_REQUIRED_MODULES := \
-    policy_criteria.xml \
-    policy_criterion_types.xml \
-    PolicySubsystem.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml \
+    PolicySubsystem.xml.common \
     PolicyClass.xml \
     ParameterFrameworkConfigurationPolicy.xml
 
 PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
 PFW_EDD_FILES := \
-        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
-        $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
-        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
         $(LOCAL_PATH)/SettingsNoInput/device_for_input_source.pfw \
         $(LOCAL_PATH)/Settings/volumes.pfw
 
 include $(BUILD_PFW_SETTINGS)
 
-endif # ifeq (1, 0)
-
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
 #######################################################################
 # Recursive call sub-folder Android.mk
 #######################################################################
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
new file mode 100644
index 0000000..ea4a58f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
@@ -0,0 +1,86 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+########## Policy PFW Structures #########
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.car
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+    ProductStrategies.xml.car \
+    PolicySubsystem-Volume.xml \
+    PolicySubsystem-CommonTypes.xml \
+    libpolicy-subsystem
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml.car
+LOCAL_MODULE_STEM := ProductStrategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.car
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+
+PFW_EDD_FILES := \
+        $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
+        $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+        $(LOCAL_PATH)/../Settings/volumes.pfw
+
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+    $(PFW_EDD_FILES)
+
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem.xml.car \
+    PolicyClass.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml \
+    ParameterFrameworkConfigurationPolicy.xml
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
new file mode 100644
index 0000000..196d82c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
@@ -0,0 +1,717 @@
+supDomain: DeviceForProductStrategies
+	supDomain: OemTrafficAnouncement
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_traffic_anouncement/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+					bus = 0
+
+	supDomain: OemStrategy1
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_1/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: OemStrategy2
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/oem_strategy_2/device_address = BUS08_OEM1
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: Radio
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/radio/device_address = BUS09_OEM2
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+	supDomain: ExtAudioSource
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ext_audio_source/device_address = BUS09_OEM2
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+					bus = 0
+
+
+
+	supDomain: VoiceCommand
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_command/device_address = BUS02_VOICE_COMMAND
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS02_VOICE_COMMAND
+
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: SafetyAlert
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/safety_alert/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Music
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/music/device_address = BUS00_MEDIA
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+
+	supDomain: NavGuidance
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/nav_guidance/device_address = BUS01_NAV_GUIDANCE
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: VoiceCall
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/voice_call/device_address = BUS04_CALL
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS04_CALL
+
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Alarm
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/alarm/device_address = BUS05_ALARM
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS05_ALARM
+
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Ring
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/ring/device_address = BUS03_CALL_RING
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS03_CALL_RING
+
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: Notification
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/notification/device_address = BUS06_NOTIFICATION
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS06_NOTIFICATION
+
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
+	supDomain: System
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/system/device_address = BUS07_SYSTEM_SOUND
+
+		domain: SelectedDevice
+			conf: Bus
+				AvailableOutputDevices Includes Bus
+				AvailableOutputDevicesAddresses Includes BUS07_SYSTEM_SOUND
+
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 0
+					bus = 1
+
+			conf: Speaker
+				AvailableOutputDevices Includes Speaker
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 1
+					bus = 0
+
+			conf: Default
+				component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+					speaker = 0
+					bus = 0
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml
new file mode 100644
index 0000000..b55ce2c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:xi="http://www.w3.org/2001/XInclude"
+           xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+           Name="policy" Type="Policy">
+
+    <ComponentLibrary>
+        <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+        <!-- Common Types defintion -->
+        <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+        <xi:include href="ProductStrategies.xml"/>
+
+
+        <!--#################### GLOBAL COMPONENTS END ####################-->
+
+        <!--#################### STREAM BEGIN ####################-->
+
+        <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+            <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+            <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+            <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+            <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+            <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+            <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+            <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+                       Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+            <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+            <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+                             Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+            <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+                             Description="For accessibility talk back prompts"/>
+            <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+                             Description="For dynamic policy output mixes"/>
+            <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+                             Description="For internal audio flinger tracks. Fixed volume"/>
+        </ComponentType>
+
+        <!--#################### STREAM END ####################-->
+
+        <!--#################### INPUT SOURCE BEGIN ####################-->
+
+        <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+                             identifier mapping must match the value of the enum">
+            <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+            <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+            <Component Name="voice_uplink" Type="InputSource"
+                                           Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+            <Component Name="voice_downlink" Type="InputSource"
+                                             Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <Component Name="voice_call" Type="InputSource"
+                                         Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+            <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+            <Component Name="voice_recognition" Type="InputSource"
+                                                Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <Component Name="voice_communication" Type="InputSource"
+                                                  Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <Component Name="remote_submix" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <Component Name="unprocessed" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+            <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+            <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+        </ComponentType>
+
+        <!--#################### INPUT SOURCE END ####################-->
+    </ComponentLibrary>
+
+    <InstanceDefinition>
+        <Component Name="streams" Type="Streams"/>
+        <Component Name="input_sources" Type="InputSources"/>
+        <Component Name="product_strategies" Type="ProductStrategies"/>
+    </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
new file mode 100644
index 0000000..53bba03
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+  <ComponentType Name="ProductStrategies" Description="">
+      <Component Name="oem_traffic_anouncement" Type="ProductStrategy"/>
+      <Component Name="oem_strategy_1" Type="ProductStrategy"/>
+      <Component Name="oem_strategy_2" Type="ProductStrategy"/>
+
+      <Component Name="radio" Type="ProductStrategy"/>
+      <Component Name="ext_audio_source" Type="ProductStrategy"/>
+      <Component Name="voice_command" Type="ProductStrategy"/>
+      <Component Name="safety_alert" Type="ProductStrategy"/>
+
+      <Component Name="music" Type="ProductStrategy"/>
+      <Component Name="nav_guidance" Type="ProductStrategy"/>
+      <Component Name="voice_call" Type="ProductStrategy"/>
+      <Component Name="alarm" Type="ProductStrategy"/>
+      <Component Name="ring" Type="ProductStrategy"/>
+      <Component Name="notification" Type="ProductStrategy"/>
+      <Component Name="system" Type="ProductStrategy"/>
+  </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
new file mode 100644
index 0000000..e9d67e9
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
@@ -0,0 +1,94 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+########## Policy PFW Structures #########
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.phone
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem-CommonTypes.xml \
+    ProductStrategies.xml.phone \
+    PolicySubsystem-Volume.xml \
+    libpolicy-subsystem \
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml.phone
+LOCAL_MODULE_STEM := ProductStrategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.phone
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+
+PFW_EDD_FILES := \
+        $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+        $(LOCAL_PATH)/../Settings/volumes.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_media.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_accessibility.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_dtmf.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_enforced_audible.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_phone.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification_respectful.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_transmitted_through_speaker.pfw \
+        $(LOCAL_PATH)/Settings/device_for_product_strategy_unknown.pfw
+
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+    $(PFW_EDD_FILES)
+
+LOCAL_REQUIRED_MODULES := \
+    PolicySubsystem.xml.phone \
+    PolicyClass.xml \
+    audio_policy_engine_criteria.xml \
+    audio_policy_engine_criterion_types.xml \
+    ParameterFrameworkConfigurationPolicy.xml
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
similarity index 87%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
index 7c87c80..53e93de 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
@@ -1,4 +1,4 @@
-supDomain: DeviceForStrategy
+supDomain: DeviceForProductStrategy
 
 	supDomain: Accessibility
 		#
@@ -9,7 +9,7 @@
 		#
 		domain: UnreachableDevices
 			conf: Calibration
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					hdmi_arc = 0
 					spdif = 0
 					aux_line = 0
@@ -18,6 +18,8 @@
 					telephony_tx = 0
 					ip = 0
 					bus = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
 
 		domain: Device
@@ -30,7 +32,7 @@
 				AvailableOutputDevices Includes RemoteSubmix
 				AvailableOutputDevicesAddresses Includes 0
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 1
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -58,7 +60,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 1
@@ -86,7 +88,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -114,7 +116,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -142,7 +144,7 @@
 				ForceUseForMedia Is ForceSpeaker
 				AvailableOutputDevices Includes Speaker
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -171,7 +173,7 @@
 				AvailableOutputDevices Includes BluetoothScoCarkit
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -200,7 +202,7 @@
 				AvailableOutputDevices Includes BluetoothScoHeadset
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -229,7 +231,7 @@
 				AvailableOutputDevices Includes BluetoothSco
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -266,7 +268,7 @@
 						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadphone
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -302,7 +304,7 @@
 					#
 				AvailableOutputDevices Includes Line
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -339,7 +341,7 @@
 						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadset
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -379,7 +381,7 @@
 						ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes UsbDevice
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -410,7 +412,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes UsbAccessory
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -440,7 +442,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes DgtlDockHeadset
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -470,7 +472,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Hdmi
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -502,7 +504,7 @@
 				AvailableOutputDevices Includes AnlgDockHeadset
 				ForceUseForDock Is ForceAnalogDock
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -531,7 +533,7 @@
 				AvailableOutputDevices Includes Earpiece
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 1
 					bluetooth_a2dp = 0
@@ -553,7 +555,7 @@
 			conf: Speaker
 				AvailableOutputDevices Includes Speaker
 
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
@@ -573,7 +575,7 @@
 					hdmi = 0
 
 			conf: Default
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					bluetooth_a2dp = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
index c830c42..b8426c6 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
@@ -1,16 +1,17 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategies
 	supDomain: Dtmf
-
 		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+			conf: calibration
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					fm = 0
 					speaker_safe = 0
 					bluetooth_sco_carkit = 0
 					ip = 0
 					bus = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
+				/Policy/policy/product_strategies/dtmf/device_address =
 
 		domain: Device2
 			conf: RemoteSubmix
@@ -22,7 +23,7 @@
 				AvailableOutputDevices Includes RemoteSubmix
 				AvailableOutputDevicesAddresses Includes 0
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 1
 					earpiece = 0
 					wired_headset = 0
@@ -50,7 +51,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -78,7 +79,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -106,7 +107,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -135,7 +136,7 @@
 				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
 				AvailableOutputDevices Includes Speaker
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -164,7 +165,7 @@
 				AvailableOutputDevices Includes BluetoothScoHeadset
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -193,7 +194,7 @@
 				AvailableOutputDevices Includes BluetoothSco
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -230,7 +231,7 @@
 						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadphone
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -269,7 +270,7 @@
 						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Line
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -306,7 +307,7 @@
 						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadset
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 1
@@ -346,7 +347,7 @@
 						ForceUseForCommunication Is ForceSpeaker
 				AvailableOutputDevices Includes UsbDevice
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -377,7 +378,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes UsbAccessory
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -407,7 +408,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes DgtlDockHeadset
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -437,7 +438,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Hdmi
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -469,7 +470,7 @@
 				ForceUseForDock Is ForceAnalogDock
 				AvailableOutputDevices Includes AnlgDockHeadset
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -498,7 +499,7 @@
 				AvailableOutputDevices Includes Earpiece
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 1
 					wired_headset = 0
@@ -536,7 +537,7 @@
 						ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
 				AvailableOutputDevices Includes Speaker
 
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -556,7 +557,7 @@
 					speaker = 1
 
 			conf: Default
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -586,10 +587,10 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes HdmiArc
 
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
 
 		domain: Spdif
 			#
@@ -602,10 +603,10 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Spdif
 
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 1
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 0
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 0
 
 		domain: AuxLine
 			#
@@ -618,7 +619,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes AuxLine
 
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 1
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 0
+				/Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
similarity index 83%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
index c641138..2daa9ac 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
@@ -1,10 +1,10 @@
-supDomain: DeviceForStrategy
+supDomain: DeviceForProductStrategy
 
 	supDomain: EnforcedAudible
 
 		domain: UnreachableDevices
 			conf: Calibration
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					# no enforced_audible on remote submix (e.g. WFD)
 					hdmi_arc = 0
 					spdif = 0
@@ -13,6 +13,8 @@
 					ip = 0
 					bus = 0
 					fm = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
 
 		domain: Speaker
@@ -51,11 +53,11 @@
 							AvailableOutputDevices Excludes AnlgDockHeadset
 							ForceUseForDock IsNot ForceAnalogDock
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					speaker = 1
 
 			conf: NotSelected
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					speaker = 0
 
 		domain: Device2
@@ -63,7 +65,7 @@
 				AvailableOutputDevices Includes RemoteSubmix
 				AvailableOutputDevicesAddresses Includes 0
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 1
 					earpiece = 0
 					wired_headset = 0
@@ -86,7 +88,7 @@
 				AvailableOutputDevices Includes BluetoothA2dp
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -109,7 +111,7 @@
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -132,7 +134,7 @@
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -155,7 +157,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes WiredHeadphone
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -178,7 +180,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes Line
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -201,7 +203,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes WiredHeadset
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 1
@@ -224,7 +226,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes UsbAccessory
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -247,7 +249,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes UsbDevice
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -270,7 +272,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes DgtlDockHeadset
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -293,7 +295,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes Hdmi
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -317,7 +319,7 @@
 				ForceUseForDock Is ForceAnalogDock
 				AvailableOutputDevices Includes AnlgDockHeadset
 
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
@@ -337,7 +339,7 @@
 					line = 0
 
 			conf: NoDevice
-				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
 					remote_submix = 0
 					earpiece = 0
 					wired_headset = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
similarity index 77%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
index f8bab3d..d6d355c 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
@@ -1,10 +1,8 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: Media
-
+supDomain: DeviceForProductStrategy
+	supDomain: Media
 		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+			conf: calibration
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					fm = 0
 					speaker_safe = 0
 					earpiece = 0
@@ -13,15 +11,18 @@
 					bluetooth_sco_carkit = 0
 					telephony_tx = 0
 					ip = 0
+					proxy = 0
+					usb_headset = 0
 					bus = 0
 					stub = 0
+				/Policy/policy/product_strategies/media/device_address =
 
 		domain: Device2
 			conf: RemoteSubmix
 				AvailableOutputDevices Includes RemoteSubmix
 				AvailableOutputDevicesAddresses Includes 0
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -41,7 +42,7 @@
 				ForceUseForCommunication IsNot ForceBtSco
 				AvailableOutputDevices Includes BluetoothA2dp
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -61,7 +62,7 @@
 				ForceUseForCommunication IsNot ForceBtSco
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -81,7 +82,7 @@
 				ForceUseForCommunication IsNot ForceBtSco
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -104,7 +105,7 @@
 				#
 				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 1
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -122,7 +123,7 @@
 			conf: WiredHeadphone
 				AvailableOutputDevices Includes WiredHeadphone
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -140,7 +141,7 @@
 			conf: Line
 				AvailableOutputDevices Includes Line
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -158,7 +159,7 @@
 			conf: WiredHeadset
 				AvailableOutputDevices Includes WiredHeadset
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -176,7 +177,7 @@
 			conf: UsbAccessory
 				AvailableOutputDevices Includes UsbAccessory
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -194,7 +195,7 @@
 			conf: UsbDevice
 				AvailableOutputDevices Includes UsbDevice
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -212,7 +213,7 @@
 			conf: DgtlDockHeadset
 				AvailableOutputDevices Includes DgtlDockHeadset
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 1
@@ -230,7 +231,7 @@
 			conf: AuxDigital
 				AvailableOutputDevices Includes Hdmi
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 1
 					dgtl_dock_headset = 0
@@ -249,7 +250,7 @@
 				AvailableOutputDevices Includes AnlgDockHeadset
 				ForceUseForDock Is ForceAnalogDock
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -272,7 +273,7 @@
 				ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
 				ForceUseForCommunication IsNot ForceBtSco
 
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 1
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -288,7 +289,7 @@
 					line = 0
 
 			conf: Default
-				component: /Policy/policy/strategies/media/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/media/selected_output_devices/mask
 					speaker = 0
 					hdmi = 0
 					dgtl_dock_headset = 0
@@ -311,10 +312,10 @@
 			conf: Selected
 				AvailableOutputDevices Includes HdmiArc
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 1
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 0
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 0
 
 		domain: Spdif
 			#
@@ -324,16 +325,16 @@
 			conf: Selected
 				AvailableOutputDevices Includes Spdif
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 1
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 0
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 0
 
 		domain: AuxLine
 			conf: Selected
 				AvailableOutputDevices Includes AuxLine
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 1
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 0
+				/Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
index d371ad9..5693d4e 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
@@ -1,10 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
 	supDomain: Phone
-
 		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+			conf: calibration
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					# no sonification on remote submix (e.g. WFD)
 					remote_submix = 0
 					hdmi_arc = 0
@@ -12,16 +10,18 @@
 					spdif = 0
 					fm = 0
 					speaker_safe = 0
-					ip = 0
 					bus = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
+				/Policy/policy/product_strategies/phone/device_address =
 
 		domain: Device
 			conf: ScoCarkit
 				AvailableOutputDevices Includes BluetoothScoCarkit
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -44,7 +44,7 @@
 				AvailableOutputDevices Includes BluetoothScoHeadset
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -67,7 +67,7 @@
 				AvailableOutputDevices Includes BluetoothSco
 				ForceUseForCommunication Is ForceBtSco
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -97,7 +97,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				ForceUseForCommunication Is ForceNone
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -127,7 +127,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				ForceUseForCommunication Is ForceNone
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -157,7 +157,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				ForceUseForCommunication Is ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -184,7 +184,7 @@
 				AvailableOutputDevices Includes WiredHeadphone
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 1
@@ -211,7 +211,7 @@
 				AvailableOutputDevices Includes WiredHeadset
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 1
 					wired_headphone = 0
@@ -234,7 +234,7 @@
 				AvailableOutputDevices Includes Line
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -272,7 +272,7 @@
 						TelephonyMode IsNot InCall
 						TelephonyMode IsNot InCommunication
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -300,7 +300,7 @@
 				TelephonyMode IsNot InCommunication
 				TelephonyMode IsNot InCall
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -328,7 +328,7 @@
 				TelephonyMode IsNot InCall
 				TelephonyMode IsNot InCommunication
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -356,7 +356,7 @@
 				TelephonyMode IsNot InCall
 				TelephonyMode IsNot InCommunication
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -384,7 +384,7 @@
 				TelephonyMode IsNot InCall
 				TelephonyMode IsNot InCommunication
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -411,7 +411,7 @@
 				AvailableOutputDevices Includes Earpiece
 				ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 1
 					wired_headset = 0
 					wired_headphone = 0
@@ -438,7 +438,7 @@
 				AvailableOutputDevices Includes Speaker
 				ForceUseForCommunication Is ForceSpeaker
 
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -461,7 +461,7 @@
 				#
 				# Fallback on default output device which can be speaker for example
 				#
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
new file mode 100644
index 0000000..c064c18
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
@@ -0,0 +1,43 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Rerouting
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					stub = 0
+				/Policy/policy/product_strategies/rerouting/device_address =
+
+		domain: SelectedDevice
+			conf: Bus
+				component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+					bus = 1
+
+			conf: Default
+				component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+					bus = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
index 70740d1..c4edeeb 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
@@ -1,11 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
 	supDomain: Sonification
-
 		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
-					# no sonification on remote submix (e.g. WFD)
+			conf: calibration
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					remote_submix = 0
 					hdmi_arc = 0
 					spdif = 0
@@ -16,9 +13,12 @@
 					# Sonification follows phone strategy if in call but HDMI is not reachable
 					#
 					hdmi = 0
-					ip = 0
 					bus = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
+				/Policy/policy/product_strategies/sonification/device_address =
 
 		domain: Speaker
 
@@ -41,11 +41,11 @@
 							TelephonyMode Is InCommunication
 						AvailableOutputDevices Excludes Line
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					speaker = 1
 
 			conf: NotSelected
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					speaker = 0
 
 		domain: Device2
@@ -59,7 +59,7 @@
 				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -85,7 +85,7 @@
 				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -111,7 +111,7 @@
 				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceNoBtA2dp
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -138,7 +138,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothScoCarkit
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -165,7 +165,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothScoHeadset
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -192,7 +192,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothSco
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -228,7 +228,7 @@
 							TelephonyMode Is InCommunication
 						ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 1
@@ -266,7 +266,7 @@
 						TelephonyMode IsNot InCommunication
 						ForceUseForMedia IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -302,7 +302,7 @@
 							TelephonyMode Is InCommunication
 						ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 1
 					wired_headphone = 0
@@ -339,7 +339,7 @@
 							TelephonyMode Is InCommunication
 						ForceUseForCommunication IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -368,7 +368,7 @@
 				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -397,7 +397,7 @@
 				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceSpeaker
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -427,7 +427,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				ForceUseForDock Is ForceAnalogDock
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -454,7 +454,7 @@
 				ForceUseForCommunication IsNot ForceSpeaker
 				AvailableOutputDevices Includes Earpiece
 
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 1
 					wired_headset = 0
 					wired_headphone = 0
@@ -472,7 +472,7 @@
 					line = 0
 
 			conf: None
-				component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
 					earpiece = 0
 					wired_headset = 0
 					wired_headphone = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
similarity index 85%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
index b673c4f..0a3dd5f 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
@@ -1,6 +1,5 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: SonificationRespectful
+supDomain: DeviceForProductStrategy
+	supDomain: SonificationRespectful
 		#
 		# Sonificiation Respectful follows:
 		#	- If in call: Strategy sonification (that follows phone strategy in call also...)
@@ -12,10 +11,9 @@
 		#	  selected.
 		#
 		# Case of stream active handled programmatically
-
 		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+			conf: calibration
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					remote_submix = 0
 					hdmi_arc = 0
 					aux_line = 0
@@ -23,8 +21,10 @@
 					fm = 0
 					telephony_tx = 0
 					ip = 0
-					bus = 0
+					proxy = 0
+					usb_headset = 0
 					stub = 0
+				/Policy/policy/product_strategies/sonification_respectful/device_address =
 
 		domain: Speakers
 
@@ -38,7 +38,7 @@
 				TelephonyMode IsNot InCall
 				TelephonyMode IsNot InCommunication
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					speaker_safe = 1
 					speaker = 0
 
@@ -61,12 +61,12 @@
 							TelephonyMode Is InCommunication
 						AvailableOutputDevices Excludes Line
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					speaker_safe = 0
 					speaker = 1
 
 			conf: None
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					speaker_safe = 0
 					speaker = 0
 
@@ -81,7 +81,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -108,7 +108,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -135,7 +135,7 @@
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -162,7 +162,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothScoCarkit
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -189,7 +189,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothScoHeadset
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 1
@@ -216,7 +216,7 @@
 				ForceUseForCommunication Is ForceBtSco
 				AvailableOutputDevices Includes BluetoothSco
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 1
 					bluetooth_sco_headset = 0
@@ -253,7 +253,7 @@
 						ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes WiredHeadphone
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -294,7 +294,7 @@
 						ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes Line
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -331,7 +331,7 @@
 						ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes WiredHeadset
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -369,7 +369,7 @@
 						AvailableOutputDevices Excludes UsbAccessory
 				AvailableOutputDevices Includes UsbDevice
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -399,7 +399,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes UsbAccessory
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -429,7 +429,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes DgtlDockHeadset
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -459,7 +459,7 @@
 				ForceUseForMedia IsNot ForceSpeaker
 				AvailableOutputDevices Includes Hdmi
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -490,7 +490,7 @@
 				ForceUseForDock Is ForceAnalogDock
 				AvailableOutputDevices Includes AnlgDockHeadset
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -517,7 +517,7 @@
 				ForceUseForCommunication IsNot ForceSpeaker
 				AvailableOutputDevices Includes Earpiece
 
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 1
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -534,20 +534,3 @@
 					usb_device = 0
 					hdmi = 0
 
-			conf: None
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
similarity index 61%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
index 9f9c211..3fc7670 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
@@ -1,9 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
 	supDomain: TransmittedThroughSpeaker
 		domain: UnreacheableDevices
 			conf: Calibration
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
 					remote_submix = 0
 					hdmi_arc = 0
 					spdif = 0
@@ -11,7 +10,7 @@
 					fm = 0
 					speaker_safe = 0
 					earpiece = 0
-					wired_headset = 1
+					wired_headset = 0
 					wired_headphone = 0
 					bluetooth_sco = 0
 					bluetooth_sco_headset = 0
@@ -29,15 +28,16 @@
 					ip = 0
 					bus = 0
 					stub = 0
+				/Policy/policy/product_strategies/transmitted_through_speaker/device_address =
 
 		domain: Speaker
 			conf: Selected
 				AvailableOutputDevices Includes Speaker
 
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
 					speaker = 1
 
 			conf: NotSelected
-				component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+				component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
 					speaker = 0
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
new file mode 100644
index 0000000..c46cf56
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
@@ -0,0 +1,36 @@
+supDomain: DeviceForProductStrategy
+	supDomain: Unknown
+		domain: UnreachableDevices
+			conf: calibration
+				component: /Policy/policy/product_strategies/unknown/selected_output_devices/mask
+					earpiece = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					remote_submix = 0
+					telephony_tx = 0
+					line = 0
+					hdmi_arc = 0
+					spdif = 0
+					fm = 0
+					aux_line = 0
+					speaker_safe = 0
+					ip = 0
+					proxy = 0
+					usb_headset = 0
+					bus = 0
+					stub = 0
+				/Policy/policy/product_strategies/unknown/device_address =
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
new file mode 100644
index 0000000..b55ce2c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xmlns:xi="http://www.w3.org/2001/XInclude"
+           xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+           Name="policy" Type="Policy">
+
+    <ComponentLibrary>
+        <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+        <!-- Common Types defintion -->
+        <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+        <xi:include href="ProductStrategies.xml"/>
+
+
+        <!--#################### GLOBAL COMPONENTS END ####################-->
+
+        <!--#################### STREAM BEGIN ####################-->
+
+        <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+            <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+            <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+            <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+            <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+            <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+            <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+            <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+                       Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+            <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+            <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+                             Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+            <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+                             Description="For accessibility talk back prompts"/>
+            <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+                             Description="For dynamic policy output mixes"/>
+            <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+                             Description="For internal audio flinger tracks. Fixed volume"/>
+        </ComponentType>
+
+        <!--#################### STREAM END ####################-->
+
+        <!--#################### INPUT SOURCE BEGIN ####################-->
+
+        <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+                             identifier mapping must match the value of the enum">
+            <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+            <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+            <Component Name="voice_uplink" Type="InputSource"
+                                           Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+            <Component Name="voice_downlink" Type="InputSource"
+                                             Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <Component Name="voice_call" Type="InputSource"
+                                         Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+            <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+            <Component Name="voice_recognition" Type="InputSource"
+                                                Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <Component Name="voice_communication" Type="InputSource"
+                                                  Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <Component Name="remote_submix" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <Component Name="unprocessed" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+            <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+            <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+        </ComponentType>
+
+        <!--#################### INPUT SOURCE END ####################-->
+    </ComponentLibrary>
+
+    <InstanceDefinition>
+        <Component Name="streams" Type="Streams"/>
+        <Component Name="input_sources" Type="InputSources"/>
+        <Component Name="product_strategies" Type="ProductStrategies"/>
+    </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
new file mode 100644
index 0000000..4cbb3da
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+  <ComponentType Name="ProductStrategies" Description="">
+      <Component Name="accessibility" Type="ProductStrategy"/>
+      <Component Name="enforced_audible" Type="ProductStrategy"/>
+      <Component Name="transmitted_through_speaker" Type="ProductStrategy"/>
+
+      <Component Name="media" Type="ProductStrategy"/>
+      <Component Name="phone" Type="ProductStrategy"/>
+      <Component Name="dtmf" Type="ProductStrategy"/>
+
+      <Component Name="sonification" Type="ProductStrategy"/>
+      <Component Name="sonification_respectful" Type="ProductStrategy"/>
+      <Component Name="rerouting" Type="ProductStrategy"/>
+      <Component Name="unknown" Type="ProductStrategy"/>
+  </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
deleted file mode 100644
index 28a3629..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
+++ /dev/null
@@ -1,301 +0,0 @@
-domainGroup: DeviceForStrategy
-
-	domainGroup: Rerouting
-		#
-		# Falls through media strategy
-		#
-		domain: UnreachableDevices
-			conf: Calibration
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					hdmi_arc = 0
-					spdif = 0
-					aux_line = 0
-					fm = 0
-					speaker_safe = 0
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					telephony_tx = 0
-					ip = 0
-					bus = 0
-					stub = 0
-
-		domain: Device2
-			conf: RemoteSubmix
-				AvailableOutputDevices Includes RemoteSubmix
-				AvailableOutputDevicesAddresses Includes 0
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 1
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dp
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dp
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 1
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpHeadphone
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 1
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: BluetoothA2dpSpeaker
-				ForceUseForMedia IsNot ForceNoBtA2dp
-				AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 1
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: ForceSpeaker
-				ForceUseForMedia Is ForceSpeaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadphone
-				AvailableOutputDevices Includes WiredHeadphone
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 1
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Line
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: WiredHeadset
-				AvailableOutputDevices Includes WiredHeadset
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 1
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbAccessory
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					hdmi = 0
-
-			conf: UsbDevice
-				AvailableOutputDevices Includes UsbDevice
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 1
-					hdmi = 0
-
-			conf: DgtlDockHeadset
-				AvailableOutputDevices Includes DgtlDockHeadset
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 1
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: AuxDigital
-				#
-				# Rerouting is similar to media and sonification (exept here: sonification is not allowed on HDMI)
-				#
-				AvailableOutputDevices Includes Hdmi
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 1
-
-			conf: AnlgDockHeadset
-				AvailableOutputDevices Includes AnlgDockHeadset
-				ForceUseForDock Is ForceAnalogDock
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 1
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Speaker
-				AvailableOutputDevices Includes Speaker
-
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 1
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
-			conf: Default
-				component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
deleted file mode 100644
index 3940b9d..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
+++ /dev/null
@@ -1,20 +0,0 @@
-domain: StrategyForStream
-
-	conf: Calibration
-		/Policy/policy/streams/voice_call/applicable_strategy/strategy = phone
-		#
-		# NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-		# while key clicks are played produces a poor result
-		#
-		/Policy/policy/streams/system/applicable_strategy/strategy = media
-		/Policy/policy/streams/ring/applicable_strategy/strategy = sonification
-		/Policy/policy/streams/music/applicable_strategy/strategy = media
-		/Policy/policy/streams/alarm/applicable_strategy/strategy = sonification
-		/Policy/policy/streams/notification/applicable_strategy/strategy = sonification_respectful
-		/Policy/policy/streams/bluetooth_sco/applicable_strategy/strategy = phone
-		/Policy/policy/streams/enforced_audible/applicable_strategy/strategy = enforced_audible
-		/Policy/policy/streams/dtmf/applicable_strategy/strategy = dtmf
-		/Policy/policy/streams/tts/applicable_strategy/strategy = transmitted_through_speaker
-		/Policy/policy/streams/accessibility/applicable_strategy/strategy = accessibility
-		/Policy/policy/streams/rerouting/applicable_strategy/strategy = rerouting
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
index daa7f68..56c5ed3 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
@@ -133,30 +133,6 @@
         </BitParameterBlock>
     </ComponentType>
 
-    <!-- Routing Strategy definition as an enumeration. Numerical value must match the value
-         of the routing strategy in policy header file. -->
-    <ComponentType Name="Strategy">
-        <EnumParameter Name="strategy" Size="32">
-            <ValuePair Literal="media" Numerical="0"/>
-            <ValuePair Literal="phone" Numerical="1"/>
-            <ValuePair Literal="sonification" Numerical="2"/>
-            <ValuePair Literal="sonification_respectful" Numerical="3"/>
-            <ValuePair Literal="dtmf" Numerical="4"/>
-            <ValuePair Literal="enforced_audible" Numerical="5"/>
-            <ValuePair Literal="transmitted_through_speaker" Numerical="6"/>
-            <ValuePair Literal="accessibility" Numerical="7"/>
-            <ValuePair Literal="rerouting" Numerical="8"/>
-        </EnumParameter>
-    </ComponentType>
-
-    <!--#################### STRATEGY COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="StrategyConfig" Mapping="Strategy">
-        <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
-    </ComponentType>
-
-    <!--#################### STRATEGY COMMON TYPES END ####################-->
-
     <!--#################### STREAM COMMON TYPES BEGIN ####################-->
 
     <ComponentType Name="VolumeProfileType">
@@ -178,21 +154,12 @@
     </ComponentType>
 
     <ComponentType Name="Stream"  Mapping="Stream">
-        <Component Name="applicable_strategy" Type="Strategy"/>
         <Component Name="applicable_volume_profile" Type="VolumeProfileType"
                    Description="Volume profile followed by a given stream type."/>
     </ComponentType>
 
     <!--#################### STREAM COMMON TYPES END ####################-->
 
-    <!--#################### USAGE COMMON TYPES BEGIN ####################-->
-
-    <ComponentType Name="Usage">
-        <Component Name="applicable_strategy" Type="Strategy" Mapping="Usage"/>
-    </ComponentType>
-
-    <!--#################### USAGE COMMON TYPES END ####################-->
-
     <!--#################### INPUT SOURCE COMMON TYPES BEGIN ####################-->
 
     <ComponentType Name="InputSource">
@@ -202,4 +169,14 @@
 
     <!--#################### INPUT SOURCE COMMON TYPES END ####################-->
 
+    <!--#################### PRODUCT STRATEGY COMMON TYPES BEGIN ####################-->
+
+    <ComponentType Name="ProductStrategy" Mapping="ProductStrategy">
+        <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
+        <StringParameter Name="device_address" MaxLength="256"
+                         Description="if any, device address associated"/>
+    </ComponentType>
+
+    <!--#################### PRODUCT STRATEGY COMMON TYPES END ####################-->
+
 </ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
index 45d1e8a..a4e7537 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
@@ -11,22 +11,6 @@
 
         <!--#################### GLOBAL COMPONENTS END ####################-->
 
-        <!--#################### STRATEGY BEGIN ####################-->
-
-        <ComponentType Name="Strategies">
-            <Component Name="media" Type="StrategyConfig" Mapping="Name:STRATEGY_MEDIA"/>
-            <Component Name="phone" Type="StrategyConfig" Mapping="Name:STRATEGY_PHONE"/>
-            <Component Name="sonification" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION"/>
-            <Component Name="sonification_respectful" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION_RESPECTFUL"/>
-            <Component Name="dtmf" Type="StrategyConfig" Mapping="Name:STRATEGY_DTMF"/>
-            <Component Name="enforced_audible" Type="StrategyConfig" Mapping="Name:STRATEGY_ENFORCED_AUDIBLE"/>
-            <Component Name="transmitted_through_speaker" Type="StrategyConfig" Mapping="Name:STRATEGY_TRANSMITTED_THROUGH_SPEAKER"/>
-            <Component Name="accessibility" Type="StrategyConfig" Mapping="Name:STRATEGY_ACCESSIBILITY"/>
-            <Component Name="rerouting" Type="StrategyConfig" Mapping=",Name:STRATEGY_REROUTING"/>
-        </ComponentType>
-
-        <!--#################### STRATEGY END ####################-->
-
         <!--#################### STREAM BEGIN ####################-->
 
         <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
@@ -52,40 +36,6 @@
 
         <!--#################### STREAM END ####################-->
 
-        <!--#################### USAGE BEGIN ####################-->
-
-        <ComponentType Name="Usages" Description="associated to audio_usage_t definition">
-            <Component Name="unknown" Type="Usage" Mapping="Name:AUDIO_USAGE_UNKNOWN"/>
-            <Component Name="media" Type="Usage" Mapping="Name:AUDIO_USAGE_MEDIA"/>
-            <Component Name="voice_communication" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION"/>
-            <Component Name="voice_communication_signalling" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
-            <Component Name="alarm" Type="Usage" Mapping="Name:AUDIO_USAGE_ALARM"/>
-            <Component Name="notification" Type="Usage" Mapping="Name:AUDIO_USAGE_NOTIFICATION"/>
-            <Component Name="notification_telephony_ringtone" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
-            <Component Name="notification_communication_request" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
-            <Component Name="notification_communication_instant" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
-            <Component Name="notification_communication_delayed" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
-            <Component Name="notification_event" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_NOTIFICATION_EVENT"/>
-            <Component Name="assistance_accessibility" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
-            <Component Name="assistance_navigation_guidance" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
-            <Component Name="assistance_sonification" Type="Usage"
-                       Mapping="Name:AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
-            <Component Name="game" Type="Usage" Mapping="Name:AUDIO_USAGE_GAME"/>
-            <Component Name="virtual_source" Type="Usage" Mapping="Name:AUDIO_USAGE_VIRTUAL_SOURCE"/>
-            <Component Name="assistant" Type="Usage" Mapping="Name:AUDIO_USAGE_ASSISTANT"/>
-        </ComponentType>
-
-        <!--#################### USAGE END ####################-->
-
         <!--#################### INPUT SOURCE BEGIN ####################-->
 
         <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
@@ -117,8 +67,6 @@
 
     <InstanceDefinition>
         <Component Name="streams" Type="Streams"/>
-        <Component Name="strategies" Type="Strategies"/>
         <Component Name="input_sources" Type="InputSources"/>
-        <Component Name="usages" Type="Usages"/>
     </InstanceDefinition>
 </Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
index db1f038..65dc9af 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
@@ -8,10 +8,9 @@
 LOCAL_SRC_FILES := \
     PolicySubsystemBuilder.cpp \
     PolicySubsystem.cpp \
-    Strategy.cpp \
     InputSource.cpp \
     Stream.cpp \
-    Usage.cpp
+    ProductStrategy.cpp
 
 LOCAL_CFLAGS += \
     -Wall \
@@ -21,9 +20,8 @@
     -fvisibility=hidden
 
 LOCAL_C_INCLUDES := \
-    frameworks/av/services/audiopolicy/common/include \
     frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
+    frameworks/av/services/audiopolicy/engineconfigurable/interface
 
 LOCAL_SHARED_LIBRARIES := \
     libaudiopolicyengineconfigurable  \
@@ -31,6 +29,11 @@
     libmedia_helper \
     liblog \
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudioclient_headers \
+    libbase_headers
+
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
 LOCAL_STATIC_LIBRARIES := libpfw_utility
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index 7374fc3..bfc1bca 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -17,10 +17,9 @@
 #include "PolicySubsystem.h"
 #include "SubsystemObjectFactory.h"
 #include "PolicyMappingKeys.h"
-#include "Strategy.h"
 #include "Stream.h"
 #include "InputSource.h"
-#include "Usage.h"
+#include "ProductStrategy.h"
 #include <AudioPolicyPluginInterface.h>
 #include <AudioPolicyEngineInstance.h>
 #include <utils/Log.h>
@@ -36,9 +35,8 @@
 
 
 const char *const PolicySubsystem::mStreamComponentName = "Stream";
-const char *const PolicySubsystem::mStrategyComponentName = "Strategy";
 const char *const PolicySubsystem::mInputSourceComponentName = "InputSource";
-const char *const PolicySubsystem::mUsageComponentName = "Usage";
+const char *const PolicySubsystem::mProductStrategyComponentName = "ProductStrategy";
 
 PolicySubsystem::PolicySubsystem(const std::string &name, core::log::Logger &logger)
     : CSubsystem(name, logger),
@@ -68,20 +66,14 @@
             (1 << MappingKeyName))
         );
     addSubsystemObjectFactory(
-        new TSubsystemObjectFactory<Strategy>(
-            mStrategyComponentName,
-            0)
-        );
-    addSubsystemObjectFactory(
-        new TSubsystemObjectFactory<Usage>(
-            mUsageComponentName,
-            (1 << MappingKeyName))
-        );
-    addSubsystemObjectFactory(
         new TSubsystemObjectFactory<InputSource>(
             mInputSourceComponentName,
             (1 << MappingKeyName))
         );
+    addSubsystemObjectFactory(
+        new TSubsystemObjectFactory<ProductStrategy>(
+            mProductStrategyComponentName, 0)
+        );
 }
 
 // Retrieve Route interface
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
index 822eeb9..9bf1c23 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
@@ -53,7 +53,6 @@
     static const char *const mKeyAmend3; /**< amend3 key mapping string. */
 
     static const char *const mStreamComponentName;
-    static const char *const mStrategyComponentName;
     static const char *const mInputSourceComponentName;
-    static const char *const mUsageComponentName;
+    static const char *const mProductStrategyComponentName;
 };
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
new file mode 100644
index 0000000..bb29ef1
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 "ProductStrategy.h"
+#include "PolicyMappingKeys.h"
+#include "PolicySubsystem.h"
+
+using std::string;
+using android::product_strategy_t;
+
+ProductStrategy::ProductStrategy(const string &mappingValue,
+                   CInstanceConfigurableElement *instanceConfigurableElement,
+                   const CMappingContext &context,
+                   core::log::Logger& logger)
+    : CFormattedSubsystemObject(instanceConfigurableElement,
+                                logger,
+                                mappingValue,
+                                MappingKeyAmend1,
+                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
+                                context)
+{
+    ALOG_ASSERT(instanceConfigurableElement != nullptr, "Invalid Configurable Element");
+    mPolicySubsystem = static_cast<const PolicySubsystem *>(
+                instanceConfigurableElement->getBelongingSubsystem());
+    ALOG_ASSERT(mPolicySubsystem != nullptr, "Invalid Policy Subsystem");
+
+    mPolicyPluginInterface = mPolicySubsystem->getPolicyPluginInterface();
+    ALOG_ASSERT(mPolicyPluginInterface != nullptr, "Invalid Policy Plugin Interface");
+
+    std::string name(instanceConfigurableElement->getName());
+    mId = mPolicyPluginInterface->getProductStrategyByName(name);
+
+    ALOG_ASSERT(mId != PRODUCT_STRATEGY_INVALID, "Product Strategy %s not found", name.c_str());
+
+    ALOGE("Product Strategy %s added", name.c_str());
+}
+
+bool ProductStrategy::sendToHW(string & /*error*/)
+{
+    Device deviceParams;
+    blackboardRead(&deviceParams, sizeof(deviceParams));
+
+    mPolicyPluginInterface->setDeviceTypesForProductStrategy(mId, deviceParams.applicableDevice);
+    mPolicyPluginInterface->setDeviceAddressForProductStrategy(mId, deviceParams.deviceAddress);
+    return true;
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
similarity index 68%
rename from services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
rename to services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
index c02b82c..244f082 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -20,14 +20,24 @@
 #include "InstanceConfigurableElement.h"
 #include "MappingContext.h"
 #include <AudioPolicyPluginInterface.h>
+#include <policy.h>
 #include <string>
 
 class PolicySubsystem;
 
-class Strategy : public CFormattedSubsystemObject
+class ProductStrategy : public CFormattedSubsystemObject
 {
+private:
+    static const uint32_t mMaxStringSize = 257; /**< max string size (plus zero terminal). */
+
+    struct Device
+    {
+        uint32_t applicableDevice; /**< applicable device for this strategy. */
+        char deviceAddress[mMaxStringSize]; /**< device address associated with this strategy. */
+    } __attribute__((packed));
+
 public:
-    Strategy(const std::string &mappingValue,
+    ProductStrategy(const std::string &mappingValue,
              CInstanceConfigurableElement *instanceConfigurableElement,
              const CMappingContext &context,
              core::log::Logger& logger);
@@ -38,10 +48,10 @@
 private:
     const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
 
+    android::product_strategy_t mId;
+
     /**
      * Interface to communicate with Audio Policy Engine.
      */
     android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
-    android::routing_strategy mId; /**< strategy identifier to link with audio.h.*/
 };
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
deleted file mode 100644
index 876bcb0..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 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 "Strategy.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-#include <RoutingStrategy.h>
-
-using std::string;
-using android::routing_strategy;
-
-namespace detail {
-
-constexpr std::pair<routing_strategy, const char*> routingStrategyMap[] = {
-    {android::STRATEGY_MEDIA, "STRATEGY_MEDIA"},
-    {android::STRATEGY_PHONE, "STRATEGY_PHONE"},
-    {android::STRATEGY_SONIFICATION, "STRATEGY_SONIFICATION"},
-    {android::STRATEGY_SONIFICATION_RESPECTFUL, "STRATEGY_SONIFICATION_RESPECTFUL"},
-    {android::STRATEGY_DTMF, "STRATEGY_DTMF"},
-    {android::STRATEGY_ENFORCED_AUDIBLE, "STRATEGY_ENFORCED_AUDIBLE"},
-    {android::STRATEGY_TRANSMITTED_THROUGH_SPEAKER, "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"},
-    {android::STRATEGY_ACCESSIBILITY, "STRATEGY_ACCESSIBILITY"},
-    {android::STRATEGY_REROUTING, "STRATEGY_REROUTING"},
-};
-
-bool fromString(const char *literalName, routing_strategy &type)
-{
-    for (auto& pair : routingStrategyMap) {
-        if (strcmp(pair.second, literalName) == 0) {
-            type = pair.first;
-            return true;
-        }
-    }
-    return false;
-}
-
-}
-
-Strategy::Strategy(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context,
-                   core::log::Logger& logger)
-    : CFormattedSubsystemObject(instanceConfigurableElement,
-                                logger,
-                                mappingValue,
-                                MappingKeyAmend1,
-                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
-                                context),
-      mPolicySubsystem(static_cast<const PolicySubsystem *>(
-                           instanceConfigurableElement->getBelongingSubsystem())),
-      mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
-    std::string name(context.getItem(MappingKeyName));
-    if (not detail::fromString(name.c_str(), mId)) {
-        LOG_ALWAYS_FATAL("Invalid Strategy %s, invalid XML structure file", name.c_str());
-    }
-    // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addStrategy(instanceConfigurableElement->getName(), mId);
-}
-
-bool Strategy::sendToHW(string & /*error*/)
-{
-    uint32_t applicableOutputDevice;
-    blackboardRead(&applicableOutputDevice, sizeof(applicableOutputDevice));
-    return mPolicyPluginInterface->setDeviceForStrategy(mId, applicableOutputDevice);
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
index 46c9e1c..5230e0e 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
@@ -20,7 +20,6 @@
 #include <media/TypeConverter.h>
 
 using std::string;
-using android::routing_strategy;
 
 Stream::Stream(const string &/*mappingValue*/,
                CInstanceConfigurableElement *instanceConfigurableElement,
@@ -45,11 +44,8 @@
     Applicable params;
     blackboardRead(&params, sizeof(params));
 
-    mPolicyPluginInterface->setStrategyForStream(mId,
-                                                 static_cast<routing_strategy>(params.strategy));
-
-    mPolicyPluginInterface->setVolumeProfileForStream(mId,
-                                                      static_cast<audio_stream_type_t>(params.volumeProfile));
+    mPolicyPluginInterface->setVolumeProfileForStream(
+                mId, static_cast<audio_stream_type_t>(params.volumeProfile));
 
     return true;
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
index 4a875db..e0ce2fa 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
@@ -29,7 +29,6 @@
 private:
     struct Applicable
     {
-        uint32_t strategy; /**< applicable strategy for this stream. */
         uint32_t volumeProfile; /**< applicable strategy for this stream. */
     } __attribute__((packed));
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
deleted file mode 100644
index 925d631..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2015 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 "Usage.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-#include <media/TypeConverter.h>
-
-using std::string;
-using android::routing_strategy;
-
-Usage::Usage(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context, core::log::Logger &logger)
-    : CFormattedSubsystemObject(instanceConfigurableElement,
-                                logger,
-                                mappingValue,
-                                MappingKeyAmend1,
-                                (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
-                                context),
-      mPolicySubsystem(static_cast<const PolicySubsystem *>(
-                           instanceConfigurableElement->getBelongingSubsystem())),
-      mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
-    std::string name(context.getItem(MappingKeyName));
-
-    if (not android::UsageTypeConverter::fromString(name, mId)) {
-        LOG_ALWAYS_FATAL("Invalid Usage name: %s, invalid XML structure file", name.c_str());
-    }
-    // Declares the strategy to audio policy engine
-    mPolicyPluginInterface->addUsage(name, mId);
-}
-
-bool Usage::sendToHW(string & /*error*/)
-{
-    uint32_t applicableStrategy;
-    blackboardRead(&applicableStrategy, sizeof(applicableStrategy));
-    return mPolicyPluginInterface->setStrategyForUsage(mId,
-                                              static_cast<routing_strategy>(applicableStrategy));
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
deleted file mode 100644
index 860204f..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-#include "FormattedSubsystemObject.h"
-#include "InstanceConfigurableElement.h"
-#include "MappingContext.h"
-#include <AudioPolicyPluginInterface.h>
-#include <string>
-
-class PolicySubsystem;
-
-class Usage : public CFormattedSubsystemObject
-{
-public:
-    Usage(const std::string &mappingValue,
-          CInstanceConfigurableElement *instanceConfigurableElement,
-          const CMappingContext &context,
-          core::log::Logger& logger);
-
-protected:
-    virtual bool sendToHW(std::string &error);
-
-private:
-    const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
-
-    /**
-     * Interface to communicate with Audio Policy Engine.
-     */
-    android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
-    audio_usage_t mId; /**< usage identifier to link with audio.h. */
-};
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
index 1f8ed8d..02b41cb 100644
--- a/services/audiopolicy/engineconfigurable/src/Collection.h
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -18,8 +18,6 @@
 
 #include "Element.h"
 #include "Stream.h"
-#include "Strategy.h"
-#include "Usage.h"
 #include "InputSource.h"
 #include <utils/Errors.h>
 #include <system/audio.h>
@@ -147,15 +145,9 @@
 template <>
 struct Collection<std::string>::collectionSupported {};
 template <>
-struct Collection<audio_usage_t>::collectionSupported {};
-template <>
 struct Collection<audio_source_t>::collectionSupported {};
-template <>
-struct Collection<routing_strategy>::collectionSupported {};
 
-typedef Collection<routing_strategy> StrategyCollection;
 typedef Collection<audio_stream_type_t> StreamCollection;
-typedef Collection<audio_usage_t> UsageCollection;
 typedef Collection<audio_source_t> InputSourceCollection;
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Element.h b/services/audiopolicy/engineconfigurable/src/Element.h
index 1b55c8c..97950d8 100644
--- a/services/audiopolicy/engineconfigurable/src/Element.h
+++ b/services/audiopolicy/engineconfigurable/src/Element.h
@@ -62,7 +62,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      *
      * @tparam Property for which this policy element has setter / getter.
@@ -73,7 +73,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      *
      * @tparam Property for which this policy element has setter / getter.
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 009cf90..f486dca 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -25,11 +25,12 @@
 #endif
 
 #include "Engine.h"
-#include "Strategy.h"
 #include "Stream.h"
 #include "InputSource.h"
-#include "Usage.h"
+
+#include <EngineConfig.h>
 #include <policy.h>
+#include <AudioIODescriptorInterface.h>
 #include <ParameterManagerWrapper.h>
 
 using std::string;
@@ -39,77 +40,48 @@
 namespace audio_policy {
 
 template <>
-StrategyCollection &Engine::getCollection<routing_strategy>()
-{
-    return mStrategyCollection;
-}
-template <>
 StreamCollection &Engine::getCollection<audio_stream_type_t>()
 {
     return mStreamCollection;
 }
 template <>
-UsageCollection &Engine::getCollection<audio_usage_t>()
-{
-    return mUsageCollection;
-}
-template <>
 InputSourceCollection &Engine::getCollection<audio_source_t>()
 {
     return mInputSourceCollection;
 }
 
 template <>
-const StrategyCollection &Engine::getCollection<routing_strategy>() const
-{
-    return mStrategyCollection;
-}
-template <>
 const StreamCollection &Engine::getCollection<audio_stream_type_t>() const
 {
     return mStreamCollection;
 }
 template <>
-const UsageCollection &Engine::getCollection<audio_usage_t>() const
-{
-    return mUsageCollection;
-}
-template <>
 const InputSourceCollection &Engine::getCollection<audio_source_t>() const
 {
     return mInputSourceCollection;
 }
 
-Engine::Engine()
-    : mManagerInterface(this),
-      mPluginInterface(this),
-      mPolicyParameterMgr(new ParameterManagerWrapper()),
-      mApmObserver(NULL)
+Engine::Engine() : mPolicyParameterMgr(new ParameterManagerWrapper())
 {
+    status_t loadResult = loadAudioPolicyEngineConfig();
+    if (loadResult < 0) {
+        ALOGE("Policy Engine configuration is invalid.");
+    }
 }
 
 Engine::~Engine()
 {
-    mStrategyCollection.clear();
     mStreamCollection.clear();
     mInputSourceCollection.clear();
-    mUsageCollection.clear();
-}
-
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
-    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
-    mApmObserver = observer;
 }
 
 status_t Engine::initCheck()
 {
-    if (mPolicyParameterMgr == NULL || mPolicyParameterMgr->start() != NO_ERROR) {
+    if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start() != NO_ERROR) {
         ALOGE("%s: could not start Policy PFW", __FUNCTION__);
         return NO_INIT;
     }
-    return (mApmObserver != NULL)? NO_ERROR : NO_INIT;
+    return EngineBase::initCheck();
 }
 
 template <typename Key>
@@ -137,55 +109,16 @@
     return element->template get<Property>();
 }
 
-routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t usage)
+bool Engine::setVolumeProfileForStream(const audio_stream_type_t &stream,
+                                       const audio_stream_type_t &profile)
 {
-    return mPolicyEngine->getPropertyForKey<routing_strategy, audio_usage_t>(usage);
-}
-
-audio_devices_t Engine::ManagerInterfaceImpl::getDeviceForStrategy(routing_strategy strategy) const
-{
-    const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs();
-
-    /** This is the only case handled programmatically because the PFW is unable to know the
-     * activity of streams.
-     *
-     * -While media is playing on a remote device, use the the sonification behavior.
-     * Note that we test this usecase before testing if media is playing because
-     * the isStreamActive() method only informs about the activity of a stream, not
-     * if it's for local playback. Note also that we use the same delay between both tests
-     *
-     * -When media is not playing anymore, fall back on the sonification behavior
-     */
-    if (strategy == STRATEGY_SONIFICATION_RESPECTFUL &&
-            !is_state_in_call(getPhoneState()) &&
-            !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
-                                    SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
-            outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
-        return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(STRATEGY_MEDIA);
-    }
-    if (strategy == STRATEGY_ACCESSIBILITY &&
-        (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
-            // do not route accessibility prompts to a digital output currently configured with a
-            // compressed format as they would likely not be mixed and dropped.
-            // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
-        return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(
-                    STRATEGY_SONIFICATION);
-    }
-    return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
-}
-
-bool Engine::PluginInterfaceImpl::setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                                            const audio_stream_type_t &profile)
-{
-    if (mPolicyEngine->setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream,
-                                                                                   profile)) {
-        mPolicyEngine->mApmObserver->getVolumeCurves().switchVolumeCurve(profile, stream);
+    if (setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream, profile)) {
+        getApmObserver()->getVolumeCurves().switchVolumeCurve(profile, stream);
         return true;
     }
     return false;
 }
 
-
 template <typename Property, typename Key>
 bool Engine::setPropertyForKey(const Property &property, const Key &key)
 {
@@ -199,7 +132,11 @@
 
 status_t Engine::setPhoneState(audio_mode_t mode)
 {
-    return mPolicyParameterMgr->setPhoneState(mode);
+    status_t status = mPolicyParameterMgr->setPhoneState(mode);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return EngineBase::setPhoneState(mode);
 }
 
 audio_mode_t Engine::getPhoneState() const
@@ -210,7 +147,11 @@
 status_t Engine::setForceUse(audio_policy_force_use_t usage,
                                       audio_policy_forced_cfg_t config)
 {
-    return mPolicyParameterMgr->setForceUse(usage, config);
+    status_t status = mPolicyParameterMgr->setForceUse(usage, config);
+    if (status != NO_ERROR) {
+        return status;
+    }
+    return EngineBase::setForceUse(usage, config);
 }
 
 audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) const
@@ -225,24 +166,210 @@
 
     if (audio_is_output_device(devDesc->type())) {
         return mPolicyParameterMgr->setAvailableOutputDevices(
-                    mApmObserver->getAvailableOutputDevices().types());
+                    getApmObserver()->getAvailableOutputDevices().types());
     } else if (audio_is_input_device(devDesc->type())) {
         return mPolicyParameterMgr->setAvailableInputDevices(
-                    mApmObserver->getAvailableInputDevices().types());
+                    getApmObserver()->getAvailableInputDevices().types());
     }
     return BAD_TYPE;
 }
 
+status_t Engine::loadAudioPolicyEngineConfig()
+{
+    auto result = EngineBase::loadAudioPolicyEngineConfig();
+
+    // Custom XML Parsing
+    auto loadCriteria= [this](const auto& configCriteria, const auto& configCriterionTypes) {
+        for (auto& criterion : configCriteria) {
+            engineConfig::CriterionType criterionType;
+            for (auto &configCriterionType : configCriterionTypes) {
+                if (configCriterionType.name == criterion.typeName) {
+                    criterionType = configCriterionType;
+                    break;
+                }
+            }
+            ALOG_ASSERT(not criterionType.name.empty(), "Invalid criterion type for %s",
+                        criterion.name.c_str());
+            mPolicyParameterMgr->addCriterion(criterion.name, criterionType.isInclusive,
+                                              criterionType.valuePairs,
+                                              criterion.defaultLiteralValue);
+        }
+    };
+
+    loadCriteria(result.parsedConfig->criteria, result.parsedConfig->criterionTypes);
+    return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const
+{
+    const auto productStrategies = getProductStrategies();
+    if (productStrategies.find(ps) == productStrategies.end()) {
+        ALOGE("%s: Trying to get device on invalid strategy %d", __FUNCTION__, ps);
+        return {};
+    }
+    const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    uint32_t availableOutputDevicesType = availableOutputDevices.types();
+
+    /** This is the only case handled programmatically because the PFW is unable to know the
+     * activity of streams.
+     *
+     * -While media is playing on a remote device, use the the sonification behavior.
+     * Note that we test this usecase before testing if media is playing because
+     * the isStreamActive() method only informs about the activity of a stream, not
+     * if it's for local playback. Note also that we use the same delay between both tests
+     *
+     * -When media is not playing anymore, fall back on the sonification behavior
+     */
+    audio_devices_t devices = AUDIO_DEVICE_NONE;
+    if (ps == getProductStrategyForStream(AUDIO_STREAM_NOTIFICATION) &&
+            !is_state_in_call(getPhoneState()) &&
+            !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
+                                            SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
+            outputs.isStreamActive(AUDIO_STREAM_MUSIC,
+                                   SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+        product_strategy_t strategyForMedia =
+                getProductStrategyForStream(AUDIO_STREAM_MUSIC);
+        devices = productStrategies.getDeviceTypesForProductStrategy(strategyForMedia);
+    } else if (ps == getProductStrategyForStream(AUDIO_STREAM_ACCESSIBILITY) &&
+        (outputs.isStreamActive(AUDIO_STREAM_RING) ||
+         outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
+            // do not route accessibility prompts to a digital output currently configured with a
+            // compressed format as they would likely not be mixed and dropped.
+            // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
+        product_strategy_t strategyNotification = getProductStrategyForStream(AUDIO_STREAM_RING);
+        devices = productStrategies.getDeviceTypesForProductStrategy(strategyNotification);
+    } else {
+        devices = productStrategies.getDeviceTypesForProductStrategy(ps);
+    }
+    if (devices == AUDIO_DEVICE_NONE ||
+            (devices & availableOutputDevicesType) == AUDIO_DEVICE_NONE) {
+        devices = getApmObserver()->getDefaultOutputDevice()->type();
+        ALOGE_IF(devices == AUDIO_DEVICE_NONE, "%s: no valid default device defined", __FUNCTION__);
+        return DeviceVector(getApmObserver()->getDefaultOutputDevice());
+    }
+    if (/*device_distinguishes_on_address(devices)*/ devices == AUDIO_DEVICE_OUT_BUS) {
+        // We do expect only one device for these types of devices
+        // Criterion device address garantee this one is available
+        // If this criterion is not wished, need to ensure this device is available
+        const String8 address(productStrategies.getDeviceAddressForProductStrategy(ps).c_str());
+        ALOGV("%s:device 0x%x %s %d", __FUNCTION__, devices, address.c_str(), ps);
+        return DeviceVector(availableOutputDevices.getDevice(devices,
+                                                             address,
+                                                             AUDIO_FORMAT_DEFAULT));
+    }
+    ALOGV("%s:device 0x%x %d", __FUNCTION__, devices, ps);
+    return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+                                                   const sp<DeviceDescriptor> &preferredDevice,
+                                                   bool fromCache) const
+{
+    // First check for explict routing device
+    if (preferredDevice != nullptr) {
+        ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+        return DeviceVector(preferredDevice);
+    }
+    product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+    const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    //
+    // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+    // be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
+    return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+    auto attributes = EngineBase::getAttributesForStreamType(stream);
+    return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+                                                         AudioMix **mix) const
+{
+    const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+    const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &inputs = getApmObserver()->getInputs();
+    std::string address;
+    //
+    // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+    // first as it used to be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device =
+            findPreferredDevice(inputs, attr.source, availableInputDevices);
+    if (device != nullptr) {
+        return device;
+    }
+
+    device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+    if (device != nullptr) {
+        return device;
+    }
+
+    audio_devices_t deviceType = getPropertyForKey<audio_devices_t, audio_source_t>(attr.source);
+
+    if (audio_is_remote_submix_device(deviceType)) {
+        address = "0";
+        std::size_t pos;
+        std::string tags { attr.tags };
+        if ((pos = tags.find("addr=")) != std::string::npos) {
+            address = tags.substr(pos + std::strlen("addr="));
+        }
+    }
+    return availableInputDevices.getDevice(deviceType, String8(address.c_str()), AUDIO_FORMAT_DEFAULT);
+}
+
+void Engine::updateDeviceSelectionCache()
+{
+    for (const auto &iter : getProductStrategies()) {
+        const auto &strategy = iter.second;
+        mDevicesForStrategies[strategy->getId()] = getDevicesForProductStrategy(strategy->getId());
+    }
+}
+
+void Engine::setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                const std::string &address)
+{
+    if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+        ALOGE("%s: Trying to set address %s on invalid strategy %d", __FUNCTION__, address.c_str(),
+              strategy);
+        return;
+    }
+    getProductStrategies().at(strategy)->setDeviceAddress(address);
+}
+
+bool Engine::setDeviceTypesForProductStrategy(product_strategy_t strategy, audio_devices_t devices)
+{
+    if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+        ALOGE("%s: set device %d on invalid strategy %d", __FUNCTION__, devices, strategy);
+        return false;
+    }
+    getProductStrategies().at(strategy)->setDeviceTypes(devices);
+    return true;
+}
+
 template <>
 AudioPolicyManagerInterface *Engine::queryInterface()
 {
-    return &mManagerInterface;
+    return this;
 }
 
 template <>
 AudioPolicyPluginInterface *Engine::queryInterface()
 {
-    return &mPluginInterface;
+    return this;
 }
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index ba4f889..5553994 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-
+#include "EngineBase.h"
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "Collection.h"
@@ -29,7 +29,7 @@
 class ParameterManagerWrapper;
 class VolumeProfile;
 
-class Engine
+class Engine : public EngineBase, AudioPolicyPluginInterface
 {
 public:
     Engine();
@@ -38,132 +38,69 @@
     template <class RequestedInterface>
     RequestedInterface *queryInterface();
 
-private:
-    /// Interface members
-    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
+    ///
+    /// from EngineBase
+    ///
+    android::status_t initCheck() override;
+
+    status_t setPhoneState(audio_mode_t mode) override;
+
+    audio_mode_t getPhoneState() const override;
+
+    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override;
+
+    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override;
+
+    android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                               audio_policy_dev_state_t state) override;
+
+    DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+                                               const sp<DeviceDescriptor> &preferedDevice = nullptr,
+                                               bool fromCache = false) const override;
+
+    DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                           bool fromCache = false) const override;
+
+    sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
+
+    void updateDeviceSelectionCache() override;
+
+    ///
+    /// from AudioPolicyPluginInterface
+    ///
+    status_t addStream(const std::string &name, audio_stream_type_t stream) override
     {
-    public:
-        ManagerInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
-
-        virtual android::status_t initCheck()
-        {
-            return mPolicyEngine->initCheck();
-        }
-        virtual void setObserver(AudioPolicyManagerObserver *observer)
-        {
-            mPolicyEngine->setObserver(observer);
-        }
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
-        {
-            return mPolicyEngine->getPropertyForKey<audio_devices_t, audio_source_t>(inputSource);
-        }
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const;
-        virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
-        {
-            return mPolicyEngine->getPropertyForKey<routing_strategy, audio_stream_type_t>(stream);
-        }
-        virtual routing_strategy getStrategyForUsage(audio_usage_t usage);
-        virtual status_t setPhoneState(audio_mode_t mode)
-        {
-            return mPolicyEngine->setPhoneState(mode);
-        }
-        virtual audio_mode_t getPhoneState() const
-        {
-            return mPolicyEngine->getPhoneState();
-        }
-        virtual status_t setForceUse(audio_policy_force_use_t usage,
-                                              audio_policy_forced_cfg_t config)
-        {
-            return mPolicyEngine->setForceUse(usage, config);
-        }
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-        {
-            return mPolicyEngine->getForceUse(usage);
-        }
-        virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                                           audio_policy_dev_state_t state)
-        {
-            return mPolicyEngine->setDeviceConnectionState(devDesc, state);
-        }
-
-    private:
-        Engine *mPolicyEngine;
-    } mManagerInterface;
-
-    class PluginInterfaceImpl : public AudioPolicyPluginInterface
+        return add<audio_stream_type_t>(name, stream);
+    }
+    status_t addInputSource(const std::string &name, audio_source_t source) override
     {
-    public:
-        PluginInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
+        return add<audio_source_t>(name, source);
+    }
+    bool setVolumeProfileForStream(const audio_stream_type_t &stream,
+                                   const audio_stream_type_t &volumeProfile) override;
 
-        virtual status_t addStrategy(const std::string &name, routing_strategy strategy)
-        {
-            return mPolicyEngine->add<routing_strategy>(name, strategy);
-        }
-        virtual status_t addStream(const std::string &name, audio_stream_type_t stream)
-        {
-            return mPolicyEngine->add<audio_stream_type_t>(name, stream);
-        }
-        virtual status_t addUsage(const std::string &name, audio_usage_t usage)
-        {
-            return mPolicyEngine->add<audio_usage_t>(name, usage);
-        }
-        virtual status_t addInputSource(const std::string &name, audio_source_t source)
-        {
-            return mPolicyEngine->add<audio_source_t>(name, source);
-        }
-        virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices)
-        {
-            return mPolicyEngine->setPropertyForKey<audio_devices_t, routing_strategy>(devices,
-                                                                                       strategy);
-        }
-        virtual bool setStrategyForStream(const audio_stream_type_t &stream,
-                                          routing_strategy strategy)
-        {
-            return mPolicyEngine->setPropertyForKey<routing_strategy, audio_stream_type_t>(strategy,
-                                                                                           stream);
-        }
-        virtual bool setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                               const audio_stream_type_t &volumeProfile);
+    bool setDeviceForInputSource(const audio_source_t &inputSource, audio_devices_t device) override
+    {
+        return setPropertyForKey<audio_devices_t, audio_source_t>(device, inputSource);
+    }
+    void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+                                                    const std::string &address) override;
 
-        virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy)
-        {
-            return mPolicyEngine->setPropertyForKey<routing_strategy, audio_usage_t>(strategy,
-                                                                                     usage);
-        }
-        virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
-                                             audio_devices_t device)
-        {
-            return mPolicyEngine->setPropertyForKey<audio_devices_t, audio_source_t>(device,
-                                                                                     inputSource);
-        }
+    bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+                                                  audio_devices_t devices) override;
 
-    private:
-        Engine *mPolicyEngine;
-    } mPluginInterface;
+    product_strategy_t getProductStrategyByName(const std::string &name) override
+    {
+        return EngineBase::getProductStrategyByName(name);
+    }
 
 private:
     /* Copy facilities are put private to disable copy. */
     Engine(const Engine &object);
     Engine &operator=(const Engine &object);
 
-    void setObserver(AudioPolicyManagerObserver *observer);
-
-    bool setVolumeProfileForStream(const audio_stream_type_t &stream,
-                                   device_category deviceCategory,
-                                   const VolumeCurvePoints &points);
-
-    status_t initCheck();
-    status_t setPhoneState(audio_mode_t mode);
-    audio_mode_t getPhoneState() const;
-    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
-    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
-    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                      audio_policy_dev_state_t state);
-    StrategyCollection mStrategyCollection; /**< Strategies indexed by their enum id. */
     StreamCollection mStreamCollection; /**< Streams indexed by their enum id.  */
-    UsageCollection mUsageCollection; /**< Usages indexed by their enum id. */
     InputSourceCollection mInputSourceCollection; /**< Input sources indexed by their enum id. */
 
     template <typename Key>
@@ -184,12 +121,16 @@
     template <typename Property, typename Key>
     bool setPropertyForKey(const Property &property, const Key &key);
 
+    status_t loadAudioPolicyEngineConfig();
+
+    DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
     /**
      * Policy Parameter Manager hidden through a wrapper.
      */
     ParameterManagerWrapper *mPolicyParameterMgr;
 
-    AudioPolicyManagerObserver *mApmObserver;
+    DeviceStrategyMap mDevicesForStrategies;
 };
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.h b/services/audiopolicy/engineconfigurable/src/InputSource.h
index 64b390e..e1865cc 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.h
@@ -59,7 +59,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      */
     template <typename Property>
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
deleted file mode 100644
index 310b35e..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Strategy"
-
-#include "Strategy.h"
-
-using std::string;
-
-namespace android {
-namespace audio_policy {
-
-status_t Element<routing_strategy>::setIdentifier(routing_strategy identifier)
-{
-    if (identifier >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    mIdentifier = identifier;
-    ALOGD("%s: Strategy %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
-    return NO_ERROR;
-}
-
-/**
- * Set the device associated to this strategy.
- * It checks if the output device is valid.
- *
- * @param[in] devices selected for the given strategy.
- *
- * @return NO_ERROR if the device is either valid or none, error code otherwise.
- */
-template <>
-status_t Element<routing_strategy>::set<audio_devices_t>(audio_devices_t devices)
-{
-    if (!audio_is_output_devices(devices) || devices == AUDIO_DEVICE_NONE) {
-        ALOGE("%s: trying to set an invalid device 0x%X for strategy %s",
-              __FUNCTION__, devices, getName().c_str());
-        return BAD_VALUE;
-    }
-    ALOGD("%s: 0x%X for strategy %s", __FUNCTION__, devices, getName().c_str());
-    mApplicableDevices = devices;
-    return NO_ERROR;
-}
-
-template <>
-audio_devices_t Element<routing_strategy>::get<audio_devices_t>() const
-{
-    ALOGV("%s: 0x%X for strategy %s", __FUNCTION__, mApplicableDevices, getName().c_str());
-    return mApplicableDevices;
-}
-
-} // namespace audio_policy
-} // namespace android
-
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.h b/services/audiopolicy/engineconfigurable/src/Strategy.h
deleted file mode 100644
index f2487fd..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android {
-namespace audio_policy {
-
-/**
- * @tparam audio_devices_t: Applicable output device(s) for this strategy.
- */
-template <>
-class Element<routing_strategy>
-{
-public:
-    Element(const std::string &name)
-        : mName(name),
-          mApplicableDevices(AUDIO_DEVICE_NONE)
-    {}
-    ~Element() {}
-
-    /**
-     * Returns identifier of this policy element
-     *
-     * @returns string representing the name of this policy element
-     */
-    const std::string &getName() const { return mName; }
-
-    /**
-    * Set the unique identifier for this policy element.
-    *
-    * @tparam Key type of the unique identifier.
-    * @param[in] identifier to be set.
-    *
-    * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
-    */
-    status_t setIdentifier(routing_strategy identifier);
-
-    /**
-     * @return the unique identifier of this policy element.
-     */
-    routing_strategy getIdentifier() const { return mIdentifier; }
-
-    /**
-     * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
-     * or a string.
-     */
-    template <typename Property>
-    Property get() const;
-
-    template <typename Property>
-    status_t set(Property property);
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    Element(const Element &object);
-    Element &operator=(const Element &object);
-
-    std::string mName; /**< Unique literal Identifier of a policy base element*/
-    routing_strategy mIdentifier; /**< Unique numerical Identifier of a policy base element*/
-
-    audio_devices_t mApplicableDevices; /**< Applicable output device(s) for this strategy. */
-};
-
-typedef Element<routing_strategy> Strategy;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
index 73fb94d..297eb02 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -34,32 +34,6 @@
     return NO_ERROR;
 }
 
-/**
-* Set the strategy to follow for this stream.
-* It checks if the strategy is valid.
-*
-* @param[in] strategy to be followed.
-*
-* @return NO_ERROR if the strategy is set correctly, error code otherwise.
-*/
-template <>
-status_t Element<audio_stream_type_t>::set<routing_strategy>(routing_strategy strategy)
-{
-    if (strategy >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    mApplicableStrategy = strategy;
-    ALOGD("%s: 0x%X for Stream %s", __FUNCTION__, strategy, getName().c_str());
-    return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_stream_type_t>::get<routing_strategy>() const
-{
-    ALOGV("%s: 0x%X for Stream %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
-    return mApplicableStrategy;
-}
-
 template <>
 status_t Element<audio_stream_type_t>::set<audio_stream_type_t>(audio_stream_type_t volumeProfile)
 {
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
index 2bf70b3..a4fdd39 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.h
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -18,22 +18,20 @@
 
 #include "Element.h"
 #include "EngineDefinition.h"
-#include <RoutingStrategy.h>
 #include <map>
 
 namespace android {
 namespace audio_policy {
 
 /**
- * @tparam routing_strategy: Applicable strategy for this stream.
+ * @tparam product_strategy_t: Applicable strategy for this stream.
  */
 template <>
 class Element<audio_stream_type_t>
 {
 public:
     Element(const std::string &name)
-        : mName(name),
-          mApplicableStrategy(STRATEGY_MEDIA)
+        : mName(name)
     {}
     ~Element() {}
 
@@ -61,7 +59,7 @@
 
     /**
      * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+     * Property may be  audio_stream_type_t, audio_usage_t, audio_source_t
      * or a string.
      */
     template <typename Property>
@@ -78,8 +76,6 @@
     std::string mName; /**< Unique literal Identifier of a policy base element*/
     audio_stream_type_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
 
-    routing_strategy mApplicableStrategy; /**< Applicable strategy for this stream. */
-
     audio_stream_type_t mVolumeProfile; /**< Volume Profile followed by this stream. */
 };
 
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.cpp b/services/audiopolicy/engineconfigurable/src/Usage.cpp
deleted file mode 100644
index 8c0dfba..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Usage"
-
-#include "Usage.h"
-
-namespace android {
-namespace audio_policy {
-
-status_t Element<audio_usage_t>::setIdentifier(audio_usage_t identifier)
-{
-    if (identifier > AUDIO_USAGE_MAX) {
-        return BAD_VALUE;
-    }
-    mIdentifier = identifier;
-    ALOGD("%s: Usage %s has identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
-    return NO_ERROR;
-}
-
-template <>
-status_t Element<audio_usage_t>::set<routing_strategy>(routing_strategy strategy)
-{
-    if (strategy >= NUM_STRATEGIES) {
-        return BAD_VALUE;
-    }
-    ALOGD("%s: %d for Usage %s", __FUNCTION__, strategy, getName().c_str());
-    mApplicableStrategy = strategy;
-    return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_usage_t>::get<routing_strategy>() const
-{
-    ALOGD("%s: %d for Usage %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
-    return mApplicableStrategy;
-}
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.h b/services/audiopolicy/engineconfigurable/src/Usage.h
deleted file mode 100644
index 72a452f..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android {
-namespace audio_policy {
-
-/**
- * @tparam routing_strategy: Applicable strategy for this usage.
- */
-template <>
-class Element<audio_usage_t>
-{
-public:
-    Element(const std::string &name)
-        : mName(name),
-          mApplicableStrategy(STRATEGY_MEDIA)
-    {}
-    ~Element() {}
-
-    /**
-     * Returns identifier of this policy element
-     *
-     * @returns string representing the name of this policy element
-     */
-    const std::string &getName() const { return mName; }
-
-    /**
-    * Set the unique identifier for this policy element.
-    *
-    * @tparam Key type of the unique identifier.
-    * @param[in] identifier to be set.
-    *
-    * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
-    */
-    status_t setIdentifier(audio_usage_t identifier);
-
-    /**
-     * @return the unique identifier of this policy element.
-     */
-    audio_usage_t getIdentifier() const { return mIdentifier; }
-
-    /**
-     * A Policy element may implement getter/setter function for a given property.
-     * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
-     * or a string.
-     */
-    template <typename Property>
-    Property get() const;
-
-    template <typename Property>
-    status_t set(Property property);
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    Element(const Element &object);
-    Element &operator=(const Element &object);
-
-    std::string mName; /**< Unique literal Identifier of a policy base element*/
-    audio_usage_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
-    routing_strategy mApplicableStrategy; /**< Applicable strategy for this usage. */
-};
-
-typedef Element<audio_usage_t> Usage;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
index 4814376..eebdfd6 100644
--- a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
+++ b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
@@ -8,7 +8,6 @@
 $(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_CONFIGURATION_FILE := $(AUDIO_POLICY_CONFIGURATION_FILE)
 $(LOCAL_BUILT_MODULE): MY_CRITERION_TOOL := $(HOST_OUT)/bin/buildPolicyCriterionTypes.py
 $(LOCAL_BUILT_MODULE): $(LOCAL_REQUIRED_MODULES) $(LOCAL_ADDITIONAL_DEPENDENCIES) \
-    buildPolicyCriterionTypes.py \
     $(CRITERION_TYPES_FILE) \
     $(ANDROID_AUDIO_BASE_HEADER_FILE)
 
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
index d19a364..c7d8d34 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
@@ -1,8 +1,5 @@
 LOCAL_PATH:= $(call my-dir)
 
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
-
 ##################################################################
 # WRAPPER LIBRARY
 ##################################################################
@@ -13,20 +10,20 @@
     $(LOCAL_PATH)/include \
     frameworks/av/services/audiopolicy/engineconfigurable/include \
     frameworks/av/services/audiopolicy/engineconfigurable/interface \
-    frameworks/av/services/audiopolicy/common/include \
     external/libxml2/include \
     external/icu/icu4c/source/common
 
 LOCAL_SRC_FILES:= \
-    ParameterManagerWrapper.cpp \
-    ParameterManagerWrapperConfig.cpp
+    ParameterManagerWrapper.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libparameter \
     libmedia_helper \
-    libicuuc \
     libxml2
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon
+
 LOCAL_STATIC_LIBRARIES := \
     libaudiopolicycomponents
 
@@ -40,39 +37,3 @@
 
 include $(BUILD_STATIC_LIBRARY)
 
-##################################################################
-# CONFIGURATION FILE
-##################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_wrapper_configuration.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_criteria.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_criterion_types.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_ADDITIONAL_DEPENDENCIES := \
-    $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
-
-AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
-ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
-CRITERION_TYPES_FILE := $(LOCAL_PATH)/config/policy_criterion_types.xml.in
-
-include $(PROVISION_CRITERION_TYPES)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 09faa4c..4b57444 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,6 @@
 //#define LOG_NDEBUG 0
 
 #include "ParameterManagerWrapper.h"
-#include "ParameterManagerWrapperConfig.h"
 #include <ParameterMgrPlatformConnector.h>
 #include <SelectionCriterionTypeInterface.h>
 #include <SelectionCriterionInterface.h>
@@ -38,7 +37,6 @@
 using std::string;
 using std::map;
 using std::vector;
-using CriterionTypes = std::map<std::string, ISelectionCriterionTypeInterface *>;
 
 /// PFW related definitions
 // Logger
@@ -106,63 +104,35 @@
 
     // Logger
     mPfwConnector->setLogger(mPfwConnectorLogger);
-
-    status_t loadResult = loadConfig();
-    if (loadResult < 0) {
-        ALOGE("Policy Wrapper configuration is partially invalid.");
-    }
 }
 
-status_t ParameterManagerWrapper::loadConfig()
+status_t ParameterManagerWrapper::addCriterion(const std::string &name, bool isInclusive,
+                                               ValuePairs pairs, const std::string &defaultValue)
 {
-    auto result = wrapper_config::parse();
-    if (result.parsedConfig == nullptr) {
-        return -ENOENT;
+    ALOG_ASSERT(not isStarted(), "Cannot add a criterion if PFW is already started");
+    auto criterionType = mPfwConnector->createSelectionCriterionType(isInclusive);
+
+    for (auto pair : pairs) {
+        std::string error;
+        ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
+              pair.second.c_str(), name.c_str());
+        criterionType->addValuePair(pair.first, pair.second, error);
     }
-    ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+    ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
+                "%s: Criterion %s already added", __FUNCTION__, name.c_str());
 
-    CriterionTypes criterionTypes;
-    for (auto criterionType : result.parsedConfig->criterionTypes) {
-        ALOG_ASSERT(criterionTypes.find(criterionType.name) == criterionTypes.end(),
-                          "CriterionType %s already added", criterionType.name.c_str());
-        ALOGV("%s: Adding new criterionType %s", __FUNCTION__, criterionType.name.c_str());
+    auto criterion = mPfwConnector->createSelectionCriterion(name, criterionType);
+    mPolicyCriteria[name] = criterion;
 
-        auto criterionTypePfw =
-                mPfwConnector->createSelectionCriterionType(criterionType.isInclusive);
-
-        for (auto pair : criterionType.valuePairs) {
-            std::string error;
-            ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
-                  pair.second.c_str(), criterionType.name.c_str());
-            criterionTypePfw->addValuePair(pair.first, pair.second, error);
+    if (not defaultValue.empty()) {
+        int numericalValue = 0;
+        if (not criterionType->getNumericalValue(defaultValue.c_str(), numericalValue)) {
+            ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
+                  defaultValue.c_str());
         }
-        criterionTypes[criterionType.name] = criterionTypePfw;
+        criterion->setCriterionState(numericalValue);
     }
-
-    for (auto criterion : result.parsedConfig->criteria) {
-        ALOG_ASSERT(mPolicyCriteria.find(criterion.name) == mPolicyCriteria.end(),
-                    "%s: Criterion %s already added", __FUNCTION__, criterion.name.c_str());
-
-        auto criterionType =
-                getElement<ISelectionCriterionTypeInterface>(criterion.typeName, criterionTypes);
-        ALOG_ASSERT(criterionType != nullptr, "No %s Criterion type found for criterion %s",
-                    criterion.typeName.c_str(), criterion.name.c_str());
-
-        auto criterionPfw = mPfwConnector->createSelectionCriterion(criterion.name, criterionType);
-        mPolicyCriteria[criterion.name] = criterionPfw;
-
-        if (not criterion.defaultLiteralValue.empty()) {
-            int numericalValue = 0;
-            if (not criterionType->getNumericalValue(criterion.defaultLiteralValue.c_str(),
-                                                     numericalValue)) {
-                ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
-                      criterion.defaultLiteralValue.c_str());
-                continue;
-            }
-            criterionPfw->setCriterionState(numericalValue);
-        }
-    }
-    return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+    return NO_ERROR;
 }
 
 ParameterManagerWrapper::~ParameterManagerWrapper()
@@ -289,7 +259,7 @@
     std::string criterionName = audio_is_output_device(devDesc->type()) ?
                 gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
 
-    ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->mAddress.string(),
+    ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().string(),
           state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
     ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
deleted file mode 100644
index bc6d046..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/PFWWrapperConfig"
-#define LOG_NDEBUG 0
-
-#include "ParameterManagerWrapperConfig.h"
-
-#include <media/convert.h>
-#include <utils/Log.h>
-#include <libxml/parser.h>
-#include <libxml/xinclude.h>
-#include <string>
-#include <vector>
-#include <sstream>
-#include <istream>
-
-
-namespace android {
-
-using utilities::convertTo;
-
-namespace audio_policy {
-namespace wrapper_config {
-namespace detail {
-
-std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
-{
-    xmlChar *xmlValue = xmlGetProp(cur, (const xmlChar *)attribute);
-    if (xmlValue == NULL) {
-        return "";
-    }
-    std::string value((const char *)xmlValue);
-    xmlFree(xmlValue);
-    return value;
-}
-
-template <class Trait>
-static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
-                                      typename Trait::Collection &collection,
-                                      size_t &nbSkippedElement)
-{
-    const xmlNode *root = cur->xmlChildrenNode;
-    while (root != NULL) {
-        if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) &&
-            xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
-            root = root->next;
-            continue;
-        }
-        const xmlNode *child = root;
-        if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
-            child = child->xmlChildrenNode;
-        }
-        while (child != NULL) {
-            if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
-                status_t status = Trait::deserialize(doc, child, collection);
-                if (status == NO_ERROR) {
-                    nbSkippedElement += 1;
-                }
-            }
-            child = child->next;
-        }
-        if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
-            return NO_ERROR;
-        }
-        root = root->next;
-    }
-    return NO_ERROR;
-}
-
-const char *const ValueTraits::tag = "value";
-const char *const ValueTraits::collectionTag = "values";
-
-const char ValueTraits::Attributes::literal[] = "literal";
-const char ValueTraits::Attributes::numerical[] = "numerical";
-
-status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
-{
-    std::string literal = getXmlAttribute(child, Attributes::literal);
-    if (literal.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
-        return BAD_VALUE;
-    }
-    uint32_t numerical = 0;
-    std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
-    if (numericalTag.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
-        return BAD_VALUE;
-    }
-    if (!convertTo(numericalTag, numerical)) {
-        ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
-        return BAD_VALUE;
-    }
-    values.push_back({numerical, literal});
-    return NO_ERROR;
-}
-
-const char *const CriterionTypeTraits::tag = "criterion_type";
-const char *const CriterionTypeTraits::collectionTag = "criterion_types";
-
-const char CriterionTypeTraits::Attributes::name[] = "name";
-const char CriterionTypeTraits::Attributes::type[] = "type";
-
-status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
-                                          Collection &criterionTypes)
-{
-    std::string name = getXmlAttribute(child, Attributes::name);
-    if (name.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
-        return BAD_VALUE;
-    }
-    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
-
-    std::string type = getXmlAttribute(child, Attributes::type);
-    if (type.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
-        return BAD_VALUE;
-    }
-    ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
-    bool isInclusive(type == "inclusive");
-
-    ValuePairs pairs;
-    size_t nbSkippedElements = 0;
-    detail::deserializeCollection<detail::ValueTraits>(doc, child, pairs, nbSkippedElements);
-
-    criterionTypes.push_back({name, isInclusive, pairs});
-    return NO_ERROR;
-}
-
-const char *const CriterionTraits::tag = "criterion";
-const char *const CriterionTraits::collectionTag = "criteria";
-
-const char CriterionTraits::Attributes::name[] = "name";
-const char CriterionTraits::Attributes::type[] = "type";
-const char CriterionTraits::Attributes::defaultVal[] = "default";
-
-status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &criteria)
-{
-    std::string name = getXmlAttribute(child, Attributes::name);
-    if (name.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
-        return BAD_VALUE;
-    }
-    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
-
-    std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
-    if (defaultValue.empty()) {
-        // Not mandatory to provide a default value for a criterion, even it is recommanded...
-        ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::defaultVal);
-    }
-    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
-
-    std::string typeName = getXmlAttribute(child, Attributes::type);
-    if (typeName.empty()) {
-        ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
-        return BAD_VALUE;
-    }
-    ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
-
-    criteria.push_back({name, typeName, defaultValue});
-    return NO_ERROR;
-}
-} // namespace detail
-
-ParsingResult parse(const char* path) {
-    xmlDocPtr doc;
-    doc = xmlParseFile(path);
-    if (doc == NULL) {
-        ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
-        return {nullptr, 0};
-    }
-    xmlNodePtr cur = xmlDocGetRootElement(doc);
-    if (cur == NULL) {
-        ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
-        xmlFreeDoc(doc);
-        return {nullptr, 0};
-    }
-    if (xmlXIncludeProcess(doc) < 0) {
-        ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
-        return {nullptr, 0};
-    }
-    size_t nbSkippedElements = 0;
-    auto config = std::make_unique<Config>();
-
-    detail::deserializeCollection<detail::CriterionTraits>(
-                doc, cur, config->criteria, nbSkippedElements);
-    detail::deserializeCollection<detail::CriterionTypeTraits>(
-                doc, cur, config->criterionTypes, nbSkippedElements);
-
-    return {std::move(config), nbSkippedElements};
-}
-
-} // namespace wrapper_config
-} // namespace audio_policy
-} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
deleted file mode 100644
index 467d0e1..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <string>
-#include <vector>
-#include <utils/Errors.h>
-
-struct _xmlNode;
-struct _xmlDoc;
-
-namespace android {
-namespace audio_policy {
-namespace wrapper_config {
-
-/** Default path of audio policy usages configuration file. */
-constexpr char DEFAULT_PATH[] = "/vendor/etc/policy_wrapper_configuration.xml";
-
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
-using ValuePair = std::pair<uint32_t, std::string>;
-using ValuePairs = std::vector<ValuePair>;
-
-struct CriterionType
-{
-    std::string name;
-    bool isInclusive;
-    ValuePairs valuePairs;
-};
-
-using CriterionTypes = std::vector<CriterionType>;
-
-struct Criterion
-{
-    std::string name;
-    std::string typeName;
-    std::string defaultLiteralValue;
-};
-
-using Criteria = std::vector<Criterion>;
-
-struct Config {
-    float version;
-    Criteria criteria;
-    CriterionTypes criterionTypes;
-};
-
-namespace detail
-{
-struct ValueTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char literal[];
-        static const char numerical[];
-    };
-
-    typedef ValuePair Element;
-    typedef ValuePair *PtrElement;
-    typedef ValuePairs Collection;
-
-    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
-                                         Collection &collection);
-};
-
-struct CriterionTypeTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char name[];
-        static const char type[];
-    };
-
-    typedef CriterionType Element;
-    typedef CriterionType *PtrElement;
-    typedef CriterionTypes Collection;
-
-    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
-                                         Collection &collection);
-};
-
-struct CriterionTraits
-{
-    static const char *const tag;
-    static const char *const collectionTag;
-
-    struct Attributes
-    {
-        static const char name[];
-        static const char type[];
-        static const char defaultVal[];
-    };
-
-    typedef Criterion Element;
-    typedef Criterion *PtrElement;
-    typedef Criteria Collection;
-
-    static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
-                                         Collection &collection);
-};
-} // namespace detail
-
-/** Result of `parse(const char*)` */
-struct ParsingResult {
-    /** Parsed config, nullptr if the xml lib could not load the file */
-    std::unique_ptr<Config> parsedConfig;
-    size_t nbSkippedElement; //< Number of skipped invalid product strategies
-};
-
-/** Parses the provided audio policy usage configuration.
- * @return audio policy usage @see Config
- */
-ParsingResult parse(const char* path = DEFAULT_PATH);
-
-} // namespace wrapper_config
-} // namespace audio_policy
-} // android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index cd39b6f..5bfad29 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -39,6 +39,9 @@
 namespace android {
 namespace audio_policy {
 
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
 class ParameterManagerWrapper
 {
 private:
@@ -118,6 +121,17 @@
     status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
                                       audio_policy_dev_state_t state);
 
+    /**
+     * @brief addCriterion to the policy pfw
+     * @param name of the criterion
+     * @param isInclusive if true, inclusive, if false exclusive criterion type
+     * @param pairs of numerical/literal values of the criterion
+     * @param defaultValue provided as literal.
+     * @return
+     */
+    status_t addCriterion(const std::string &name, bool isInclusive, ValuePairs pairs,
+                          const std::string &defaultValue);
+
 private:
     /**
      * Apply the configuration of the platform on the policy parameter manager.
@@ -131,13 +145,6 @@
      */
     void applyPlatformConfiguration();
 
-    /**
-     * Load the criterion configuration file.
-     *
-     * @return NO_ERROR is parsing successful, error code otherwise.
-     */
-    status_t loadConfig();
-
      /**
      * Retrieve an element from a map by its name.
      *
diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk
index 837d5bb..95eac1c 100644
--- a/services/audiopolicy/enginedefault/Android.mk
+++ b/services/audiopolicy/enginedefault/Android.mk
@@ -8,10 +8,11 @@
 LOCAL_SRC_FILES := \
     src/Engine.cpp \
     src/EngineInstance.cpp \
+    ../engine/common/src/ProductStrategy.cpp \
+    ../engine/common/src/EngineBase.cpp
 
 audio_policy_engine_includes_common := \
-    $(LOCAL_PATH)/include \
-    frameworks/av/services/audiopolicy/engine/interface
+    $(LOCAL_PATH)/include
 
 LOCAL_CFLAGS += \
     -Wall \
@@ -26,8 +27,7 @@
     $(TARGET_OUT_HEADERS)/hw \
     $(call include-path-for, frameworks-av) \
     $(call include-path-for, audio-utils) \
-    $(call include-path-for, bionic) \
-    frameworks/av/services/audiopolicy/common/include
+    $(call include-path-for, bionic)
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
@@ -37,12 +37,19 @@
 LOCAL_HEADER_LIBRARIES := libbase_headers
 
 LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents \
+    libaudiopolicycomponents
 
-LOCAL_SHARED_LIBRARIES += \
+LOCAL_SHARED_LIBRARIES := \
     liblog \
     libcutils \
     libutils \
-    libmedia_helper
+    libmedia_helper \
+    libaudiopolicyengineconfig \
+    libaudiopolicy
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_common_headers \
+    libaudiopolicyengine_interface_headers
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/enginedefault/config/Android.mk b/services/audiopolicy/enginedefault/config/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
new file mode 100644
index 0000000..866466f
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH := $(call my-dir)
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+    audio_policy_engine_product_strategies_phone.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
similarity index 67%
copy from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
copy to services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
index 5d9193b..ab61d8a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
@@ -12,14 +12,11 @@
      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.
--->
-<!--
-    These are the minimum required criteria to be used by Audio HAL to ensure a basic
-    user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+     -->
 
-    <xi:include href="policy_criterion_types.xml"/>
-    <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+    <xi:include href="audio_policy_engine_product_strategies.xml"/>
 
 </configuration>
+
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..f72e379
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 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.
+     -->
+
+<ProductStrategies>
+
+    <!-- "hidden strategies" like TTS, enforced audible:
+            Shall we expose them here or keep it hard coded -->
+
+    <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+         countries (e.g. camera in Japan)
+         This strategy will only have higher priority than phone if force for system is set to
+         enforced. -->
+
+    <ProductStrategy name="STRATEGY_PHONE">
+        <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO">
+            <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION">
+        <AttributesGroup streamType="AUDIO_STREAM_RING">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+            <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+        <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE">
+            <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+        <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+        <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_MEDIA">
+         <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+            <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+            <Attributes></Attributes>
+        </AttributesGroup>
+        <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+            <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <ProductStrategy name="STRATEGY_DTMF">
+        <AttributesGroup streamType="AUDIO_STREAM_DTMF">
+            <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Used to identify the volume of audio streams exclusively transmitted through the  speaker
+         (TTS) of the device -->
+    <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+        <AttributesGroup streamType="AUDIO_STREAM_TTS">
+            <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Routing Strategy rerouting may be removed as following media??? -->
+    <ProductStrategy name="STRATEGY_REROUTING">
+        <AttributesGroup streamType="AUDIO_STREAM_REROUTING">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+    <!-- Default product strategy has empty attributes -->
+    <ProductStrategy name="STRATEGY_PATCH">
+        <AttributesGroup streamType="AUDIO_STREAM_PATCH">
+            <Attributes></Attributes>
+        </AttributesGroup>
+    </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index cc5a025..93af8a6 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -29,6 +29,7 @@
 #include <AudioPolicyManagerObserver.h>
 #include <AudioPort.h>
 #include <IOProfile.h>
+#include <AudioIODescriptorInterface.h>
 #include <policy.h>
 #include <utils/String8.h>
 #include <utils/Log.h>
@@ -38,31 +39,33 @@
 namespace audio_policy
 {
 
+struct legacy_strategy_map { const char *name; legacy_strategy id; };
+static const std::vector<legacy_strategy_map> gLegacyStrategy = {
+    { "STRATEGY_NONE", STRATEGY_NONE },
+    { "STRATEGY_MEDIA", STRATEGY_MEDIA },
+    { "STRATEGY_PHONE", STRATEGY_PHONE },
+    { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
+    { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
+    { "STRATEGY_DTMF", STRATEGY_DTMF },
+    { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
+    { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
+    { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
+    { "STRATEGY_REROUTING", STRATEGY_REROUTING },
+    { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
+};
+
 Engine::Engine()
-    : mManagerInterface(this),
-      mPhoneState(AUDIO_MODE_NORMAL),
-      mApmObserver(NULL)
 {
-    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
-        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
+    auto result = EngineBase::loadAudioPolicyEngineConfig();
+    ALOGE_IF(result.nbSkippedElement != 0,
+             "Policy Engine configuration is partially invalid, skipped %zu elements",
+             result.nbSkippedElement);
+
+    for (const auto &strategy : gLegacyStrategy) {
+        mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
     }
 }
 
-Engine::~Engine()
-{
-}
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
-    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
-    mApmObserver = observer;
-}
-
-status_t Engine::initCheck()
-{
-    return (mApmObserver != NULL) ?  NO_ERROR : NO_INIT;
-}
-
 status_t Engine::setPhoneState(audio_mode_t state)
 {
     ALOGV("setPhoneState() state %d", state);
@@ -72,22 +75,22 @@
         return BAD_VALUE;
     }
 
-    if (state == mPhoneState ) {
+    if (state == getPhoneState()) {
         ALOGW("setPhoneState() setting same state %d", state);
         return BAD_VALUE;
     }
 
     // store previous phone state for management of sonification strategy below
-    int oldState = mPhoneState;
-    mPhoneState = state;
+    int oldState = getPhoneState();
+    EngineBase::setPhoneState(state);
 
     if (!is_state_in_call(oldState) && is_state_in_call(state)) {
         ALOGV("  Entering call in setPhoneState()");
-        mApmObserver->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
+        getApmObserver()->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
                                                           AUDIO_STREAM_DTMF);
     } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
         ALOGV("  Exiting call in setPhoneState()");
-        mApmObserver->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
+        getApmObserver()->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
     }
     return NO_ERROR;
 }
@@ -101,7 +104,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_MEDIA:
         if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
@@ -112,7 +114,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_RECORD:
         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
@@ -120,7 +121,6 @@
             ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_DOCK:
         if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
@@ -130,21 +130,18 @@
             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
             ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_SYSTEM:
         if (config != AUDIO_POLICY_FORCE_NONE &&
             config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
             ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
         if (config != AUDIO_POLICY_FORCE_NONE &&
             config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
             ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
         if (config != AUDIO_POLICY_FORCE_NONE &&
@@ -154,109 +151,25 @@
             ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
             ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
             return BAD_VALUE;
         }
-        mForceUse[usage] = config;
         break;
     default:
         ALOGW("setForceUse() invalid usage %d", usage);
         break; // TODO return BAD_VALUE?
     }
-    return NO_ERROR;
+    return EngineBase::setForceUse(usage, config);
 }
 
-routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
-{
-    // stream to strategy mapping
-    switch (stream) {
-    case AUDIO_STREAM_VOICE_CALL:
-    case AUDIO_STREAM_BLUETOOTH_SCO:
-        return STRATEGY_PHONE;
-    case AUDIO_STREAM_RING:
-    case AUDIO_STREAM_ALARM:
-        return STRATEGY_SONIFICATION;
-    case AUDIO_STREAM_NOTIFICATION:
-        return STRATEGY_SONIFICATION_RESPECTFUL;
-    case AUDIO_STREAM_DTMF:
-        return STRATEGY_DTMF;
-    default:
-        ALOGE("unknown stream type %d", stream);
-        FALLTHROUGH_INTENDED;
-    case AUDIO_STREAM_SYSTEM:
-        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-        // while key clicks are played produces a poor result
-    case AUDIO_STREAM_MUSIC:
-        return STRATEGY_MEDIA;
-    case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        return STRATEGY_ENFORCED_AUDIBLE;
-    case AUDIO_STREAM_TTS:
-        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
-    case AUDIO_STREAM_ACCESSIBILITY:
-        return STRATEGY_ACCESSIBILITY;
-    case AUDIO_STREAM_REROUTING:
-        return STRATEGY_REROUTING;
-    }
-}
-
-routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
-{
-    // usage to strategy mapping
-    switch (usage) {
-    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        return STRATEGY_ACCESSIBILITY;
-
-    case AUDIO_USAGE_MEDIA:
-    case AUDIO_USAGE_GAME:
-    case AUDIO_USAGE_ASSISTANT:
-    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
-    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
-        return STRATEGY_MEDIA;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION:
-        return STRATEGY_PHONE;
-
-    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
-        return STRATEGY_DTMF;
-
-    case AUDIO_USAGE_ALARM:
-    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
-        return STRATEGY_SONIFICATION;
-
-    case AUDIO_USAGE_NOTIFICATION:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
-    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
-    case AUDIO_USAGE_NOTIFICATION_EVENT:
-        return STRATEGY_SONIFICATION_RESPECTFUL;
-
-    case AUDIO_USAGE_UNKNOWN:
-    default:
-        return STRATEGY_MEDIA;
-    }
-}
-
-audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
-{
-    DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
-    DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
-
-    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
-
-    return getDeviceForStrategyInt(strategy, availableOutputDevices,
-                                   availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
-}
-
-
-audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
-        DeviceVector availableOutputDevices,
-        DeviceVector availableInputDevices,
-        const SwAudioOutputCollection &outputs,
-        uint32_t outputDeviceTypesToIgnore) const
+audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
+                                                DeviceVector availableOutputDevices,
+                                                DeviceVector availableInputDevices,
+                                                const SwAudioOutputCollection &outputs,
+                                                uint32_t outputDeviceTypesToIgnore) const
 {
     uint32_t device = AUDIO_DEVICE_NONE;
     uint32_t availableOutputDevicesType =
@@ -334,7 +247,7 @@
         }
         // for phone strategy, we first consider the forced use and then the available devices by
         // order of priority
-        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+        switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             if (!isInCall() || strategy != STRATEGY_DTMF) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
@@ -352,7 +265,7 @@
             if (device) break;
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
             if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                      outputs.isA2dpSupported()) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
                 if (device) break;
@@ -386,7 +299,7 @@
             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
             // A2DP speaker when forcing to speaker output
             if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                    (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                      outputs.isA2dpSupported()) {
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                 if (device) break;
@@ -426,7 +339,7 @@
         //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
 
         if ((strategy == STRATEGY_SONIFICATION) ||
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
         }
 
@@ -442,9 +355,9 @@
                 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
             }
             // Use ONLY Bluetooth SCO output when ringing in vibration mode
-            if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+            if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
                     && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
-                if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
+                if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
                         == AUDIO_POLICY_FORCE_BT_SCO) {
                     if (device2 != AUDIO_DEVICE_NONE) {
                         device = device2;
@@ -453,7 +366,7 @@
                 }
             }
             // Use both Bluetooth SCO and phone default output when ringing in normal mode
-            if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
+            if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
                 if ((strategy == STRATEGY_SONIFICATION) &&
                         (device & AUDIO_DEVICE_OUT_SPEAKER) &&
                         (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
@@ -520,7 +433,7 @@
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                  outputs.isA2dpSupported()) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
             if (device2 == AUDIO_DEVICE_NONE) {
@@ -531,7 +444,7 @@
             }
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-            (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
+            (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
         }
         if (device2 == AUDIO_DEVICE_NONE) {
@@ -560,7 +473,7 @@
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
+                (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
         }
         if (device2 == AUDIO_DEVICE_NONE) {
@@ -581,7 +494,7 @@
 
         // If hdmi system audio mode is on, remove speaker out of output list.
         if ((strategy == STRATEGY_MEDIA) &&
-            (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
+            (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
             device &= ~AUDIO_DEVICE_OUT_SPEAKER;
         }
@@ -603,7 +516,7 @@
 
     if (device == AUDIO_DEVICE_NONE) {
         ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
-        device = mApmObserver->getDefaultOutputDevice()->type();
+        device = getApmObserver()->getDefaultOutputDevice()->type();
         ALOGE_IF(device == AUDIO_DEVICE_NONE,
                  "getDeviceForStrategy() no default device defined");
     }
@@ -614,9 +527,9 @@
 
 audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
 {
-    const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
-    const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
-    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
+    const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
     audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
 
     uint32_t device = AUDIO_DEVICE_NONE;
@@ -651,7 +564,7 @@
     case AUDIO_SOURCE_MIC:
     if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
         device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
-    } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
+    } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
         (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
         device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
     } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -675,7 +588,7 @@
                     primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
         }
 
-        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+        switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             // if SCO device is requested but no SCO device is available, fall back to default case
             if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
@@ -709,7 +622,7 @@
     case AUDIO_SOURCE_VOICE_RECOGNITION:
     case AUDIO_SOURCE_UNPROCESSED:
     case AUDIO_SOURCE_HOTWORD:
-        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
+        if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
                 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
             device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -780,10 +693,107 @@
     return device;
 }
 
+void Engine::updateDeviceSelectionCache()
+{
+    for (const auto &iter : getProductStrategies()) {
+        const auto &strategy = iter.second;
+        auto devices = getDevicesForProductStrategy(strategy->getId());
+        mDevicesForStrategies[strategy->getId()] = devices;
+        strategy->setDeviceTypes(devices.types());
+        strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
+    }
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
+{
+    DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+
+    auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
+                mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+    audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
+                                                      availableOutputDevices,
+                                                      availableInputDevices, outputs,
+                                                      (uint32_t)AUDIO_DEVICE_NONE);
+    return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+                                                   const sp<DeviceDescriptor> &preferredDevice,
+                                                   bool fromCache) const
+{
+    // First check for explict routing device
+    if (preferredDevice != nullptr) {
+        ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+        return DeviceVector(preferredDevice);
+    }
+    product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+    const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+    //
+    // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+    // be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
+    return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+    auto attributes = getAttributesForStreamType(stream);
+    return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+                                                         AudioMix **mix) const
+{
+    const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+    const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &inputs = getApmObserver()->getInputs();
+    std::string address;
+
+    //
+    // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+    // first as it used to be by APM?
+    //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device =
+            findPreferredDevice(inputs, attr.source, availableInputDevices);
+    if (device != nullptr) {
+        return device;
+    }
+
+    device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+    if (device != nullptr) {
+        return device;
+    }
+    audio_devices_t deviceType = getDeviceForInputSource(attr.source);
+
+    if (audio_is_remote_submix_device(deviceType)) {
+        address = "0";
+        std::size_t pos;
+        std::string tags { attr.tags };
+        if ((pos = tags.find("addr=")) != std::string::npos) {
+            address = tags.substr(pos + std::strlen("addr="));
+        }
+    }
+    return availableInputDevices.getDevice(deviceType,
+                                           String8(address.c_str()),
+                                           AUDIO_FORMAT_DEFAULT);
+}
+
 template <>
 AudioPolicyManagerInterface *Engine::queryInterface()
 {
-    return &mManagerInterface;
+    return this;
 }
 
 } // namespace audio_policy
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 06186c1..15fc358 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-
+#include "EngineBase.h"
 #include "AudioPolicyManagerInterface.h"
 #include <AudioGain.h>
 #include <policy.h>
@@ -29,114 +29,69 @@
 namespace audio_policy
 {
 
-class Engine
+enum legacy_strategy {
+    STRATEGY_NONE = -1,
+    STRATEGY_MEDIA,
+    STRATEGY_PHONE,
+    STRATEGY_SONIFICATION,
+    STRATEGY_SONIFICATION_RESPECTFUL,
+    STRATEGY_DTMF,
+    STRATEGY_ENFORCED_AUDIBLE,
+    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+    STRATEGY_ACCESSIBILITY,
+    STRATEGY_REROUTING,
+};
+
+class Engine : public EngineBase
 {
 public:
     Engine();
-    virtual ~Engine();
+    virtual ~Engine() = default;
 
     template <class RequestedInterface>
     RequestedInterface *queryInterface();
 
 private:
-    /// Interface members
-    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
-    {
-    public:
-        explicit ManagerInterfaceImpl(Engine *policyEngine)
-            : mPolicyEngine(policyEngine) {}
+    ///
+    /// from EngineBase, so from AudioPolicyManagerInterface
+    ///
+    status_t setPhoneState(audio_mode_t mode) override;
 
-        virtual void setObserver(AudioPolicyManagerObserver *observer)
-        {
-            mPolicyEngine->setObserver(observer);
-        }
-        virtual status_t initCheck()
-        {
-            return mPolicyEngine->initCheck();
-        }
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
-        {
-            return mPolicyEngine->getDeviceForInputSource(inputSource);
-        }
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy) const
-        {
-            return mPolicyEngine->getDeviceForStrategy(strategy);
-        }
-        virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
-        {
-            return mPolicyEngine->getStrategyForStream(stream);
-        }
-        virtual routing_strategy getStrategyForUsage(audio_usage_t usage)
-        {
-            return mPolicyEngine->getStrategyForUsage(usage);
-        }
-        virtual status_t setPhoneState(audio_mode_t mode)
-        {
-            return mPolicyEngine->setPhoneState(mode);
-        }
-        virtual audio_mode_t getPhoneState() const
-        {
-            return mPolicyEngine->getPhoneState();
-        }
-        virtual status_t setForceUse(audio_policy_force_use_t usage,
-                                     audio_policy_forced_cfg_t config)
-        {
-            return mPolicyEngine->setForceUse(usage, config);
-        }
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-        {
-            return mPolicyEngine->getForceUse(usage);
-        }
-        virtual status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
-                                                  audio_policy_dev_state_t /*state*/)
-        {
-            return NO_ERROR;
-        }
-    private:
-        Engine *mPolicyEngine;
-    } mManagerInterface;
+    status_t setForceUse(audio_policy_force_use_t usage,
+                         audio_policy_forced_cfg_t config) override;
+
+    DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+                                               const sp<DeviceDescriptor> &preferedDevice = nullptr,
+                                               bool fromCache = false) const override;
+
+    DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+                                           bool fromCache = false) const override;
+
+    sp<DeviceDescriptor> getInputDeviceForAttributes(
+            const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
+
+    void updateDeviceSelectionCache() override;
 
 private:
     /* Copy facilities are put private to disable copy. */
     Engine(const Engine &object);
     Engine &operator=(const Engine &object);
 
-    void setObserver(AudioPolicyManagerObserver *observer);
-
-    status_t initCheck();
-
-    inline bool isInCall() const
-    {
-        return is_state_in_call(mPhoneState);
-    }
-
-    status_t setPhoneState(audio_mode_t mode);
-    audio_mode_t getPhoneState() const
-    {
-        return mPhoneState;
-    }
-    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
-    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
-    {
-        return mForceUse[usage];
-    }
     status_t setDefaultDevice(audio_devices_t device);
 
-    routing_strategy getStrategyForStream(audio_stream_type_t stream);
-    routing_strategy getStrategyForUsage(audio_usage_t usage);
-    audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
-    audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
-            DeviceVector availableOutputDevices,
-            DeviceVector availableInputDevices,
-            const SwAudioOutputCollection &outputs,
-            uint32_t outputDeviceTypesToIgnore) const;
+    audio_devices_t getDeviceForStrategyInt(legacy_strategy strategy,
+                                            DeviceVector availableOutputDevices,
+                                            DeviceVector availableInputDevices,
+                                            const SwAudioOutputCollection &outputs,
+                                            uint32_t outputDeviceTypesToIgnore) const;
+
+    DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
     audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
-    audio_mode_t mPhoneState;  /**< current phone state. */
 
-    /** current forced use configuration. */
-    audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];
+    DeviceStrategyMap mDevicesForStrategies;
 
-    AudioPolicyManagerObserver *mApmObserver;
+    std::map<product_strategy_t, legacy_strategy> mLegacyStrategyMap;
 };
 } // namespace audio_policy
 } // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d7c7b4d..0eee3f2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -44,7 +44,6 @@
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
 #include <private/android_filesystem_config.h>
 #include <soundtrigger/SoundTrigger.h>
 #include <system/audio.h>
@@ -495,9 +494,10 @@
     ALOG_ASSERT(!rxDevices.isEmpty(), "updateCallRouting() no selected output device");
 
     audio_attributes_t attr = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
-    auto txSourceDevice = getDeviceAndMixForAttributes(attr);
+    auto txSourceDevice = mEngine->getInputDeviceForAttributes(attr);
     ALOG_ASSERT(txSourceDevice != 0, "updateCallRouting() input selected device not available");
-    ALOGV("updateCallRouting device rxDevice %s txDevice %s", 
+
+    ALOGV("updateCallRouting device rxDevice %s txDevice %s",
           rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());
 
     // release existing RX patch if any
@@ -677,26 +677,27 @@
     int delayMs = 0;
     if (isStateInCall(state)) {
         nsecs_t sysTime = systemTime();
+        auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+        auto sonificationStrategy = streamToStrategy(AUDIO_STREAM_ALARM);
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             // mute media and sonification strategies and delay device switch by the largest
             // latency of any output where either strategy is active.
             // This avoid sending the ring tone or music tail into the earpiece or headset.
-            if ((isStrategyActive(desc, STRATEGY_MEDIA,
-                                  SONIFICATION_HEADSET_MUSIC_DELAY,
-                                  sysTime) ||
-                 isStrategyActive(desc, STRATEGY_SONIFICATION,
-                                  SONIFICATION_HEADSET_MUSIC_DELAY,
-                                  sysTime)) &&
+            if ((desc->isStrategyActive(musicStrategy, SONIFICATION_HEADSET_MUSIC_DELAY, sysTime) ||
+                 desc->isStrategyActive(sonificationStrategy, SONIFICATION_HEADSET_MUSIC_DELAY,
+                                        sysTime)) &&
                     (delayMs < (int)desc->latency()*2)) {
                 delayMs = desc->latency()*2;
             }
-            setStrategyMute(STRATEGY_MEDIA, true, desc);
-            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
-            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
-            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+            setStrategyMute(musicStrategy, true, desc);
+            setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+                mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                                       nullptr, true /*fromCache*/).types());
+            setStrategyMute(sonificationStrategy, true, desc);
+            setStrategyMute(sonificationStrategy, false, desc, MUTE_TIME_MS,
+                mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_ALARM),
+                                                       nullptr, true /*fromCache*/).types());
         }
     }
 
@@ -743,12 +744,8 @@
     }
 
     // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
-    if (state == AUDIO_MODE_RINGTONE &&
-        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
-        mLimitRingtoneVolume = true;
-    } else {
-        mLimitRingtoneVolume = false;
-    }
+    mLimitRingtoneVolume = (state == AUDIO_MODE_RINGTONE &&
+                            isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY));
 }
 
 audio_mode_t AudioPolicyManager::getPhoneState() {
@@ -871,8 +868,7 @@
 
 audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream)
 {
-    routing_strategy strategy = getStrategy(stream);
-    DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+    DeviceVector devices = mEngine->getOutputDevicesForStream(stream, false /*fromCache*/);
 
     // Note that related method getOutputForAttr() uses getOutputForDevice() not selectOutput().
     // We use selectOutput() here since we don't have the desired AudioTrack sample rate,
@@ -906,7 +902,7 @@
             ALOGE("%s:  invalid stream type", __func__);
             return BAD_VALUE;
         }
-        stream_type_to_audio_attributes(srcStream, dstAttr);
+        *dstAttr = mEngine->getAttributesForStreamType(srcStream);
     }
     return NO_ERROR;
 }
@@ -919,59 +915,55 @@
                                                  uid_t uid,
                                                  const audio_config_t *config,
                                                  audio_output_flags_t *flags,
-                                                 audio_port_handle_t *selectedDeviceId)
+                                                 audio_port_handle_t *selectedDeviceId,
+                                                 bool *isRequestedDeviceForExclusiveUse)
 {
-    DeviceVector devices;
-    routing_strategy strategy;
-    audio_devices_t deviceType = AUDIO_DEVICE_NONE;
+    DeviceVector outputDevices;
     const audio_port_handle_t requestedPortId = *selectedDeviceId;
     DeviceVector msdDevices = getMsdAudioOutDevices();
+    const sp<DeviceDescriptor> requestedDevice =
+        mAvailableOutputDevices.getDeviceFromId(requestedPortId);
+
+
 
     status_t status = getAudioAttributes(resultAttr, attr, *stream);
     if (status != NO_ERROR) {
         return status;
     }
+    *stream = mEngine->getStreamTypeForAttributes(*resultAttr);
 
-    ALOGV("%s usage=%d, content=%d, tag=%s flags=%08x"
-          " session %d selectedDeviceId %d",
-          __func__,
-          resultAttr->usage, resultAttr->content_type, resultAttr->tags, resultAttr->flags,
-          session, requestedPortId);
+    ALOGV("%s() attributes=%s stream=%s session %d selectedDeviceId %d", __func__,
+          toString(*resultAttr).c_str(), toString(*stream).c_str(), session, requestedPortId);
 
-    *stream = streamTypefromAttributesInt(resultAttr);
-
-    strategy = getStrategyForAttr(resultAttr);
-
-    // First check for explicit routing (eg. setPreferredDevice)
-    sp<DeviceDescriptor> requestedDevice = mAvailableOutputDevices.getDeviceFromId(requestedPortId);
-    if (requestedDevice != nullptr) {
-        deviceType = requestedDevice->type();
-    } else {
-        // If no explict route, is there a matching dynamic policy that applies?
-        sp<SwAudioOutputDescriptor> desc;
-        if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
-            ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
-            if (!audio_has_proportional_frames(config->format)) {
-                return BAD_VALUE;
-            }
-            *stream = streamTypefromAttributesInt(resultAttr);
-            *output = desc->mIoHandle;
-            AudioMix *mix = desc->mPolicyMix;
-            sp<DeviceDescriptor> deviceDesc =
-                mAvailableOutputDevices.getDevice(
-                        mix->mDeviceType, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
-            *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
-            ALOGV("%s returns output %d", __func__, *output);
-            return NO_ERROR;
-        }
-
-        // Virtual sources must always be dynamicaly or explicitly routed
-        if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
-            ALOGW("%s no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE", __func__);
+    // 1/ First check for explicit routing (eg. setPreferredDevice): NOTE: now handled by engine
+    // 2/ If no explict route, is there a matching dynamic policy that applies?
+    //    NOTE: new engine product strategy does not make use of dynamic routing, keep it for
+    //          remote-submix and legacy
+    sp<SwAudioOutputDescriptor> desc;
+    if (requestedDevice == nullptr &&
+            mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
+        ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
+        if (!audio_has_proportional_frames(config->format)) {
             return BAD_VALUE;
         }
-        deviceType = getDeviceForStrategy(strategy, false /*fromCache*/);
+        *output = desc->mIoHandle;
+        AudioMix *mix = desc->mPolicyMix;
+        sp<DeviceDescriptor> deviceDesc =
+                mAvailableOutputDevices.getDevice(mix->mDeviceType,
+                                                  mix->mDeviceAddress,
+                                                  AUDIO_FORMAT_DEFAULT);
+        *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
+        ALOGV("getOutputForAttr() returns output %d", *output);
+        return NO_ERROR;
     }
+    // Virtual sources must always be dynamicaly or explicitly routed
+    if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
+        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
+        return BAD_VALUE;
+    }
+    // explicit routing managed by getDeviceForStrategy in APM is now handled by engine
+    // in order to let the choice of the order to future vendor engine
+    outputDevices = mEngine->getOutputDevicesForAttributes(*resultAttr, requestedDevice, false);
 
     if ((resultAttr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
         *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
@@ -982,45 +974,40 @@
     // FIXME: provide a more generic approach which is not device specific and move this back
     // to getOutputForDevice.
     // TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
-    if (deviceType == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
-        (*stream == AUDIO_STREAM_MUSIC || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
+    if (outputDevices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+        (*stream == AUDIO_STREAM_MUSIC  || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
         audio_is_linear_pcm(config->format) &&
         isInCall()) {
         if (requestedPortId != AUDIO_PORT_HANDLE_NONE) {
             *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
-        } else {
-            // Get the devce type directly from the engine to bypass preferred route logic
-            deviceType = mEngine->getDeviceForStrategy(strategy);
+            *isRequestedDeviceForExclusiveUse = true;
         }
     }
 
-    ALOGV("%s device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
-          "flags %#x",
-          __func__,
-          deviceType, config->sample_rate, config->format, config->channel_mask, *flags);
+    ALOGV("%s() device %s, sampling rate %d, format %#x, channel mask %#x, flags %#x stream %s",
+          __func__, outputDevices.toString().c_str(), config->sample_rate, config->format,
+          config->channel_mask, *flags, toString(*stream).c_str());
 
     *output = AUDIO_IO_HANDLE_NONE;
     if (!msdDevices.isEmpty()) {
         *output = getOutputForDevices(msdDevices, session, *stream, config, flags);
-        sp<DeviceDescriptor> deviceDesc =
-                mAvailableOutputDevices.getDevice(deviceType, String8(), AUDIO_FORMAT_DEFAULT);
-        if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(deviceDesc) == NO_ERROR) {
-            ALOGV("%s() Using MSD devices %s instead of device %s",
-                    __func__, msdDevices.toString().c_str(), deviceDesc->toString().c_str());
-            deviceType = msdDevices.types();
+        sp<DeviceDescriptor> device = outputDevices.isEmpty() ? nullptr : outputDevices.itemAt(0);
+        if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(device) == NO_ERROR) {
+            ALOGV("%s() Using MSD devices %s instead of devices %s",
+                  __func__, msdDevices.toString().c_str(), outputDevices.toString().c_str());
+            outputDevices = msdDevices;
         } else {
             *output = AUDIO_IO_HANDLE_NONE;
         }
     }
-    devices = mAvailableOutputDevices.getDevicesFromTypeMask(deviceType);
     if (*output == AUDIO_IO_HANDLE_NONE) {
-        *output = getOutputForDevices(devices, session, *stream, config, flags);
+        *output = getOutputForDevices(outputDevices, session, *stream, config, flags);
     }
     if (*output == AUDIO_IO_HANDLE_NONE) {
         return INVALID_OPERATION;
     }
 
-    *selectedDeviceId = getFirstDeviceId(devices);
+    *selectedDeviceId = getFirstDeviceId(outputDevices);
 
     ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
 
@@ -1043,8 +1030,9 @@
     }
     const audio_port_handle_t requestedPortId = *selectedDeviceId;
     audio_attributes_t resultAttr;
+    bool isRequestedDeviceForExclusiveUse = false;
     status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
-            config, flags, selectedDeviceId);
+            config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse);
     if (status != NO_ERROR) {
         return status;
     }
@@ -1057,13 +1045,13 @@
     sp<TrackClientDescriptor> clientDesc =
         new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
                                   requestedPortId, *stream,
-                                  getStrategyForAttr(&resultAttr),
-                                  *flags);
+                                  mEngine->getProductStrategyForAttributes(resultAttr),
+                                  *flags, isRequestedDeviceForExclusiveUse);
     sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
     outputDesc->addClient(clientDesc);
 
-    ALOGV("%s returns output %d selectedDeviceId %d for port ID %d",
-          __func__, *output, requestedPortId, *portId);
+    ALOGV("%s() returns output %d selectedDeviceId %d for port ID %d", __func__,
+          *output, *selectedDeviceId, *portId);
 
     return NO_ERROR;
 }
@@ -1368,7 +1356,8 @@
         // Use media strategy for unspecified output device. This should only
         // occur on checkForDeviceAndOutputChanges(). Device connection events may
         // therefore invalidate explicit routing requests.
-        DeviceVector devices = getDevicesForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
+        DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+                    attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
         LOG_ALWAYS_FATAL_IF(devices.isEmpty(), "no outpudevice to set Msd Patch");
         device = devices.itemAt(0);
     }
@@ -1547,6 +1536,8 @@
 
     *delayMs = 0;
     audio_stream_type_t stream = client->stream();
+    auto clientStrategy = client->strategy();
+    auto clientAttr = client->attributes();
     if (stream == AUDIO_STREAM_TTS) {
         ALOGV("\t found BEACON stream");
         if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
@@ -1594,11 +1585,11 @@
     if (client->hasPreferredDevice(true)) {
         devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
         if (devices != outputDesc->devices()) {
-            checkStrategyRoute(getStrategy(stream), outputDesc->mIoHandle);
+            checkStrategyRoute(clientStrategy, outputDesc->mIoHandle);
         }
     }
 
-    if (stream == AUDIO_STREAM_MUSIC) {
+    if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
         selectOutputForMusicEffects();
     }
 
@@ -1607,11 +1598,10 @@
         if (devices.isEmpty()) {
             devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
         }
-
-        routing_strategy strategy = getStrategy(stream);
-        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
-                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
-                            (beaconMuteLatency > 0);
+        bool shouldWait =
+            (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) ||
+             followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) ||
+             (beaconMuteLatency > 0));
         uint32_t waitMs = beaconMuteLatency;
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1666,7 +1656,7 @@
         handleNotificationRoutingForStream(stream);
 
         // force reevaluating accessibility routing when ringtone or alarm starts
-        if (strategy == STRATEGY_SONIFICATION) {
+        if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
             mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
         }
 
@@ -1685,7 +1675,7 @@
 
     if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-        setStrategyMute(STRATEGY_SONIFICATION, true, outputDesc);
+        setStrategyMute(streamToStrategy(AUDIO_STREAM_ALARM), true, outputDesc);
     }
 
     // Automatically enable the remote submix input when output is started on a re routing mix
@@ -1747,7 +1737,7 @@
         }
         bool forceDeviceUpdate = false;
         if (client->hasPreferredDevice(true)) {
-            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
+            checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE);
             forceDeviceUpdate = true;
         }
 
@@ -1756,7 +1746,7 @@
 
         // store time at which the stream was stopped - see isStreamActive()
         if (outputDesc->streamActiveCount(stream) == 0 || forceDeviceUpdate) {
-            outputDesc->mStopTime[stream] = systemTime();
+            outputDesc->setStopTime(client, systemTime());
             DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
             // delay the device switch by twice the latency because stopOutput() is executed when
             // the track stop() command is received and at that time the audio track buffer can
@@ -1791,10 +1781,10 @@
 
         if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
                 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-            setStrategyMute(STRATEGY_SONIFICATION, false, outputDesc);
+            setStrategyMute(streamToStrategy(AUDIO_STREAM_RING), false, outputDesc);
         }
 
-        if (stream == AUDIO_STREAM_MUSIC) {
+        if (followsSameRouting(client->attributes(), attributes_initializer(AUDIO_USAGE_MEDIA))) {
             selectOutputForMusicEffects();
         }
         return NO_ERROR;
@@ -1849,9 +1839,9 @@
                                              input_type_t *inputType,
                                              audio_port_handle_t *portId)
 {
-    ALOGV("getInputForAttr() source %d, sampling rate %d, format %#x, channel mask %#x,"
-            "session %d, flags %#x",
-          attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
+    ALOGV("%s() source %d, sampling rate %d, format %#x, channel mask %#x, session %d, "
+          "flags %#x attributes=%s", __func__, attr->source, config->sample_rate,
+          config->format, config->channel_mask, session, flags, toString(*attr).c_str());
 
     status_t status = NO_ERROR;
     audio_source_t halInputSource;
@@ -1940,7 +1930,7 @@
         if (explicitRoutingDevice != nullptr) {
             device = explicitRoutingDevice;
         } else {
-            device = getDeviceAndMixForAttributes(attributes, &policyMix);
+            device = mEngine->getInputDeviceForAttributes(attributes, &policyMix);
         }
         if (device == nullptr) {
             ALOGW("getInputForAttr() could not find device for source %d", attributes.source);
@@ -1954,8 +1944,6 @@
             // know about it and is therefore considered "legacy"
             *inputType = API_INPUT_LEGACY;
         } else if (audio_is_remote_submix_device(device->type())) {
-            device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"),
-                                                      AUDIO_FORMAT_DEFAULT);
             *inputType = API_INPUT_MIX_CAPTURE;
         } else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
             *inputType = API_INPUT_TELEPHONY_RX;
@@ -1965,9 +1953,7 @@
 
     }
 
-    *input = getInputForDevice(device, session, attributes.source,
-                               config, flags,
-                               policyMix);
+    *input = getInputForDevice(device, session, attributes, config, flags, policyMix);
     if (*input == AUDIO_IO_HANDLE_NONE) {
         status = INVALID_OPERATION;
         goto error;
@@ -1975,8 +1961,8 @@
 
 exit:
 
-    *selectedDeviceId = mAvailableInputDevices.contains(device) ? 
-            device->getId() : AUDIO_PORT_HANDLE_NONE;
+    *selectedDeviceId = mAvailableInputDevices.contains(device) ?
+                device->getId() : AUDIO_PORT_HANDLE_NONE;
 
     isSoundTrigger = attributes.source == AUDIO_SOURCE_HOTWORD &&
         mSoundTriggerSessions.indexOfKey(session) > 0;
@@ -2000,16 +1986,16 @@
 
 audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescriptor> &device,
                                                         audio_session_t session,
-                                                        audio_source_t inputSource,
+                                                        const audio_attributes_t &attributes,
                                                         const audio_config_base_t *config,
                                                         audio_input_flags_t flags,
                                                         AudioMix *policyMix)
 {
     audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-    audio_source_t halInputSource = inputSource;
+    audio_source_t halInputSource = attributes.source;
     bool isSoundTrigger = false;
 
-    if (inputSource == AUDIO_SOURCE_HOTWORD) {
+    if (attributes.source == AUDIO_SOURCE_HOTWORD) {
         ssize_t index = mSoundTriggerSessions.indexOfKey(session);
         if (index >= 0) {
             input = mSoundTriggerSessions.valueFor(session);
@@ -2019,7 +2005,7 @@
         } else {
             halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
         }
-    } else if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+    } else if (attributes.source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
                audio_is_linear_pcm(config->format)) {
         flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_VOIP_TX);
     }
@@ -2374,10 +2360,10 @@
 
     // update volume on all outputs and streams matching the following:
     // - The requested stream (or a stream matching for volume control) is active on the output
-    // - The device (or devices) selected by the strategy corresponding to this stream includes
+    // - The device (or devices) selected by the engine for this stream includes
     // the requested device
     // - For non default requested device, currently selected device on the output is either the
-    // requested device or one of the devices selected by the strategy
+    // requested device or one of the devices selected by the engine for this stream
     // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
     // no specific device volume value exists for currently selected device.
     status_t status = NO_ERROR;
@@ -2391,9 +2377,9 @@
             if (!(desc->isStreamActive((audio_stream_type_t)curStream) || isInCall())) {
                 continue;
             }
-            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
-            audio_devices_t curStreamDevice = Volume::getDeviceForVolume(getDeviceForStrategy(
-                    curStrategy, false /*fromCache*/));
+            audio_devices_t curStreamDevice = Volume::getDeviceForVolume(
+                        mEngine->getOutputDevicesForStream((audio_stream_type_t)curStream,
+                                                           false /*fromCache*/).types());
             if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
                     ((curStreamDevice & device) == 0)) {
                 continue;
@@ -2435,10 +2421,10 @@
     if (!audio_is_output_device(device)) {
         return BAD_VALUE;
     }
-    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
-    // the strategy the stream belongs to.
+    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
+    // stream by the engine.
     if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
-        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
+        device = mEngine->getOutputDevicesForStream(stream, true /*fromCache*/).types();
     }
     device = Volume::getDeviceForVolume(device);
 
@@ -2458,8 +2444,8 @@
     // 3: The primary output
     // 4: the first output in the list
 
-    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
-    DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+    DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+                attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
     SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
 
     if (outputs.size() == 0) {
@@ -2531,7 +2517,9 @@
             return INVALID_OPERATION;
         }
     }
-    return mEffects.registerEffect(desc, io, strategy, session, id);
+    return mEffects.registerEffect(desc, io, session, id,
+                                   (strategy == streamToStrategy(AUDIO_STREAM_MUSIC) ||
+                                   strategy == PRODUCT_STRATEGY_NONE));
 }
 
 status_t AudioPolicyManager::unregisterEffect(int id)
@@ -2870,6 +2858,9 @@
     mAudioPatches.dump(dst);
     mPolicyMixes.dump(dst);
     mAudioSources.dump(dst);
+
+    dst->appendFormat("\nPolicy Engine dump:\n");
+    mEngine->dump(dst);
 }
 
 status_t AudioPolicyManager::dump(int fd)
@@ -2956,7 +2947,7 @@
 bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& config,
                                                  const audio_attributes_t& attributes) {
     audio_output_flags_t output_flags = AUDIO_OUTPUT_FLAG_NONE;
-    audio_attributes_flags_to_audio_output_flags(attributes.flags, output_flags);
+    audio_flags_to_audio_output_flags(attributes.flags, &output_flags);
     sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
                                             config.sample_rate,
                                             config.format,
@@ -3461,27 +3452,27 @@
     }
 }
 
-void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
-                                            audio_io_handle_t ouptutToSkip)
+void AudioPolicyManager::checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip)
 {
-    DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+    // Take the first attributes following the product strategy as it is used to retrieve the routed
+    // device. All attributes wihin a strategy follows the same "routing strategy"
+    auto attributes = mEngine->getAllAttributesForProductStrategy(ps).front();
+    DeviceVector devices = mEngine->getOutputDevicesForAttributes(attributes, nullptr, false);
     SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
     for (size_t j = 0; j < mOutputs.size(); j++) {
         if (mOutputs.keyAt(j) == ouptutToSkip) {
             continue;
         }
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
-        if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
+        if (!outputDesc->isStrategyActive(ps)) {
             continue;
         }
         // If the default device for this strategy is on another output mix,
         // invalidate all tracks in this strategy to force re connection.
         // Otherwise select new device on the output mix.
         if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
-            for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-                if (getStrategy((audio_stream_type_t)stream) == strategy) {
-                    mpClientInterface->invalidateStream((audio_stream_type_t)stream);
-                }
+            for (auto stream : mEngine->getStreamTypesForProductStrategy(ps)) {
+                mpClientInterface->invalidateStream(stream);
             }
         } else {
             setOutputDevices(
@@ -3493,13 +3484,18 @@
 void AudioPolicyManager::clearSessionRoutes(uid_t uid)
 {
     // remove output routes associated with this uid
-    SortedVector<routing_strategy> affectedStrategies;
+    std::vector<product_strategy_t> affectedStrategies;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
         for (const auto& client : outputDesc->getClientIterable()) {
             if (client->hasPreferredDevice() && client->uid() == uid) {
                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
-                affectedStrategies.add(getStrategy(client->stream()));
+                auto clientStrategy = client->strategy();
+                if (std::find(begin(affectedStrategies), end(affectedStrategies), clientStrategy) !=
+                        end(affectedStrategies)) {
+                    continue;
+                }
+                affectedStrategies.push_back(client->strategy());
             }
         }
     }
@@ -3549,7 +3545,7 @@
     *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
     *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
     audio_attributes_t attr = { .source = AUDIO_SOURCE_HOTWORD };
-    *device = getDeviceAndMixForAttributes(attr)->type();
+    *device = mEngine->getInputDeviceForAttributes(attr)->type();
 
     return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
 }
@@ -3591,8 +3587,8 @@
 
     sp<SourceClientDescriptor> sourceDesc =
         new SourceClientDescriptor(*portId, uid, *attributes, patchDesc, srcDevice,
-                                   streamTypefromAttributesInt(attributes),
-                                   getStrategyForAttr(attributes));
+                                   mEngine->getStreamTypeForAttributes(*attributes),
+                                   mEngine->getProductStrategyForAttributes(*attributes));
 
     status_t status = connectAudioSource(sourceDesc);
     if (status == NO_ERROR) {
@@ -3609,12 +3605,12 @@
     disconnectAudioSource(sourceDesc);
 
     audio_attributes_t attributes = sourceDesc->attributes();
-    routing_strategy strategy = getStrategyForAttr(&attributes);
     audio_stream_type_t stream = sourceDesc->stream();
     sp<DeviceDescriptor> srcDevice = sourceDesc->srcDevice();
 
-    DeviceVector sinkDevices = getDevicesForStrategy(strategy, true);
-    ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for strategy");
+    DeviceVector sinkDevices =
+            mEngine->getOutputDevicesForAttributes(attributes, nullptr, true);
+    ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for attributes");
     sp<DeviceDescriptor> sinkDevice = sinkDevices.itemAt(0);
     ALOG_ASSERT(mAvailableOutputDevices.contains(sinkDevice), "%s: Device %s not available",
                 __FUNCTION__, sinkDevice->toString().c_str());
@@ -3638,8 +3634,10 @@
         config.format = sourceDesc->config().format;
         audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
         audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+        bool isRequestedDeviceForExclusiveUse = false;
         getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
-                &attributes, &stream, sourceDesc->uid(), &config, &flags, &selectedDeviceId);
+                &attributes, &stream, sourceDesc->uid(), &config, &flags,
+                &selectedDeviceId, &isRequestedDeviceForExclusiveUse);
         if (output == AUDIO_IO_HANDLE_NONE) {
             ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevices.types());
             return INVALID_OPERATION;
@@ -3968,16 +3966,15 @@
     return NO_ERROR;
 }
 
-sp<SourceClientDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
-        audio_io_handle_t output, routing_strategy strategy)
+sp<SourceClientDescriptor> AudioPolicyManager::getSourceForAttributesOnOutput(
+        audio_io_handle_t output, const audio_attributes_t &attr)
 {
     sp<SourceClientDescriptor> source;
     for (size_t i = 0; i < mAudioSources.size(); i++)  {
         sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
-        audio_attributes_t attributes = sourceDesc->attributes();
-        routing_strategy sourceStrategy = getStrategyForAttr(&attributes);
         sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->swOutput().promote();
-        if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
+        if (followsSameRouting(attr, sourceDesc->attributes()) &&
+                               outputDesc != 0 && outputDesc->mIoHandle == output) {
             source = sourceDesc;
             break;
         }
@@ -4792,16 +4789,25 @@
     }
 }
 
-void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
+bool AudioPolicyManager::followsSameRouting(const audio_attributes_t &lAttr,
+                                            const audio_attributes_t &rAttr) const
 {
-    DeviceVector oldDevices = getDevicesForStrategy(strategy, true /*fromCache*/);
-    DeviceVector newDevices = getDevicesForStrategy(strategy, false /*fromCache*/);
+    return mEngine->getProductStrategyForAttributes(lAttr) ==
+            mEngine->getProductStrategyForAttributes(rAttr);
+}
+
+void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
+{
+    auto psId = mEngine->getProductStrategyForAttributes(attr);
+
+    DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
+    DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
     SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
     SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
 
     // also take into account external policy-related changes: add all outputs which are
     // associated with policies in the "before" and "after" output vectors
-    ALOGVV("checkOutputForStrategy(): policy related outputs");
+    ALOGVV("%s(): policy related outputs", __func__);
     for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
         const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
         if (desc != 0 && desc->mPolicyMix != NULL) {
@@ -4817,7 +4823,7 @@
         }
     }
 
-    if (!dstOutputs.isEmpty() && srcOutputs != dstOutputs) {
+    if (srcOutputs != dstOutputs) {
         // get maximum latency of all source outputs to determine the minimum mute time guaranteeing
         // audio from invalidated tracks will be rendered when unmuting
         uint32_t maxLatency = 0;
@@ -4828,50 +4834,40 @@
             }
         }
         ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
-              "%s: strategy %d, moving from output %s to output %s", __func__, strategy,
+              "%s: strategy %d, moving from output %s to output %s", __func__, psId,
               std::to_string(srcOutputs[0]).c_str(),
               std::to_string(dstOutputs[0]).c_str());
         // mute strategy while moving tracks from one output to another
         for (audio_io_handle_t srcOut : srcOutputs) {
             sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
-            if (desc != 0 && isStrategyActive(desc, strategy)) {
-                setStrategyMute(strategy, true, desc);
-                setStrategyMute(strategy, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
+            if (desc != 0 && desc->isStrategyActive(psId)) {
+                setStrategyMute(psId, true, desc);
+                setStrategyMute(psId, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
                                 newDevices.types());
             }
-            sp<SourceClientDescriptor> source =
-                    getSourceForStrategyOnOutput(srcOut, strategy);
+            sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
             if (source != 0){
                 connectAudioSource(source);
             }
         }
 
-        // Move effects associated to this strategy from previous output to new output
-        if (strategy == STRATEGY_MEDIA) {
+        // Move effects associated to this stream from previous output to new output
+        if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
             selectOutputForMusicEffects();
         }
-        // Move tracks associated to this strategy from previous output to new output
-        for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
-            if (getStrategy((audio_stream_type_t)i) == strategy) {
-                mpClientInterface->invalidateStream((audio_stream_type_t)i);
-            }
+        // Move tracks associated to this stream (and linked) from previous output to new output
+        for (auto stream :  mEngine->getStreamTypesForProductStrategy(psId)) {
+            mpClientInterface->invalidateStream(stream);
         }
     }
 }
 
 void AudioPolicyManager::checkOutputForAllStrategies()
 {
-    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
-        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
-    checkOutputForStrategy(STRATEGY_PHONE);
-    if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
-        checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
-    checkOutputForStrategy(STRATEGY_SONIFICATION);
-    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
-    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
-    checkOutputForStrategy(STRATEGY_MEDIA);
-    checkOutputForStrategy(STRATEGY_DTMF);
-    checkOutputForStrategy(STRATEGY_REROUTING);
+    for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
+        auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
+        checkOutputForAttributes(attributes);
+    }
 }
 
 void AudioPolicyManager::checkA2dpSuspend()
@@ -4924,38 +4920,6 @@
     }
 }
 
-template <class IoDescriptor, class Filter>
-sp<DeviceDescriptor> AudioPolicyManager::findPreferredDevice(
-        IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
-{
-    auto activeClients = desc->clientsList(true /*activeOnly*/);
-    auto activeClientsWithRoute =
-        desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
-    active = activeClients.size() > 0;
-    if (active && activeClients.size() == activeClientsWithRoute.size()) {
-        return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
-    }
-    return nullptr;
-}
-
-template <class IoCollection, class Filter>
-sp<DeviceDescriptor> AudioPolicyManager::findPreferredDevice(
-        IoCollection& ioCollection, Filter filter, const DeviceVector& devices)
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < ioCollection.size(); i++) {
-        auto desc = ioCollection.valueAt(i);
-        bool active;
-        sp<DeviceDescriptor> curDevice = findPreferredDevice(desc, filter, active, devices);
-        if (active && curDevice == nullptr) {
-            return nullptr;
-        } else if (curDevice != nullptr) {
-            device = curDevice;
-        }
-    }
-    return device;
-}
-
 DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
                                                      bool fromCache)
 {
@@ -4975,7 +4939,7 @@
     // input: a specific app can not force routing for other apps by setting a preferred device.
     bool active; // unused
     sp<DeviceDescriptor> device =
-        findPreferredDevice(outputDesc, STRATEGY_NONE, active, mAvailableOutputDevices);
+        findPreferredDevice(outputDesc, PRODUCT_STRATEGY_NONE, active, mAvailableOutputDevices);
     if (device != nullptr) {
         return DeviceVector(device);
     }
@@ -4987,54 +4951,22 @@
         return DeviceVector(device);
     }
 
-    // check the following by order of priority to request a routing change if necessary:
-    // 1: the strategy enforced audible is active and enforced on the output:
-    //      use device for strategy enforced audible
-    // 2: we are in call or the strategy phone is active on the output:
-    //      use device for strategy phone
-    // 3: the strategy sonification is active on the output:
-    //      use device for strategy sonification
-    // 4: the strategy for enforced audible is active but not enforced on the output:
-    //      use the device for strategy enforced audible
-    // 5: the strategy accessibility is active on the output:
-    //      use device for strategy accessibility
-    // 6: the strategy "respectful" sonification is active on the output:
-    //      use device for strategy "respectful" sonification
-    // 7: the strategy media is active on the output:
-    //      use device for strategy media
-    // 8: the strategy DTMF is active on the output:
-    //      use device for strategy DTMF
-    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
-    //      use device for strategy t-t-s
+    for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
+        StreamTypeVector streams = mEngine->getStreamTypesForProductStrategy(productStrategy);
+        auto attr = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
 
-    // FIXME: extend use of isStrategyActiveOnSameModule() to all strategies
-    // with a refined rule considering mutually exclusive devices (using same backend)
-    // as opposed to all streams on the same audio HAL module.
-    if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
-        mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-        devices = getDevicesForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isInCall() ||
-               isStrategyActiveOnSameModule(outputDesc, STRATEGY_PHONE)) {
-        devices = getDevicesForStrategy(STRATEGY_PHONE, fromCache);
-    } else if (isStrategyActiveOnSameModule(outputDesc, STRATEGY_SONIFICATION)) {
-        devices = getDevicesForStrategy(STRATEGY_SONIFICATION, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
-        devices = getDevicesForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
-        devices = getDevicesForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
-        devices = getDevicesForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
-        devices = getDevicesForStrategy(STRATEGY_MEDIA, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
-        devices = getDevicesForStrategy(STRATEGY_DTMF, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
-        devices = getDevicesForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
-        devices = getDevicesForStrategy(STRATEGY_REROUTING, fromCache);
+        if ((hasVoiceStream(streams) &&
+             (isInCall() || mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc))) ||
+             (hasStream(streams, AUDIO_STREAM_ALARM) &&
+                mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) ||
+                outputDesc->isStrategyActive(productStrategy)) {
+            // Retrieval of devices for voice DL is done on primary output profile, cannot
+            // check the route (would force modifying configuration file for this profile)
+            devices = mEngine->getOutputDevicesForAttributes(attr, nullptr, fromCache);
+            break;
+        }
     }
-
-    ALOGV("getNewOutputDevice() selected devices %s", devices.toString().c_str());
+    ALOGV("%s selected devices %s", __func__, devices.toString().c_str());
     return devices;
 }
 
@@ -5068,7 +5000,7 @@
         attributes.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
     }
     if (attributes.source != AUDIO_SOURCE_DEFAULT) {
-        device = getDeviceAndMixForAttributes(attributes);
+        device = mEngine->getInputDeviceForAttributes(attributes);
     }
 
     return device;
@@ -5079,26 +5011,22 @@
     return (stream1 == stream2);
 }
 
-uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
-    return (uint32_t)getStrategy(stream);
-}
-
 audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
     // By checking the range of stream before calling getStrategy, we avoid
-    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
-    // and then return STRATEGY_MEDIA, but we want to return the empty set.
-    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
+    // getOutputDevicesForStream's behavior for invalid streams.
+    // engine's getOutputDevicesForStream would fallback on its default behavior (most probably
+    // device for music stream), but we want to return the empty set.
+    if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
         return AUDIO_DEVICE_NONE;
     }
     DeviceVector activeDevices;
     DeviceVector devices;
-    for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
-        if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
+    for (audio_stream_type_t curStream = AUDIO_STREAM_MIN; curStream < AUDIO_STREAM_PUBLIC_CNT;
+         curStream = (audio_stream_type_t) (curStream + 1)) {
+        if (!streamsMatchForvolume(stream, curStream)) {
             continue;
         }
-        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
-        DeviceVector curDevices =
-                getDevicesForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
+        DeviceVector curDevices = mEngine->getOutputDevicesForStream(curStream, false/*fromCache*/);
         devices.merge(curDevices);
         for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
             sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
@@ -5123,28 +5051,10 @@
     return devices.types();
 }
 
-routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
-{
-    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
-    return mEngine->getStrategyForStream(stream);
-}
-
-routing_strategy AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
-    // flags to strategy mapping
-    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
-        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
-    }
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return STRATEGY_ENFORCED_AUDIBLE;
-    }
-    // usage to strategy mapping
-    return mEngine->getStrategyForUsage(attr->usage);
-}
-
 void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
     switch(stream) {
     case AUDIO_STREAM_MUSIC:
-        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+        checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION));
         updateDevicesAndOutputs();
         break;
     default:
@@ -5211,33 +5121,14 @@
     return 0;
 }
 
-DeviceVector AudioPolicyManager::getDevicesForStrategy(routing_strategy strategy, bool fromCache)
-{
-    // Honor explicit routing requests only if all active clients have a preferred route in which
-    // case the last active client route is used
-    sp<DeviceDescriptor> device = findPreferredDevice(mOutputs, strategy, mAvailableOutputDevices);
-    if (device != nullptr) {
-        return DeviceVector(device);
-    }
-
-    if (fromCache) {
-        ALOGVV("%s from cache strategy %d, device %s", __func__, strategy,
-               mDevicesForStrategy[strategy].toString().c_str());
-        return mDevicesForStrategy[strategy];
-    }
-    return mAvailableOutputDevices.getDevicesFromTypeMask(mEngine->getDeviceForStrategy(strategy));
-}
-
 void AudioPolicyManager::updateDevicesAndOutputs()
 {
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mDevicesForStrategy[i] = getDevicesForStrategy((routing_strategy)i, false /*fromCache*/);
-    }
+    mEngine->updateDeviceSelectionCache();
     mPreviousOutputs = mOutputs;
 }
 
 uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
-                                                       audio_devices_t prevDeviceType,
+                                                       const DeviceVector &prevDevices,
                                                        uint32_t delayMs)
 {
     // mute/unmute strategies using an incompatible device combination
@@ -5248,22 +5139,24 @@
     }
 
     uint32_t muteWaitMs = 0;
-    audio_devices_t deviceType = outputDesc->devices().types();
-    bool shouldMute = outputDesc->isActive() && (popcount(deviceType) >= 2);
+    DeviceVector devices = outputDesc->devices();
+    bool shouldMute = outputDesc->isActive() && (devices.size() >= 2);
 
-    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-        audio_devices_t curDeviceType =
-                getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
-        curDeviceType = curDeviceType & outputDesc->supportedDevices().types();
-        bool mute = shouldMute && (curDeviceType & deviceType) && (curDeviceType != deviceType);
+    auto productStrategies = mEngine->getOrderedProductStrategies();
+    for (const auto &productStrategy : productStrategies) {
+        auto attributes = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
+        DeviceVector curDevices =
+                mEngine->getOutputDevicesForAttributes(attributes, nullptr, false/*fromCache*/);
+        curDevices = curDevices.filter(outputDesc->supportedDevices());
+        bool mute = shouldMute && curDevices.containsAtLeastOne(devices) && curDevices != devices;
         bool doMute = false;
 
-        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
+        if (mute && !outputDesc->isStrategyMutedByDevice(productStrategy)) {
             doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = true;
-        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
+            outputDesc->setStrategyMutedByDevice(productStrategy, true);
+        } else if (!mute && outputDesc->isStrategyMutedByDevice(productStrategy)) {
             doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = false;
+            outputDesc->setStrategyMutedByDevice(productStrategy, false);
         }
         if (doMute) {
             for (size_t j = 0; j < mOutputs.size(); j++) {
@@ -5272,10 +5165,10 @@
                 if (!desc->supportedDevices().containsAtLeastOne(outputDesc->supportedDevices())) {
                     continue;
                 }
-                ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
-                      mute ? "muting" : "unmuting", i, curDeviceType);
-                setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
-                if (isStrategyActive(desc, (routing_strategy)i)) {
+                ALOGVV("%s() %s (curDevice %s)", __func__,
+                      mute ? "muting" : "unmuting", curDevices.toString().c_str());
+                setStrategyMute(productStrategy, mute, desc, mute ? 0 : delayMs);
+                if (desc->isStrategyActive(productStrategy)) {
                     if (mute) {
                         // FIXME: should not need to double latency if volume could be applied
                         // immediately by the audioflinger mixer. We must account for the delay
@@ -5293,7 +5186,7 @@
 
     // temporary mute output if device selection changes to avoid volume bursts due to
     // different per device volumes
-    if (outputDesc->isActive() && (deviceType != prevDeviceType)) {
+    if (outputDesc->isActive() && (devices != prevDevices)) {
         uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
         // temporary mute duration is conservatively set to 4 times the reported latency
         uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
@@ -5301,13 +5194,13 @@
             muteWaitMs = tempMuteWaitMs;
         }
 
-        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-            if (isStrategyActive(outputDesc, (routing_strategy)i)) {
+        for (const auto &productStrategy : productStrategies) {
+            if (outputDesc->isStrategyActive(productStrategy)) {
                 // make sure that we do not start the temporary mute period too early in case of
                 // delayed device change
-                setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
-                setStrategyMute((routing_strategy)i, false, outputDesc,
-                                delayMs + tempMuteDurationMs, deviceType);
+                setStrategyMute(productStrategy, true, outputDesc, delayMs);
+                setStrategyMute(productStrategy, false, outputDesc, delayMs + tempMuteDurationMs,
+                                devices.types());
             }
         }
     }
@@ -5359,7 +5252,7 @@
 
     // if the outputs are not materially active, there is no need to mute.
     if (requiresMuteCheck) {
-        muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevices.types(), delayMs);
+        muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevices, delayMs);
     } else {
         ALOGV("%s: suppressing checkDeviceMuteStrategies", __func__);
         muteWaitMs = 0;
@@ -5531,36 +5424,6 @@
     return NULL;
 }
 
-sp<DeviceDescriptor> AudioPolicyManager::getDeviceAndMixForAttributes(
-        const audio_attributes_t &attributes, AudioMix **policyMix)
-{
-    // Honor explicit routing requests only if all active clients have a preferred route in which
-    // case the last active client route is used
-    sp<DeviceDescriptor> device =
-        findPreferredDevice(mInputs, attributes.source, mAvailableInputDevices);
-    if (device != nullptr) {
-        return device;
-    }
-
-    sp<DeviceDescriptor> selectedDeviceFromMix =
-           mPolicyMixes.getDeviceAndMixForInputSource(attributes.source, mAvailableInputDevices,
-                                                      policyMix);
-    return (selectedDeviceFromMix != nullptr) ?
-           selectedDeviceFromMix : getDeviceForAttributes(attributes);
-}
-
-sp<DeviceDescriptor> AudioPolicyManager::getDeviceForAttributes(const audio_attributes_t &attributes)
-{
-    audio_devices_t device = mEngine->getDeviceForInputSource(attributes.source);
-    if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
-                strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
-        return mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
-                                                String8(attributes.tags + strlen("addr=")),
-                                                AUDIO_FORMAT_DEFAULT);
-    }
-    return mAvailableInputDevices.getDevice(device, String8(), AUDIO_FORMAT_DEFAULT);
-}
-
 float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
                                         int index,
                                         audio_devices_t device)
@@ -5613,18 +5476,18 @@
     // speaker is part of the select devices
     // - if music is playing, always limit the volume to current music volume,
     // with a minimum threshold at -36dB so that notification is always perceived.
-    const routing_strategy stream_strategy = getStrategy(stream);
     if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
             AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
             AUDIO_DEVICE_OUT_WIRED_HEADSET |
             AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
             AUDIO_DEVICE_OUT_USB_HEADSET |
             AUDIO_DEVICE_OUT_HEARING_AID)) &&
-        ((stream_strategy == STRATEGY_SONIFICATION)
-                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
+        ((stream == AUDIO_STREAM_ALARM || stream == AUDIO_STREAM_RING)
+                || (stream == AUDIO_STREAM_NOTIFICATION)
                 || (stream == AUDIO_STREAM_SYSTEM)
-                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
-                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
+                || ((stream == AUDIO_STREAM_ENFORCED_AUDIBLE) &&
+                    (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
+                     AUDIO_POLICY_FORCE_NONE))) &&
             mVolumeCurves->canBeMuted(stream)) {
         // when the phone is ringing we must consider that music could have been paused just before
         // by the music application and behave as if music was active if the last music track was
@@ -5632,7 +5495,9 @@
         if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
                 mLimitRingtoneVolume) {
             volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
-            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
+            audio_devices_t musicDevice =
+                    mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                                           nullptr, true /*fromCache*/).types();
             float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
                                              mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
                                                                               musicDevice),
@@ -5656,7 +5521,7 @@
                 }
             }
         } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
-                stream_strategy != STRATEGY_SONIFICATION) {
+                (stream != AUDIO_STREAM_ALARM && stream != AUDIO_STREAM_RING)) {
             volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
         }
     }
@@ -5761,18 +5626,16 @@
     }
 }
 
-void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
-                                             bool on,
-                                             const sp<AudioOutputDescriptor>& outputDesc,
-                                             int delayMs,
-                                             audio_devices_t device)
+void AudioPolicyManager::setStrategyMute(product_strategy_t strategy,
+                                         bool on,
+                                         const sp<AudioOutputDescriptor>& outputDesc,
+                                         int delayMs,
+                                         audio_devices_t device)
 {
-    ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
-           strategy, on, outputDesc->getId());
-    for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
-        if (getStrategy((audio_stream_type_t)stream) == strategy) {
-            setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
-        }
+    for (auto stream: mEngine->getStreamTypesForProductStrategy(strategy)) {
+        ALOGVV("%s() stream %d, mute %d, output ID %d", __FUNCTION__, stream, on,
+               outputDesc->getId());
+        setStreamMute(stream, on, outputDesc, delayMs, device);
     }
 }
 
@@ -5814,25 +5677,9 @@
     }
 }
 
-audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
-{
-    // flags to stream type mapping
-    if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
-        return AUDIO_STREAM_ENFORCED_AUDIBLE;
-    }
-    if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
-        return AUDIO_STREAM_BLUETOOTH_SCO;
-    }
-    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
-        return AUDIO_STREAM_TTS;
-    }
-
-    return audio_usage_to_stream_type(attr->usage);
-}
-
 bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
 {
-    // has flags that map to a strategy?
+    // has flags that map to a stream type?
     if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
         return true;
     }
@@ -5863,37 +5710,6 @@
     return true;
 }
 
-bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
-                                          routing_strategy strategy, uint32_t inPastMs,
-                                          nsecs_t sysTime) const
-{
-    if ((sysTime == 0) && (inPastMs != 0)) {
-        sysTime = systemTime();
-    }
-    for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
-        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
-                (STRATEGY_NONE == strategy)) &&
-                outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::isStrategyActiveOnSameModule(const sp<SwAudioOutputDescriptor>& outputDesc,
-                                                      routing_strategy strategy, uint32_t inPastMs,
-                                                      nsecs_t sysTime) const
-{
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-        if (outputDesc->sharesHwModuleWith(desc)
-            && isStrategyActive(desc, strategy, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
 audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
 {
     return mEngine->getForceUse(usage);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index de6d489..73c3b56 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -153,9 +153,15 @@
                                               audio_devices_t device);
 
         // return the strategy corresponding to a given stream type
-        virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
-        // return the strategy corresponding to the given audio attributes
-        virtual routing_strategy getStrategyForAttr(const audio_attributes_t *attr);
+        virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
+        {
+            return streamToStrategy(stream);
+        }
+        product_strategy_t streamToStrategy(audio_stream_type_t stream) const
+        {
+            auto attributes = mEngine->getAttributesForStreamType(stream);
+            return mEngine->getProductStrategyForAttributes(attributes);
+        }
 
         // return the enabled output devices for the given stream type
         virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
@@ -244,13 +250,20 @@
         virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
                     std::vector<audio_format_t> *formats);
 
-        // return the strategy corresponding to a given stream type
-        routing_strategy getStrategy(audio_stream_type_t stream) const;
-
         virtual void setAppState(uid_t uid, app_state_t state);
 
         virtual bool isHapticPlaybackSupported();
 
+        virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+        {
+            return mEngine->listAudioProductStrategies(strategies);
+        }
+
+        virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+        {
+            return mEngine->getProductStrategyForAttributes(aa.getAttributes());
+        }
+
 protected:
         // A constructor that allows more fine-grained control over initialization process,
         // used in automatic tests.
@@ -306,32 +319,6 @@
         void removeOutput(audio_io_handle_t output);
         void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
 
-        // return appropriate device for streams handled by the specified strategy according to current
-        // phone state, connected devices...
-        // if fromCache is true, the device is returned from mDeviceForStrategy[],
-        // otherwise it is determine by current state
-        // (device connected,phone state, force use, a2dp output...)
-        // This allows to:
-        //  1 speed up process when the state is stable (when starting or stopping an output)
-        //  2 access to either current device selection (fromCache == true) or
-        // "future" device selection (fromCache == false) when called from a context
-        //  where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
-        //  before updateDevicesAndOutputs() is called.
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy,
-                                                     bool fromCache)
-        {
-            return getDevicesForStrategy(strategy, fromCache).types();
-        }
-
-        DeviceVector getDevicesForStrategy(routing_strategy strategy, bool fromCache);
-
-        bool isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc, routing_strategy strategy,
-                              uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
-
-        bool isStrategyActiveOnSameModule(const sp<SwAudioOutputDescriptor>& outputDesc,
-                                          routing_strategy strategy, uint32_t inPastMs = 0,
-                                          nsecs_t sysTime = 0) const;
-
         // change the route of the specified output. Returns the number of ms we have slept to
         // allow new routing to take effect in certain cases.
         uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
@@ -350,9 +337,6 @@
         status_t resetInputDevice(audio_io_handle_t input,
                                   audio_patch_handle_t *patchHandle = NULL);
 
-        // select input device corresponding to requested audio source
-        sp<DeviceDescriptor> getDeviceForAttributes(const audio_attributes_t &attributes);
-
         // compute the actual volume for a given stream according to the requested index and a particular
         // device
         virtual float computeVolume(audio_stream_type_t stream,
@@ -373,8 +357,16 @@
         void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
                                 audio_devices_t device, int delayMs = 0, bool force = false);
 
-        // Mute or unmute all streams handled by the specified strategy on the specified output
-        void setStrategyMute(routing_strategy strategy,
+        /**
+         * @brief setStrategyMute Mute or unmute all active clients on the considered output
+         * following the given strategy.
+         * @param strategy to be considered
+         * @param on true for mute, false for unmute
+         * @param outputDesc to be considered
+         * @param delayMs
+         * @param device
+         */
+        void setStrategyMute(product_strategy_t strategy,
                              bool on,
                              const sp<AudioOutputDescriptor>& outputDesc,
                              int delayMs = 0,
@@ -420,26 +412,28 @@
         // A2DP suspend status is rechecked.
         void checkForDeviceAndOutputChanges(std::function<bool()> onOutputsChecked = nullptr);
 
-        // checks and if necessary changes outputs used for all strategies.
-        // must be called every time a condition that affects the output choice for a given strategy
-        // changes: connected device, phone state, force use...
-        // Must be called before updateDevicesAndOutputs()
-        void checkOutputForStrategy(routing_strategy strategy);
+        /**
+         * @brief checkOutputForAttributes checks and if necessary changes outputs used for the
+         * given audio attributes.
+         * must be called every time a condition that affects the output choice for a given
+         * attributes changes: connected device, phone state, force use...
+         * Must be called before updateDevicesAndOutputs()
+         * @param attr to be considered
+         */
+        void checkOutputForAttributes(const audio_attributes_t &attr);
 
-        // Same as checkOutputForStrategy() but for a all strategies in order of priority
+        bool followsSameRouting(const audio_attributes_t &lAttr,
+                                const audio_attributes_t &rAttr) const;
+
+        /**
+         * @brief checkOutputForAllStrategies Same as @see checkOutputForAttributes()
+         *      but for a all product strategies in order of priority
+         */
         void checkOutputForAllStrategies();
 
         // manages A2DP output suspend/restore according to phone state and BT SCO usage
         void checkA2dpSuspend();
 
-        template <class IoDescriptor, class Filter>
-        sp<DeviceDescriptor> findPreferredDevice(IoDescriptor& desc, Filter filter,
-                                                bool& active, const DeviceVector& devices);
-
-        template <class IoCollection, class Filter>
-        sp<DeviceDescriptor> findPreferredDevice(IoCollection& ioCollection, Filter filter,
-                                                const DeviceVector& devices);
-
         // selects the most appropriate device on output for current state
         // must be called every time a condition that affects the device choice for a given output is
         // changed: connected device, phone state, force use, output start, output stop..
@@ -447,11 +441,14 @@
         DeviceVector getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
                                          bool fromCache);
 
-        // updates cache of device used by all strategies (mDeviceForStrategy[])
-        // must be called every time a condition that affects the device choice for a given strategy is
-        // changed: connected device, phone state, force use...
-        // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
-         // Must be called after checkOutputForAllStrategies()
+        /**
+         * @brief updateDevicesAndOutputs: updates cache of devices of the engine
+         * must be called every time a condition that affects the device choice is changed:
+         * connected device, phone state, force use...
+         * cached values are used by getOutputDevicesForStream()/getDevicesForAttributes if
+         * parameter fromCache is true.
+         * Must be called after checkOutputForAllStrategies()
+         */
         void updateDevicesAndOutputs();
 
         // selects the most appropriate device on input for current state
@@ -470,13 +467,19 @@
         SortedVector<audio_io_handle_t> getOutputsForDevices(
                 const DeviceVector &devices, const SwAudioOutputCollection& openOutputs);
 
-        // mute/unmute strategies using an incompatible device combination
-        // if muting, wait for the audio in pcm buffer to be drained before proceeding
-        // if unmuting, unmute only after the specified delay
-        // Returns the number of ms waited
-        virtual uint32_t  checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
-                                                    audio_devices_t prevDeviceType,
-                                                    uint32_t delayMs);
+        /**
+         * @brief checkDeviceMuteStrategies mute/unmute strategies
+         *      using an incompatible device combination.
+         *      if muting, wait for the audio in pcm buffer to be drained before proceeding
+         *      if unmuting, unmute only after the specified delay
+         * @param outputDesc
+         * @param prevDevice
+         * @param delayMs
+         * @return the number of ms waited
+         */
+        virtual uint32_t checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
+                                                   const DeviceVector &prevDevices,
+                                                   uint32_t delayMs);
 
         audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
                                        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
@@ -570,15 +573,22 @@
 
         void clearAudioPatches(uid_t uid);
         void clearSessionRoutes(uid_t uid);
-        void checkStrategyRoute(routing_strategy strategy, audio_io_handle_t ouptutToSkip);
+
+        /**
+         * @brief checkStrategyRoute: when an output is beeing rerouted, reconsider each output
+         * that may host a strategy playing on the considered output.
+         * @param ps product strategy that initiated the rerouting
+         * @param ouptutToSkip output that initiated the rerouting
+         */
+        void checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip);
 
         status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
 
         status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
         status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
 
-        sp<SourceClientDescriptor> getSourceForStrategyOnOutput(audio_io_handle_t output,
-                                                               routing_strategy strategy);
+        sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
+                                                                  const audio_attributes_t &attr);
 
         void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
 
@@ -606,15 +616,6 @@
 
         bool    mLimitRingtoneVolume;        // limit ringtone volume to music volume if headset connected
 
-        /**
-         * @brief mDevicesForStrategy vector of devices that are assigned for a given strategy.
-         * Note: in case of removal of device (@see setDeviceConnectionState), the device descriptor
-         * will be removed from the @see mAvailableOutputDevices or @see mAvailableInputDevices
-         * but the devices for strategies will be reevaluated within the
-         * @see setDeviceConnectionState function.
-         */
-        DeviceVector mDevicesForStrategy[NUM_STRATEGIES];
-
         float   mLastVoiceVolume;            // last voice volume value sent to audio HAL
         bool    mA2dpSuspended;  // true if A2DP output is suspended
 
@@ -709,7 +710,8 @@
                 uid_t uid,
                 const audio_config_t *config,
                 audio_output_flags_t *flags,
-                audio_port_handle_t *selectedDeviceId);
+                audio_port_handle_t *selectedDeviceId,
+                bool *isRequestedDeviceForExclusiveUse);
         // internal method to return the output handle for the given device and format
         audio_io_handle_t getOutputForDevices(
                 const DeviceVector &devices,
@@ -717,16 +719,26 @@
                 audio_stream_type_t stream,
                 const audio_config_t *config,
                 audio_output_flags_t *flags);
-        // internal method to return the input handle for the given device and format
+
+        /**
+         * @brief getInputForDevice selects an input handle for a given input device and
+         * requester context
+         * @param device to be used by requester, selected by policy mix rules or engine
+         * @param session requester session id
+         * @param uid requester uid
+         * @param attributes requester audio attributes (e.g. input source and tags matter)
+         * @param config requester audio configuration (e.g. sample rate, format, channel mask).
+         * @param flags requester input flags
+         * @param policyMix may be null, policy rules to be followed by the requester
+         * @return input io handle aka unique input identifier selected for this device.
+         */
         audio_io_handle_t getInputForDevice(const sp<DeviceDescriptor> &device,
                 audio_session_t session,
-                audio_source_t inputSource,
+                const audio_attributes_t &attributes,
                 const audio_config_base_t *config,
                 audio_input_flags_t flags,
                 AudioMix *policyMix);
 
-        // internal function to derive a stream type value from audio attributes
-        audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
         // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
         // returns 0 if no mute/unmute event happened, the largest latency of the device where
         //   the mute/unmute happened
@@ -734,11 +746,6 @@
         uint32_t setBeaconMute(bool mute);
         bool     isValidAttributes(const audio_attributes_t *paa);
 
-        // select input device corresponding to requested audio source and return associated policy
-        // mix if any. Calls getDeviceForInputSource().
-        sp<DeviceDescriptor> getDeviceAndMixForAttributes(const audio_attributes_t &attributes,
-                                                          AudioMix **policyMix = NULL);
-
         // Called by setDeviceConnectionState().
         status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
                                              audio_policy_dev_state_t state,
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 919a90d..4947714 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -23,7 +23,6 @@
 #include <memory>
 #include <cutils/misc.h>
 #include <media/AudioEffect.h>
-#include <media/AudioPolicyHelper.h>
 #include <media/EffectsConfig.h>
 #include <mediautils/ServiceUtilities.h>
 #include <system/audio.h>
@@ -398,8 +397,7 @@
         ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
         return BAD_VALUE;
     }
-
-    audio_stream_type_t stream = audio_usage_to_stream_type(usage);
+    audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
 
     if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
         ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 45fb174..7768ea3 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -19,7 +19,6 @@
 
 #include "AudioPolicyService.h"
 #include "TypeConverter.h"
-#include <media/AudioPolicyHelper.h>
 #include <media/MediaAnalyticsItem.h>
 #include <mediautils/ServiceUtilities.h>
 #include <utils/Log.h>
@@ -703,11 +702,12 @@
 uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
-        return 0;
+        return PRODUCT_STRATEGY_NONE;
     }
     if (mAudioPolicyManager == NULL) {
-        return 0;
+        return PRODUCT_STRATEGY_NONE;
     }
+    // DO NOT LOCK, may be called from AudioFlinger with lock held, reaching deadlock
     AutoCallerClear acc;
     return mAudioPolicyManager->getStrategyForStream(stream);
 }
@@ -1186,4 +1186,22 @@
     return mAudioPolicyManager->isHapticPlaybackSupported();
 }
 
+status_t AudioPolicyService::listAudioProductStrategies(AudioProductStrategyVector &strategies)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->listAudioProductStrategies(strategies);
+}
+
+product_strategy_t AudioPolicyService::getProductStrategyFromAudioAttributes(
+        const AudioAttributes &aa)
+{
+    if (mAudioPolicyManager == NULL) {
+        return PRODUCT_STRATEGY_NONE;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->getProductStrategyFromAudioAttributes(aa);
+}
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c073b7c..ee293a7 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -229,6 +229,9 @@
 
     virtual bool     isHapticPlaybackSupported();
 
+    virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+    virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa);
+
             status_t doStopOutput(audio_port_handle_t portId);
             void doReleaseOutput(audio_port_handle_t portId);
 
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
index e4fba0f..97be44c 100644
--- a/services/audiopolicy/tests/Android.mk
+++ b/services/audiopolicy/tests/Android.mk
@@ -4,8 +4,6 @@
 
 LOCAL_C_INCLUDES := \
   frameworks/av/services/audiopolicy \
-  frameworks/av/services/audiopolicy/common/include \
-  frameworks/av/services/audiopolicy/engine/interface \
   $(call include-path-for, audio-utils) \
 
 LOCAL_SHARED_LIBRARIES := \
@@ -18,6 +16,10 @@
 LOCAL_STATIC_LIBRARIES := \
   libaudiopolicycomponents \
 
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers
+
 LOCAL_SRC_FILES := \
   audiopolicymanager_tests.cpp \
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c3113bf..ee8d7e1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -49,6 +49,7 @@
 #include <hardware/hardware.h>
 #include "hidl/HidlCameraService.h"
 #include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
 #include <memunreachable/memunreachable.h>
 #include <media/AudioSystem.h>
 #include <media/IMediaHTTPService.h>
@@ -226,7 +227,7 @@
     Mutex::Autolock lock(mStatusListenerLock);
 
     for (auto& i : mListenerList) {
-        i->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
+        i.second->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
     }
 }
 
@@ -1287,6 +1288,18 @@
     return ret;
 }
 
+bool CameraService::shouldRejectHiddenCameraConnection(const String8 & cameraId) {
+    // If the thread serving this call is not a hwbinder thread and the caller
+    // isn't the cameraserver itself, and the camera id being requested is to be
+    // publically hidden, we should reject the connection.
+    if (!hardware::IPCThreadState::self()->isServingCall() &&
+            CameraThreadState::getCallingPid() != getpid() &&
+            mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+        return true;
+    }
+    return false;
+}
+
 Status CameraService::connectDevice(
         const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
         const String16& cameraId,
@@ -1299,6 +1312,7 @@
     Status ret = Status::ok();
     String8 id = String8(cameraId);
     sp<CameraDeviceClient> client = nullptr;
+
     ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
             /*api1CameraId*/-1,
             CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
@@ -1330,6 +1344,14 @@
             (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
             static_cast<int>(effectiveApiLevel));
 
+    if (shouldRejectHiddenCameraConnection(cameraId)) {
+        ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
+              cameraId.c_str());
+        return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
+                                "No camera device with ID \"%s\" currently available",
+                                cameraId.string());
+
+    }
     sp<CLIENT> client = nullptr;
     {
         // Acquire mServiceLock and prevent other clients from connecting
@@ -1635,6 +1657,14 @@
 Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
         /*out*/
         std::vector<hardware::CameraStatus> *cameraStatuses) {
+    return addListenerHelper(listener, cameraStatuses);
+}
+
+Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener,
+        /*out*/
+        std::vector<hardware::CameraStatus> *cameraStatuses,
+        bool isVendorListener) {
+
     ATRACE_CALL();
 
     ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
@@ -1649,20 +1679,26 @@
     {
         Mutex::Autolock lock(mStatusListenerLock);
         for (auto& it : mListenerList) {
-            if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
+            if (IInterface::asBinder(it.second) == IInterface::asBinder(listener)) {
                 ALOGW("%s: Tried to add listener %p which was already subscribed",
                       __FUNCTION__, listener.get());
                 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
             }
         }
 
-        mListenerList.push_back(listener);
+        mListenerList.emplace_back(isVendorListener, listener);
     }
 
     /* Collect current devices and status */
     {
         Mutex::Autolock lock(mCameraStatesLock);
         for (auto& i : mCameraStates) {
+            if (!isVendorListener &&
+                mCameraProviderManager->isPublicallyHiddenSecureCamera(i.first.c_str())) {
+                ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
+                      i.first.c_str(), CameraThreadState::getCallingPid());
+                continue;
+            }
             cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
         }
     }
@@ -1697,7 +1733,7 @@
     {
         Mutex::Autolock lock(mStatusListenerLock);
         for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
-            if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
+            if (IInterface::asBinder(it->second) == IInterface::asBinder(listener)) {
                 mListenerList.erase(it);
                 return Status::ok();
             }
@@ -3033,7 +3069,13 @@
             Mutex::Autolock lock(mStatusListenerLock);
 
             for (auto& listener : mListenerList) {
-                listener->onStatusChanged(mapToInterface(status), String16(cameraId));
+                if (!listener.first &&
+                    mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+                    ALOGV("Skipping camera discovery callback for system-only camera %s",
+                          cameraId.c_str());
+                    continue;
+                }
+                listener.second->onStatusChanged(mapToInterface(status), String16(cameraId));
             }
         });
 }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a296198..3af52fa 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -173,6 +173,10 @@
 
     virtual status_t    shellCommand(int in, int out, int err, const Vector<String16>& args);
 
+    binder::Status      addListenerHelper(const sp<hardware::ICameraServiceListener>& listener,
+            /*out*/
+            std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false);
+
     /////////////////////////////////////////////////////////////////////
     // Client functionality
 
@@ -615,6 +619,10 @@
         sp<BasicClient>* client,
         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
 
+    // Should an operation attempt on a cameraId be rejected, if the camera id is
+    // advertised as a publically hidden secure camera, by the camera HAL ?
+    bool shouldRejectHiddenCameraConnection(const String8 & cameraId);
+
     // Single implementation shared between the various connect calls
     template<class CALLBACK, class CLIENT>
     binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
@@ -781,7 +789,8 @@
     sp<CameraProviderManager> mCameraProviderManager;
 
     // Guarded by mStatusListenerMutex
-    std::vector<sp<hardware::ICameraServiceListener>> mListenerList;
+    std::vector<std::pair<bool, sp<hardware::ICameraServiceListener>>> mListenerList;
+
     Mutex       mStatusListenerLock;
 
     /**
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 7c32e84..8ee3298 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -499,6 +499,17 @@
     }
 }
 
+bool CameraProviderManager::ProviderInfo::DeviceInfo3::isPublicallyHiddenSecureCamera() {
+    camera_metadata_entry_t entryCap;
+    entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    if (entryCap.count != 1) {
+        // Do NOT hide this camera device if the capabilities specify anything more
+        // than ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA.
+        return false;
+    }
+    return entryCap.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+}
+
 void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedSizes(
         const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
         std::vector<std::tuple<size_t, size_t>> *sizes/*out*/) {
@@ -643,7 +654,7 @@
     bool isDepthExclusivePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
             depthExclTag) != (chTags.data.i32 + chTags.count);
     bool isDepthSizePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
-            depthExclTag) != (chTags.data.i32 + chTags.count);
+            depthSizesTag) != (chTags.data.i32 + chTags.count);
     if (!(isDepthExclusivePresent && isDepthSizePresent)) {
         // No depth support, nothing more to do.
         return OK;
@@ -671,7 +682,6 @@
     getSupportedDynamicDepthSizes(supportedBlobSizes, supportedDepthSizes,
             &supportedDynamicDepthSizes, &internalDepthSizes);
     if (supportedDynamicDepthSizes.empty()) {
-        ALOGE("%s: No dynamic depth size matched!", __func__);
         // Nothing more to do.
         return OK;
     }
@@ -877,6 +887,16 @@
     return deviceInfo->mIsLogicalCamera;
 }
 
+bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) {
+    std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+    auto deviceInfo = findDeviceInfoLocked(id);
+    if (deviceInfo == nullptr) {
+        return false;
+    }
+    return deviceInfo->mIsPublicallyHiddenSecureCamera;
+}
+
 bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
     for (auto& provider : mProviders) {
         for (auto& deviceInfo : provider->mDevices) {
@@ -1704,17 +1724,19 @@
                 __FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
         return;
     }
+
+    mIsPublicallyHiddenSecureCamera = isPublicallyHiddenSecureCamera();
+
     status_t res = fixupMonochromeTags();
     if (OK != res) {
         ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
                 __FUNCTION__, strerror(-res), res);
         return;
     }
-    res = addDynamicDepthTags();
-    if (OK != res) {
-        ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-res),
-                res);
-        return;
+    auto stat = addDynamicDepthTags();
+    if (OK != stat) {
+        ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+                stat);
     }
     camera_metadata_entry flashAvailable =
             mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
@@ -1726,6 +1748,7 @@
     }
 
     queryPhysicalCameraIds();
+
     // Get physical camera characteristics if applicable
     auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
     if (!castResult.isOk()) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index fbd7d2e..18869f5 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -264,6 +264,7 @@
      */
     bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);
 
+    bool isPublicallyHiddenSecureCamera(const std::string& id);
     bool isHiddenPhysicalCamera(const std::string& cameraId);
 
     static const float kDepthARTolerance;
@@ -354,6 +355,7 @@
             std::vector<std::string> mPhysicalIds;
             hardware::CameraInfo mInfo;
             sp<IBase> mSavedInterface;
+            bool mIsPublicallyHiddenSecureCamera = false;
 
             const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
 
@@ -471,6 +473,7 @@
             CameraMetadata mCameraCharacteristics;
             std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics;
             void queryPhysicalCameraIds();
+            bool isPublicallyHiddenSecureCamera();
             status_t fixupMonochromeTags();
             status_t addDynamicDepthTags();
             static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 48f1d37..74cfe42 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -182,7 +182,8 @@
         }
     }
     std::vector<hardware::CameraStatus> cameraStatusAndIds{};
-    binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
+    binder::Status serviceRet =
+        mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
     HStatus status = HStatus::NO_ERROR;
     if (!serviceRet.isOk()) {
       ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index ae832ba..4f3ac1b 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -51,7 +51,6 @@
 #include <utils/Timers.h>
 #include <utils/Vector.h>
 
-#include <media/AudioPolicyHelper.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>