audiopolicy: engineconfigurable: Migrate to XML criteria and criterion type defintion

Test: make
Change-Id: Ia7eb6b86dffb31bcb4191f5e265e85135934dc36
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index baaefd2..7506734 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -7,10 +7,10 @@
 #
 ################################################################################################
 
-ifeq (1, 0)
-
 LOCAL_PATH := $(call my-dir)
 
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+
 PFW_CORE := external/parameter-framework
 BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
 PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
@@ -25,7 +25,8 @@
 LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework
 LOCAL_SRC_FILES := $(LOCAL_MODULE).in
 
 AUDIO_PATTERN = @TUNING_ALLOWED@
@@ -46,7 +47,8 @@
 LOCAL_MODULE := PolicyClass.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
 LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
@@ -54,12 +56,12 @@
 LOCAL_MODULE := 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 \
+    libpolicy-subsystem
 
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
 LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
@@ -67,7 +69,8 @@
 LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
 LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
@@ -76,14 +79,15 @@
 LOCAL_MODULE := parameter-framework.policy
 LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
+LOCAL_REQUIRED_MODULES := \
         PolicyClass.xml \
         PolicySubsystem.xml \
         ParameterFrameworkConfigurationPolicy.xml
 
 ifeq ($(pfw_rebuild_settings),true)
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
 PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
 PFW_EDD_FILES := \
         $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
@@ -107,18 +111,23 @@
 include $(BUILD_PREBUILT)
 endif # pfw_rebuild_settings
 
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 0)
+
 ######### Policy PFW Settings - No Output #########
+ifeq (0, 1)
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := parameter-framework.policy.no-output
 LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
+LOCAL_REQUIRED_MODULES := \
         PolicyClass.xml \
         PolicySubsystem.xml \
         ParameterFrameworkConfigurationPolicy.xml
 
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
 PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
 PFW_EDD_FILES := \
         $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
@@ -128,19 +137,22 @@
         $(LOCAL_PATH)/Settings/volumes.pfw
 
 include $(BUILD_PFW_SETTINGS)
-
+endif # ifeq (0, 1)
 ######### Policy PFW Settings - No Input #########
+ifeq (0, 1)
+
 include $(CLEAR_VARS)
 LOCAL_MODULE := parameter-framework.policy.no-input
 LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
 LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
+LOCAL_REQUIRED_MODULES := \
         PolicyClass.xml \
         PolicySubsystem.xml \
         ParameterFrameworkConfigurationPolicy.xml
 
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
 PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
 PFW_EDD_FILES := \
         $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
index 917d4a7..f923610 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
@@ -9,7 +9,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -37,7 +37,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -65,7 +65,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -93,7 +93,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -121,7 +121,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -149,7 +149,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -177,7 +177,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -205,7 +205,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
@@ -233,7 +233,7 @@
 				bluetooth_sco = 0
 				bluetooth_sco_headset = 0
 				bluetooth_sco_carkit = 0
-				bluetooth_a2dp = 0>
+				bluetooth_a2dp = 0
 				bluetooth_a2dp_headphones = 0
 				bluetooth_a2dp_speaker = 0
 				hdmi = 0
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 461e44a..f410773 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
@@ -37,6 +37,10 @@
             <BitParameter Name="speaker_safe" Size="1" Pos="22"/>
             <BitParameter Name="ip" Size="1" Pos="23"/>
             <BitParameter Name="bus" Size="1" Pos="24"/>
+            <BitParameter Name="proxy" Size="1" Pos="25"/>
+            <BitParameter Name="usb_headset" Size="1" Pos="26"/>
+            <BitParameter Name="hearing_aid" Size="1" Pos="27"/>
+            <BitParameter Name="echo_canceller" Size="1" Pos="28"/>
             <BitParameter Name="stub" Size="1" Pos="30"/>
         </BitParameterBlock>
     </ComponentType>
@@ -67,6 +71,9 @@
             <BitParameter Name="loopback" Size="1" Pos="18"/>
             <BitParameter Name="ip" Size="1" Pos="19"/>
             <BitParameter Name="bus" Size="1" Pos="20"/>
+            <BitParameter Name="proxy" Size="1" Pos="21"/>
+            <BitParameter Name="usb_headset" Size="1" Pos="22"/>
+            <BitParameter Name="bluetooth_ble" Size="1" Pos="23"/>
             <BitParameter Name="stub" Size="1" Pos="30"/>
         </BitParameterBlock>
     </ComponentType>
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
new file mode 100644
index 0000000..d8f29dc
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -0,0 +1,31 @@
+// 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.
+
+python_binary_host {
+    name: "buildPolicyCriterionTypes.py",
+    owner: "renault",
+    main: "buildPolicyCriterionTypes.py",
+    srcs: [
+        "buildPolicyCriterionTypes.py",
+    ],
+    version: {
+        py2: {
+            enabled: true,
+        },
+        py3: {
+            enabled: false,
+        },
+    },
+}
+
diff --git a/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
new file mode 100755
index 0000000..0fb70a6
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
@@ -0,0 +1,243 @@
+#!/usr/bin/python
+
+#
+# Copyright 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.
+#
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+import xml.etree.ElementInclude as EI
+import xml.dom.minidom as MINIDOM
+from collections import OrderedDict
+
+#
+# Helper script that helps to feed at build time the XML criterion types file used by
+# the engineconfigurable to start the parameter-framework.
+# It prevents to fill them manually and avoid divergences with android.
+#
+# The Device Types criterion types are fed from audio-base.h file with the option
+#           --androidaudiobaseheader <path/to/android/audio/base/file/audio-base.h>
+#
+# The Device Addresses criterion types are fed from the audio policy configuration file
+# in order to discover all the devices for which the address matter.
+#           --audiopolicyconfigurationfile <path/to/audio_policy_configuration.xml>
+#
+# The reference file of criterion types must also be set as an input of the script:
+#           --criteriontypes <path/to/criterion/file/audio_criterion_types.xml.in>
+#
+# At last, the output of the script shall be set also:
+#           --outputfile <path/to/out/vendor/etc/audio_criterion_types.xml>
+#
+
+def parseArgs():
+    argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+        audio criterion type file generator.\n\
+        Exit with the number of (recoverable or not) error that occured.")
+    argparser.add_argument('--androidaudiobaseheader',
+            help="Android Audio Base C header file, Mandatory.",
+            metavar="ANDROID_AUDIO_BASE_HEADER",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--audiopolicyconfigurationfile',
+            help="Android Audio Policy Configuration file, Mandatory.",
+            metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--criteriontypes',
+            help="Criterion types XML base file, in \
+            '<criterion_types> \
+                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/>' \
+        format. Mandatory.",
+            metavar="CRITERION_TYPE_FILE",
+            type=argparse.FileType('r'),
+            required=True)
+    argparser.add_argument('--outputfile',
+            help="Criterion types outputfile file. Mandatory.",
+            metavar="CRITERION_TYPE_OUTPUT_FILE",
+            type=argparse.FileType('w'),
+            required=True)
+    argparser.add_argument('--verbose',
+            action='store_true')
+
+    return argparser.parse_args()
+
+
+def generateXmlCriterionTypesFile(criterionTypes, addressCriteria, criterionTypesFile, outputFile):
+
+    logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
+    criterion_types_in_tree = ET.parse(criterionTypesFile)
+
+    criterion_types_root = criterion_types_in_tree.getroot()
+
+    for criterion_name, values_dict in criterionTypes.items():
+        for criterion_type in criterion_types_root.findall('criterion_type'):
+            if criterion_type.get('name') == criterion_name:
+                values_node = ET.SubElement(criterion_type, "values")
+                ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
+                for key, value in ordered_values.items():
+                    value_node = ET.SubElement(values_node, "value")
+                    value_node.set('numerical', str(value))
+                    value_node.set('literal', key)
+
+    if addressCriteria:
+        for criterion_name, values_list in addressCriteria.items():
+            for criterion_type in criterion_types_root.findall('criterion_type'):
+                if criterion_type.get('name') == criterion_name:
+                    values_node = ET.SubElement(criterion_type, "values")
+                    index = 0
+                    for value in values_list:
+                        value_node = ET.SubElement(values_node, "value", literal=value)
+                        value_node.set('numerical', str(1 << index))
+                        index += 1
+
+    xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
+    reparsed = MINIDOM.parseString(xmlstr)
+    prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
+    prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
+    outputFile.write(prettyXmlStr.encode('utf-8'))
+
+def capitalizeLine(line):
+    return ' '.join((w.capitalize() for w in line.split(' ')))
+
+
+#
+# Parse the audio policy configuration file and output a dictionary of device criteria addresses
+#
+def parseAndroidAudioPolicyConfigurationFile(audiopolicyconfigurationfile):
+
+    logging.info("Checking Audio Policy Configuration file {}".format(audiopolicyconfigurationfile))
+    #
+    # extract all devices addresses from audio policy configuration file
+    #
+    address_criteria_mapping_table = {
+        'sink' : "OutputDevicesAddressesType",
+        'source' : "InputDevicesAddressesType" }
+
+    address_criteria = {
+        'OutputDevicesAddressesType' : [],
+        'InputDevicesAddressesType' : [] }
+
+    oldWorkingDir = os.getcwd()
+    print "Current working directory %s" % oldWorkingDir
+
+    newDir = os.path.join(oldWorkingDir , audiopolicyconfigurationfile.name)
+
+    policy_in_tree = ET.parse(audiopolicyconfigurationfile)
+    os.chdir(os.path.dirname(os.path.normpath(newDir)))
+
+    print "new working directory %s" % os.getcwd()
+
+    policy_root = policy_in_tree.getroot()
+    EI.include(policy_root)
+
+    os.chdir(oldWorkingDir)
+
+    for device in policy_root.iter('devicePort'):
+        for key in address_criteria_mapping_table.keys():
+            if device.get('role') == key and device.get('address') :
+                logging.info("{}: <{}>".format(key, device.get('address')))
+                address_criteria[address_criteria_mapping_table[key]].append(device.get('address'))
+
+    for criteria in address_criteria:
+        values = ','.join(address_criteria[criteria])
+        logging.info("{}: <{}>".format(criteria, values))
+
+    return address_criteria
+
+#
+# Parse the audio-base.h file and output a dictionary of android dependent criterion types:
+#   -Android Mode
+#   -Output devices type
+#   -Input devices type
+#
+def parseAndroidAudioFile(androidaudiobaseheaderFile):
+    #
+    # Adaptation table between Android Enumeration prefix and Audio PFW Criterion type names
+    #
+    criterion_mapping_table = {
+        'AUDIO_MODE' : "AndroidModeType",
+        'AUDIO_DEVICE_OUT' : "OutputDevicesMaskType",
+        'AUDIO_DEVICE_IN' : "InputDevicesMaskType"}
+
+    all_criteria = {
+        'AndroidModeType' : {},
+        'OutputDevicesMaskType' : {},
+        'InputDevicesMaskType' : {} }
+
+    #
+    # _CNT, _MAX, _ALL and _NONE are prohibited values as ther are just helpers for enum users.
+    #
+    ignored_values = [ 'CNT', 'MAX', 'ALL', 'NONE' ]
+
+    criteria_pattern = re.compile(
+        r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))\_" \
+        r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
+        r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")
+
+    logging.info("Checking Android Header file {}".format(androidaudiobaseheaderFile))
+
+    for line_number, line in enumerate(androidaudiobaseheaderFile):
+        match = criteria_pattern.match(line)
+        if match:
+            logging.debug("The following line is VALID: {}:{}\n{}".format(
+                androidaudiobaseheaderFile.name, line_number, line))
+
+            criterion_name = criterion_mapping_table[match.groupdict()['type']]
+            literal = ''.join((w.capitalize() for w in match.groupdict()['literal'].split('_')))
+            numerical_value = match.groupdict()['values']
+
+            # for AUDIO_DEVICE_IN: need to remove sign bit
+            if criterion_name == "InputDevicesMaskType":
+                numerical_value = str(int(numerical_value, 0) & ~2147483648)
+
+            # Remove duplicated numerical values
+            if int(numerical_value, 0) in all_criteria[criterion_name].values():
+                logging.info("criterion {} duplicated values:".format(criterion_name))
+                logging.info("{}:{}".format(numerical_value, literal))
+                logging.info("KEEPING LATEST")
+                for key in all_criteria[criterion_name].keys():
+                    if all_criteria[criterion_name][key] == int(numerical_value, 0):
+                        del all_criteria[criterion_name][key]
+
+            all_criteria[criterion_name][literal] = int(numerical_value, 0)
+
+            logging.debug("type:{},".format(criterion_name))
+            logging.debug("iteral:{},".format(literal))
+            logging.debug("values:{}.".format(numerical_value))
+
+    return all_criteria
+
+
+def main():
+    logging.root.setLevel(logging.INFO)
+    args = parseArgs()
+
+    all_criteria = parseAndroidAudioFile(args.androidaudiobaseheader)
+
+    address_criteria = parseAndroidAudioPolicyConfigurationFile(args.audiopolicyconfigurationfile)
+
+    criterion_types = args.criteriontypes
+
+    generateXmlCriterionTypesFile(all_criteria, address_criteria, criterion_types, args.outputfile)
+
+# If this file is directly executed
+if __name__ == "__main__":
+    exit(main())
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
new file mode 100644
index 0000000..4814376
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
@@ -0,0 +1,24 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): MY_ANDROID_AUDIO_BASE_HEADER_FILE := $(ANDROID_AUDIO_BASE_HEADER_FILE)
+$(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)
+
+	"$(MY_CRITERION_TOOL)" \
+		--androidaudiobaseheader "$(MY_ANDROID_AUDIO_BASE_HEADER_FILE)" \
+		--audiopolicyconfigurationfile "$(MY_AUDIO_POLICY_CONFIGURATION_FILE)" \
+		--criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
+		--outputfile "$(@)"
+
+# Clear variables for further use
+CRITERION_TYPES_FILE :=
+ANDROID_AUDIO_BASE_HEADER_FILE :=
+AUDIO_POLICY_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
index b128a38..d19a364 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
@@ -1,5 +1,8 @@
 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
 ##################################################################
@@ -10,12 +13,22 @@
     $(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
+LOCAL_SRC_FILES:= \
+    ParameterManagerWrapper.cpp \
+    ParameterManagerWrapperConfig.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libparameter \
-    libmedia_helper
+    libmedia_helper \
+    libicuuc \
+    libxml2
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
@@ -31,11 +44,35 @@
 # CONFIGURATION FILE
 ##################################################################
 
-# specific management of audio_policy_criteria.conf
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+
 include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_criteria.conf
+LOCAL_MODULE := policy_wrapper_configuration.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_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 f8174f8..fc6c1e4 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include "ParameterManagerWrapper.h"
-#include "audio_policy_criteria_conf.h"
+#include "ParameterManagerWrapperConfig.h"
 #include <ParameterMgrPlatformConnector.h>
 #include <SelectionCriterionTypeInterface.h>
 #include <SelectionCriterionInterface.h>
@@ -38,6 +38,7 @@
 using std::string;
 using std::map;
 using std::vector;
+using CriterionTypes = std::map<std::string, ISelectionCriterionTypeInterface *>;
 
 /// PFW related definitions
 // Logger
@@ -65,6 +66,27 @@
 const char *const ParameterManagerWrapper::mPolicyPfwDefaultConfFileName =
     "/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
 
+static const char *const gInputDeviceCriterionName = "AvailableInputDevices";
+static const char *const gOutputDeviceCriterionName = "AvailableOutputDevices";
+static const char *const gPhoneStateCriterionName = "TelephonyMode";
+static const char *const gOutputDeviceAddressCriterionName = "AvailableOutputDevicesAddresses";
+static const char *const gInputDeviceAddressCriterionName = "AvailableInputDevicesAddresses";
+
+/**
+ * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
+ */
+static const char *const gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
+{
+    [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] =        "ForceUseForCommunication",
+    [AUDIO_POLICY_FORCE_FOR_MEDIA] =                "ForceUseForMedia",
+    [AUDIO_POLICY_FORCE_FOR_RECORD] =               "ForceUseForRecord",
+    [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
+    [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
+    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
+    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround",
+    [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] =      "ForceUseForVibrateRinging"
+};
+
 template <>
 struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionInterface> {};
 template <>
@@ -79,15 +101,64 @@
     // Logger
     mPfwConnector->setLogger(mPfwConnectorLogger);
 
-    // Load criteria file
-    if ((loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaVendorConfFilePath) != NO_ERROR) &&
-        (loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaConfFilePath) != NO_ERROR)) {
-        ALOGE("%s: Neither vendor conf file (%s) nor system conf file (%s) could be found",
-              __FUNCTION__, gAudioPolicyCriteriaVendorConfFilePath,
-              gAudioPolicyCriteriaConfFilePath);
+    status_t loadResult = loadConfig();
+    if (loadResult < 0) {
+        ALOGE("Policy Wrapper configuration is partially invalid.");
     }
 }
 
+status_t ParameterManagerWrapper::loadConfig()
+{
+    auto result = wrapper_config::parse();
+    if (result.parsedConfig == nullptr) {
+        return -ENOENT;
+    }
+    ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+
+    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 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);
+        }
+        criterionTypes[criterionType.name] = criterionTypePfw;
+    }
+
+    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;
+}
+
 ParameterManagerWrapper::~ParameterManagerWrapper()
 {
     // Unset logger
@@ -111,112 +182,6 @@
     return NO_ERROR;
 }
 
-
-void ParameterManagerWrapper::addCriterionType(const string &typeName, bool isInclusive)
-{
-    ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) == mPolicyCriterionTypes.end(),
-                      "CriterionType %s already added", typeName.c_str());
-    ALOGD("%s: Adding new criterionType %s", __FUNCTION__, typeName.c_str());
-
-    mPolicyCriterionTypes[typeName] = mPfwConnector->createSelectionCriterionType(isInclusive);
-}
-
-void ParameterManagerWrapper::addCriterionTypeValuePair(
-    const string &typeName,
-    uint32_t numericValue,
-    const string &literalValue)
-{
-    ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) != mPolicyCriterionTypes.end(),
-                      "CriterionType %s not found", typeName.c_str());
-    ALOGV("%s: Adding new value pair (%d,%s) for criterionType %s", __FUNCTION__,
-          numericValue, literalValue.c_str(), typeName.c_str());
-    ISelectionCriterionTypeInterface *criterionType = mPolicyCriterionTypes[typeName];
-    std::string error;
-    criterionType->addValuePair(numericValue, literalValue, error);
-}
-
-void ParameterManagerWrapper::loadCriterionType(cnode *root, bool isInclusive)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node;
-    for (node = root->first_child; node != NULL; node = node->next) {
-
-        ALOG_ASSERT(node != NULL, "error in parsing file");
-        const char *typeName = node->name;
-        char *valueNames = strndup(node->value, strlen(node->value));
-
-        addCriterionType(typeName, isInclusive);
-
-        uint32_t index = 0;
-        char *ctx;
-        char *valueName = strtok_r(valueNames, ",", &ctx);
-        while (valueName != NULL) {
-            if (strlen(valueName) != 0) {
-
-                // Conf file may use or not pair, if no pair, use incremental index, else
-                // use provided index.
-                if (strchr(valueName, ':') != NULL) {
-
-                    char *first = strtok(valueName, ":");
-                    char *second = strtok(NULL, ":");
-                    ALOG_ASSERT((first != NULL) && (strlen(first) != 0) &&
-                                      (second != NULL) && (strlen(second) != 0),
-                                      "invalid value pair");
-
-                    if (!convertTo<string, uint32_t>(first, index)) {
-                        ALOGE("%s: Invalid index(%s) found", __FUNCTION__, first);
-                    }
-                    addCriterionTypeValuePair(typeName, index, second);
-                } else {
-
-                    uint32_t pfwIndex = isInclusive ? 1 << index : index;
-                    addCriterionTypeValuePair(typeName, pfwIndex, valueName);
-                    index += 1;
-                }
-            }
-            valueName = strtok_r(NULL, ",", &ctx);
-        }
-        free(valueNames);
-    }
-}
-
-void ParameterManagerWrapper::loadInclusiveCriterionType(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gInclusiveCriterionTypeTag.c_str());
-    if (node == NULL) {
-        return;
-    }
-    loadCriterionType(node, true);
-}
-
-void ParameterManagerWrapper::loadExclusiveCriterionType(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gExclusiveCriterionTypeTag.c_str());
-    if (node == NULL) {
-        return;
-    }
-    loadCriterionType(node, false);
-}
-
-void ParameterManagerWrapper::parseChildren(cnode *root, string &defaultValue, string &type)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node;
-    for (node = root->first_child; node != NULL; node = node->next) {
-        ALOG_ASSERT(node != NULL, "error in parsing file");
-
-        if (string(node->name) == gDefaultTag) {
-            defaultValue = node->value;
-        } else if (string(node->name) == gTypeTag) {
-            type = node->value;
-        } else {
-             ALOGE("%s: Unrecognized %s %s node", __FUNCTION__, node->name, node->value);
-        }
-    }
-}
-
 template <typename T>
 T *ParameterManagerWrapper::getElement(const string &name, std::map<string, T *> &elementsMap)
 {
@@ -235,97 +200,6 @@
     return it != elementsMap.end() ? it->second : NULL;
 }
 
-void ParameterManagerWrapper::loadCriteria(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gCriterionTag.c_str());
-
-    if (node == NULL) {
-        ALOGW("%s: no inclusive criteria found", __FUNCTION__);
-        return;
-    }
-    for (node = node->first_child; node != NULL; node = node->next) {
-        loadCriterion(node);
-    }
-}
-
-void ParameterManagerWrapper::addCriterion(const string &name, const string &typeName,
-                              const string &defaultLiteralValue)
-{
-    ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
-                "Route Criterion %s already added", name.c_str());
-
-    ISelectionCriterionTypeInterface *criterionType =
-            getElement<ISelectionCriterionTypeInterface>(typeName, mPolicyCriterionTypes);
-
-    ISelectionCriterionInterface *criterion =
-            mPfwConnector->createSelectionCriterion(name, criterionType);
-
-    mPolicyCriteria[name] = criterion;
-    int numericalValue = 0;
-    if (!criterionType->getNumericalValue(defaultLiteralValue.c_str(),  numericalValue)) {
-        ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
-              defaultLiteralValue.c_str());
-    }
-    criterion->setCriterionState(numericalValue);
-}
-
-void ParameterManagerWrapper::loadCriterion(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    const char *criterionName = root->name;
-
-    ALOG_ASSERT(mPolicyCriteria.find(criterionName) == mPolicyCriteria.end(),
-                      "Criterion %s already added", criterionName);
-
-    string paramKeyName = "";
-    string path = "";
-    string typeName = "";
-    string defaultValue = "";
-
-    parseChildren(root, defaultValue, typeName);
-
-    addCriterion(criterionName, typeName, defaultValue);
-}
-
-void ParameterManagerWrapper::loadConfig(cnode *root)
-{
-    ALOG_ASSERT(root != NULL, "error in parsing file");
-    cnode *node = config_find(root, gPolicyConfTag.c_str());
-    if (node == NULL) {
-        ALOGW("%s: Could not find node for pfw", __FUNCTION__);
-        return;
-    }
-    ALOGD("%s: Loading conf for pfw", __FUNCTION__);
-    loadInclusiveCriterionType(node);
-    loadExclusiveCriterionType(node);
-    loadCriteria(node);
-}
-
-
-status_t ParameterManagerWrapper::loadAudioPolicyCriteriaConfig(const char *path)
-{
-    ALOG_ASSERT(path != NULL, "error in parsing file: empty path");
-    cnode *root;
-    char *data;
-    ALOGD("%s", __FUNCTION__);
-    data = (char *)load_file(path, NULL);
-    if (data == NULL) {
-        return -ENODEV;
-    }
-    root = config_node("", "");
-    ALOG_ASSERT(root != NULL, "Unable to allocate a configuration node");
-    config_load(root, data);
-
-    loadConfig(root);
-
-    config_free(root);
-    free(root);
-    free(data);
-    ALOGD("%s: loaded", __FUNCTION__);
-    return NO_ERROR;
-}
-
 bool ParameterManagerWrapper::isStarted()
 {
     return mPfwConnector && mPfwConnector->isStarted();
@@ -334,9 +208,9 @@
 status_t ParameterManagerWrapper::setPhoneState(audio_mode_t mode)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
         return BAD_VALUE;
     }
     if (!isValueValidForCriterion(criterion, static_cast<int>(mode))) {
@@ -350,9 +224,9 @@
 audio_mode_t ParameterManagerWrapper::getPhoneState() const
 {
     const ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
         return AUDIO_MODE_NORMAL;
     }
     return static_cast<audio_mode_t>(criterion->getCriterionState());
@@ -369,7 +243,7 @@
     ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
         return BAD_VALUE;
     }
     if (!isValueValidForCriterion(criterion, static_cast<int>(config))) {
@@ -389,7 +263,7 @@
     const ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
         return AUDIO_POLICY_FORCE_NONE;
     }
     return static_cast<audio_policy_forced_cfg_t>(criterion->getCriterionState());
@@ -403,12 +277,45 @@
     return interface->getLiteralValue(valueToCheck, literalValue);
 }
 
+status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                                           audio_policy_dev_state_t state)
+{
+    std::string criterionName = audio_is_output_device(devDesc->type()) ?
+                gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
+
+    ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->mAddress.string(),
+          state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
+    ISelectionCriterionInterface *criterion =
+            getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
+
+    if (criterion == NULL) {
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, criterionName.c_str());
+        return DEAD_OBJECT;
+    }
+
+    auto criterionType = criterion->getCriterionType();
+    int deviceAddressId;
+    if (not criterionType->getNumericalValue(devDesc->mAddress.string(), deviceAddressId)) {
+        ALOGE("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->mAddress.c_str());
+        return BAD_TYPE;
+    }
+    int currentValueMask = criterion->getCriterionState();
+    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+        currentValueMask |= deviceAddressId;
+    }
+    else {
+        currentValueMask &= ~deviceAddressId;
+    }
+    criterion->setCriterionState(currentValueMask);
+    return NO_ERROR;
+}
+
 status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gInputDeviceCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gInputDeviceCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionName);
         return DEAD_OBJECT;
     }
     criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
@@ -419,9 +326,9 @@
 status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
 {
     ISelectionCriterionInterface *criterion =
-            getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionTag, mPolicyCriteria);
+            getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionName, mPolicyCriteria);
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionTag.c_str());
+        ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionName);
         return DEAD_OBJECT;
     }
     criterion->setCriterionState(outputDevices);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
new file mode 100644
index 0000000..bc6d046
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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
new file mode 100644
index 0000000..467d0e1
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
@@ -0,0 +1,139 @@
+/*
+ * 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/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
deleted file mode 100644
index e4fd176..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ /dev/null
@@ -1,73 +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 <string>
-#include <system/audio_policy.h>
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-//      Definitions for audio policy criteria configuration file (audio_policy_criteria.conf)   //
-//                                                                                              //
-//      @TODO: scripted from audio.h & audio_policy,h                                           //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static const char *const gAudioPolicyCriteriaConfFilePath =
-    "/system/etc/audio_policy_criteria.conf";
-static const char *const gAudioPolicyCriteriaVendorConfFilePath =
-    "/vendor/etc/audio_policy_criteria.conf";
-
-/**
- * PFW instances tags
- */
-static const std::string &gPolicyConfTag = "Policy";
-static const std::string &gDefaultTag = "Default";
-static const std::string &gTypeTag = "Type";
-
-/**
- * PFW elements tags
- */
-static const std::string &gInclusiveCriterionTypeTag = "InclusiveCriterionType";
-static const std::string &gExclusiveCriterionTypeTag = "ExclusiveCriterionType";
-static const std::string &gCriterionTag = "Criterion";
-
-/**
- * PFW known criterion tags
- */
-static const std::string &gInputDeviceCriterionTag = "AvailableInputDevices";
-static const std::string &gOutputDeviceCriterionTag = "AvailableOutputDevices";
-static const std::string &gPhoneStateCriterionTag = "TelephonyMode";
-
-/**
- * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
- */
-static const std::string gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
-{
-    [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] =        "ForceUseForCommunication",
-    [AUDIO_POLICY_FORCE_FOR_MEDIA] =                "ForceUseForMedia",
-    [AUDIO_POLICY_FORCE_FOR_RECORD] =               "ForceUseForRecord",
-    [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
-    [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
-    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
-    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround",
-    [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] =      "ForceUseForVibrateRinging"
-};
-
-
-
-
-
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf b/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
deleted file mode 100644
index 043d5a6..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
+++ /dev/null
@@ -1,146 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Criteria file example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-#########################################################
-# Criterion type Example:
-# For each criterion, a couple of numerical, literal values must be provided to the PFW.
-# The numerical part is not mandatory. If not filled by the user, a default numerical value will be
-# automatically provided by audio HAL using the following logic:
-#   - Exclusive criterion:
-#          * 0 -> first literal value,
-#          * 1 -> second literal value,
-#               ...
-#          * N -> (N+1)th literal value.
-#   - Inclusive criterion:
-#          * 1 << 0 -> first literal value,
-#          * 1 << 1 -> second literal value,
-#               ...
-#          * 1 << N -> (N+1)th literal value,
-#
-#########################################################
-# Policy {
-#    InclusiveCriterionType|ExclusiveCriterionType {
-#        <Criterion Name>  [numerical value 1:]<literal value 1>,[numerical value 2:]<literal value 2>,<literal value 3>,...
-#    }
-# }
-
-#########################################################
-# Criterion:
-#########################################################
-# Policy {
-#    Criterion {
-#        <Criterion Name> {
-#            Type            <Criterion type name>
-#            Default         <default value of the criterion>
-#        }
-#    }
-# }
-
-Policy {
-    InclusiveCriterionType {
-        #
-        # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
-        # AUDIO_DEVICE_OUT_* within <system/audio.h> file of android.
-        #
-        OutputDevicesMaskType   Earpiece,Speaker,WiredHeadset,WiredHeadphone,BluetoothSco,BluetoothScoHeadset,BluetoothScoCarkit,BluetoothA2dp,BluetoothA2dpHeadphones,BluetoothA2dpSpeaker,Hdmi,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,RemoteSubmix,TelephonyTx,Line,HdmiArc,Spdif,Fm,AuxLine,SpeakerSafe
-        #
-        # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
-        # AUDIO_DEVICE_IN_* within <system/audio.h> file of android.
-        # Note also that direction bit will be decimated by AudioHAL in order to allow using a mask
-        # with the cardinality of 1 between a bit and an input device.
-        #
-        InputDevicesMaskType    Communication,Ambient,BuiltinMic,BluetoothScoHeadset,WiredHeadset,Hdmi,TelephonyRx,BackMic,RemoteSubmix,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,FmTuner,TvTune,Line,Spdif,BluetoothA2dp,Loopback
-    }
-    ExclusiveCriterionType {
-        #
-        # The values of the mode MUST be aligned with the definition of the audio_mode_t
-        # from system/audio.h
-        #
-        AndroidModeType     0:Normal,1:RingTone,2:InCall,3:InCommunication
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForCommunicationType    0:ForceNone,1:ForceSpeaker,3:ForceBtSco
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForMediaType            0:ForceNone,1:ForceSpeaker,2:ForceHeadphones,4:ForceBtA2dp,5:ForceWiredAccessory,8:ForceAnalogDock,9:ForceDigitalDock,10:ForceNoBtA2dp
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForRecordType           0:ForceNone,3:ForceBtSco,5:ForceWiredAccessory
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForDockType             0:ForceNone,5:ForceWiredAccessory,6:ForceBtCarDock,7:ForceBtDeskDock,8:ForceAnalogDock,9:ForceDigitalDock
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForSystemType           0:ForceNone,11:ForceSystemEnforced
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio.h
-        #
-        ForceUseForHdmiSystemAudioType  0:ForceNone,12:ForceHdmiSystemEnforced
-        #
-        # The values of the mode MUST be aligned with the definition of the
-        # audio_policy_forced_config_t from system/audio_policy.h
-        #
-        ForceUseForEncodedSurroundType  0:ForceNone,13:ForceEncodedSurroundNever,14:ForceEncodedSurroundAlways
-    }
-
-    Criterion {
-        AvailableInputDevices {
-            Type            InputDevicesMaskType
-            Default         none
-        }
-        AvailableOutputDevices {
-            Type            OutputDevicesMaskType
-            Default         none
-        }
-        TelephonyMode {
-            Type            AndroidModeType
-            Default         Normal
-        }
-        ForceUseForCommunication {
-            Type            ForceUseForCommunicationType
-            Default         ForceNone
-        }
-        ForceUseForMedia {
-            Type            ForceUseForMediaType
-            Default         ForceNone
-        }
-        ForceUseForRecord {
-            Type            ForceUseForRecordType
-            Default         ForceNone
-        }
-        ForceUseForDock {
-            Type            ForceUseForDockType
-            Default         ForceNone
-        }
-        ForceUseForSystem {
-            Type            ForceUseForSystemType
-            Default         ForceNone
-        }
-        ForceUseForHdmiSystemAudio {
-            Type            ForceUseForHdmiSystemAudioType
-            Default         ForceNone
-        }
-        ForceUseForEncodedSurround {
-            Type            ForceUseForEncodedSurroundType
-            Default         ForceNone
-        }
-    }
-}
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
new file mode 100644
index 0000000..ec82b2e
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<criteria>
+    <criterion name="AvailableInputDevices" type="InputDevicesMaskType" default="none"/>
+    <criterion name="AvailableOutputDevices" type="OutputDevicesMaskType" default="none"/>
+    <criterion name="AvailableOutputDevicesAddresses" type="OutputDevicesAddressesType" default="none"/>
+    <criterion name="AvailableInputDevicesAddresses" type="InputDevicesAddressesType" default="none"/>
+    <criterion name="TelephonyMode" type="AndroidModeType" default="Normal"/>
+    <criterion name="ForceUseForCommunication" type="ForceUseForCommunicationType" default="ForceNone"/>
+    <criterion name="ForceUseForMedia" type="ForceUseForMediaType" default="ForceNone"/>
+    <criterion name="ForceUseForRecord" type="ForceUseForRecordType" default="ForceNone"/>
+    <criterion name="ForceUseForDock" type="ForceUseForDockType" default="ForceNone"/>
+    <criterion name="ForceUseForSystem" type="ForceUseForSystemType" default="ForceNone"/>
+    <criterion name="ForceUseForHdmiSystemAudio" type="ForceUseForHdmiSystemAudioType" default="ForceNone"/>
+    <criterion name="ForceUseForEncodedSurround" type="ForceUseForEncodedSurroundType" default="ForceNone"/>
+    <criterion name="ForceUseForVibrateRinging" type="ForceUseForVibrateRingingType" default="ForceNone"/>
+</criteria>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
new file mode 100644
index 0000000..6cb799f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
@@ -0,0 +1,91 @@
+<?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.
+-->
+<criterion_types>
+    <criterion_type name="OutputDevicesMaskType" type="inclusive"/>
+    <criterion_type name="InputDevicesMaskType" type="inclusive"/>
+    <criterion_type name="OutputDevicesAddressesType" type="inclusive"/>
+    <criterion_type name="InputDevicesAddressesType" type="inclusive"/>
+    <criterion_type name="AndroidModeType" type="exclusive"/>
+    <criterion_type name="BooleanType" type="exclusive">
+        <values>
+            <value literal="False" numerical="0"/>
+            <value literal="True" numerical="1"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForCommunicationType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSpeaker" numerical="1"/>
+            <value literal="ForceBtSco" numerical="3"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForMediaType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSpeaker" numerical="1"/>
+            <value literal="ForceHeadphones" numerical="2"/>
+            <value literal="ForceBtA2dp" numerical="4"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+            <value literal="ForceAnalogDock" numerical="8"/>
+            <value literal="ForceDigitalDock" numerical="9"/>
+            <value literal="ForceNoBtA2dp" numerical="10"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForRecordType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceBtSco" numerical="3"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForDockType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceWiredAccessory" numerical="5"/>
+            <value literal="ForceBtCarDock" numerical="6"/>
+            <value literal="ForceBtDeskDock" numerical="7"/>
+            <value literal="ForceAnalogDock" numerical="8"/>
+            <value literal="ForceDigitalDock" numerical="9"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForSystemType" type="exclusive" >
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceSystemEnforced" numerical="11"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForHdmiSystemAudioType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceHdmiSystemEnforced" numerical="12"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForEncodedSurroundType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceEncodedSurroundNever" numerical="13"/>
+            <value literal="ForceEncodedSurroundAlways" numerical="14"/>
+        </values>
+    </criterion_type>
+    <criterion_type name="ForceUseForVibrateRingingType" type="exclusive">
+        <values>
+            <value literal="ForceNone" numerical="0"/>
+            <value literal="ForceBtSco" numerical="3"/>
+        </values>
+    </criterion_type>
+</criterion_types>
+
+
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
new file mode 100644
index 0000000..5d9193b
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<!--
+    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>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 107ef12..1a634a1 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -16,10 +16,15 @@
 
 #pragma once
 
+#include <AudioGain.h>
+#include <AudioPort.h>
+#include <HwModule.h>
+#include <DeviceDescriptor.h>
 #include <system/audio.h>
 #include <system/audio_policy.h>
 #include <utils/Errors.h>
 #include <utils/RWLock.h>
+#include <utils/RefBase.h>
 #include <list>
 #include <map>
 #include <string>
@@ -27,7 +32,6 @@
 
 class CParameterMgrPlatformConnector;
 class ISelectionCriterionInterface;
-class ISelectionCriterionTypeInterface;
 struct cnode;
 
 class ParameterMgrPlatformConnectorLogger;
@@ -38,14 +42,7 @@
 class ParameterManagerWrapper
 {
 private:
-    typedef std::pair<int, const char *> CriterionTypeValuePair;
-
-    typedef std::map<std::string, ISelectionCriterionInterface *> CriterionCollection;
-    typedef std::map<std::string, ISelectionCriterionTypeInterface *> CriterionTypeCollection;
-    typedef CriterionCollection::iterator CriterionMapIterator;
-    typedef CriterionCollection::const_iterator CriterionMapConstIterator;
-    typedef CriterionTypeCollection::iterator CriterionTypeMapIterator;
-    typedef CriterionTypeCollection::const_iterator CriteriaTypeMapConstIterator;
+    using Criteria = std::map<std::string, ISelectionCriterionInterface *>;
 
 public:
     ParameterManagerWrapper();
@@ -118,6 +115,9 @@
      */
     status_t setAvailableOutputDevices(audio_devices_t outputDevices);
 
+    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                      audio_policy_dev_state_t state);
+
 private:
     /**
      * Apply the configuration of the platform on the policy parameter manager.
@@ -134,93 +134,11 @@
     /**
      * Load the criterion configuration file.
      *
-     * @param[in] path Criterion conf file path.
-     *
      * @return NO_ERROR is parsing successful, error code otherwise.
      */
-    status_t loadAudioPolicyCriteriaConfig(const char *path);
+    status_t loadConfig();
 
-    /**
-     * Add a criterion type to AudioPolicyPfw.
-     *
-     * @param[in] typeName of the PFW criterion type.
-     * @param[in] isInclusive attribute of the criterion type.
-     */
-    void addCriterionType(const std::string &typeName, bool isInclusive);
-
-    /**
-     * Add a criterion type value pair to AudioPolicyPfw.
-     *
-     * @param[in] typeName criterion type name to which this value pair is added to.
-     * @param[in] numeric part of the value pair.
-     * @param[in] literal part of the value pair.
-     */
-    void addCriterionTypeValuePair(const std::string &typeName, uint32_t numeric,
-                                   const std::string &literal);
-
-    /**
-     * Add a criterion to AudioPolicyPfw.
-     *
-     * @param[in] name of the PFW criterion.
-     * @param[in] typeName criterion type name to which this criterion is associated to.
-     * @param[in] defaultLiteralValue of the PFW criterion.
-     */
-    void addCriterion(const std::string &name,
-                      const std::string &typeName,
-                      const std::string &defaultLiteralValue);
-    /**
-     * Parse and load the inclusive criterion type from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadInclusiveCriterionType(cnode *root);
-
-    /**
-     * Parse and load the exclusive criterion type from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadExclusiveCriterionType(cnode *root);
-
-    /**
-     * Parse and load the criteria from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadCriteria(cnode *root);
-
-    /**
-     * Parse and load a criterion from configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadCriterion(cnode *root);
-
-    /**
-     * Parse and load the criterion types from configuration file.
-     *
-     * @param[in] root node of the configuration file
-     * @param[in] isInclusive true if inclusive, false is exclusive.
-     */
-    void loadCriterionType(cnode *root, bool isInclusive);
-
-    /**
-     * Load the configuration file.
-     *
-     * @param[in] root node of the configuration file.
-     */
-    void loadConfig(cnode *root);
-
-    /**
-     * Parse and load the chidren node from a given root node.
-     *
-     * @param[in] root node of the configuration file
-     * @param[out] defaultValue of the parameter manager element to retrieve.
-     * @param[out] type of the parameter manager element to retrieve.
-    */
-    void parseChildren(cnode *root, std::string &defaultValue, std::string &type);
-
-    /**
+     /**
      * Retrieve an element from a map by its name.
      *
      * @tparam T type of element to search.
@@ -264,8 +182,7 @@
 
     bool isValueValidForCriterion(ISelectionCriterionInterface *criterion, int valueToCheck);
 
-    CriterionTypeCollection mPolicyCriterionTypes; /**< Policy Criterion Type map. */
-    CriterionCollection mPolicyCriteria; /**< Policy Criterion Map. */
+    Criteria mPolicyCriteria; /**< Policy Criterion Map. */
 
     CParameterMgrPlatformConnector *mPfwConnector; /**< Policy Parameter Manager connector. */
     ParameterMgrPlatformConnectorLogger *mPfwConnectorLogger; /**< Policy PFW logger. */