diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index af1c9e6..263dd32 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -33,7 +33,7 @@
 #include "CameraService.h"
 #include "MediaLogService.h"
 #include "MediaPlayerService.h"
-#include "AudioPolicyService.h"
+#include "service/AudioPolicyService.h"
 #include "SoundTriggerHwService.h"
 
 using namespace android;
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 188fc89..351ed79 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -3,19 +3,19 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    AudioPolicyService.cpp \
-    AudioPolicyEffects.cpp
+    service/AudioPolicyService.cpp \
+    service/AudioPolicyEffects.cpp
 
 ifeq ($(USE_LEGACY_AUDIO_POLICY), 1)
 LOCAL_SRC_FILES += \
-    AudioPolicyInterfaceImplLegacy.cpp \
-    AudioPolicyClientImplLegacy.cpp
+    service/AudioPolicyInterfaceImplLegacy.cpp \
+    service/AudioPolicyClientImplLegacy.cpp
 
     LOCAL_CFLAGS += -DUSE_LEGACY_AUDIO_POLICY
 else
 LOCAL_SRC_FILES += \
-    AudioPolicyInterfaceImpl.cpp \
-    AudioPolicyClientImpl.cpp
+    service/AudioPolicyInterfaceImpl.cpp \
+    service/AudioPolicyClientImpl.cpp
 endif
 
 LOCAL_C_INCLUDES := \
@@ -53,7 +53,15 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    AudioPolicyManager.cpp
+    managerdefault/AudioPolicyManager.cpp \
+    managerdefault/ConfigParsingUtils.cpp \
+    managerdefault/Devices.cpp \
+    managerdefault/Gains.cpp \
+    managerdefault/HwModule.cpp \
+    managerdefault/IOProfile.cpp \
+    managerdefault/Ports.cpp \
+    managerdefault/AudioInputDescriptor.cpp \
+    managerdefault/AudioOutputDescriptor.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
@@ -73,7 +81,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    AudioPolicyFactory.cpp
+    manager/AudioPolicyFactory.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libaudiopolicymanagerdefault
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
deleted file mode 100644
index 81d4f14..0000000
--- a/services/audiopolicy/AudioPolicyManager.h
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * Copyright (C) 2009 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 <stdint.h>
-#include <sys/types.h>
-#include <cutils/config_utils.h>
-#include <cutils/misc.h>
-#include <utils/Timers.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/SortedVector.h>
-#include <media/AudioPolicy.h>
-#include "AudioPolicyInterface.h"
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
-#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
-// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
-#define SONIFICATION_HEADSET_VOLUME_MIN  0.016
-// Time in milliseconds during which we consider that music is still active after a music
-// track was stopped - see computeVolume()
-#define SONIFICATION_HEADSET_MUSIC_DELAY  5000
-// 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
-// Time in milliseconds during witch some streams are muted while the audio path
-// is switched
-#define MUTE_TIME_MS 2000
-
-#define NUM_TEST_OUTPUTS 5
-
-#define NUM_VOL_CURVE_KNEES 2
-
-// Default minimum length allowed for offloading a compressed track
-// Can be overridden by the audio.offload.min.duration.secs property
-#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
-
-#define MAX_MIXER_SAMPLING_RATE 48000
-#define MAX_MIXER_CHANNEL_COUNT 8
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManager implements audio policy manager behavior common to all platforms.
-// ----------------------------------------------------------------------------
-
-class AudioPolicyManager: public AudioPolicyInterface
-#ifdef AUDIO_POLICY_TEST
-    , public Thread
-#endif //AUDIO_POLICY_TEST
-{
-
-public:
-                AudioPolicyManager(AudioPolicyClientInterface *clientInterface);
-        virtual ~AudioPolicyManager();
-
-        // AudioPolicyInterface
-        virtual status_t setDeviceConnectionState(audio_devices_t device,
-                                                          audio_policy_dev_state_t state,
-                                                          const char *device_address,
-                                                          const char *device_name);
-        virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
-                                                                              const char *device_address);
-        virtual void setPhoneState(audio_mode_t state);
-        virtual void setForceUse(audio_policy_force_use_t usage,
-                                 audio_policy_forced_cfg_t config);
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
-        virtual void setSystemProperty(const char* property, const char* value);
-        virtual status_t initCheck();
-        virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
-                                            uint32_t samplingRate,
-                                            audio_format_t format,
-                                            audio_channel_mask_t channelMask,
-                                            audio_output_flags_t flags,
-                                            const audio_offload_info_t *offloadInfo);
-        virtual status_t getOutputForAttr(const audio_attributes_t *attr,
-                                          audio_io_handle_t *output,
-                                          audio_session_t session,
-                                          audio_stream_type_t *stream,
-                                          uint32_t samplingRate,
-                                          audio_format_t format,
-                                          audio_channel_mask_t channelMask,
-                                          audio_output_flags_t flags,
-                                          const audio_offload_info_t *offloadInfo);
-        virtual status_t startOutput(audio_io_handle_t output,
-                                     audio_stream_type_t stream,
-                                     audio_session_t session);
-        virtual status_t stopOutput(audio_io_handle_t output,
-                                    audio_stream_type_t stream,
-                                    audio_session_t session);
-        virtual void releaseOutput(audio_io_handle_t output,
-                                   audio_stream_type_t stream,
-                                   audio_session_t session);
-        virtual status_t getInputForAttr(const audio_attributes_t *attr,
-                                         audio_io_handle_t *input,
-                                         audio_session_t session,
-                                         uint32_t samplingRate,
-                                         audio_format_t format,
-                                         audio_channel_mask_t channelMask,
-                                         audio_input_flags_t flags,
-                                         input_type_t *inputType);
-
-        // indicates to the audio policy manager that the input starts being used.
-        virtual status_t startInput(audio_io_handle_t input,
-                                    audio_session_t session);
-
-        // indicates to the audio policy manager that the input stops being used.
-        virtual status_t stopInput(audio_io_handle_t input,
-                                   audio_session_t session);
-        virtual void releaseInput(audio_io_handle_t input,
-                                  audio_session_t session);
-        virtual void closeAllInputs();
-        virtual void initStreamVolume(audio_stream_type_t stream,
-                                                    int indexMin,
-                                                    int indexMax);
-        virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
-                                              int index,
-                                              audio_devices_t device);
-        virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
-                                              int *index,
-                                              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 uint32_t getStrategyForAttr(const audio_attributes_t *attr);
-
-        // return the enabled output devices for the given stream type
-        virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
-
-        virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc = NULL);
-        virtual status_t registerEffect(const effect_descriptor_t *desc,
-                                        audio_io_handle_t io,
-                                        uint32_t strategy,
-                                        int session,
-                                        int id);
-        virtual status_t unregisterEffect(int id);
-        virtual status_t setEffectEnabled(int id, bool enabled);
-
-        virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
-        // return whether a stream is playing remotely, override to change the definition of
-        //   local/remote playback, used for instance by notification manager to not make
-        //   media players lose audio focus when not playing locally
-        //   For the base implementation, "remotely" means playing during screen mirroring which
-        //   uses an output for playback with a non-empty, non "0" address.
-        virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
-        virtual bool isSourceActive(audio_source_t source) const;
-
-        virtual status_t dump(int fd);
-
-        virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
-
-        virtual status_t listAudioPorts(audio_port_role_t role,
-                                        audio_port_type_t type,
-                                        unsigned int *num_ports,
-                                        struct audio_port *ports,
-                                        unsigned int *generation);
-        virtual status_t getAudioPort(struct audio_port *port);
-        virtual status_t createAudioPatch(const struct audio_patch *patch,
-                                           audio_patch_handle_t *handle,
-                                           uid_t uid);
-        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
-                                              uid_t uid);
-        virtual status_t listAudioPatches(unsigned int *num_patches,
-                                          struct audio_patch *patches,
-                                          unsigned int *generation);
-        virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-        virtual void clearAudioPatches(uid_t uid);
-
-        virtual status_t acquireSoundTriggerSession(audio_session_t *session,
-                                               audio_io_handle_t *ioHandle,
-                                               audio_devices_t *device);
-
-        virtual status_t releaseSoundTriggerSession(audio_session_t session);
-
-        virtual status_t registerPolicyMixes(Vector<AudioMix> mixes);
-        virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
-
-protected:
-
-        enum routing_strategy {
-            STRATEGY_MEDIA,
-            STRATEGY_PHONE,
-            STRATEGY_SONIFICATION,
-            STRATEGY_SONIFICATION_RESPECTFUL,
-            STRATEGY_DTMF,
-            STRATEGY_ENFORCED_AUDIBLE,
-            STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
-            STRATEGY_ACCESSIBILITY,
-            STRATEGY_REROUTING,
-            NUM_STRATEGIES
-        };
-
-        // 4 points to define the volume attenuation curve, each characterized by the volume
-        // index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
-        // we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
-
-        enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4};
-
-        class VolumeCurvePoint
-        {
-        public:
-            int mIndex;
-            float mDBAttenuation;
-        };
-
-        // device categories used for volume curve management.
-        enum device_category {
-            DEVICE_CATEGORY_HEADSET,
-            DEVICE_CATEGORY_SPEAKER,
-            DEVICE_CATEGORY_EARPIECE,
-            DEVICE_CATEGORY_EXT_MEDIA,
-            DEVICE_CATEGORY_CNT
-        };
-
-        class HwModule;
-
-        class AudioGain: public RefBase
-        {
-        public:
-            AudioGain(int index, bool useInChannelMask);
-            virtual ~AudioGain() {}
-
-            void dump(int fd, int spaces, int index) const;
-
-            void getDefaultConfig(struct audio_gain_config *config);
-            status_t checkConfig(const struct audio_gain_config *config);
-            int               mIndex;
-            struct audio_gain mGain;
-            bool              mUseInChannelMask;
-        };
-
-        class AudioPort: public virtual RefBase
-        {
-        public:
-            AudioPort(const String8& name, audio_port_type_t type,
-                      audio_port_role_t role, const sp<HwModule>& module);
-            virtual ~AudioPort() {}
-
-            audio_port_handle_t getHandle() { return mId; }
-
-            void attach(const sp<HwModule>& module);
-            bool isAttached() { return mId != 0; }
-
-            virtual void toAudioPort(struct audio_port *port) const;
-
-            void importAudioPort(const sp<AudioPort> port);
-            void clearCapabilities();
-
-            void loadSamplingRates(char *name);
-            void loadFormats(char *name);
-            void loadOutChannels(char *name);
-            void loadInChannels(char *name);
-
-            audio_gain_mode_t loadGainMode(char *name);
-            void loadGain(cnode *root, int index);
-            virtual void loadGains(cnode *root);
-
-            // searches for an exact match
-            status_t checkExactSamplingRate(uint32_t samplingRate) const;
-            // searches for a compatible match, and returns the best match via updatedSamplingRate
-            status_t checkCompatibleSamplingRate(uint32_t samplingRate,
-                    uint32_t *updatedSamplingRate) const;
-            // searches for an exact match
-            status_t checkExactChannelMask(audio_channel_mask_t channelMask) const;
-            // searches for a compatible match, currently implemented for input channel masks only
-            status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask) const;
-            status_t checkFormat(audio_format_t format) const;
-            status_t checkGain(const struct audio_gain_config *gainConfig, int index) const;
-
-            uint32_t pickSamplingRate() const;
-            audio_channel_mask_t pickChannelMask() const;
-            audio_format_t pickFormat() const;
-
-            static const audio_format_t sPcmFormatCompareTable[];
-            static int compareFormats(audio_format_t format1, audio_format_t format2);
-
-            void dump(int fd, int spaces) const;
-
-            String8           mName;
-            audio_port_type_t mType;
-            audio_port_role_t mRole;
-            bool              mUseInChannelMask;
-            // by convention, "0' in the first entry in mSamplingRates, mChannelMasks or mFormats
-            // indicates the supported parameters should be read from the output stream
-            // after it is opened for the first time
-            Vector <uint32_t> mSamplingRates; // supported sampling rates
-            Vector <audio_channel_mask_t> mChannelMasks; // supported channel masks
-            Vector <audio_format_t> mFormats; // supported audio formats
-            Vector < sp<AudioGain> > mGains; // gain controllers
-            sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
-            uint32_t mFlags; // attribute flags (e.g primary output,
-                                                // direct output...).
-
-        protected:
-            //TODO - clarify the role of mId in this case, both an "attached" indicator
-            // and a unique ID for identifying a port to the (upcoming) selection API,
-            // and its relationship to the mId in AudioOutputDescriptor and AudioInputDescriptor.
-            audio_port_handle_t mId;
-        };
-
-        class AudioPortConfig: public virtual RefBase
-        {
-        public:
-            AudioPortConfig();
-            virtual ~AudioPortConfig() {}
-
-            status_t applyAudioPortConfig(const struct audio_port_config *config,
-                                          struct audio_port_config *backupConfig = NULL);
-            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const = 0;
-            virtual sp<AudioPort> getAudioPort() const = 0;
-            uint32_t mSamplingRate;
-            audio_format_t mFormat;
-            audio_channel_mask_t mChannelMask;
-            struct audio_gain_config mGain;
-        };
-
-
-        class AudioPatch: public RefBase
-        {
-        public:
-            AudioPatch(audio_patch_handle_t handle,
-                       const struct audio_patch *patch, uid_t uid) :
-                           mHandle(handle), mPatch(*patch), mUid(uid), mAfPatchHandle(0) {}
-
-            status_t dump(int fd, int spaces, int index) const;
-
-            audio_patch_handle_t mHandle;
-            struct audio_patch mPatch;
-            uid_t mUid;
-            audio_patch_handle_t mAfPatchHandle;
-        };
-
-        class DeviceDescriptor: public AudioPort, public AudioPortConfig
-        {
-        public:
-            DeviceDescriptor(const String8& name, audio_devices_t type);
-
-            virtual ~DeviceDescriptor() {}
-
-            bool equals(const sp<DeviceDescriptor>& other) const;
-
-            // AudioPortConfig
-            virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
-            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-
-            // AudioPort
-            virtual void loadGains(cnode *root);
-            virtual void toAudioPort(struct audio_port *port) const;
-
-            status_t dump(int fd, int spaces, int index) const;
-
-            audio_devices_t mDeviceType;
-            String8 mAddress;
-
-            static String8  emptyNameStr;
-        };
-
-        class DeviceVector : public SortedVector< sp<DeviceDescriptor> >
-        {
-        public:
-            DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
-
-            ssize_t         add(const sp<DeviceDescriptor>& item);
-            ssize_t         remove(const sp<DeviceDescriptor>& item);
-            ssize_t         indexOf(const sp<DeviceDescriptor>& item) const;
-
-            audio_devices_t types() const { return mDeviceTypes; }
-
-            void loadDevicesFromType(audio_devices_t types);
-            void loadDevicesFromName(char *name, const DeviceVector& declaredDevices);
-
-            sp<DeviceDescriptor> getDevice(audio_devices_t type, String8 address) const;
-            DeviceVector getDevicesFromType(audio_devices_t types) const;
-            sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
-            sp<DeviceDescriptor> getDeviceFromName(const String8& name) const;
-            DeviceVector getDevicesFromTypeAddr(audio_devices_t type, String8 address)
-                    const;
-
-        private:
-            void refreshTypes();
-            audio_devices_t mDeviceTypes;
-        };
-
-        // the IOProfile class describes the capabilities of an output or input stream.
-        // It is currently assumed that all combination of listed parameters are supported.
-        // It is used by the policy manager to determine if an output or input is suitable for
-        // a given use case,  open/close it accordingly and connect/disconnect audio tracks
-        // to/from it.
-        class IOProfile : public AudioPort
-        {
-        public:
-            IOProfile(const String8& name, audio_port_role_t role, const sp<HwModule>& module);
-            virtual ~IOProfile();
-
-            // This method is used for both output and input.
-            // If parameter updatedSamplingRate is non-NULL, it is assigned the actual sample rate.
-            // For input, flags is interpreted as audio_input_flags_t.
-            // TODO: merge audio_output_flags_t and audio_input_flags_t.
-            bool isCompatibleProfile(audio_devices_t device,
-                                     String8 address,
-                                     uint32_t samplingRate,
-                                     uint32_t *updatedSamplingRate,
-                                     audio_format_t format,
-                                     audio_channel_mask_t channelMask,
-                                     uint32_t flags) const;
-
-            void dump(int fd);
-            void log();
-
-            DeviceVector  mSupportedDevices; // supported devices
-                                             // (devices this output can be routed to)
-        };
-
-        class HwModule : public RefBase
-        {
-        public:
-                    HwModule(const char *name);
-                    ~HwModule();
-
-            status_t loadOutput(cnode *root);
-            status_t loadInput(cnode *root);
-            status_t loadDevice(cnode *root);
-
-            status_t addOutputProfile(String8 name, const audio_config_t *config,
-                                      audio_devices_t device, String8 address);
-            status_t removeOutputProfile(String8 name);
-            status_t addInputProfile(String8 name, const audio_config_t *config,
-                                      audio_devices_t device, String8 address);
-            status_t removeInputProfile(String8 name);
-
-            void dump(int fd);
-
-            const char *const        mName; // base name of the audio HW module (primary, a2dp ...)
-            uint32_t                 mHalVersion; // audio HAL API version
-            audio_module_handle_t    mHandle;
-            Vector < sp<IOProfile> > mOutputProfiles; // output profiles exposed by this module
-            Vector < sp<IOProfile> > mInputProfiles;  // input profiles exposed by this module
-            DeviceVector             mDeclaredDevices; // devices declared in audio_policy.conf
-
-        };
-
-        // default volume curve
-        static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManager::VOLCNT];
-        // default volume curve for media strategy
-        static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT];
-        // volume curve for non-media audio on ext media outputs (HDMI, Line, etc)
-        static const VolumeCurvePoint sExtMediaSystemVolumeCurve[AudioPolicyManager::VOLCNT];
-        // volume curve for media strategy on speakers
-        static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT];
-        // volume curve for sonification strategy on speakers
-        static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sLinearVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSilentVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT];
-        // default volume curves per stream and device category. See initializeVolumeCurves()
-        static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
-
-        // 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:
-            AudioOutputDescriptor(const sp<IOProfile>& profile);
-
-            status_t    dump(int fd);
-
-            audio_devices_t device() const;
-            void changeRefCount(audio_stream_type_t stream, int delta);
-
-            bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
-            audio_devices_t supportedDevices();
-            uint32_t latency();
-            bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
-            bool isActive(uint32_t inPastMs = 0) const;
-            bool isStreamActive(audio_stream_type_t stream,
-                                uint32_t inPastMs = 0,
-                                nsecs_t sysTime = 0) const;
-            bool isStrategyActive(routing_strategy strategy,
-                             uint32_t inPastMs = 0,
-                             nsecs_t sysTime = 0) const;
-
-            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-            virtual sp<AudioPort> getAudioPort() const { return mProfile; }
-            void toAudioPort(struct audio_port *port) const;
-
-            audio_port_handle_t mId;
-            audio_io_handle_t mIoHandle;              // output handle
-            uint32_t mLatency;                  //
-            audio_output_flags_t mFlags;   //
-            audio_devices_t mDevice;                   // current device this output is routed to
-            AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
-            audio_patch_handle_t mPatchHandle;
-            uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
-            nsecs_t mStopTime[AUDIO_STREAM_CNT];
-            sp<AudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
-            sp<AudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
-            float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume
-            int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
-            const sp<IOProfile> mProfile;          // I/O profile this output derives from
-            bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
-                                                // device selection. See checkDeviceMuteStrategies()
-            uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
-        };
-
-        // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
-        // and keep track of the usage of this input.
-        class AudioInputDescriptor: public AudioPortConfig
-        {
-        public:
-            AudioInputDescriptor(const sp<IOProfile>& profile);
-
-            status_t    dump(int fd);
-
-            audio_port_handle_t           mId;
-            audio_io_handle_t             mIoHandle;       // input handle
-            audio_devices_t               mDevice;         // current device this input is routed to
-            AudioMix                      *mPolicyMix;     // non NULL when used by a dynamic policy
-            audio_patch_handle_t          mPatchHandle;
-            uint32_t                      mRefCount;       // number of AudioRecord clients using
-                                                           // this input
-            uint32_t                      mOpenRefCount;
-            audio_source_t                mInputSource;    // input source selected by application
-                                                           //(mediarecorder.h)
-            const sp<IOProfile>           mProfile;        // I/O profile this output derives from
-            SortedVector<audio_session_t> mSessions;       // audio sessions attached to this input
-            bool                          mIsSoundTrigger; // used by a soundtrigger capture
-
-            virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-            virtual sp<AudioPort> getAudioPort() const { return mProfile; }
-            void toAudioPort(struct audio_port *port) const;
-        };
-
-        // stream descriptor used for volume control
-        class StreamDescriptor
-        {
-        public:
-            StreamDescriptor();
-
-            int getVolumeIndex(audio_devices_t device);
-            void dump(int fd);
-
-            int mIndexMin;      // min volume index
-            int mIndexMax;      // max volume index
-            KeyedVector<audio_devices_t, int> mIndexCur;   // current volume index per device
-            bool mCanBeMuted;   // true is the stream can be muted
-
-            const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT];
-        };
-
-        // stream descriptor used for volume control
-        class EffectDescriptor : public RefBase
-        {
-        public:
-
-            status_t dump(int fd);
-
-            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
-        };
-
-        void addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc);
-        void addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc);
-
-        // return the strategy corresponding to a given stream type
-        static routing_strategy getStrategy(audio_stream_type_t stream);
-
-        // 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);
-
-        // 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.
-        virtual uint32_t setOutputDevice(audio_io_handle_t output,
-                             audio_devices_t device,
-                             bool force = false,
-                             int delayMs = 0,
-                             audio_patch_handle_t *patchHandle = NULL,
-                             const char* address = NULL);
-        status_t resetOutputDevice(audio_io_handle_t output,
-                                   int delayMs = 0,
-                                   audio_patch_handle_t *patchHandle = NULL);
-        status_t setInputDevice(audio_io_handle_t input,
-                                audio_devices_t device,
-                                bool force = false,
-                                audio_patch_handle_t *patchHandle = NULL);
-        status_t resetInputDevice(audio_io_handle_t input,
-                                  audio_patch_handle_t *patchHandle = NULL);
-
-        // select input device corresponding to requested audio source
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
-
-        // return io handle of active input or 0 if no input is active
-        //    Only considers inputs from physical devices (e.g. main mic, headset mic) when
-        //    ignoreVirtualInputs is true.
-        audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
-
-        uint32_t activeInputsCount() const;
-
-        // initialize volume curves for each strategy and device category
-        void initializeVolumeCurves();
-
-        // 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, int index,
-                                    audio_io_handle_t output, audio_devices_t device);
-
-        // check that volume change is permitted, compute and send new volume to audio hardware
-        virtual status_t checkAndSetVolume(audio_stream_type_t stream, int index,
-                                           audio_io_handle_t output,
-                                           audio_devices_t device,
-                                           int delayMs = 0, bool force = false);
-
-        // apply all stream volumes to the specified output and device
-        void applyStreamVolumes(audio_io_handle_t output, 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,
-                             bool on,
-                             audio_io_handle_t output,
-                             int delayMs = 0,
-                             audio_devices_t device = (audio_devices_t)0);
-
-        // Mute or unmute the stream on the specified output
-        void setStreamMute(audio_stream_type_t stream,
-                           bool on,
-                           audio_io_handle_t output,
-                           int delayMs = 0,
-                           audio_devices_t device = (audio_devices_t)0);
-
-        // handle special cases for sonification strategy while in call: mute streams or replace by
-        // a special tone in the device used for communication
-        void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
-
-        // true if device is in a telephony or VoIP call
-        virtual bool isInCall();
-
-        // true if given state represents a device in a telephony or VoIP call
-        virtual bool isStateInCall(int state);
-
-        // when a device is connected, checks if an open output can be routed
-        // to this device. If none is open, tries to open one of the available outputs.
-        // Returns an output suitable to this device or 0.
-        // when a device is disconnected, checks if an output is not used any more and
-        // returns its handle if any.
-        // transfers the audio tracks and effects from one output thread to another accordingly.
-        status_t checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
-                                       audio_policy_dev_state_t state,
-                                       SortedVector<audio_io_handle_t>& outputs,
-                                       const String8 address);
-
-        status_t checkInputsForDevice(audio_devices_t device,
-                                      audio_policy_dev_state_t state,
-                                      SortedVector<audio_io_handle_t>& inputs,
-                                      const String8 address);
-
-        // close an output and its companion duplicating output.
-        void closeOutput(audio_io_handle_t output);
-
-        // close an input.
-        void closeInput(audio_io_handle_t input);
-
-        // 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);
-
-        // Same as checkOutputForStrategy() but for a all strategies in order of priority
-        void checkOutputForAllStrategies();
-
-        // manages A2DP output suspend/restore according to phone state and BT SCO usage
-        void checkA2dpSuspend();
-
-        // returns the A2DP output handle if it is open or 0 otherwise
-        audio_io_handle_t getA2dpOutput();
-
-        // 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..
-        // see getDeviceForStrategy() for the use of fromCache parameter
-        audio_devices_t getNewOutputDevice(audio_io_handle_t output, 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()
-        void updateDevicesAndOutputs();
-
-        // selects the most appropriate device on input for current state
-        audio_devices_t getNewInputDevice(audio_io_handle_t input);
-
-        virtual uint32_t getMaxEffectsCpuLoad();
-        virtual uint32_t getMaxEffectsMemory();
-#ifdef AUDIO_POLICY_TEST
-        virtual     bool        threadLoop();
-                    void        exit();
-        int testOutputIndex(audio_io_handle_t output);
-#endif //AUDIO_POLICY_TEST
-
-        status_t setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled);
-
-        // returns the category the device belongs to with regard to volume curve management
-        static device_category getDeviceCategory(audio_devices_t device);
-
-        // extract one device relevant for volume control from multiple device selection
-        static audio_devices_t getDeviceForVolume(audio_devices_t device);
-
-        SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
-                        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs);
-        bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
-                                           SortedVector<audio_io_handle_t>& outputs2);
-
-        // 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(sp<AudioOutputDescriptor> outputDesc,
-                                            audio_devices_t prevDevice,
-                                            uint32_t delayMs);
-
-        audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
-                                       audio_output_flags_t flags,
-                                       audio_format_t format);
-        // samplingRate parameter is an in/out and so may be modified
-        sp<IOProfile> getInputProfile(audio_devices_t device,
-                                      String8 address,
-                                      uint32_t& samplingRate,
-                                      audio_format_t format,
-                                      audio_channel_mask_t channelMask,
-                                      audio_input_flags_t flags);
-        sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
-                                                       uint32_t samplingRate,
-                                                       audio_format_t format,
-                                                       audio_channel_mask_t channelMask,
-                                                       audio_output_flags_t flags);
-
-        audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
-
-        bool isNonOffloadableEffectEnabled();
-
-        virtual status_t addAudioPatch(audio_patch_handle_t handle,
-                               const sp<AudioPatch>& patch);
-        virtual status_t removeAudioPatch(audio_patch_handle_t handle);
-
-        sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
-        sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const;
-        sp<HwModule> getModuleForDevice(audio_devices_t device) const;
-        sp<HwModule> getModuleFromName(const char *name) const;
-        audio_devices_t availablePrimaryOutputDevices();
-        audio_devices_t availablePrimaryInputDevices();
-
-        void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0);
-
-        //
-        // Audio policy configuration file parsing (audio_policy.conf)
-        //
-        static uint32_t stringToEnum(const struct StringToEnum *table,
-                                     size_t size,
-                                     const char *name);
-        static const char *enumToString(const struct StringToEnum *table,
-                                      size_t size,
-                                      uint32_t value);
-        static bool stringToBool(const char *value);
-        static uint32_t parseOutputFlagNames(char *name);
-        static uint32_t parseInputFlagNames(char *name);
-        static audio_devices_t parseDeviceNames(char *name);
-        void loadHwModule(cnode *root);
-        void loadHwModules(cnode *root);
-        void loadGlobalConfig(cnode *root, const sp<HwModule>& module);
-        status_t loadAudioPolicyConfig(const char *path);
-        void defaultAudioPolicyConfig(void);
-
-
-        uid_t mUidCached;
-        AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
-        audio_io_handle_t mPrimaryOutput;              // primary output handle
-        // list of descriptors for outputs currently opened
-        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mOutputs;
-        // copy of mOutputs before setDeviceConnectionState() opens new outputs
-        // reset to mOutputs when updateDevicesAndOutputs() is called.
-        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mPreviousOutputs;
-        DefaultKeyedVector<audio_io_handle_t, sp<AudioInputDescriptor> > mInputs;     // list of input descriptors
-        DeviceVector  mAvailableOutputDevices; // all available output devices
-        DeviceVector  mAvailableInputDevices;  // all available input devices
-        int mPhoneState;                                                    // current phone state
-        audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];   // current forced use configuration
-
-        StreamDescriptor mStreams[AUDIO_STREAM_CNT];           // stream descriptors for volume control
-        bool    mLimitRingtoneVolume;                                       // limit ringtone volume to music volume if headset connected
-        audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
-        float   mLastVoiceVolume;                                           // last voice volume value sent to audio HAL
-
-        // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
-        static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
-        // Maximum memory allocated to audio effects in KB
-        static const uint32_t MAX_EFFECTS_MEMORY = 512;
-        uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
-        uint32_t mTotalEffectsMemory;  // current memory used by effects
-        KeyedVector<int, sp<EffectDescriptor> > mEffects;  // list of registered audio effects
-        bool    mA2dpSuspended;  // true if A2DP output is suspended
-        sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
-        bool mSpeakerDrcEnabled;// true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
-                                // to boost soft sounds, used to adjust volume curves accordingly
-
-        Vector < sp<HwModule> > mHwModules;
-        static volatile int32_t mNextUniqueId;
-        volatile int32_t mAudioPortGeneration;
-
-        DefaultKeyedVector<audio_patch_handle_t, sp<AudioPatch> > mAudioPatches;
-
-        DefaultKeyedVector<audio_session_t, audio_io_handle_t> mSoundTriggerSessions;
-
-        sp<AudioPatch> mCallTxPatch;
-        sp<AudioPatch> mCallRxPatch;
-
-        // for supporting "beacon" streams, i.e. streams that only play on speaker, and never
-        // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing
-        enum {
-            STARTING_OUTPUT,
-            STARTING_BEACON,
-            STOPPING_OUTPUT,
-            STOPPING_BEACON
-        };
-        uint32_t mBeaconMuteRefCount;   // ref count for stream that would mute beacon
-        uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams
-        bool mBeaconMuted;              // has STREAM_TTS been muted
-
-        // custom mix entry in mPolicyMixes
-        class AudioPolicyMix : public RefBase {
-        public:
-            AudioPolicyMix() {}
-
-            AudioMix    mMix;                   // Audio policy mix descriptor
-            sp<AudioOutputDescriptor> mOutput;  // Corresponding output stream
-        };
-        DefaultKeyedVector<String8, sp<AudioPolicyMix> > mPolicyMixes; // list of registered mixes
-
-
-#ifdef AUDIO_POLICY_TEST
-        Mutex   mLock;
-        Condition mWaitWorkCV;
-
-        int             mCurOutput;
-        bool            mDirectOutput;
-        audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
-        int             mTestInput;
-        uint32_t        mTestDevice;
-        uint32_t        mTestSamplingRate;
-        uint32_t        mTestFormat;
-        uint32_t        mTestChannels;
-        uint32_t        mTestLatencyMs;
-#endif //AUDIO_POLICY_TEST
-        static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
-                int indexInUi);
-        static bool isVirtualInputDevice(audio_devices_t device);
-        static uint32_t nextUniqueId();
-        uint32_t nextAudioPortGeneration();
-private:
-        // updates device caching and output for streams that can influence the
-        //    routing of notifications
-        void handleNotificationRoutingForStream(audio_stream_type_t stream);
-        static bool deviceDistinguishesOnAddress(audio_devices_t device);
-        // find the outputs on a given output descriptor that have the given address.
-        // to be called on an AudioOutputDescriptor whose supported devices (as defined
-        //   in mProfile->mSupportedDevices) matches the device whose address is to be matched.
-        // see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
-        //   where addresses are used to distinguish between one connected device and another.
-        void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
-                const audio_devices_t device /*in*/,
-                const String8 address /*in*/,
-                SortedVector<audio_io_handle_t>& outputs /*out*/);
-        uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
-        // internal method to return the output handle for the given device and format
-        audio_io_handle_t getOutputForDevice(
-                audio_devices_t device,
-                audio_session_t session,
-                audio_stream_type_t stream,
-                uint32_t samplingRate,
-                audio_format_t format,
-                audio_channel_mask_t channelMask,
-                audio_output_flags_t flags,
-                const audio_offload_info_t *offloadInfo);
-        // internal function to derive a stream type value from audio attributes
-        audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
-        // return true if any output is playing anything besides the stream to ignore
-        bool isAnyOutputActive(audio_stream_type_t streamToIgnore);
-        // 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
-        uint32_t handleEventForBeacon(int event);
-        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().
-        audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
-                                                        AudioMix **policyMix = NULL);
-
-        // Called by setDeviceConnectionState().
-        status_t setDeviceConnectionStateInt(audio_devices_t device,
-                                                          audio_policy_dev_state_t state,
-                                                          const char *device_address,
-                                                          const char *device_name);
-        sp<DeviceDescriptor>  getDeviceDescriptor(const audio_devices_t device,
-                                                  const char *device_address,
-                                                  const char *device_name);
-};
-
-};
diff --git a/services/audiopolicy/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
similarity index 94%
rename from services/audiopolicy/AudioPolicyFactory.cpp
rename to services/audiopolicy/manager/AudioPolicyFactory.cpp
index 2ae7bc1..9910a1f 100644
--- a/services/audiopolicy/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "AudioPolicyManager.h"
+#include "managerdefault/AudioPolicyManager.h"
 
 namespace android {
 
diff --git a/services/audiopolicy/AudioPolicyFactory.cpp b/services/audiopolicy/managerdefault/ApmImplDefinitions.h
similarity index 60%
copy from services/audiopolicy/AudioPolicyFactory.cpp
copy to services/audiopolicy/managerdefault/ApmImplDefinitions.h
index 2ae7bc1..620979b 100644
--- a/services/audiopolicy/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/managerdefault/ApmImplDefinitions.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,19 +14,19 @@
  * limitations under the License.
  */
 
-#include "AudioPolicyManager.h"
-
 namespace android {
 
-extern "C" AudioPolicyInterface* createAudioPolicyManager(
-        AudioPolicyClientInterface *clientInterface)
-{
-    return new AudioPolicyManager(clientInterface);
-}
+enum routing_strategy {
+    STRATEGY_MEDIA,
+    STRATEGY_PHONE,
+    STRATEGY_SONIFICATION,
+    STRATEGY_SONIFICATION_RESPECTFUL,
+    STRATEGY_DTMF,
+    STRATEGY_ENFORCED_AUDIBLE,
+    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+    STRATEGY_ACCESSIBILITY,
+    STRATEGY_REROUTING,
+    NUM_STRATEGIES
+};
 
-extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
-{
-    delete interface;
-}
-
-}; // namespace android
+}; //namespace android
diff --git a/services/audiopolicy/managerdefault/AudioInputDescriptor.cpp b/services/audiopolicy/managerdefault/AudioInputDescriptor.cpp
new file mode 100644
index 0000000..f4054c8
--- /dev/null
+++ b/services/audiopolicy/managerdefault/AudioInputDescriptor.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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::AudioInputDescriptor"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+namespace android {
+
+AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
+    : mId(0), mIoHandle(0),
+      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0),
+      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)
+{
+    if (profile != NULL) {
+        mSamplingRate = profile->pickSamplingRate();
+        mFormat = profile->pickFormat();
+        mChannelMask = profile->pickChannelMask();
+        if (profile->mGains.size() > 0) {
+            profile->mGains[0]->getDefaultConfig(&mGain);
+        }
+    }
+}
+
+void AudioInputDescriptor::toAudioPortConfig(
+                                                   struct audio_port_config *dstConfig,
+                                                   const struct audio_port_config *srcConfig) const
+{
+    ALOG_ASSERT(mProfile != 0,
+                "toAudioPortConfig() called on input with null profile %d", mIoHandle);
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
+                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask |= srcConfig->config_mask;
+    }
+
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
+    dstConfig->id = mId;
+    dstConfig->role = AUDIO_PORT_ROLE_SINK;
+    dstConfig->type = AUDIO_PORT_TYPE_MIX;
+    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
+    dstConfig->ext.mix.handle = mIoHandle;
+    dstConfig->ext.mix.usecase.source = mInputSource;
+}
+
+void AudioInputDescriptor::toAudioPort(
+                                                    struct audio_port *port) const
+{
+    ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
+
+    mProfile->toAudioPort(port);
+    port->id = mId;
+    toAudioPortConfig(&port->active_config);
+    port->ext.mix.hw_module = mProfile->mModule->mHandle;
+    port->ext.mix.handle = mIoHandle;
+    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
+}
+
+status_t AudioInputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " ID: %d\n", mId);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount);
+    result.append(buffer);
+
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+}; //namespace android
diff --git a/services/audiopolicy/managerdefault/AudioInputDescriptor.h b/services/audiopolicy/managerdefault/AudioInputDescriptor.h
new file mode 100644
index 0000000..02579e6
--- /dev/null
+++ b/services/audiopolicy/managerdefault/AudioInputDescriptor.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
+// and keep track of the usage of this input.
+class AudioInputDescriptor: public AudioPortConfig
+{
+public:
+    AudioInputDescriptor(const sp<IOProfile>& profile);
+
+    status_t    dump(int fd);
+
+    audio_port_handle_t           mId;
+    audio_io_handle_t             mIoHandle;       // input handle
+    audio_devices_t               mDevice;         // current device this input is routed to
+    AudioMix                      *mPolicyMix;     // non NULL when used by a dynamic policy
+    audio_patch_handle_t          mPatchHandle;
+    uint32_t                      mRefCount;       // number of AudioRecord clients using
+    // this input
+    uint32_t                      mOpenRefCount;
+    audio_source_t                mInputSource;    // input source selected by application
+    //(mediarecorder.h)
+    const sp<IOProfile>           mProfile;        // I/O profile this output derives from
+    SortedVector<audio_session_t> mSessions;       // audio sessions attached to this input
+    bool                          mIsSoundTrigger; // used by a soundtrigger capture
+
+    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+            const struct audio_port_config *srcConfig = NULL) const;
+    virtual sp<AudioPort> getAudioPort() const { return mProfile; }
+    void toAudioPort(struct audio_port *port) const;
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioOutputDescriptor.cpp b/services/audiopolicy/managerdefault/AudioOutputDescriptor.cpp
new file mode 100644
index 0000000..4b85972
--- /dev/null
+++ b/services/audiopolicy/managerdefault/AudioOutputDescriptor.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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::AudioOutputDescriptor"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+namespace android {
+
+AudioOutputDescriptor::AudioOutputDescriptor(
+        const sp<IOProfile>& profile)
+    : mId(0), mIoHandle(0), mLatency(0),
+    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
+    mPatchHandle(0),
+    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
+{
+    // clear usage count for all stream types
+    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
+        mRefCount[i] = 0;
+        mCurVolume[i] = -1.0;
+        mMuteCount[i] = 0;
+        mStopTime[i] = 0;
+    }
+    for (int i = 0; i < NUM_STRATEGIES; i++) {
+        mStrategyMutedByDevice[i] = false;
+    }
+    if (profile != NULL) {
+        mFlags = (audio_output_flags_t)profile->mFlags;
+        mSamplingRate = profile->pickSamplingRate();
+        mFormat = profile->pickFormat();
+        mChannelMask = profile->pickChannelMask();
+        if (profile->mGains.size() > 0) {
+            profile->mGains[0]->getDefaultConfig(&mGain);
+        }
+    }
+}
+
+audio_devices_t AudioOutputDescriptor::device() const
+{
+    if (isDuplicated()) {
+        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
+    } else {
+        return mDevice;
+    }
+}
+
+uint32_t AudioOutputDescriptor::latency()
+{
+    if (isDuplicated()) {
+        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
+    } else {
+        return mLatency;
+    }
+}
+
+bool AudioOutputDescriptor::sharesHwModuleWith(
+        const sp<AudioOutputDescriptor> outputDesc)
+{
+    if (isDuplicated()) {
+        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
+    } else if (outputDesc->isDuplicated()){
+        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
+    } else {
+        return (mProfile->mModule == outputDesc->mProfile->mModule);
+    }
+}
+
+void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
+                                                                   int delta)
+{
+    // forward usage count change to attached outputs
+    if (isDuplicated()) {
+        mOutput1->changeRefCount(stream, delta);
+        mOutput2->changeRefCount(stream, delta);
+    }
+    if ((delta + (int)mRefCount[stream]) < 0) {
+        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
+              delta, stream, mRefCount[stream]);
+        mRefCount[stream] = 0;
+        return;
+    }
+    mRefCount[stream] += delta;
+    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
+}
+
+audio_devices_t AudioOutputDescriptor::supportedDevices()
+{
+    if (isDuplicated()) {
+        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
+    } else {
+        return mProfile->mSupportedDevices.types() ;
+    }
+}
+
+bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
+{
+    return isStrategyActive(NUM_STRATEGIES, inPastMs);
+}
+
+bool AudioOutputDescriptor::isStrategyActive(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_CNT; i++) {
+        if (i == AUDIO_STREAM_PATCH) {
+            continue;
+        }
+        if (((AudioPolicyManager::getStrategy((audio_stream_type_t)i) == strategy) ||
+                (NUM_STRATEGIES == strategy)) &&
+                isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
+                                                                       uint32_t inPastMs,
+                                                                       nsecs_t sysTime) const
+{
+    if (mRefCount[stream] != 0) {
+        return true;
+    }
+    if (inPastMs == 0) {
+        return false;
+    }
+    if (sysTime == 0) {
+        sysTime = systemTime();
+    }
+    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
+        return true;
+    }
+    return false;
+}
+
+void AudioOutputDescriptor::toAudioPortConfig(
+                                                 struct audio_port_config *dstConfig,
+                                                 const struct audio_port_config *srcConfig) const
+{
+    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
+
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
+                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask |= srcConfig->config_mask;
+    }
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
+    dstConfig->id = mId;
+    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
+    dstConfig->type = AUDIO_PORT_TYPE_MIX;
+    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
+    dstConfig->ext.mix.handle = mIoHandle;
+    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
+}
+
+void AudioOutputDescriptor::toAudioPort(
+                                                    struct audio_port *port) const
+{
+    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
+    mProfile->toAudioPort(port);
+    port->id = mId;
+    toAudioPortConfig(&port->active_config);
+    port->ext.mix.hw_module = mProfile->mModule->mHandle;
+    port->ext.mix.handle = mIoHandle;
+    port->ext.mix.latency_class =
+            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
+}
+
+status_t AudioOutputDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, " ID: %d\n", mId);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Devices %08x\n", device());
+    result.append(buffer);
+    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
+    result.append(buffer);
+    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
+        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
+                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+
+    return NO_ERROR;
+}
+
+
+
+}; //namespace android
diff --git a/services/audiopolicy/managerdefault/AudioOutputDescriptor.h b/services/audiopolicy/managerdefault/AudioOutputDescriptor.h
new file mode 100644
index 0000000..32f46e4
--- /dev/null
+++ b/services/audiopolicy/managerdefault/AudioOutputDescriptor.h
@@ -0,0 +1,69 @@
+/*
+ * 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 "ApmImplDefinitions.h"
+
+namespace android {
+
+// 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:
+    AudioOutputDescriptor(const sp<IOProfile>& profile);
+
+    status_t    dump(int fd);
+
+    audio_devices_t device() const;
+    void changeRefCount(audio_stream_type_t stream, int delta);
+
+    bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
+    audio_devices_t supportedDevices();
+    uint32_t latency();
+    bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
+    bool isActive(uint32_t inPastMs = 0) const;
+    bool isStreamActive(audio_stream_type_t stream,
+                        uint32_t inPastMs = 0,
+                        nsecs_t sysTime = 0) const;
+    bool isStrategyActive(routing_strategy strategy,
+                     uint32_t inPastMs = 0,
+                     nsecs_t sysTime = 0) const;
+
+    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+                           const struct audio_port_config *srcConfig = NULL) const;
+    virtual sp<AudioPort> getAudioPort() const { return mProfile; }
+    void toAudioPort(struct audio_port *port) const;
+
+    audio_port_handle_t mId;
+    audio_io_handle_t mIoHandle;              // output handle
+    uint32_t mLatency;                  //
+    audio_output_flags_t mFlags;   //
+    audio_devices_t mDevice;                   // current device this output is routed to
+    AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
+    audio_patch_handle_t mPatchHandle;
+    uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
+    nsecs_t mStopTime[AUDIO_STREAM_CNT];
+    sp<AudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
+    sp<AudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
+    float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume
+    int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
+    const sp<IOProfile> mProfile;          // I/O profile this output derives from
+    bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
+                                        // device selection. See checkDeviceMuteStrategies()
+    uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
similarity index 73%
rename from services/audiopolicy/AudioPolicyManager.cpp
rename to services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 50ea6ff..b48dc80 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "AudioPolicyManager"
+#define LOG_TAG "APM::AudioPolicyManager"
 //#define LOG_NDEBUG 0
 
 //#define VERY_VERBOSE_LOGGING
@@ -51,163 +51,6 @@
 namespace android {
 
 // ----------------------------------------------------------------------------
-// Definitions for audio_policy.conf file parsing
-// ----------------------------------------------------------------------------
-
-struct StringToEnum {
-    const char *name;
-    uint32_t value;
-};
-
-#define STRING_TO_ENUM(string) { #string, string }
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-const StringToEnum sDeviceNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
-};
-
-const StringToEnum sOutputFlagNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
-};
-
-const StringToEnum sInputFlagNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_INPUT_FLAG_FAST),
-    STRING_TO_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD),
-};
-
-const StringToEnum sFormatNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
-    STRING_TO_ENUM(AUDIO_FORMAT_MP3),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD),
-    STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
-    STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1),
-    STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2),
-    STRING_TO_ENUM(AUDIO_FORMAT_OPUS),
-    STRING_TO_ENUM(AUDIO_FORMAT_AC3),
-    STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
-};
-
-const StringToEnum sOutChannelsNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
-};
-
-const StringToEnum sInChannelsNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
-};
-
-const StringToEnum sGainModeNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT),
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS),
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP),
-};
-
-
-uint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table,
-                                              size_t size,
-                                              const char *name)
-{
-    for (size_t i = 0; i < size; i++) {
-        if (strcmp(table[i].name, name) == 0) {
-            ALOGV("stringToEnum() found %s", table[i].name);
-            return table[i].value;
-        }
-    }
-    return 0;
-}
-
-const char *AudioPolicyManager::enumToString(const struct StringToEnum *table,
-                                              size_t size,
-                                              uint32_t value)
-{
-    for (size_t i = 0; i < size; i++) {
-        if (table[i].value == value) {
-            return table[i].name;
-        }
-    }
-    return "";
-}
-
-bool AudioPolicyManager::stringToBool(const char *value)
-{
-    return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
-}
-
-
-// ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
 // ----------------------------------------------------------------------------
 
@@ -276,8 +119,7 @@
             ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
                   outputs.size());
 
-
-            // Set connect to HALs
+            // Send connect to HALs
             AudioParameter param = AudioParameter(devDesc->mAddress);
             param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
             mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
@@ -452,10 +294,9 @@
     }
 }
 
-sp<AudioPolicyManager::DeviceDescriptor>  AudioPolicyManager::getDeviceDescriptor(
-                                                                    const audio_devices_t device,
-                                                                    const char *device_address,
-                                                                    const char *device_name)
+sp<DeviceDescriptor>  AudioPolicyManager::getDeviceDescriptor(const audio_devices_t device,
+                                                              const char *device_address,
+                                                              const char *device_name)
 {
     String8 address = (device_address == NULL) ? String8("") : String8(device_address);
     // handle legacy remote submix case where the address was not always specified
@@ -642,18 +483,18 @@
         // force routing command to audio hardware when starting a call
         // even if no device change is needed
         force = true;
-        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
+        for (int j = 0; j < ApmGains::DEVICE_CATEGORY_CNT; j++) {
             mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
-                    sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
+                    ApmGains::sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
         }
     } else if (isStateInCall(oldState) && !isStateInCall(state)) {
         ALOGV("  Exiting call in setPhoneState()");
         // force routing command to audio hardware when exiting a call
         // even if no device change is needed
         force = true;
-        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
+        for (int j = 0; j < ApmGains::DEVICE_CATEGORY_CNT; j++) {
             mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
-                    sVolumeProfiles[AUDIO_STREAM_DTMF][j];
+                    ApmGains::sVolumeProfiles[AUDIO_STREAM_DTMF][j];
         }
     } else if (isStateInCall(state) && (state != oldState)) {
         ALOGV("  Switching between telephony and VoIP in setPhoneState()");
@@ -844,7 +685,7 @@
 
 // Find a direct output profile compatible with the parameters passed, even if the input flags do
 // not explicitly request a direct output
-sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput(
+sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
                                                                audio_devices_t device,
                                                                uint32_t samplingRate,
                                                                audio_format_t format,
@@ -1132,6 +973,10 @@
             if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
                 goto non_direct_output;
             }
+            // fall back to mixer output if possible when the direct output could not be open
+            if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
+                goto non_direct_output;
+            }
             return AUDIO_IO_HANDLE_NONE;
         }
         outputDesc->mSamplingRate = config.sample_rate;
@@ -1853,7 +1698,7 @@
     status_t status = NO_ERROR;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         audio_devices_t curDevice =
-                getDeviceForVolume(mOutputs.valueAt(i)->device());
+                ApmGains::getDeviceForVolume(mOutputs.valueAt(i)->device());
         if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {
             status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
             if (volStatus != NO_ERROR) {
@@ -1883,7 +1728,7 @@
     if (device == AUDIO_DEVICE_OUT_DEFAULT) {
         device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
     }
-    device = getDeviceForVolume(device);
+    device = ApmGains::getDeviceForVolume(device);
 
     *index =  mStreams[stream].getVolumeIndex(device);
     ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
@@ -2467,7 +2312,7 @@
     return NO_ERROR;
 }
 
-sp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId(
+sp<AudioOutputDescriptor> AudioPolicyManager::getOutputFromId(
                                                                     audio_port_handle_t id) const
 {
     sp<AudioOutputDescriptor> outputDesc = NULL;
@@ -2480,7 +2325,7 @@
     return outputDesc;
 }
 
-sp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId(
+sp<AudioInputDescriptor> AudioPolicyManager::getInputFromId(
                                                                     audio_port_handle_t id) const
 {
     sp<AudioInputDescriptor> inputDesc = NULL;
@@ -2493,7 +2338,7 @@
     return inputDesc;
 }
 
-sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice(
+sp <HwModule> AudioPolicyManager::getModuleForDevice(
                                                                     audio_devices_t device) const
 {
     sp <HwModule> module;
@@ -2521,7 +2366,7 @@
     return module;
 }
 
-sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const
+sp <HwModule> AudioPolicyManager::getModuleFromName(const char *name) const
 {
     sp <HwModule> module;
 
@@ -4332,7 +4177,7 @@
         return AUDIO_DEVICE_NONE;
     }
     audio_devices_t devices;
-    AudioPolicyManager::routing_strategy strategy = getStrategy(stream);
+    routing_strategy strategy = getStrategy(stream);
     devices = getDeviceForStrategy(strategy, true /*fromCache*/);
     SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
     for (size_t i = 0; i < outputs.size(); i++) {
@@ -4353,7 +4198,7 @@
     return devices;
 }
 
-AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
+routing_strategy AudioPolicyManager::getStrategy(
         audio_stream_type_t stream) {
 
     ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
@@ -5132,7 +4977,7 @@
     return status;
 }
 
-sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
+sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
                                                    String8 address,
                                                    uint32_t& samplingRate,
                                                    audio_format_t format,
@@ -5342,305 +5187,29 @@
 }
 
 
-audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
-{
-    if (device == AUDIO_DEVICE_NONE) {
-        // this happens when forcing a route update and no track is active on an output.
-        // In this case the returned category is not important.
-        device =  AUDIO_DEVICE_OUT_SPEAKER;
-    } else if (popcount(device) > 1) {
-        // Multiple device selection is either:
-        //  - speaker + one other device: give priority to speaker in this case.
-        //  - one A2DP device + another device: happens with duplicated output. In this case
-        // retain the device on the A2DP output as the other must not correspond to an active
-        // selection if not the speaker.
-        //  - HDMI-CEC system audio mode only output: give priority to available item in order.
-        if (device & AUDIO_DEVICE_OUT_SPEAKER) {
-            device = AUDIO_DEVICE_OUT_SPEAKER;
-        } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) {
-            device = AUDIO_DEVICE_OUT_HDMI_ARC;
-        } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) {
-            device = AUDIO_DEVICE_OUT_AUX_LINE;
-        } else if (device & AUDIO_DEVICE_OUT_SPDIF) {
-            device = AUDIO_DEVICE_OUT_SPDIF;
-        } else {
-            device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
-        }
-    }
-
-    /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/
-    if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE)
-        device = AUDIO_DEVICE_OUT_SPEAKER;
-
-    ALOGW_IF(popcount(device) != 1,
-            "getDeviceForVolume() invalid device combination: %08x",
-            device);
-
-    return device;
-}
-
-AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
-{
-    switch(getDeviceForVolume(device)) {
-        case AUDIO_DEVICE_OUT_EARPIECE:
-            return DEVICE_CATEGORY_EARPIECE;
-        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
-        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
-            return DEVICE_CATEGORY_HEADSET;
-        case AUDIO_DEVICE_OUT_LINE:
-        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
-        /*USB?  Remote submix?*/
-            return DEVICE_CATEGORY_EXT_MEDIA;
-        case AUDIO_DEVICE_OUT_SPEAKER:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
-        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
-        case AUDIO_DEVICE_OUT_USB_DEVICE:
-        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
-        default:
-            return DEVICE_CATEGORY_SPEAKER;
-    }
-}
-
-/* static */
-float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
-        int indexInUi)
-{
-    device_category deviceCategory = getDeviceCategory(device);
-    const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
-
-    // the volume index in the UI is relative to the min and max volume indices for this stream type
-    int nbSteps = 1 + curve[VOLMAX].mIndex -
-            curve[VOLMIN].mIndex;
-    int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
-            (streamDesc.mIndexMax - streamDesc.mIndexMin);
-
-    // find what part of the curve this index volume belongs to, or if it's out of bounds
-    int segment = 0;
-    if (volIdx < curve[VOLMIN].mIndex) {         // out of bounds
-        return 0.0f;
-    } else if (volIdx < curve[VOLKNEE1].mIndex) {
-        segment = 0;
-    } else if (volIdx < curve[VOLKNEE2].mIndex) {
-        segment = 1;
-    } else if (volIdx <= curve[VOLMAX].mIndex) {
-        segment = 2;
-    } else {                                                               // out of bounds
-        return 1.0f;
-    }
-
-    // linear interpolation in the attenuation table in dB
-    float decibels = curve[segment].mDBAttenuation +
-            ((float)(volIdx - curve[segment].mIndex)) *
-                ( (curve[segment+1].mDBAttenuation -
-                        curve[segment].mDBAttenuation) /
-                    ((float)(curve[segment+1].mIndex -
-                            curve[segment].mIndex)) );
-
-    float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
-
-    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
-            curve[segment].mIndex, volIdx,
-            curve[segment+1].mIndex,
-            curve[segment].mDBAttenuation,
-            decibels,
-            curve[segment+1].mDBAttenuation,
-            amplification);
-
-    return amplification;
-}
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sExtMediaSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
-};
-
-// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
-// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
-// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
-// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sLinearVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSilentVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-            *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
-                                                   [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
-    { // AUDIO_STREAM_VOICE_CALL
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_SYSTEM
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_RING
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_MUSIC
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_ALARM
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_NOTIFICATION
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_BLUETOOTH_SCO
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_ENFORCED_AUDIBLE
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    {  // AUDIO_STREAM_DTMF
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_TTS
-      // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER
-        sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sSilentVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_ACCESSIBILITY
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_REROUTING
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-    { // AUDIO_STREAM_PATCH
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
-    },
-};
-
 void AudioPolicyManager::initializeVolumeCurves()
 {
     for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
+        for (int j = 0; j < ApmGains::DEVICE_CATEGORY_CNT; j++) {
             mStreams[i].mVolumeCurve[j] =
-                    sVolumeProfiles[i][j];
+                    ApmGains::sVolumeProfiles[i][j];
         }
     }
 
     // Check availability of DRC on speaker path: if available, override some of the speaker curves
     if (mSpeakerDrcEnabled) {
-        mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sDefaultSystemVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerMediaVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_ACCESSIBILITY].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerMediaVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sDefaultSystemVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_RING].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sSpeakerSonificationVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sSpeakerSonificationVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sSpeakerSonificationVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sSpeakerMediaVolumeCurveDrc;
+        mStreams[AUDIO_STREAM_ACCESSIBILITY].mVolumeCurve[ApmGains::DEVICE_CATEGORY_SPEAKER] =
+                ApmGains::sSpeakerMediaVolumeCurveDrc;
     }
 }
 
@@ -5657,7 +5226,7 @@
         device = outputDesc->device();
     }
 
-    volume = volIndexToAmpl(device, streamDesc, index);
+    volume = ApmGains::volIndexToAmpl(device, streamDesc, index);
 
     // if a headset is connected, apply the following rules to ring tones and notifications
     // to avoid sound level bursts in user's ears:
@@ -5913,319 +5482,6 @@
 }
 
 
-// --- AudioOutputDescriptor class implementation
-
-AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
-        const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mLatency(0),
-    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
-    mPatchHandle(0),
-    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
-{
-    // clear usage count for all stream types
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        mRefCount[i] = 0;
-        mCurVolume[i] = -1.0;
-        mMuteCount[i] = 0;
-        mStopTime[i] = 0;
-    }
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mStrategyMutedByDevice[i] = false;
-    }
-    if (profile != NULL) {
-        mFlags = (audio_output_flags_t)profile->mFlags;
-        mSamplingRate = profile->pickSamplingRate();
-        mFormat = profile->pickFormat();
-        mChannelMask = profile->pickChannelMask();
-        if (profile->mGains.size() > 0) {
-            profile->mGains[0]->getDefaultConfig(&mGain);
-        }
-    }
-}
-
-audio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const
-{
-    if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
-    } else {
-        return mDevice;
-    }
-}
-
-uint32_t AudioPolicyManager::AudioOutputDescriptor::latency()
-{
-    if (isDuplicated()) {
-        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
-    } else {
-        return mLatency;
-    }
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
-        const sp<AudioOutputDescriptor> outputDesc)
-{
-    if (isDuplicated()) {
-        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
-    } else if (outputDesc->isDuplicated()){
-        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
-    } else {
-        return (mProfile->mModule == outputDesc->mProfile->mModule);
-    }
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
-                                                                   int delta)
-{
-    // forward usage count change to attached outputs
-    if (isDuplicated()) {
-        mOutput1->changeRefCount(stream, delta);
-        mOutput2->changeRefCount(stream, delta);
-    }
-    if ((delta + (int)mRefCount[stream]) < 0) {
-        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
-              delta, stream, mRefCount[stream]);
-        mRefCount[stream] = 0;
-        return;
-    }
-    mRefCount[stream] += delta;
-    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
-}
-
-audio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices()
-{
-    if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
-    } else {
-        return mProfile->mSupportedDevices.types() ;
-    }
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const
-{
-    return isStrategyActive(NUM_STRATEGIES, inPastMs);
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(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_CNT; i++) {
-        if (i == AUDIO_STREAM_PATCH) {
-            continue;
-        }
-        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
-                (NUM_STRATEGIES == strategy)) &&
-                isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
-                                                                       uint32_t inPastMs,
-                                                                       nsecs_t sysTime) const
-{
-    if (mRefCount[stream] != 0) {
-        return true;
-    }
-    if (inPastMs == 0) {
-        return false;
-    }
-    if (sysTime == 0) {
-        sysTime = systemTime();
-    }
-    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
-        return true;
-    }
-    return false;
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig(
-                                                 struct audio_port_config *dstConfig,
-                                                 const struct audio_port_config *srcConfig) const
-{
-    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
-
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
-    if (srcConfig != NULL) {
-        dstConfig->config_mask |= srcConfig->config_mask;
-    }
-    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
-
-    dstConfig->id = mId;
-    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
-    dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
-    dstConfig->ext.mix.handle = mIoHandle;
-    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
-{
-    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
-    mProfile->toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
-    port->ext.mix.handle = mIoHandle;
-    port->ext.mix.latency_class =
-            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
-}
-
-status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " ID: %d\n", mId);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", device());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
-    result.append(buffer);
-    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
-                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- AudioInputDescriptor class implementation
-
-AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0),
-      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0),
-      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)
-{
-    if (profile != NULL) {
-        mSamplingRate = profile->pickSamplingRate();
-        mFormat = profile->pickFormat();
-        mChannelMask = profile->pickChannelMask();
-        if (profile->mGains.size() > 0) {
-            profile->mGains[0]->getDefaultConfig(&mGain);
-        }
-    }
-}
-
-void AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig(
-                                                   struct audio_port_config *dstConfig,
-                                                   const struct audio_port_config *srcConfig) const
-{
-    ALOG_ASSERT(mProfile != 0,
-                "toAudioPortConfig() called on input with null profile %d", mIoHandle);
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
-    if (srcConfig != NULL) {
-        dstConfig->config_mask |= srcConfig->config_mask;
-    }
-
-    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
-
-    dstConfig->id = mId;
-    dstConfig->role = AUDIO_PORT_ROLE_SINK;
-    dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
-    dstConfig->ext.mix.handle = mIoHandle;
-    dstConfig->ext.mix.usecase.source = mInputSource;
-}
-
-void AudioPolicyManager::AudioInputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
-{
-    ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
-
-    mProfile->toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
-    port->ext.mix.handle = mIoHandle;
-    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
-}
-
-status_t AudioPolicyManager::AudioInputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " ID: %d\n", mId);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- StreamDescriptor class implementation
-
-AudioPolicyManager::StreamDescriptor::StreamDescriptor()
-    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
-{
-    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
-}
-
-int AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device)
-{
-    device = AudioPolicyManager::getDeviceForVolume(device);
-    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
-    if (mIndexCur.indexOfKey(device) < 0) {
-        device = AUDIO_DEVICE_OUT_DEFAULT;
-    }
-    return mIndexCur.valueFor(device);
-}
-
-void AudioPolicyManager::StreamDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
-             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
-    result.append(buffer);
-    for (size_t i = 0; i < mIndexCur.size(); i++) {
-        snprintf(buffer, SIZE, "%04x : %02d, ",
-                 mIndexCur.keyAt(i),
-                 mIndexCur.valueAt(i));
-        result.append(buffer);
-    }
-    result.append("\n");
-
-    write(fd, result.string(), result.size());
-}
-
 // --- EffectDescriptor class implementation
 
 status_t AudioPolicyManager::EffectDescriptor::dump(int fd)
@@ -6249,1611 +5505,9 @@
     return NO_ERROR;
 }
 
-// --- HwModule class implementation
-
-AudioPolicyManager::HwModule::HwModule(const char *name)
-    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)),
-      mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0)
-{
-}
-
-AudioPolicyManager::HwModule::~HwModule()
-{
-    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-        mOutputProfiles[i]->mSupportedDevices.clear();
-    }
-    for (size_t i = 0; i < mInputProfiles.size(); i++) {
-        mInputProfiles[i]->mSupportedDevices.clear();
-    }
-    free((void *)mName);
-}
-
-status_t AudioPolicyManager::HwModule::loadInput(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
-
-    while (node) {
-        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
-            profile->loadSamplingRates((char *)node->value);
-        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
-            profile->loadFormats((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            profile->loadInChannels((char *)node->value);
-        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
-            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
-                                                           mDeclaredDevices);
-        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
-            profile->mFlags = parseInputFlagNames((char *)node->value);
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            profile->loadGains(node);
-        }
-        node = node->next;
-    }
-    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
-            "loadInput() invalid supported devices");
-    ALOGW_IF(profile->mChannelMasks.size() == 0,
-            "loadInput() invalid supported channel masks");
-    ALOGW_IF(profile->mSamplingRates.size() == 0,
-            "loadInput() invalid supported sampling rates");
-    ALOGW_IF(profile->mFormats.size() == 0,
-            "loadInput() invalid supported formats");
-    if (!profile->mSupportedDevices.isEmpty() &&
-            (profile->mChannelMasks.size() != 0) &&
-            (profile->mSamplingRates.size() != 0) &&
-            (profile->mFormats.size() != 0)) {
-
-        ALOGV("loadInput() adding input Supported Devices %04x",
-              profile->mSupportedDevices.types());
-
-        mInputProfiles.add(profile);
-        return NO_ERROR;
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-status_t AudioPolicyManager::HwModule::loadOutput(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
-
-    while (node) {
-        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
-            profile->loadSamplingRates((char *)node->value);
-        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
-            profile->loadFormats((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            profile->loadOutChannels((char *)node->value);
-        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
-            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
-                                                           mDeclaredDevices);
-        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
-            profile->mFlags = parseOutputFlagNames((char *)node->value);
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            profile->loadGains(node);
-        }
-        node = node->next;
-    }
-    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
-            "loadOutput() invalid supported devices");
-    ALOGW_IF(profile->mChannelMasks.size() == 0,
-            "loadOutput() invalid supported channel masks");
-    ALOGW_IF(profile->mSamplingRates.size() == 0,
-            "loadOutput() invalid supported sampling rates");
-    ALOGW_IF(profile->mFormats.size() == 0,
-            "loadOutput() invalid supported formats");
-    if (!profile->mSupportedDevices.isEmpty() &&
-            (profile->mChannelMasks.size() != 0) &&
-            (profile->mSamplingRates.size() != 0) &&
-            (profile->mFormats.size() != 0)) {
-
-        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
-              profile->mSupportedDevices.types(), profile->mFlags);
-
-        mOutputProfiles.add(profile);
-        return NO_ERROR;
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-status_t AudioPolicyManager::HwModule::loadDevice(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    audio_devices_t type = AUDIO_DEVICE_NONE;
-    while (node) {
-        if (strcmp(node->name, DEVICE_TYPE) == 0) {
-            type = parseDeviceNames((char *)node->value);
-            break;
-        }
-        node = node->next;
-    }
-    if (type == AUDIO_DEVICE_NONE ||
-            (!audio_is_input_device(type) && !audio_is_output_device(type))) {
-        ALOGW("loadDevice() bad type %08x", type);
-        return BAD_VALUE;
-    }
-    sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
-    deviceDesc->mModule = this;
-
-    node = root->first_child;
-    while (node) {
-        if (strcmp(node->name, DEVICE_ADDRESS) == 0) {
-            deviceDesc->mAddress = String8((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            if (audio_is_input_device(type)) {
-                deviceDesc->loadInChannels((char *)node->value);
-            } else {
-                deviceDesc->loadOutChannels((char *)node->value);
-            }
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            deviceDesc->loadGains(node);
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadDevice() adding device name %s type %08x address %s",
-          deviceDesc->mName.string(), type, deviceDesc->mAddress.string());
-
-    mDeclaredDevices.add(deviceDesc);
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::HwModule::addOutputProfile(String8 name, const audio_config_t *config,
-                                                  audio_devices_t device, String8 address)
-{
-    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this);
-
-    profile->mSamplingRates.add(config->sample_rate);
-    profile->mChannelMasks.add(config->channel_mask);
-    profile->mFormats.add(config->format);
-
-    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
-    devDesc->mAddress = address;
-    profile->mSupportedDevices.add(devDesc);
-
-    mOutputProfiles.add(profile);
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::HwModule::removeOutputProfile(String8 name)
-{
-    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-        if (mOutputProfiles[i]->mName == name) {
-            mOutputProfiles.removeAt(i);
-            break;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::HwModule::addInputProfile(String8 name, const audio_config_t *config,
-                                                  audio_devices_t device, String8 address)
-{
-    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this);
-
-    profile->mSamplingRates.add(config->sample_rate);
-    profile->mChannelMasks.add(config->channel_mask);
-    profile->mFormats.add(config->format);
-
-    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
-    devDesc->mAddress = address;
-    profile->mSupportedDevices.add(devDesc);
-
-    ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask);
-
-    mInputProfiles.add(profile);
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::HwModule::removeInputProfile(String8 name)
-{
-    for (size_t i = 0; i < mInputProfiles.size(); i++) {
-        if (mInputProfiles[i]->mName == name) {
-            mInputProfiles.removeAt(i);
-            break;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-
-void AudioPolicyManager::HwModule::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "  - name: %s\n", mName);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    if (mOutputProfiles.size()) {
-        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
-        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    output %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mOutputProfiles[i]->dump(fd);
-        }
-    }
-    if (mInputProfiles.size()) {
-        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
-        for (size_t i = 0; i < mInputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    input %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mInputProfiles[i]->dump(fd);
-        }
-    }
-    if (mDeclaredDevices.size()) {
-        write(fd, "  - devices:\n", strlen("  - devices:\n"));
-        for (size_t i = 0; i < mDeclaredDevices.size(); i++) {
-            mDeclaredDevices[i]->dump(fd, 4, i);
-        }
-    }
-}
-
-// --- AudioPort class implementation
-
-
-AudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type,
-          audio_port_role_t role, const sp<HwModule>& module) :
-    mName(name), mType(type), mRole(role), mModule(module), mFlags(0), mId(0)
-{
-    mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
-                    ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
-}
-
-void AudioPolicyManager::AudioPort::attach(const sp<HwModule>& module) {
-    mId = AudioPolicyManager::nextUniqueId();
-    mModule = module;
-}
-
-void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const
-{
-    port->role = mRole;
-    port->type = mType;
-    strlcpy(port->name, mName, AUDIO_PORT_MAX_NAME_LEN);
-    unsigned int i;
-    for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) {
-        if (mSamplingRates[i] != 0) {
-            port->sample_rates[i] = mSamplingRates[i];
-        }
-    }
-    port->num_sample_rates = i;
-    for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) {
-        if (mChannelMasks[i] != 0) {
-            port->channel_masks[i] = mChannelMasks[i];
-        }
-    }
-    port->num_channel_masks = i;
-    for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) {
-        if (mFormats[i] != 0) {
-            port->formats[i] = mFormats[i];
-        }
-    }
-    port->num_formats = i;
-
-    ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
-
-    for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
-        port->gains[i] = mGains[i]->mGain;
-    }
-    port->num_gains = i;
-}
-
-void AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) {
-    for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) {
-        const uint32_t rate = port->mSamplingRates.itemAt(k);
-        if (rate != 0) { // skip "dynamic" rates
-            bool hasRate = false;
-            for (size_t l = 0 ; l < mSamplingRates.size() ; l++) {
-                if (rate == mSamplingRates.itemAt(l)) {
-                    hasRate = true;
-                    break;
-                }
-            }
-            if (!hasRate) { // never import a sampling rate twice
-                mSamplingRates.add(rate);
-            }
-        }
-    }
-    for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) {
-        const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k);
-        if (mask != 0) { // skip "dynamic" masks
-            bool hasMask = false;
-            for (size_t l = 0 ; l < mChannelMasks.size() ; l++) {
-                if (mask == mChannelMasks.itemAt(l)) {
-                    hasMask = true;
-                    break;
-                }
-            }
-            if (!hasMask) { // never import a channel mask twice
-                mChannelMasks.add(mask);
-            }
-        }
-    }
-    for (size_t k = 0 ; k < port->mFormats.size() ; k++) {
-        const audio_format_t format = port->mFormats.itemAt(k);
-        if (format != 0) { // skip "dynamic" formats
-            bool hasFormat = false;
-            for (size_t l = 0 ; l < mFormats.size() ; l++) {
-                if (format == mFormats.itemAt(l)) {
-                    hasFormat = true;
-                    break;
-                }
-            }
-            if (!hasFormat) { // never import a channel mask twice
-                mFormats.add(format);
-            }
-        }
-    }
-    for (size_t k = 0 ; k < port->mGains.size() ; k++) {
-        sp<AudioGain> gain = port->mGains.itemAt(k);
-        if (gain != 0) {
-            bool hasGain = false;
-            for (size_t l = 0 ; l < mGains.size() ; l++) {
-                if (gain == mGains.itemAt(l)) {
-                    hasGain = true;
-                    break;
-                }
-            }
-            if (!hasGain) { // never import a gain twice
-                mGains.add(gain);
-            }
-        }
-    }
-}
-
-void AudioPolicyManager::AudioPort::clearCapabilities() {
-    mChannelMasks.clear();
-    mFormats.clear();
-    mSamplingRates.clear();
-    mGains.clear();
-}
-
-void AudioPolicyManager::AudioPort::loadSamplingRates(char *name)
-{
-    char *str = strtok(name, "|");
-
-    // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
-    // rates should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mSamplingRates.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        uint32_t rate = atoi(str);
-        if (rate != 0) {
-            ALOGV("loadSamplingRates() adding rate %d", rate);
-            mSamplingRates.add(rate);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadFormats(char *name)
-{
-    char *str = strtok(name, "|");
-
-    // by convention, "0' in the first entry in mFormats indicates the supported formats
-    // should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mFormats.add(AUDIO_FORMAT_DEFAULT);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable,
-                                                             ARRAY_SIZE(sFormatNameToEnumTable),
-                                                             str);
-        if (format != AUDIO_FORMAT_DEFAULT) {
-            mFormats.add(format);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadInChannels(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadInChannels() %s", name);
-
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mChannelMasks.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_channel_mask_t channelMask =
-                (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
-                                                   ARRAY_SIZE(sInChannelsNameToEnumTable),
-                                                   str);
-        if (channelMask != 0) {
-            ALOGV("loadInChannels() adding channelMask %04x", channelMask);
-            mChannelMasks.add(channelMask);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadOutChannels(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadOutChannels() %s", name);
-
-    // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
-    // masks should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mChannelMasks.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_channel_mask_t channelMask =
-                (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
-                                                   ARRAY_SIZE(sOutChannelsNameToEnumTable),
-                                                   str);
-        if (channelMask != 0) {
-            mChannelMasks.add(channelMask);
-        }
-        str = strtok(NULL, "|");
-    }
-    return;
-}
-
-audio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadGainMode() %s", name);
-    audio_gain_mode_t mode = 0;
-    while (str != NULL) {
-        mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable,
-                                                ARRAY_SIZE(sGainModeNameToEnumTable),
-                                                str);
-        str = strtok(NULL, "|");
-    }
-    return mode;
-}
-
-void AudioPolicyManager::AudioPort::loadGain(cnode *root, int index)
-{
-    cnode *node = root->first_child;
-
-    sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask);
-
-    while (node) {
-        if (strcmp(node->name, GAIN_MODE) == 0) {
-            gain->mGain.mode = loadGainMode((char *)node->value);
-        } else if (strcmp(node->name, GAIN_CHANNELS) == 0) {
-            if (mUseInChannelMask) {
-                gain->mGain.channel_mask =
-                        (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
-                                                           ARRAY_SIZE(sInChannelsNameToEnumTable),
-                                                           (char *)node->value);
-            } else {
-                gain->mGain.channel_mask =
-                        (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
-                                                           ARRAY_SIZE(sOutChannelsNameToEnumTable),
-                                                           (char *)node->value);
-            }
-        } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) {
-            gain->mGain.min_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) {
-            gain->mGain.max_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) {
-            gain->mGain.default_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) {
-            gain->mGain.step_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) {
-            gain->mGain.min_ramp_ms = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) {
-            gain->mGain.max_ramp_ms = atoi((char *)node->value);
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d",
-          gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value);
-
-    if (gain->mGain.mode == 0) {
-        return;
-    }
-    mGains.add(gain);
-}
-
-void AudioPolicyManager::AudioPort::loadGains(cnode *root)
-{
-    cnode *node = root->first_child;
-    int index = 0;
-    while (node) {
-        ALOGV("loadGains() loading gain %s", node->name);
-        loadGain(node, index++);
-        node = node->next;
-    }
-}
-
-status_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t samplingRate) const
-{
-    if (mSamplingRates.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    for (size_t i = 0; i < mSamplingRates.size(); i ++) {
-        if (mSamplingRates[i] == samplingRate) {
-            return NO_ERROR;
-        }
-    }
-    return BAD_VALUE;
-}
-
-status_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate,
-        uint32_t *updatedSamplingRate) const
-{
-    if (mSamplingRates.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    // Search for the closest supported sampling rate that is above (preferred)
-    // or below (acceptable) the desired sampling rate, within a permitted ratio.
-    // The sampling rates do not need to be sorted in ascending order.
-    ssize_t maxBelow = -1;
-    ssize_t minAbove = -1;
-    uint32_t candidate;
-    for (size_t i = 0; i < mSamplingRates.size(); i++) {
-        candidate = mSamplingRates[i];
-        if (candidate == samplingRate) {
-            if (updatedSamplingRate != NULL) {
-                *updatedSamplingRate = candidate;
-            }
-            return NO_ERROR;
-        }
-        // candidate < desired
-        if (candidate < samplingRate) {
-            if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) {
-                maxBelow = i;
-            }
-        // candidate > desired
-        } else {
-            if (minAbove < 0 || candidate < mSamplingRates[minAbove]) {
-                minAbove = i;
-            }
-        }
-    }
-    // This uses hard-coded knowledge about AudioFlinger resampling ratios.
-    // TODO Move these assumptions out.
-    static const uint32_t kMaxDownSampleRatio = 6;  // beyond this aliasing occurs
-    static const uint32_t kMaxUpSampleRatio = 256;  // beyond this sample rate inaccuracies occur
-                                                    // due to approximation by an int32_t of the
-                                                    // phase increments
-    // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum.
-    if (minAbove >= 0) {
-        candidate = mSamplingRates[minAbove];
-        if (candidate / kMaxDownSampleRatio <= samplingRate) {
-            if (updatedSamplingRate != NULL) {
-                *updatedSamplingRate = candidate;
-            }
-            return NO_ERROR;
-        }
-    }
-    // But if we have to up-sample from a lower sampling rate, that's OK.
-    if (maxBelow >= 0) {
-        candidate = mSamplingRates[maxBelow];
-        if (candidate * kMaxUpSampleRatio >= samplingRate) {
-            if (updatedSamplingRate != NULL) {
-                *updatedSamplingRate = candidate;
-            }
-            return NO_ERROR;
-        }
-    }
-    // leave updatedSamplingRate unmodified
-    return BAD_VALUE;
-}
-
-status_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const
-{
-    if (mChannelMasks.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    for (size_t i = 0; i < mChannelMasks.size(); i++) {
-        if (mChannelMasks[i] == channelMask) {
-            return NO_ERROR;
-        }
-    }
-    return BAD_VALUE;
-}
-
-status_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask)
-        const
-{
-    if (mChannelMasks.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
-    for (size_t i = 0; i < mChannelMasks.size(); i ++) {
-        // FIXME Does not handle multi-channel automatic conversions yet
-        audio_channel_mask_t supported = mChannelMasks[i];
-        if (supported == channelMask) {
-            return NO_ERROR;
-        }
-        if (isRecordThread) {
-            // This uses hard-coded knowledge that AudioFlinger can silently down-mix and up-mix.
-            // FIXME Abstract this out to a table.
-            if (((supported == AUDIO_CHANNEL_IN_FRONT_BACK || supported == AUDIO_CHANNEL_IN_STEREO)
-                    && channelMask == AUDIO_CHANNEL_IN_MONO) ||
-                (supported == AUDIO_CHANNEL_IN_MONO && (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK
-                    || channelMask == AUDIO_CHANNEL_IN_STEREO))) {
-                return NO_ERROR;
-            }
-        }
-    }
-    return BAD_VALUE;
-}
-
-status_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const
-{
-    if (mFormats.isEmpty()) {
-        return NO_ERROR;
-    }
-
-    for (size_t i = 0; i < mFormats.size(); i ++) {
-        if (mFormats[i] == format) {
-            return NO_ERROR;
-        }
-    }
-    return BAD_VALUE;
-}
-
-
-uint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const
-{
-    // special case for uninitialized dynamic profile
-    if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) {
-        return 0;
-    }
-
-    // For direct outputs, pick minimum sampling rate: this helps ensuring that the
-    // channel count / sampling rate combination chosen will be supported by the connected
-    // sink
-    if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
-            (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) {
-        uint32_t samplingRate = UINT_MAX;
-        for (size_t i = 0; i < mSamplingRates.size(); i ++) {
-            if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) {
-                samplingRate = mSamplingRates[i];
-            }
-        }
-        return (samplingRate == UINT_MAX) ? 0 : samplingRate;
-    }
-
-    uint32_t samplingRate = 0;
-    uint32_t maxRate = MAX_MIXER_SAMPLING_RATE;
-
-    // For mixed output and inputs, use max mixer sampling rates. Do not
-    // limit sampling rate otherwise
-    if (mType != AUDIO_PORT_TYPE_MIX) {
-        maxRate = UINT_MAX;
-    }
-    for (size_t i = 0; i < mSamplingRates.size(); i ++) {
-        if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) {
-            samplingRate = mSamplingRates[i];
-        }
-    }
-    return samplingRate;
-}
-
-audio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const
-{
-    // special case for uninitialized dynamic profile
-    if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) {
-        return AUDIO_CHANNEL_NONE;
-    }
-    audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE;
-
-    // For direct outputs, pick minimum channel count: this helps ensuring that the
-    // channel count / sampling rate combination chosen will be supported by the connected
-    // sink
-    if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
-            (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) {
-        uint32_t channelCount = UINT_MAX;
-        for (size_t i = 0; i < mChannelMasks.size(); i ++) {
-            uint32_t cnlCount;
-            if (mUseInChannelMask) {
-                cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]);
-            } else {
-                cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]);
-            }
-            if ((cnlCount < channelCount) && (cnlCount > 0)) {
-                channelMask = mChannelMasks[i];
-                channelCount = cnlCount;
-            }
-        }
-        return channelMask;
-    }
-
-    uint32_t channelCount = 0;
-    uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT;
-
-    // For mixed output and inputs, use max mixer channel count. Do not
-    // limit channel count otherwise
-    if (mType != AUDIO_PORT_TYPE_MIX) {
-        maxCount = UINT_MAX;
-    }
-    for (size_t i = 0; i < mChannelMasks.size(); i ++) {
-        uint32_t cnlCount;
-        if (mUseInChannelMask) {
-            cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]);
-        } else {
-            cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]);
-        }
-        if ((cnlCount > channelCount) && (cnlCount <= maxCount)) {
-            channelMask = mChannelMasks[i];
-            channelCount = cnlCount;
-        }
-    }
-    return channelMask;
-}
-
-/* format in order of increasing preference */
-const audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = {
-        AUDIO_FORMAT_DEFAULT,
-        AUDIO_FORMAT_PCM_16_BIT,
-        AUDIO_FORMAT_PCM_8_24_BIT,
-        AUDIO_FORMAT_PCM_24_BIT_PACKED,
-        AUDIO_FORMAT_PCM_32_BIT,
-        AUDIO_FORMAT_PCM_FLOAT,
-};
-
-int AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1,
-                                                  audio_format_t format2)
-{
-    // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any
-    // compressed format and better than any PCM format. This is by design of pickFormat()
-    if (!audio_is_linear_pcm(format1)) {
-        if (!audio_is_linear_pcm(format2)) {
-            return 0;
-        }
-        return 1;
-    }
-    if (!audio_is_linear_pcm(format2)) {
-        return -1;
-    }
-
-    int index1 = -1, index2 = -1;
-    for (size_t i = 0;
-            (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1));
-            i ++) {
-        if (sPcmFormatCompareTable[i] == format1) {
-            index1 = i;
-        }
-        if (sPcmFormatCompareTable[i] == format2) {
-            index2 = i;
-        }
-    }
-    // format1 not found => index1 < 0 => format2 > format1
-    // format2 not found => index2 < 0 => format2 < format1
-    return index1 - index2;
-}
-
-audio_format_t AudioPolicyManager::AudioPort::pickFormat() const
-{
-    // special case for uninitialized dynamic profile
-    if (mFormats.size() == 1 && mFormats[0] == 0) {
-        return AUDIO_FORMAT_DEFAULT;
-    }
-
-    audio_format_t format = AUDIO_FORMAT_DEFAULT;
-    audio_format_t bestFormat =
-            AudioPolicyManager::AudioPort::sPcmFormatCompareTable[
-                ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1];
-    // For mixed output and inputs, use best mixer output format. Do not
-    // limit format otherwise
-    if ((mType != AUDIO_PORT_TYPE_MIX) ||
-            ((mRole == AUDIO_PORT_ROLE_SOURCE) &&
-             (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) {
-        bestFormat = AUDIO_FORMAT_INVALID;
-    }
-
-    for (size_t i = 0; i < mFormats.size(); i ++) {
-        if ((compareFormats(mFormats[i], format) > 0) &&
-                (compareFormats(mFormats[i], bestFormat) <= 0)) {
-            format = mFormats[i];
-        }
-    }
-    return format;
-}
-
-status_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig,
-                                                  int index) const
-{
-    if (index < 0 || (size_t)index >= mGains.size()) {
-        return BAD_VALUE;
-    }
-    return mGains[index]->checkConfig(gainConfig);
-}
-
-void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    if (mName.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
-    }
-
-    if (mSamplingRates.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mSamplingRates.size(); i++) {
-            if (i == 0 && mSamplingRates[i] == 0) {
-                snprintf(buffer, SIZE, "Dynamic");
-            } else {
-                snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
-            }
-            result.append(buffer);
-            result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-
-    if (mChannelMasks.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mChannelMasks.size(); i++) {
-            ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]);
-
-            if (i == 0 && mChannelMasks[i] == 0) {
-                snprintf(buffer, SIZE, "Dynamic");
-            } else {
-                snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
-            }
-            result.append(buffer);
-            result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-
-    if (mFormats.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- formats: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mFormats.size(); i++) {
-            const char *formatStr = enumToString(sFormatNameToEnumTable,
-                                                 ARRAY_SIZE(sFormatNameToEnumTable),
-                                                 mFormats[i]);
-            if (i == 0 && strcmp(formatStr, "") == 0) {
-                snprintf(buffer, SIZE, "Dynamic");
-            } else {
-                snprintf(buffer, SIZE, "%s", formatStr);
-            }
-            result.append(buffer);
-            result.append(i == (mFormats.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-    write(fd, result.string(), result.size());
-    if (mGains.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
-        write(fd, buffer, strlen(buffer) + 1);
-        result.append(buffer);
-        for (size_t i = 0; i < mGains.size(); i++) {
-            mGains[i]->dump(fd, spaces + 2, i);
-        }
-    }
-}
-
-// --- AudioGain class implementation
-
-AudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask)
-{
-    mIndex = index;
-    mUseInChannelMask = useInChannelMask;
-    memset(&mGain, 0, sizeof(struct audio_gain));
-}
-
-void AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config)
-{
-    config->index = mIndex;
-    config->mode = mGain.mode;
-    config->channel_mask = mGain.channel_mask;
-    if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
-        config->values[0] = mGain.default_value;
-    } else {
-        uint32_t numValues;
-        if (mUseInChannelMask) {
-            numValues = audio_channel_count_from_in_mask(mGain.channel_mask);
-        } else {
-            numValues = audio_channel_count_from_out_mask(mGain.channel_mask);
-        }
-        for (size_t i = 0; i < numValues; i++) {
-            config->values[i] = mGain.default_value;
-        }
-    }
-    if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
-        config->ramp_duration_ms = mGain.min_ramp_ms;
-    }
-}
-
-status_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config)
-{
-    if ((config->mode & ~mGain.mode) != 0) {
-        return BAD_VALUE;
-    }
-    if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
-        if ((config->values[0] < mGain.min_value) ||
-                    (config->values[0] > mGain.max_value)) {
-            return BAD_VALUE;
-        }
-    } else {
-        if ((config->channel_mask & ~mGain.channel_mask) != 0) {
-            return BAD_VALUE;
-        }
-        uint32_t numValues;
-        if (mUseInChannelMask) {
-            numValues = audio_channel_count_from_in_mask(config->channel_mask);
-        } else {
-            numValues = audio_channel_count_from_out_mask(config->channel_mask);
-        }
-        for (size_t i = 0; i < numValues; i++) {
-            if ((config->values[i] < mGain.min_value) ||
-                    (config->values[i] > mGain.max_value)) {
-                return BAD_VALUE;
-            }
-        }
-    }
-    if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
-        if ((config->ramp_duration_ms < mGain.min_ramp_ms) ||
-                    (config->ramp_duration_ms > mGain.max_ramp_ms)) {
-            return BAD_VALUE;
-        }
-    }
-    return NO_ERROR;
-}
-
-void AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-}
-
-// --- AudioPortConfig class implementation
-
-AudioPolicyManager::AudioPortConfig::AudioPortConfig()
-{
-    mSamplingRate = 0;
-    mChannelMask = AUDIO_CHANNEL_NONE;
-    mFormat = AUDIO_FORMAT_INVALID;
-    mGain.index = -1;
-}
-
-status_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig(
-                                                        const struct audio_port_config *config,
-                                                        struct audio_port_config *backupConfig)
-{
-    struct audio_port_config localBackupConfig;
-    status_t status = NO_ERROR;
-
-    localBackupConfig.config_mask = config->config_mask;
-    toAudioPortConfig(&localBackupConfig);
-
-    sp<AudioPort> audioport = getAudioPort();
-    if (audioport == 0) {
-        status = NO_INIT;
-        goto exit;
-    }
-    if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-        status = audioport->checkExactSamplingRate(config->sample_rate);
-        if (status != NO_ERROR) {
-            goto exit;
-        }
-        mSamplingRate = config->sample_rate;
-    }
-    if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-        status = audioport->checkExactChannelMask(config->channel_mask);
-        if (status != NO_ERROR) {
-            goto exit;
-        }
-        mChannelMask = config->channel_mask;
-    }
-    if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-        status = audioport->checkFormat(config->format);
-        if (status != NO_ERROR) {
-            goto exit;
-        }
-        mFormat = config->format;
-    }
-    if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-        status = audioport->checkGain(&config->gain, config->gain.index);
-        if (status != NO_ERROR) {
-            goto exit;
-        }
-        mGain = config->gain;
-    }
-
-exit:
-    if (status != NO_ERROR) {
-        applyAudioPortConfig(&localBackupConfig);
-    }
-    if (backupConfig != NULL) {
-        *backupConfig = localBackupConfig;
-    }
-    return status;
-}
-
-void AudioPolicyManager::AudioPortConfig::toAudioPortConfig(
-                                                    struct audio_port_config *dstConfig,
-                                                    const struct audio_port_config *srcConfig) const
-{
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-        dstConfig->sample_rate = mSamplingRate;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-    } else {
-        dstConfig->sample_rate = 0;
-    }
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-        dstConfig->channel_mask = mChannelMask;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-    } else {
-        dstConfig->channel_mask = AUDIO_CHANNEL_NONE;
-    }
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-        dstConfig->format = mFormat;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
-            dstConfig->format = srcConfig->format;
-        }
-    } else {
-        dstConfig->format = AUDIO_FORMAT_INVALID;
-    }
-    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-        dstConfig->gain = mGain;
-        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) {
-            dstConfig->gain = srcConfig->gain;
-        }
-    } else {
-        dstConfig->gain.index = -1;
-    }
-    if (dstConfig->gain.index != -1) {
-        dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-    } else {
-        dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
-    }
-}
-
-// --- IOProfile class implementation
-
-AudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role,
-                                         const sp<HwModule>& module)
-    : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module)
-{
-}
-
-AudioPolicyManager::IOProfile::~IOProfile()
-{
-}
-
-// checks if the IO profile is compatible with specified parameters.
-// Sampling rate, format and channel mask must be specified in order to
-// get a valid a match
-bool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device,
-                                                        String8 address,
-                                                        uint32_t samplingRate,
-                                                        uint32_t *updatedSamplingRate,
-                                                        audio_format_t format,
-                                                        audio_channel_mask_t channelMask,
-                                                        uint32_t flags) const
-{
-    const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;
-    const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
-    ALOG_ASSERT(isPlaybackThread != isRecordThread);
-
-    if (device != AUDIO_DEVICE_NONE && mSupportedDevices.getDevice(device, address) == 0) {
-        return false;
-    }
-
-    if (samplingRate == 0) {
-         return false;
-    }
-    uint32_t myUpdatedSamplingRate = samplingRate;
-    if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) {
-         return false;
-    }
-    if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) !=
-            NO_ERROR) {
-         return false;
-    }
-
-    if (!audio_is_valid_format(format) || checkFormat(format) != NO_ERROR) {
-        return false;
-    }
-
-    if (isPlaybackThread && (!audio_is_output_channel(channelMask) ||
-            checkExactChannelMask(channelMask) != NO_ERROR)) {
-        return false;
-    }
-    if (isRecordThread && (!audio_is_input_channel(channelMask) ||
-            checkCompatibleChannelMask(channelMask) != NO_ERROR)) {
-        return false;
-    }
-
-    if (isPlaybackThread && (mFlags & flags) != flags) {
-        return false;
-    }
-    // The only input flag that is allowed to be different is the fast flag.
-    // An existing fast stream is compatible with a normal track request.
-    // An existing normal stream is compatible with a fast track request,
-    // but the fast request will be denied by AudioFlinger and converted to normal track.
-    if (isRecordThread && ((mFlags ^ flags) &
-            ~AUDIO_INPUT_FLAG_FAST)) {
-        return false;
-    }
-
-    if (updatedSamplingRate != NULL) {
-        *updatedSamplingRate = myUpdatedSamplingRate;
-    }
-    return true;
-}
-
-void AudioPolicyManager::IOProfile::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    AudioPort::dump(fd, 4);
-
-    snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "    - devices:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    for (size_t i = 0; i < mSupportedDevices.size(); i++) {
-        mSupportedDevices[i]->dump(fd, 6, i);
-    }
-}
-
-void AudioPolicyManager::IOProfile::log()
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    ALOGV("    - sampling rates: ");
-    for (size_t i = 0; i < mSamplingRates.size(); i++) {
-        ALOGV("  %d", mSamplingRates[i]);
-    }
-
-    ALOGV("    - channel masks: ");
-    for (size_t i = 0; i < mChannelMasks.size(); i++) {
-        ALOGV("  0x%04x", mChannelMasks[i]);
-    }
-
-    ALOGV("    - formats: ");
-    for (size_t i = 0; i < mFormats.size(); i++) {
-        ALOGV("  0x%08x", mFormats[i]);
-    }
-
-    ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
-    ALOGV("    - flags: 0x%04x\n", mFlags);
-}
-
-
-// --- DeviceDescriptor implementation
-
-String8 AudioPolicyManager::DeviceDescriptor::emptyNameStr = String8("");
-
-AudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) :
-                     AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
-                               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
-                                                              AUDIO_PORT_ROLE_SOURCE,
-                             NULL),
-                     mDeviceType(type), mAddress("")
-{
-}
-
-bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
-{
-    // Devices are considered equal if they:
-    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
-    // - have the same address or one device does not specify the address
-    // - have the same channel mask or one device does not specify the channel mask
-    return (mDeviceType == other->mDeviceType) &&
-           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
-           (mChannelMask == 0 || other->mChannelMask == 0 ||
-                mChannelMask == other->mChannelMask);
-}
-
-void AudioPolicyManager::DeviceDescriptor::loadGains(cnode *root)
-{
-    AudioPort::loadGains(root);
-    if (mGains.size() > 0) {
-        mGains[0]->getDefaultConfig(&mGain);
-    }
-}
-
-
-void AudioPolicyManager::DeviceVector::refreshTypes()
-{
-    mDeviceTypes = AUDIO_DEVICE_NONE;
-    for(size_t i = 0; i < size(); i++) {
-        mDeviceTypes |= itemAt(i)->mDeviceType;
-    }
-    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
-}
-
-ssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
-{
-    for(size_t i = 0; i < size(); i++) {
-        if (item->equals(itemAt(i))) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-ssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item)
-{
-    ssize_t ret = indexOf(item);
-
-    if (ret < 0) {
-        ret = SortedVector::add(item);
-        if (ret >= 0) {
-            refreshTypes();
-        }
-    } else {
-        ALOGW("DeviceVector::add device %08x already in", item->mDeviceType);
-        ret = -1;
-    }
-    return ret;
-}
-
-ssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item)
-{
-    size_t i;
-    ssize_t ret = indexOf(item);
-
-    if (ret < 0) {
-        ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType);
-    } else {
-        ret = SortedVector::removeAt(ret);
-        if (ret >= 0) {
-            refreshTypes();
-        }
-    }
-    return ret;
-}
-
-void AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types)
-{
-    DeviceVector deviceList;
-
-    uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
-    types &= ~role_bit;
-
-    while (types) {
-        uint32_t i = 31 - __builtin_clz(types);
-        uint32_t type = 1 << i;
-        types &= ~type;
-        add(new DeviceDescriptor(String8("device_type"), type | role_bit));
-    }
-}
-
-void AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name,
-                                                           const DeviceVector& declaredDevices)
-{
-    char *devName = strtok(name, "|");
-    while (devName != NULL) {
-        if (strlen(devName) != 0) {
-            audio_devices_t type = stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
-                                 devName);
-            if (type != AUDIO_DEVICE_NONE) {
-                sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(name), type);
-                if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX ||
-                        type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
-                    dev->mAddress = String8("0");
-                }
-                add(dev);
-            } else {
-                sp<DeviceDescriptor> deviceDesc =
-                        declaredDevices.getDeviceFromName(String8(devName));
-                if (deviceDesc != 0) {
-                    add(deviceDesc);
-                }
-            }
-         }
-         devName = strtok(NULL, "|");
-     }
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice(
-                                                        audio_devices_t type, String8 address) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mDeviceType == type) {
-            if (address == "" || itemAt(i)->mAddress == address) {
-                device = itemAt(i);
-                if (itemAt(i)->mAddress == address) {
-                    break;
-                }
-            }
-        }
-    }
-    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
-          type, address.string(), device.get());
-    return device;
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId(
-                                                                    audio_port_handle_t id) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->getHandle() == id) {
-            device = itemAt(i);
-            break;
-        }
-    }
-    return device;
-}
-
-AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType(
-                                                                        audio_devices_t type) const
-{
-    DeviceVector devices;
-    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
-        if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) {
-            devices.add(itemAt(i));
-            type &= ~itemAt(i)->mDeviceType;
-            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
-                  itemAt(i)->mDeviceType, itemAt(i).get());
-        }
-    }
-    return devices;
-}
-
-AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromTypeAddr(
-        audio_devices_t type, String8 address) const
-{
-    DeviceVector devices;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mDeviceType == type) {
-            if (itemAt(i)->mAddress == address) {
-                devices.add(itemAt(i));
-            }
-        }
-    }
-    return devices;
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName(
-        const String8& name) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mName == name) {
-            device = itemAt(i);
-            break;
-        }
-    }
-    return device;
-}
-
-void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(
-                                                    struct audio_port_config *dstConfig,
-                                                    const struct audio_port_config *srcConfig) const
-{
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
-    if (srcConfig != NULL) {
-        dstConfig->config_mask |= srcConfig->config_mask;
-    }
-
-    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
-    dstConfig->id = mId;
-    dstConfig->role = audio_is_output_device(mDeviceType) ?
-                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
-    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
-    dstConfig->ext.device.type = mDeviceType;
-
-    //TODO Understand why this test is necessary. i.e. why at boot time does it crash
-    // without the test?
-    // This has been demonstrated to NOT be true (at start up)
-    // ALOG_ASSERT(mModule != NULL);
-    dstConfig->ext.device.hw_module = mModule != NULL ? mModule->mHandle : NULL;
-    strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
-}
-
-void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
-{
-    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
-    AudioPort::toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.device.type = mDeviceType;
-    port->ext.device.hw_module = mModule->mHandle;
-    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
-}
-
-status_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    if (mId != 0) {
-        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
-        result.append(buffer);
-    }
-    snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "",
-                                              enumToString(sDeviceNameToEnumTable,
-                                                           ARRAY_SIZE(sDeviceNameToEnumTable),
-                                                           mDeviceType));
-    result.append(buffer);
-    if (mAddress.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-    AudioPort::dump(fd, spaces);
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::AudioPatch::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-
-    snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources);
-    result.append(buffer);
-    for (size_t i = 0; i < mPatch.num_sources; i++) {
-        if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
-            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sources[i].id, enumToString(sDeviceNameToEnumTable,
-                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
-                                                        mPatch.sources[i].ext.device.type));
-        } else {
-            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
-                     mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle);
-        }
-        result.append(buffer);
-    }
-    snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks);
-    result.append(buffer);
-    for (size_t i = 0; i < mPatch.num_sinks; i++) {
-        if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
-            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
-                     mPatch.sinks[i].id, enumToString(sDeviceNameToEnumTable,
-                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
-                                                        mPatch.sinks[i].ext.device.type));
-        } else {
-            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
-                     mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle);
-        }
-        result.append(buffer);
-    }
-
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
 
 // --- audio_policy.conf file parsing
-
-uint32_t AudioPolicyManager::parseOutputFlagNames(char *name)
-{
-    uint32_t flag = 0;
-
-    // it is OK to cast name to non const here as we are not going to use it after
-    // strtok() modifies it
-    char *flagName = strtok(name, "|");
-    while (flagName != NULL) {
-        if (strlen(flagName) != 0) {
-            flag |= stringToEnum(sOutputFlagNameToEnumTable,
-                               ARRAY_SIZE(sOutputFlagNameToEnumTable),
-                               flagName);
-        }
-        flagName = strtok(NULL, "|");
-    }
-    //force direct flag if offload flag is set: offloading implies a direct output stream
-    // and all common behaviors are driven by checking only the direct flag
-    // this should normally be set appropriately in the policy configuration file
-    if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
-        flag |= AUDIO_OUTPUT_FLAG_DIRECT;
-    }
-
-    return flag;
-}
-
-uint32_t AudioPolicyManager::parseInputFlagNames(char *name)
-{
-    uint32_t flag = 0;
-
-    // it is OK to cast name to non const here as we are not going to use it after
-    // strtok() modifies it
-    char *flagName = strtok(name, "|");
-    while (flagName != NULL) {
-        if (strlen(flagName) != 0) {
-            flag |= stringToEnum(sInputFlagNameToEnumTable,
-                               ARRAY_SIZE(sInputFlagNameToEnumTable),
-                               flagName);
-        }
-        flagName = strtok(NULL, "|");
-    }
-    return flag;
-}
-
-audio_devices_t AudioPolicyManager::parseDeviceNames(char *name)
-{
-    uint32_t device = 0;
-
-    char *devName = strtok(name, "|");
-    while (devName != NULL) {
-        if (strlen(devName) != 0) {
-            device |= stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
-                                 devName);
-         }
-        devName = strtok(NULL, "|");
-     }
-    return device;
-}
-
+// TODO candidate to be moved to ConfigParsingUtils
 void AudioPolicyManager::loadHwModule(cnode *root)
 {
     status_t status = NAME_NOT_FOUND;
@@ -7903,6 +5557,7 @@
     }
 }
 
+// TODO candidate to be moved to ConfigParsingUtils
 void AudioPolicyManager::loadHwModules(cnode *root)
 {
     cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
@@ -7918,6 +5573,7 @@
     }
 }
 
+// TODO candidate to be moved to ConfigParsingUtils
 void AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module)
 {
     cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
@@ -7938,9 +5594,10 @@
             ALOGV("loadGlobalConfig() Attached Output Devices %08x",
                   mAvailableOutputDevices.types());
         } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
-            audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,
-                                              ARRAY_SIZE(sDeviceNameToEnumTable),
-                                              (char *)node->value);
+            audio_devices_t device = (audio_devices_t)ConfigParsingUtils::stringToEnum(
+                    sDeviceNameToEnumTable,
+                    ARRAY_SIZE(sDeviceNameToEnumTable),
+                    (char *)node->value);
             if (device != AUDIO_DEVICE_NONE) {
                 mDefaultOutputDevice = new DeviceDescriptor(String8("default-output"), device);
             } else {
@@ -7952,7 +5609,7 @@
                                                        declaredDevices);
             ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types());
         } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
-            mSpeakerDrcEnabled = stringToBool((char *)node->value);
+            mSpeakerDrcEnabled = ConfigParsingUtils::stringToBool((char *)node->value);
             ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);
         } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) {
             uint32_t major, minor;
@@ -7965,6 +5622,7 @@
     }
 }
 
+// TODO candidate to be moved to ConfigParsingUtils
 status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
 {
     cnode *root;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
new file mode 100644
index 0000000..61ea6f2
--- /dev/null
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2009 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 <stdint.h>
+#include <sys/types.h>
+#include <cutils/config_utils.h>
+#include <cutils/misc.h>
+#include <utils/Timers.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <media/AudioPolicy.h>
+#include "AudioPolicyInterface.h"
+
+#include "Gains.h"
+#include "Ports.h"
+#include "ConfigParsingUtils.h"
+#include "Devices.h"
+#include "IOProfile.h"
+#include "HwModule.h"
+#include "AudioInputDescriptor.h"
+#include "AudioOutputDescriptor.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
+#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
+// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
+#define SONIFICATION_HEADSET_VOLUME_MIN  0.016
+// Time in milliseconds during which we consider that music is still active after a music
+// track was stopped - see computeVolume()
+#define SONIFICATION_HEADSET_MUSIC_DELAY  5000
+// 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
+// Time in milliseconds during witch some streams are muted while the audio path
+// is switched
+#define MUTE_TIME_MS 2000
+
+#define NUM_TEST_OUTPUTS 5
+
+#define NUM_VOL_CURVE_KNEES 2
+
+// Default minimum length allowed for offloading a compressed track
+// Can be overridden by the audio.offload.min.duration.secs property
+#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
+
+#define MAX_MIXER_SAMPLING_RATE 48000
+#define MAX_MIXER_CHANNEL_COUNT 8
+
+// ----------------------------------------------------------------------------
+// AudioPolicyManager implements audio policy manager behavior common to all platforms.
+// ----------------------------------------------------------------------------
+
+class AudioPolicyManager: public AudioPolicyInterface
+#ifdef AUDIO_POLICY_TEST
+    , public Thread
+#endif //AUDIO_POLICY_TEST
+{
+
+public:
+                AudioPolicyManager(AudioPolicyClientInterface *clientInterface);
+        virtual ~AudioPolicyManager();
+
+        // AudioPolicyInterface
+        virtual status_t setDeviceConnectionState(audio_devices_t device,
+                                                          audio_policy_dev_state_t state,
+                                                          const char *device_address,
+                                                          const char *device_name);
+        virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
+                                                                              const char *device_address);
+        virtual void setPhoneState(audio_mode_t state);
+        virtual void setForceUse(audio_policy_force_use_t usage,
+                                 audio_policy_forced_cfg_t config);
+        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
+        virtual void setSystemProperty(const char* property, const char* value);
+        virtual status_t initCheck();
+        virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
+                                            uint32_t samplingRate,
+                                            audio_format_t format,
+                                            audio_channel_mask_t channelMask,
+                                            audio_output_flags_t flags,
+                                            const audio_offload_info_t *offloadInfo);
+        virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+                                          audio_io_handle_t *output,
+                                          audio_session_t session,
+                                          audio_stream_type_t *stream,
+                                          uint32_t samplingRate,
+                                          audio_format_t format,
+                                          audio_channel_mask_t channelMask,
+                                          audio_output_flags_t flags,
+                                          const audio_offload_info_t *offloadInfo);
+        virtual status_t startOutput(audio_io_handle_t output,
+                                     audio_stream_type_t stream,
+                                     audio_session_t session);
+        virtual status_t stopOutput(audio_io_handle_t output,
+                                    audio_stream_type_t stream,
+                                    audio_session_t session);
+        virtual void releaseOutput(audio_io_handle_t output,
+                                   audio_stream_type_t stream,
+                                   audio_session_t session);
+        virtual status_t getInputForAttr(const audio_attributes_t *attr,
+                                         audio_io_handle_t *input,
+                                         audio_session_t session,
+                                         uint32_t samplingRate,
+                                         audio_format_t format,
+                                         audio_channel_mask_t channelMask,
+                                         audio_input_flags_t flags,
+                                         input_type_t *inputType);
+
+        // indicates to the audio policy manager that the input starts being used.
+        virtual status_t startInput(audio_io_handle_t input,
+                                    audio_session_t session);
+
+        // indicates to the audio policy manager that the input stops being used.
+        virtual status_t stopInput(audio_io_handle_t input,
+                                   audio_session_t session);
+        virtual void releaseInput(audio_io_handle_t input,
+                                  audio_session_t session);
+        virtual void closeAllInputs();
+        virtual void initStreamVolume(audio_stream_type_t stream,
+                                                    int indexMin,
+                                                    int indexMax);
+        virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
+                                              int index,
+                                              audio_devices_t device);
+        virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
+                                              int *index,
+                                              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 uint32_t getStrategyForAttr(const audio_attributes_t *attr);
+
+        // return the enabled output devices for the given stream type
+        virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
+
+        virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc = NULL);
+        virtual status_t registerEffect(const effect_descriptor_t *desc,
+                                        audio_io_handle_t io,
+                                        uint32_t strategy,
+                                        int session,
+                                        int id);
+        virtual status_t unregisterEffect(int id);
+        virtual status_t setEffectEnabled(int id, bool enabled);
+
+        virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+        // return whether a stream is playing remotely, override to change the definition of
+        //   local/remote playback, used for instance by notification manager to not make
+        //   media players lose audio focus when not playing locally
+        //   For the base implementation, "remotely" means playing during screen mirroring which
+        //   uses an output for playback with a non-empty, non "0" address.
+        virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+        virtual bool isSourceActive(audio_source_t source) const;
+
+        virtual status_t dump(int fd);
+
+        virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
+
+        virtual status_t listAudioPorts(audio_port_role_t role,
+                                        audio_port_type_t type,
+                                        unsigned int *num_ports,
+                                        struct audio_port *ports,
+                                        unsigned int *generation);
+        virtual status_t getAudioPort(struct audio_port *port);
+        virtual status_t createAudioPatch(const struct audio_patch *patch,
+                                           audio_patch_handle_t *handle,
+                                           uid_t uid);
+        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
+                                              uid_t uid);
+        virtual status_t listAudioPatches(unsigned int *num_patches,
+                                          struct audio_patch *patches,
+                                          unsigned int *generation);
+        virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+        virtual void clearAudioPatches(uid_t uid);
+
+        virtual status_t acquireSoundTriggerSession(audio_session_t *session,
+                                               audio_io_handle_t *ioHandle,
+                                               audio_devices_t *device);
+
+        virtual status_t releaseSoundTriggerSession(audio_session_t session);
+
+        virtual status_t registerPolicyMixes(Vector<AudioMix> mixes);
+        virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
+
+        // Audio policy configuration file parsing (audio_policy.conf)
+        // TODO candidates to be moved to ConfigParsingUtils
+                void loadHwModule(cnode *root);
+                void loadHwModules(cnode *root);
+                void loadGlobalConfig(cnode *root, const sp<HwModule>& module);
+                status_t loadAudioPolicyConfig(const char *path);
+                void defaultAudioPolicyConfig(void);
+
+                // return the strategy corresponding to a given stream type
+                static routing_strategy getStrategy(audio_stream_type_t stream);
+
+                static uint32_t nextUniqueId();
+protected:
+
+        class EffectDescriptor : public RefBase
+        {
+        public:
+
+            status_t dump(int fd);
+
+            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
+        };
+
+        void addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc);
+        void addInput(audio_io_handle_t input, 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);
+
+        // 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.
+        virtual uint32_t setOutputDevice(audio_io_handle_t output,
+                             audio_devices_t device,
+                             bool force = false,
+                             int delayMs = 0,
+                             audio_patch_handle_t *patchHandle = NULL,
+                             const char* address = NULL);
+        status_t resetOutputDevice(audio_io_handle_t output,
+                                   int delayMs = 0,
+                                   audio_patch_handle_t *patchHandle = NULL);
+        status_t setInputDevice(audio_io_handle_t input,
+                                audio_devices_t device,
+                                bool force = false,
+                                audio_patch_handle_t *patchHandle = NULL);
+        status_t resetInputDevice(audio_io_handle_t input,
+                                  audio_patch_handle_t *patchHandle = NULL);
+
+        // select input device corresponding to requested audio source
+        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
+
+        // return io handle of active input or 0 if no input is active
+        //    Only considers inputs from physical devices (e.g. main mic, headset mic) when
+        //    ignoreVirtualInputs is true.
+        audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
+
+        uint32_t activeInputsCount() const;
+
+        // initialize volume curves for each strategy and device category
+        void initializeVolumeCurves();
+
+        // 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, int index,
+                                    audio_io_handle_t output, audio_devices_t device);
+
+        // check that volume change is permitted, compute and send new volume to audio hardware
+        virtual status_t checkAndSetVolume(audio_stream_type_t stream, int index,
+                                           audio_io_handle_t output,
+                                           audio_devices_t device,
+                                           int delayMs = 0, bool force = false);
+
+        // apply all stream volumes to the specified output and device
+        void applyStreamVolumes(audio_io_handle_t output, 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,
+                             bool on,
+                             audio_io_handle_t output,
+                             int delayMs = 0,
+                             audio_devices_t device = (audio_devices_t)0);
+
+        // Mute or unmute the stream on the specified output
+        void setStreamMute(audio_stream_type_t stream,
+                           bool on,
+                           audio_io_handle_t output,
+                           int delayMs = 0,
+                           audio_devices_t device = (audio_devices_t)0);
+
+        // handle special cases for sonification strategy while in call: mute streams or replace by
+        // a special tone in the device used for communication
+        void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
+
+        // true if device is in a telephony or VoIP call
+        virtual bool isInCall();
+
+        // true if given state represents a device in a telephony or VoIP call
+        virtual bool isStateInCall(int state);
+
+        // when a device is connected, checks if an open output can be routed
+        // to this device. If none is open, tries to open one of the available outputs.
+        // Returns an output suitable to this device or 0.
+        // when a device is disconnected, checks if an output is not used any more and
+        // returns its handle if any.
+        // transfers the audio tracks and effects from one output thread to another accordingly.
+        status_t checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
+                                       audio_policy_dev_state_t state,
+                                       SortedVector<audio_io_handle_t>& outputs,
+                                       const String8 address);
+
+        status_t checkInputsForDevice(audio_devices_t device,
+                                      audio_policy_dev_state_t state,
+                                      SortedVector<audio_io_handle_t>& inputs,
+                                      const String8 address);
+
+        // close an output and its companion duplicating output.
+        void closeOutput(audio_io_handle_t output);
+
+        // close an input.
+        void closeInput(audio_io_handle_t input);
+
+        // 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);
+
+        // Same as checkOutputForStrategy() but for a all strategies in order of priority
+        void checkOutputForAllStrategies();
+
+        // manages A2DP output suspend/restore according to phone state and BT SCO usage
+        void checkA2dpSuspend();
+
+        // returns the A2DP output handle if it is open or 0 otherwise
+        audio_io_handle_t getA2dpOutput();
+
+        // 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..
+        // see getDeviceForStrategy() for the use of fromCache parameter
+        audio_devices_t getNewOutputDevice(audio_io_handle_t output, 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()
+        void updateDevicesAndOutputs();
+
+        // selects the most appropriate device on input for current state
+        audio_devices_t getNewInputDevice(audio_io_handle_t input);
+
+        virtual uint32_t getMaxEffectsCpuLoad();
+        virtual uint32_t getMaxEffectsMemory();
+#ifdef AUDIO_POLICY_TEST
+        virtual     bool        threadLoop();
+                    void        exit();
+        int testOutputIndex(audio_io_handle_t output);
+#endif //AUDIO_POLICY_TEST
+
+        status_t setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled);
+
+        SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
+                        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs);
+        bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
+                                           SortedVector<audio_io_handle_t>& outputs2);
+
+        // 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(sp<AudioOutputDescriptor> outputDesc,
+                                            audio_devices_t prevDevice,
+                                            uint32_t delayMs);
+
+        audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
+                                       audio_output_flags_t flags,
+                                       audio_format_t format);
+        // samplingRate parameter is an in/out and so may be modified
+        sp<IOProfile> getInputProfile(audio_devices_t device,
+                                      String8 address,
+                                      uint32_t& samplingRate,
+                                      audio_format_t format,
+                                      audio_channel_mask_t channelMask,
+                                      audio_input_flags_t flags);
+        sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
+                                                       uint32_t samplingRate,
+                                                       audio_format_t format,
+                                                       audio_channel_mask_t channelMask,
+                                                       audio_output_flags_t flags);
+
+        audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
+
+        bool isNonOffloadableEffectEnabled();
+
+        virtual status_t addAudioPatch(audio_patch_handle_t handle,
+                               const sp<AudioPatch>& patch);
+        virtual status_t removeAudioPatch(audio_patch_handle_t handle);
+
+        sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
+        sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const;
+        sp<HwModule> getModuleForDevice(audio_devices_t device) const;
+        sp<HwModule> getModuleFromName(const char *name) const;
+        audio_devices_t availablePrimaryOutputDevices();
+        audio_devices_t availablePrimaryInputDevices();
+
+        void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0);
+
+
+        uid_t mUidCached;
+        AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
+        audio_io_handle_t mPrimaryOutput;              // primary output handle
+        // list of descriptors for outputs currently opened
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mOutputs;
+        // copy of mOutputs before setDeviceConnectionState() opens new outputs
+        // reset to mOutputs when updateDevicesAndOutputs() is called.
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mPreviousOutputs;
+        DefaultKeyedVector<audio_io_handle_t, sp<AudioInputDescriptor> > mInputs;     // list of input descriptors
+        DeviceVector  mAvailableOutputDevices; // all available output devices
+        DeviceVector  mAvailableInputDevices;  // all available input devices
+        int mPhoneState;                                                    // current phone state
+        audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];   // current forced use configuration
+
+        StreamDescriptor mStreams[AUDIO_STREAM_CNT];           // stream descriptors for volume control
+        bool    mLimitRingtoneVolume;                                       // limit ringtone volume to music volume if headset connected
+        audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
+        float   mLastVoiceVolume;                                           // last voice volume value sent to audio HAL
+
+        // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
+        static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
+        // Maximum memory allocated to audio effects in KB
+        static const uint32_t MAX_EFFECTS_MEMORY = 512;
+        uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
+        uint32_t mTotalEffectsMemory;  // current memory used by effects
+        KeyedVector<int, sp<EffectDescriptor> > mEffects;  // list of registered audio effects
+        bool    mA2dpSuspended;  // true if A2DP output is suspended
+        sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
+        bool mSpeakerDrcEnabled;// true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
+                                // to boost soft sounds, used to adjust volume curves accordingly
+
+        Vector < sp<HwModule> > mHwModules;
+        static volatile int32_t mNextUniqueId;
+        volatile int32_t mAudioPortGeneration;
+
+        DefaultKeyedVector<audio_patch_handle_t, sp<AudioPatch> > mAudioPatches;
+
+        DefaultKeyedVector<audio_session_t, audio_io_handle_t> mSoundTriggerSessions;
+
+        sp<AudioPatch> mCallTxPatch;
+        sp<AudioPatch> mCallRxPatch;
+
+        // for supporting "beacon" streams, i.e. streams that only play on speaker, and never
+        // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing
+        enum {
+            STARTING_OUTPUT,
+            STARTING_BEACON,
+            STOPPING_OUTPUT,
+            STOPPING_BEACON
+        };
+        uint32_t mBeaconMuteRefCount;   // ref count for stream that would mute beacon
+        uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams
+        bool mBeaconMuted;              // has STREAM_TTS been muted
+
+        // custom mix entry in mPolicyMixes
+        class AudioPolicyMix : public RefBase {
+        public:
+            AudioPolicyMix() {}
+
+            AudioMix    mMix;                   // Audio policy mix descriptor
+            sp<AudioOutputDescriptor> mOutput;  // Corresponding output stream
+        };
+        DefaultKeyedVector<String8, sp<AudioPolicyMix> > mPolicyMixes; // list of registered mixes
+
+
+#ifdef AUDIO_POLICY_TEST
+        Mutex   mLock;
+        Condition mWaitWorkCV;
+
+        int             mCurOutput;
+        bool            mDirectOutput;
+        audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
+        int             mTestInput;
+        uint32_t        mTestDevice;
+        uint32_t        mTestSamplingRate;
+        uint32_t        mTestFormat;
+        uint32_t        mTestChannels;
+        uint32_t        mTestLatencyMs;
+#endif //AUDIO_POLICY_TEST
+
+        static bool isVirtualInputDevice(audio_devices_t device);
+
+        uint32_t nextAudioPortGeneration();
+private:
+        // updates device caching and output for streams that can influence the
+        //    routing of notifications
+        void handleNotificationRoutingForStream(audio_stream_type_t stream);
+        static bool deviceDistinguishesOnAddress(audio_devices_t device);
+        // find the outputs on a given output descriptor that have the given address.
+        // to be called on an AudioOutputDescriptor whose supported devices (as defined
+        //   in mProfile->mSupportedDevices) matches the device whose address is to be matched.
+        // see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
+        //   where addresses are used to distinguish between one connected device and another.
+        void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+                const audio_devices_t device /*in*/,
+                const String8 address /*in*/,
+                SortedVector<audio_io_handle_t>& outputs /*out*/);
+        uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
+        // internal method to return the output handle for the given device and format
+        audio_io_handle_t getOutputForDevice(
+                audio_devices_t device,
+                audio_session_t session,
+                audio_stream_type_t stream,
+                uint32_t samplingRate,
+                audio_format_t format,
+                audio_channel_mask_t channelMask,
+                audio_output_flags_t flags,
+                const audio_offload_info_t *offloadInfo);
+        // internal function to derive a stream type value from audio attributes
+        audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
+        // return true if any output is playing anything besides the stream to ignore
+        bool isAnyOutputActive(audio_stream_type_t streamToIgnore);
+        // 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
+        uint32_t handleEventForBeacon(int event);
+        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().
+        audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
+                                                        AudioMix **policyMix = NULL);
+
+        // Called by setDeviceConnectionState().
+        status_t setDeviceConnectionStateInt(audio_devices_t device,
+                                                          audio_policy_dev_state_t state,
+                                                          const char *device_address,
+                                                          const char *device_name);
+        sp<DeviceDescriptor>  getDeviceDescriptor(const audio_devices_t device,
+                                                  const char *device_address,
+                                                  const char *device_name);
+};
+
+};
diff --git a/services/audiopolicy/managerdefault/ConfigParsingUtils.cpp b/services/audiopolicy/managerdefault/ConfigParsingUtils.cpp
new file mode 100644
index 0000000..1afd487
--- /dev/null
+++ b/services/audiopolicy/managerdefault/ConfigParsingUtils.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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::ConfigParsingUtils"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+namespace android {
+
+//static
+uint32_t ConfigParsingUtils::stringToEnum(const struct StringToEnum *table,
+                                              size_t size,
+                                              const char *name)
+{
+    for (size_t i = 0; i < size; i++) {
+        if (strcmp(table[i].name, name) == 0) {
+            ALOGV("stringToEnum() found %s", table[i].name);
+            return table[i].value;
+        }
+    }
+    return 0;
+}
+
+//static
+const char *ConfigParsingUtils::enumToString(const struct StringToEnum *table,
+                                              size_t size,
+                                              uint32_t value)
+{
+    for (size_t i = 0; i < size; i++) {
+        if (table[i].value == value) {
+            return table[i].name;
+        }
+    }
+    return "";
+}
+
+//static
+bool ConfigParsingUtils::stringToBool(const char *value)
+{
+    return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
+}
+
+
+// --- audio_policy.conf file parsing
+//static
+uint32_t ConfigParsingUtils::parseOutputFlagNames(char *name)
+{
+    uint32_t flag = 0;
+
+    // it is OK to cast name to non const here as we are not going to use it after
+    // strtok() modifies it
+    char *flagName = strtok(name, "|");
+    while (flagName != NULL) {
+        if (strlen(flagName) != 0) {
+            flag |= ConfigParsingUtils::stringToEnum(sOutputFlagNameToEnumTable,
+                               ARRAY_SIZE(sOutputFlagNameToEnumTable),
+                               flagName);
+        }
+        flagName = strtok(NULL, "|");
+    }
+    //force direct flag if offload flag is set: offloading implies a direct output stream
+    // and all common behaviors are driven by checking only the direct flag
+    // this should normally be set appropriately in the policy configuration file
+    if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+        flag |= AUDIO_OUTPUT_FLAG_DIRECT;
+    }
+
+    return flag;
+}
+
+//static
+uint32_t ConfigParsingUtils::parseInputFlagNames(char *name)
+{
+    uint32_t flag = 0;
+
+    // it is OK to cast name to non const here as we are not going to use it after
+    // strtok() modifies it
+    char *flagName = strtok(name, "|");
+    while (flagName != NULL) {
+        if (strlen(flagName) != 0) {
+            flag |= stringToEnum(sInputFlagNameToEnumTable,
+                               ARRAY_SIZE(sInputFlagNameToEnumTable),
+                               flagName);
+        }
+        flagName = strtok(NULL, "|");
+    }
+    return flag;
+}
+
+//static
+audio_devices_t ConfigParsingUtils::parseDeviceNames(char *name)
+{
+    uint32_t device = 0;
+
+    char *devName = strtok(name, "|");
+    while (devName != NULL) {
+        if (strlen(devName) != 0) {
+            device |= stringToEnum(sDeviceNameToEnumTable,
+                                 ARRAY_SIZE(sDeviceNameToEnumTable),
+                                 devName);
+         }
+        devName = strtok(NULL, "|");
+     }
+    return device;
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/ConfigParsingUtils.h b/services/audiopolicy/managerdefault/ConfigParsingUtils.h
new file mode 100644
index 0000000..7969661
--- /dev/null
+++ b/services/audiopolicy/managerdefault/ConfigParsingUtils.h
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+// Definitions for audio_policy.conf file parsing
+// ----------------------------------------------------------------------------
+
+struct StringToEnum {
+    const char *name;
+    uint32_t value;
+};
+
+#define STRING_TO_ENUM(string) { #string, string }
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+const StringToEnum sDeviceNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+    STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
+};
+
+const StringToEnum sOutputFlagNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
+};
+
+const StringToEnum sInputFlagNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_INPUT_FLAG_FAST),
+    STRING_TO_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD),
+};
+
+const StringToEnum sFormatNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
+    STRING_TO_ENUM(AUDIO_FORMAT_MP3),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD),
+    STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
+    STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1),
+    STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2),
+    STRING_TO_ENUM(AUDIO_FORMAT_OPUS),
+    STRING_TO_ENUM(AUDIO_FORMAT_AC3),
+    STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
+};
+
+const StringToEnum sOutChannelsNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
+};
+
+const StringToEnum sInChannelsNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
+    STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
+    STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
+};
+
+const StringToEnum sGainModeNameToEnumTable[] = {
+    STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT),
+    STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS),
+    STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP),
+};
+
+class ConfigParsingUtils
+{
+public:
+    static uint32_t stringToEnum(const struct StringToEnum *table,
+            size_t size,
+            const char *name);
+    static const char *enumToString(const struct StringToEnum *table,
+            size_t size,
+            uint32_t value);
+    static bool stringToBool(const char *value);
+    static uint32_t parseOutputFlagNames(char *name);
+    static uint32_t parseInputFlagNames(char *name);
+    static audio_devices_t parseDeviceNames(char *name);
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Devices.cpp b/services/audiopolicy/managerdefault/Devices.cpp
new file mode 100644
index 0000000..13c8bbc
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Devices.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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::Devices"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+namespace android {
+
+String8 DeviceDescriptor::emptyNameStr = String8("");
+
+DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) :
+                     AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
+                               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
+                                                              AUDIO_PORT_ROLE_SOURCE,
+                             NULL),
+                     mDeviceType(type), mAddress("")
+{
+
+}
+
+bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
+{
+    // Devices are considered equal if they:
+    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
+    // - have the same address or one device does not specify the address
+    // - have the same channel mask or one device does not specify the channel mask
+    return (mDeviceType == other->mDeviceType) &&
+           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
+           (mChannelMask == 0 || other->mChannelMask == 0 ||
+                mChannelMask == other->mChannelMask);
+}
+
+void DeviceDescriptor::loadGains(cnode *root)
+{
+    AudioPort::loadGains(root);
+    if (mGains.size() > 0) {
+        mGains[0]->getDefaultConfig(&mGain);
+    }
+}
+
+void DeviceVector::refreshTypes()
+{
+    mDeviceTypes = AUDIO_DEVICE_NONE;
+    for(size_t i = 0; i < size(); i++) {
+        mDeviceTypes |= itemAt(i)->mDeviceType;
+    }
+    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
+}
+
+ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
+{
+    for(size_t i = 0; i < size(); i++) {
+        if (item->equals(itemAt(i))) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
+{
+    ssize_t ret = indexOf(item);
+
+    if (ret < 0) {
+        ret = SortedVector::add(item);
+        if (ret >= 0) {
+            refreshTypes();
+        }
+    } else {
+        ALOGW("DeviceVector::add device %08x already in", item->mDeviceType);
+        ret = -1;
+    }
+    return ret;
+}
+
+ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
+{
+    size_t i;
+    ssize_t ret = indexOf(item);
+
+    if (ret < 0) {
+        ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType);
+    } else {
+        ret = SortedVector::removeAt(ret);
+        if (ret >= 0) {
+            refreshTypes();
+        }
+    }
+    return ret;
+}
+
+void DeviceVector::loadDevicesFromType(audio_devices_t types)
+{
+    DeviceVector deviceList;
+
+    uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
+    types &= ~role_bit;
+
+    while (types) {
+        uint32_t i = 31 - __builtin_clz(types);
+        uint32_t type = 1 << i;
+        types &= ~type;
+        add(new DeviceDescriptor(String8("device_type"), type | role_bit));
+    }
+}
+
+void DeviceVector::loadDevicesFromName(char *name,
+                                       const DeviceVector& declaredDevices)
+{
+    char *devName = strtok(name, "|");
+    while (devName != NULL) {
+        if (strlen(devName) != 0) {
+            audio_devices_t type = ConfigParsingUtils::stringToEnum(sDeviceNameToEnumTable,
+                                 ARRAY_SIZE(sDeviceNameToEnumTable),
+                                 devName);
+            if (type != AUDIO_DEVICE_NONE) {
+                sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(name), type);
+                if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX ||
+                        type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
+                    dev->mAddress = String8("0");
+                }
+                add(dev);
+            } else {
+                sp<DeviceDescriptor> deviceDesc =
+                        declaredDevices.getDeviceFromName(String8(devName));
+                if (deviceDesc != 0) {
+                    add(deviceDesc);
+                }
+            }
+         }
+         devName = strtok(NULL, "|");
+     }
+}
+
+sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, String8 address) const
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->mDeviceType == type) {
+            if (address == "" || itemAt(i)->mAddress == address) {
+                device = itemAt(i);
+                if (itemAt(i)->mAddress == address) {
+                    break;
+                }
+            }
+        }
+    }
+    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
+          type, address.string(), device.get());
+    return device;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->getHandle() == id) {
+            device = itemAt(i);
+            break;
+        }
+    }
+    return device;
+}
+
+DeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
+{
+    DeviceVector devices;
+    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
+        if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) {
+            devices.add(itemAt(i));
+            type &= ~itemAt(i)->mDeviceType;
+            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
+                  itemAt(i)->mDeviceType, itemAt(i).get());
+        }
+    }
+    return devices;
+}
+
+DeviceVector DeviceVector::getDevicesFromTypeAddr(
+        audio_devices_t type, String8 address) const
+{
+    DeviceVector devices;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->mDeviceType == type) {
+            if (itemAt(i)->mAddress == address) {
+                devices.add(itemAt(i));
+            }
+        }
+    }
+    return devices;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDeviceFromName(const String8& name) const
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->mName == name) {
+            device = itemAt(i);
+            break;
+        }
+    }
+    return device;
+}
+
+void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
+                                         const struct audio_port_config *srcConfig) const
+{
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
+    if (srcConfig != NULL) {
+        dstConfig->config_mask |= srcConfig->config_mask;
+    }
+
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+
+    dstConfig->id = mId;
+    dstConfig->role = audio_is_output_device(mDeviceType) ?
+                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
+    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
+    dstConfig->ext.device.type = mDeviceType;
+
+    //TODO Understand why this test is necessary. i.e. why at boot time does it crash
+    // without the test?
+    // This has been demonstrated to NOT be true (at start up)
+    // ALOG_ASSERT(mModule != NULL);
+    dstConfig->ext.device.hw_module = mModule != NULL ? mModule->mHandle : NULL;
+    strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
+}
+
+void DeviceDescriptor::toAudioPort(struct audio_port *port) const
+{
+    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
+    AudioPort::toAudioPort(port);
+    port->id = mId;
+    toAudioPortConfig(&port->active_config);
+    port->ext.device.type = mDeviceType;
+    port->ext.device.hw_module = mModule->mHandle;
+    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
+}
+
+status_t DeviceDescriptor::dump(int fd, int spaces, int index) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
+    result.append(buffer);
+    if (mId != 0) {
+        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
+        result.append(buffer);
+    }
+    snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "",
+            ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
+                    ARRAY_SIZE(sDeviceNameToEnumTable),
+                    mDeviceType));
+    result.append(buffer);
+    if (mAddress.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    AudioPort::dump(fd, spaces);
+
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Devices.h b/services/audiopolicy/managerdefault/Devices.h
new file mode 100644
index 0000000..65e1416
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Devices.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class AudioPort;
+class AudioPortConfig;
+
+class DeviceDescriptor: public AudioPort, public AudioPortConfig
+{
+public:
+    DeviceDescriptor(const String8& name, audio_devices_t type);
+
+    virtual ~DeviceDescriptor() {}
+
+    bool equals(const sp<DeviceDescriptor>& other) const;
+
+    // AudioPortConfig
+    virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
+    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+            const struct audio_port_config *srcConfig = NULL) const;
+
+    // AudioPort
+    virtual void loadGains(cnode *root);
+    virtual void toAudioPort(struct audio_port *port) const;
+
+    status_t dump(int fd, int spaces, int index) const;
+
+    audio_devices_t mDeviceType;
+    String8 mAddress;
+    audio_port_handle_t mId;
+
+    static String8  emptyNameStr;
+};
+
+class DeviceVector : public SortedVector< sp<DeviceDescriptor> >
+{
+public:
+    DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
+
+    ssize_t         add(const sp<DeviceDescriptor>& item);
+    ssize_t         remove(const sp<DeviceDescriptor>& item);
+    ssize_t         indexOf(const sp<DeviceDescriptor>& item) const;
+
+    audio_devices_t types() const { return mDeviceTypes; }
+
+    void loadDevicesFromType(audio_devices_t types);
+    void loadDevicesFromName(char *name, const DeviceVector& declaredDevices);
+
+    sp<DeviceDescriptor> getDevice(audio_devices_t type, String8 address) const;
+    DeviceVector getDevicesFromType(audio_devices_t types) const;
+    sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
+    sp<DeviceDescriptor> getDeviceFromName(const String8& name) const;
+    DeviceVector getDevicesFromTypeAddr(audio_devices_t type, String8 address)
+    const;
+
+private:
+    void refreshTypes();
+    audio_devices_t mDeviceTypes;
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Gains.cpp b/services/audiopolicy/managerdefault/Gains.cpp
new file mode 100644
index 0000000..4aca26d
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Gains.cpp
@@ -0,0 +1,446 @@
+/*
+ * 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::Gains"
+//#define LOG_NDEBUG 0
+
+//#define VERY_VERBOSE_LOGGING
+#ifdef VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while(0)
+#endif
+
+#include "AudioPolicyManager.h"
+
+#include <math.h>
+
+namespace android {
+
+const VolumeCurvePoint
+ApmGains::sDefaultVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
+};
+
+
+const VolumeCurvePoint
+ApmGains::sDefaultMediaVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sExtMediaSystemVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSpeakerMediaVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSpeakerMediaVolumeCurveDrc[ApmGains::VOLCNT] = {
+    {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSpeakerSonificationVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSpeakerSonificationVolumeCurveDrc[ApmGains::VOLCNT] = {
+    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
+};
+
+// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
+// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
+// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
+// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
+
+const VolumeCurvePoint
+ApmGains::sDefaultSystemVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sDefaultSystemVolumeCurveDrc[ApmGains::VOLCNT] = {
+    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sHeadsetSystemVolumeCurve[ApmGains::VOLCNT] = {
+    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sDefaultVoiceVolumeCurve[ApmGains::VOLCNT] = {
+    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSpeakerVoiceVolumeCurve[ApmGains::VOLCNT] = {
+    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sLinearVolumeCurve[ApmGains::VOLCNT] = {
+    {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sSilentVolumeCurve[ApmGains::VOLCNT] = {
+    {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f}
+};
+
+const VolumeCurvePoint
+ApmGains::sFullScaleVolumeCurve[ApmGains::VOLCNT] = {
+    {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f}
+};
+
+const VolumeCurvePoint *ApmGains::sVolumeProfiles[AUDIO_STREAM_CNT]
+                                                  [ApmGains::DEVICE_CATEGORY_CNT] = {
+    { // AUDIO_STREAM_VOICE_CALL
+        ApmGains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_SYSTEM
+        ApmGains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultSystemVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_RING
+        ApmGains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_MUSIC
+        ApmGains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_ALARM
+        ApmGains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_NOTIFICATION
+        ApmGains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_BLUETOOTH_SCO
+        ApmGains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_ENFORCED_AUDIBLE
+        ApmGains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    {  // AUDIO_STREAM_DTMF
+        ApmGains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_TTS
+      // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER
+        ApmGains::sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sSilentVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_ACCESSIBILITY
+        ApmGains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_REROUTING
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+    { // AUDIO_STREAM_PATCH
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+        ApmGains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+        ApmGains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+    },
+};
+
+//static
+audio_devices_t ApmGains::getDeviceForVolume(audio_devices_t device)
+{
+    if (device == AUDIO_DEVICE_NONE) {
+        // this happens when forcing a route update and no track is active on an output.
+        // In this case the returned category is not important.
+        device =  AUDIO_DEVICE_OUT_SPEAKER;
+    } else if (popcount(device) > 1) {
+        // Multiple device selection is either:
+        //  - speaker + one other device: give priority to speaker in this case.
+        //  - one A2DP device + another device: happens with duplicated output. In this case
+        // retain the device on the A2DP output as the other must not correspond to an active
+        // selection if not the speaker.
+        //  - HDMI-CEC system audio mode only output: give priority to available item in order.
+        if (device & AUDIO_DEVICE_OUT_SPEAKER) {
+            device = AUDIO_DEVICE_OUT_SPEAKER;
+        } else if (device & AUDIO_DEVICE_OUT_HDMI_ARC) {
+            device = AUDIO_DEVICE_OUT_HDMI_ARC;
+        } else if (device & AUDIO_DEVICE_OUT_AUX_LINE) {
+            device = AUDIO_DEVICE_OUT_AUX_LINE;
+        } else if (device & AUDIO_DEVICE_OUT_SPDIF) {
+            device = AUDIO_DEVICE_OUT_SPDIF;
+        } else {
+            device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
+        }
+    }
+
+    /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/
+    if (device == AUDIO_DEVICE_OUT_SPEAKER_SAFE)
+        device = AUDIO_DEVICE_OUT_SPEAKER;
+
+    ALOGW_IF(popcount(device) != 1,
+            "getDeviceForVolume() invalid device combination: %08x",
+            device);
+
+    return device;
+}
+
+//static
+ApmGains::device_category ApmGains::getDeviceCategory(audio_devices_t device)
+{
+    switch(getDeviceForVolume(device)) {
+        case AUDIO_DEVICE_OUT_EARPIECE:
+            return ApmGains::DEVICE_CATEGORY_EARPIECE;
+        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+            return ApmGains::DEVICE_CATEGORY_HEADSET;
+        case AUDIO_DEVICE_OUT_LINE:
+        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
+        /*USB?  Remote submix?*/
+            return ApmGains::DEVICE_CATEGORY_EXT_MEDIA;
+        case AUDIO_DEVICE_OUT_SPEAKER:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
+        case AUDIO_DEVICE_OUT_USB_DEVICE:
+        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+        default:
+            return ApmGains::DEVICE_CATEGORY_SPEAKER;
+    }
+}
+
+//static
+float ApmGains::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
+        int indexInUi)
+{
+    ApmGains::device_category deviceCategory = ApmGains::getDeviceCategory(device);
+    const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
+
+    // the volume index in the UI is relative to the min and max volume indices for this stream type
+    int nbSteps = 1 + curve[ApmGains::VOLMAX].mIndex -
+            curve[ApmGains::VOLMIN].mIndex;
+    int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
+            (streamDesc.mIndexMax - streamDesc.mIndexMin);
+
+    // find what part of the curve this index volume belongs to, or if it's out of bounds
+    int segment = 0;
+    if (volIdx < curve[ApmGains::VOLMIN].mIndex) {         // out of bounds
+        return 0.0f;
+    } else if (volIdx < curve[ApmGains::VOLKNEE1].mIndex) {
+        segment = 0;
+    } else if (volIdx < curve[ApmGains::VOLKNEE2].mIndex) {
+        segment = 1;
+    } else if (volIdx <= curve[ApmGains::VOLMAX].mIndex) {
+        segment = 2;
+    } else {                                                               // out of bounds
+        return 1.0f;
+    }
+
+    // linear interpolation in the attenuation table in dB
+    float decibels = curve[segment].mDBAttenuation +
+            ((float)(volIdx - curve[segment].mIndex)) *
+                ( (curve[segment+1].mDBAttenuation -
+                        curve[segment].mDBAttenuation) /
+                    ((float)(curve[segment+1].mIndex -
+                            curve[segment].mIndex)) );
+
+    float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
+
+    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
+            curve[segment].mIndex, volIdx,
+            curve[segment+1].mIndex,
+            curve[segment].mDBAttenuation,
+            decibels,
+            curve[segment+1].mDBAttenuation,
+            amplification);
+
+    return amplification;
+}
+
+
+
+AudioGain::AudioGain(int index, bool useInChannelMask)
+{
+    mIndex = index;
+    mUseInChannelMask = useInChannelMask;
+    memset(&mGain, 0, sizeof(struct audio_gain));
+}
+
+void AudioGain::getDefaultConfig(struct audio_gain_config *config)
+{
+    config->index = mIndex;
+    config->mode = mGain.mode;
+    config->channel_mask = mGain.channel_mask;
+    if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
+        config->values[0] = mGain.default_value;
+    } else {
+        uint32_t numValues;
+        if (mUseInChannelMask) {
+            numValues = audio_channel_count_from_in_mask(mGain.channel_mask);
+        } else {
+            numValues = audio_channel_count_from_out_mask(mGain.channel_mask);
+        }
+        for (size_t i = 0; i < numValues; i++) {
+            config->values[i] = mGain.default_value;
+        }
+    }
+    if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
+        config->ramp_duration_ms = mGain.min_ramp_ms;
+    }
+}
+
+status_t AudioGain::checkConfig(const struct audio_gain_config *config)
+{
+    if ((config->mode & ~mGain.mode) != 0) {
+        return BAD_VALUE;
+    }
+    if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
+        if ((config->values[0] < mGain.min_value) ||
+                    (config->values[0] > mGain.max_value)) {
+            return BAD_VALUE;
+        }
+    } else {
+        if ((config->channel_mask & ~mGain.channel_mask) != 0) {
+            return BAD_VALUE;
+        }
+        uint32_t numValues;
+        if (mUseInChannelMask) {
+            numValues = audio_channel_count_from_in_mask(config->channel_mask);
+        } else {
+            numValues = audio_channel_count_from_out_mask(config->channel_mask);
+        }
+        for (size_t i = 0; i < numValues; i++) {
+            if ((config->values[i] < mGain.min_value) ||
+                    (config->values[i] > mGain.max_value)) {
+                return BAD_VALUE;
+            }
+        }
+    }
+    if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
+        if ((config->ramp_duration_ms < mGain.min_ramp_ms) ||
+                    (config->ramp_duration_ms > mGain.max_ramp_ms)) {
+            return BAD_VALUE;
+        }
+    }
+    return NO_ERROR;
+}
+
+void AudioGain::dump(int fd, int spaces, int index) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
+    result.append(buffer);
+
+    write(fd, result.string(), result.size());
+}
+
+
+// --- StreamDescriptor class implementation
+
+StreamDescriptor::StreamDescriptor()
+    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
+{
+    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
+}
+
+int StreamDescriptor::getVolumeIndex(audio_devices_t device)
+{
+    device = ApmGains::getDeviceForVolume(device);
+    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
+    if (mIndexCur.indexOfKey(device) < 0) {
+        device = AUDIO_DEVICE_OUT_DEFAULT;
+    }
+    return mIndexCur.valueFor(device);
+}
+
+void StreamDescriptor::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
+             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
+    result.append(buffer);
+    for (size_t i = 0; i < mIndexCur.size(); i++) {
+        snprintf(buffer, SIZE, "%04x : %02d, ",
+                 mIndexCur.keyAt(i),
+                 mIndexCur.valueAt(i));
+        result.append(buffer);
+    }
+    result.append("\n");
+
+    write(fd, result.string(), result.size());
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Gains.h b/services/audiopolicy/managerdefault/Gains.h
new file mode 100644
index 0000000..b4ab129
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Gains.h
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class VolumeCurvePoint
+{
+public:
+    int mIndex;
+    float mDBAttenuation;
+};
+
+class StreamDescriptor;
+
+class ApmGains
+{
+public :
+    // 4 points to define the volume attenuation curve, each characterized by the volume
+    // index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
+    // we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
+    enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4};
+
+    // device categories used for volume curve management.
+    enum device_category {
+        DEVICE_CATEGORY_HEADSET,
+        DEVICE_CATEGORY_SPEAKER,
+        DEVICE_CATEGORY_EARPIECE,
+        DEVICE_CATEGORY_EXT_MEDIA,
+        DEVICE_CATEGORY_CNT
+    };
+
+    // returns the category the device belongs to with regard to volume curve management
+    static ApmGains::device_category getDeviceCategory(audio_devices_t device);
+
+    // extract one device relevant for volume control from multiple device selection
+    static audio_devices_t getDeviceForVolume(audio_devices_t device);
+
+    static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
+                    int indexInUi);
+
+    // default volume curve
+    static const VolumeCurvePoint sDefaultVolumeCurve[ApmGains::VOLCNT];
+    // default volume curve for media strategy
+    static const VolumeCurvePoint sDefaultMediaVolumeCurve[ApmGains::VOLCNT];
+    // volume curve for non-media audio on ext media outputs (HDMI, Line, etc)
+    static const VolumeCurvePoint sExtMediaSystemVolumeCurve[ApmGains::VOLCNT];
+    // volume curve for media strategy on speakers
+    static const VolumeCurvePoint sSpeakerMediaVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sSpeakerMediaVolumeCurveDrc[ApmGains::VOLCNT];
+    // volume curve for sonification strategy on speakers
+    static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sSpeakerSonificationVolumeCurveDrc[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sDefaultSystemVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sHeadsetSystemVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sDefaultVoiceVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sLinearVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sSilentVolumeCurve[ApmGains::VOLCNT];
+    static const VolumeCurvePoint sFullScaleVolumeCurve[ApmGains::VOLCNT];
+    // default volume curves per stream and device category. See initializeVolumeCurves()
+    static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][ApmGains::DEVICE_CATEGORY_CNT];
+};
+
+
+class AudioGain: public RefBase
+{
+public:
+    AudioGain(int index, bool useInChannelMask);
+    virtual ~AudioGain() {}
+
+    void dump(int fd, int spaces, int index) const;
+
+    void getDefaultConfig(struct audio_gain_config *config);
+    status_t checkConfig(const struct audio_gain_config *config);
+    int               mIndex;
+    struct audio_gain mGain;
+    bool              mUseInChannelMask;
+};
+
+
+// stream descriptor used for volume control
+class StreamDescriptor
+{
+public:
+    StreamDescriptor();
+
+    int getVolumeIndex(audio_devices_t device);
+    void dump(int fd);
+
+    int mIndexMin;      // min volume index
+    int mIndexMax;      // max volume index
+    KeyedVector<audio_devices_t, int> mIndexCur;   // current volume index per device
+    bool mCanBeMuted;   // true is the stream can be muted
+
+    const VolumeCurvePoint *mVolumeCurve[ApmGains::DEVICE_CATEGORY_CNT];
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/HwModule.cpp b/services/audiopolicy/managerdefault/HwModule.cpp
new file mode 100644
index 0000000..a04bdc8
--- /dev/null
+++ b/services/audiopolicy/managerdefault/HwModule.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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::HwModule"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+#include "audio_policy_conf.h"
+#include <hardware/audio.h>
+
+namespace android {
+
+HwModule::HwModule(const char *name)
+    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)),
+      mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0)
+{
+}
+
+HwModule::~HwModule()
+{
+    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
+        mOutputProfiles[i]->mSupportedDevices.clear();
+    }
+    for (size_t i = 0; i < mInputProfiles.size(); i++) {
+        mInputProfiles[i]->mSupportedDevices.clear();
+    }
+    free((void *)mName);
+}
+
+status_t HwModule::loadInput(cnode *root)
+{
+    cnode *node = root->first_child;
+
+    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
+
+    while (node) {
+        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
+            profile->loadSamplingRates((char *)node->value);
+        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
+            profile->loadFormats((char *)node->value);
+        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
+            profile->loadInChannels((char *)node->value);
+        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
+            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
+                                                           mDeclaredDevices);
+        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
+            profile->mFlags = ConfigParsingUtils::parseInputFlagNames((char *)node->value);
+        } else if (strcmp(node->name, GAINS_TAG) == 0) {
+            profile->loadGains(node);
+        }
+        node = node->next;
+    }
+    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
+            "loadInput() invalid supported devices");
+    ALOGW_IF(profile->mChannelMasks.size() == 0,
+            "loadInput() invalid supported channel masks");
+    ALOGW_IF(profile->mSamplingRates.size() == 0,
+            "loadInput() invalid supported sampling rates");
+    ALOGW_IF(profile->mFormats.size() == 0,
+            "loadInput() invalid supported formats");
+    if (!profile->mSupportedDevices.isEmpty() &&
+            (profile->mChannelMasks.size() != 0) &&
+            (profile->mSamplingRates.size() != 0) &&
+            (profile->mFormats.size() != 0)) {
+
+        ALOGV("loadInput() adding input Supported Devices %04x",
+              profile->mSupportedDevices.types());
+
+        mInputProfiles.add(profile);
+        return NO_ERROR;
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+status_t HwModule::loadOutput(cnode *root)
+{
+    cnode *node = root->first_child;
+
+    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
+
+    while (node) {
+        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
+            profile->loadSamplingRates((char *)node->value);
+        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
+            profile->loadFormats((char *)node->value);
+        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
+            profile->loadOutChannels((char *)node->value);
+        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
+            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
+                                                           mDeclaredDevices);
+        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
+            profile->mFlags = ConfigParsingUtils::parseOutputFlagNames((char *)node->value);
+        } else if (strcmp(node->name, GAINS_TAG) == 0) {
+            profile->loadGains(node);
+        }
+        node = node->next;
+    }
+    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
+            "loadOutput() invalid supported devices");
+    ALOGW_IF(profile->mChannelMasks.size() == 0,
+            "loadOutput() invalid supported channel masks");
+    ALOGW_IF(profile->mSamplingRates.size() == 0,
+            "loadOutput() invalid supported sampling rates");
+    ALOGW_IF(profile->mFormats.size() == 0,
+            "loadOutput() invalid supported formats");
+    if (!profile->mSupportedDevices.isEmpty() &&
+            (profile->mChannelMasks.size() != 0) &&
+            (profile->mSamplingRates.size() != 0) &&
+            (profile->mFormats.size() != 0)) {
+
+        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
+              profile->mSupportedDevices.types(), profile->mFlags);
+
+        mOutputProfiles.add(profile);
+        return NO_ERROR;
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+status_t HwModule::loadDevice(cnode *root)
+{
+    cnode *node = root->first_child;
+
+    audio_devices_t type = AUDIO_DEVICE_NONE;
+    while (node) {
+        if (strcmp(node->name, DEVICE_TYPE) == 0) {
+            type = ConfigParsingUtils::parseDeviceNames((char *)node->value);
+            break;
+        }
+        node = node->next;
+    }
+    if (type == AUDIO_DEVICE_NONE ||
+            (!audio_is_input_device(type) && !audio_is_output_device(type))) {
+        ALOGW("loadDevice() bad type %08x", type);
+        return BAD_VALUE;
+    }
+    sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
+    deviceDesc->mModule = this;
+
+    node = root->first_child;
+    while (node) {
+        if (strcmp(node->name, DEVICE_ADDRESS) == 0) {
+            deviceDesc->mAddress = String8((char *)node->value);
+        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
+            if (audio_is_input_device(type)) {
+                deviceDesc->loadInChannels((char *)node->value);
+            } else {
+                deviceDesc->loadOutChannels((char *)node->value);
+            }
+        } else if (strcmp(node->name, GAINS_TAG) == 0) {
+            deviceDesc->loadGains(node);
+        }
+        node = node->next;
+    }
+
+    ALOGV("loadDevice() adding device name %s type %08x address %s",
+          deviceDesc->mName.string(), type, deviceDesc->mAddress.string());
+
+    mDeclaredDevices.add(deviceDesc);
+
+    return NO_ERROR;
+}
+
+status_t HwModule::addOutputProfile(String8 name, const audio_config_t *config,
+                                                  audio_devices_t device, String8 address)
+{
+    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this);
+
+    profile->mSamplingRates.add(config->sample_rate);
+    profile->mChannelMasks.add(config->channel_mask);
+    profile->mFormats.add(config->format);
+
+    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
+    devDesc->mAddress = address;
+    profile->mSupportedDevices.add(devDesc);
+
+    mOutputProfiles.add(profile);
+
+    return NO_ERROR;
+}
+
+status_t HwModule::removeOutputProfile(String8 name)
+{
+    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
+        if (mOutputProfiles[i]->mName == name) {
+            mOutputProfiles.removeAt(i);
+            break;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t HwModule::addInputProfile(String8 name, const audio_config_t *config,
+                                                  audio_devices_t device, String8 address)
+{
+    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this);
+
+    profile->mSamplingRates.add(config->sample_rate);
+    profile->mChannelMasks.add(config->channel_mask);
+    profile->mFormats.add(config->format);
+
+    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
+    devDesc->mAddress = address;
+    profile->mSupportedDevices.add(devDesc);
+
+    ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask);
+
+    mInputProfiles.add(profile);
+
+    return NO_ERROR;
+}
+
+status_t HwModule::removeInputProfile(String8 name)
+{
+    for (size_t i = 0; i < mInputProfiles.size(); i++) {
+        if (mInputProfiles[i]->mName == name) {
+            mInputProfiles.removeAt(i);
+            break;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+
+void HwModule::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "  - name: %s\n", mName);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "  - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    if (mOutputProfiles.size()) {
+        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
+        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
+            snprintf(buffer, SIZE, "    output %zu:\n", i);
+            write(fd, buffer, strlen(buffer));
+            mOutputProfiles[i]->dump(fd);
+        }
+    }
+    if (mInputProfiles.size()) {
+        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
+        for (size_t i = 0; i < mInputProfiles.size(); i++) {
+            snprintf(buffer, SIZE, "    input %zu:\n", i);
+            write(fd, buffer, strlen(buffer));
+            mInputProfiles[i]->dump(fd);
+        }
+    }
+    if (mDeclaredDevices.size()) {
+        write(fd, "  - devices:\n", strlen("  - devices:\n"));
+        for (size_t i = 0; i < mDeclaredDevices.size(); i++) {
+            mDeclaredDevices[i]->dump(fd, 4, i);
+        }
+    }
+}
+
+} //namespace android
diff --git a/services/audiopolicy/managerdefault/HwModule.h b/services/audiopolicy/managerdefault/HwModule.h
new file mode 100644
index 0000000..f814dd9
--- /dev/null
+++ b/services/audiopolicy/managerdefault/HwModule.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class HwModule : public RefBase
+{
+public:
+    HwModule(const char *name);
+    ~HwModule();
+
+    status_t loadOutput(cnode *root);
+    status_t loadInput(cnode *root);
+    status_t loadDevice(cnode *root);
+
+    status_t addOutputProfile(String8 name, const audio_config_t *config,
+            audio_devices_t device, String8 address);
+    status_t removeOutputProfile(String8 name);
+    status_t addInputProfile(String8 name, const audio_config_t *config,
+            audio_devices_t device, String8 address);
+    status_t removeInputProfile(String8 name);
+
+    void dump(int fd);
+
+    const char *const        mName; // base name of the audio HW module (primary, a2dp ...)
+    uint32_t                 mHalVersion; // audio HAL API version
+    audio_module_handle_t    mHandle;
+    Vector < sp<IOProfile> > mOutputProfiles; // output profiles exposed by this module
+    Vector < sp<IOProfile> > mInputProfiles;  // input profiles exposed by this module
+    DeviceVector             mDeclaredDevices; // devices declared in audio_policy.conf
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/IOProfile.cpp b/services/audiopolicy/managerdefault/IOProfile.cpp
new file mode 100644
index 0000000..538ac1a
--- /dev/null
+++ b/services/audiopolicy/managerdefault/IOProfile.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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::IOProfile"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+namespace android {
+
+IOProfile::IOProfile(const String8& name, audio_port_role_t role,
+                                         const sp<HwModule>& module)
+    : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module)
+{
+}
+
+IOProfile::~IOProfile()
+{
+}
+
+// checks if the IO profile is compatible with specified parameters.
+// Sampling rate, format and channel mask must be specified in order to
+// get a valid a match
+bool IOProfile::isCompatibleProfile(audio_devices_t device,
+                                                        String8 address,
+                                                        uint32_t samplingRate,
+                                                        uint32_t *updatedSamplingRate,
+                                                        audio_format_t format,
+                                                        audio_channel_mask_t channelMask,
+                                                        uint32_t flags) const
+{
+    const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;
+    const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
+    ALOG_ASSERT(isPlaybackThread != isRecordThread);
+
+    if (device != AUDIO_DEVICE_NONE && mSupportedDevices.getDevice(device, address) == 0) {
+        return false;
+    }
+
+    if (samplingRate == 0) {
+         return false;
+    }
+    uint32_t myUpdatedSamplingRate = samplingRate;
+    if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) {
+         return false;
+    }
+    if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) !=
+            NO_ERROR) {
+         return false;
+    }
+
+    if (!audio_is_valid_format(format) || checkFormat(format) != NO_ERROR) {
+        return false;
+    }
+
+    if (isPlaybackThread && (!audio_is_output_channel(channelMask) ||
+            checkExactChannelMask(channelMask) != NO_ERROR)) {
+        return false;
+    }
+    if (isRecordThread && (!audio_is_input_channel(channelMask) ||
+            checkCompatibleChannelMask(channelMask) != NO_ERROR)) {
+        return false;
+    }
+
+    if (isPlaybackThread && (mFlags & flags) != flags) {
+        return false;
+    }
+    // The only input flag that is allowed to be different is the fast flag.
+    // An existing fast stream is compatible with a normal track request.
+    // An existing normal stream is compatible with a fast track request,
+    // but the fast request will be denied by AudioFlinger and converted to normal track.
+    if (isRecordThread && ((mFlags ^ flags) &
+            ~AUDIO_INPUT_FLAG_FAST)) {
+        return false;
+    }
+
+    if (updatedSamplingRate != NULL) {
+        *updatedSamplingRate = myUpdatedSamplingRate;
+    }
+    return true;
+}
+
+void IOProfile::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    AudioPort::dump(fd, 4);
+
+    snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "    - devices:\n");
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    for (size_t i = 0; i < mSupportedDevices.size(); i++) {
+        mSupportedDevices[i]->dump(fd, 6, i);
+    }
+}
+
+void IOProfile::log()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    ALOGV("    - sampling rates: ");
+    for (size_t i = 0; i < mSamplingRates.size(); i++) {
+        ALOGV("  %d", mSamplingRates[i]);
+    }
+
+    ALOGV("    - channel masks: ");
+    for (size_t i = 0; i < mChannelMasks.size(); i++) {
+        ALOGV("  0x%04x", mChannelMasks[i]);
+    }
+
+    ALOGV("    - formats: ");
+    for (size_t i = 0; i < mFormats.size(); i++) {
+        ALOGV("  0x%08x", mFormats[i]);
+    }
+
+    ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
+    ALOGV("    - flags: 0x%04x\n", mFlags);
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/IOProfile.h b/services/audiopolicy/managerdefault/IOProfile.h
new file mode 100644
index 0000000..3317969
--- /dev/null
+++ b/services/audiopolicy/managerdefault/IOProfile.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class HwModule;
+
+// the IOProfile class describes the capabilities of an output or input stream.
+// It is currently assumed that all combination of listed parameters are supported.
+// It is used by the policy manager to determine if an output or input is suitable for
+// a given use case,  open/close it accordingly and connect/disconnect audio tracks
+// to/from it.
+class IOProfile : public AudioPort
+{
+public:
+    IOProfile(const String8& name, audio_port_role_t role, const sp<HwModule>& module);
+    virtual ~IOProfile();
+
+    // This method is used for both output and input.
+    // If parameter updatedSamplingRate is non-NULL, it is assigned the actual sample rate.
+    // For input, flags is interpreted as audio_input_flags_t.
+    // TODO: merge audio_output_flags_t and audio_input_flags_t.
+    bool isCompatibleProfile(audio_devices_t device,
+                             String8 address,
+                             uint32_t samplingRate,
+                             uint32_t *updatedSamplingRate,
+                             audio_format_t format,
+                             audio_channel_mask_t channelMask,
+                             uint32_t flags) const;
+
+    void dump(int fd);
+    void log();
+
+    DeviceVector  mSupportedDevices; // supported devices
+                                     // (devices this output can be routed to)
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Ports.cpp b/services/audiopolicy/managerdefault/Ports.cpp
new file mode 100644
index 0000000..3e55cee
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Ports.cpp
@@ -0,0 +1,844 @@
+/*
+ * 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::Ports"
+//#define LOG_NDEBUG 0
+
+#include "AudioPolicyManager.h"
+
+#include "audio_policy_conf.h"
+
+namespace android {
+
+// --- AudioPort class implementation
+
+AudioPort::AudioPort(const String8& name, audio_port_type_t type,
+          audio_port_role_t role, const sp<HwModule>& module) :
+    mName(name), mType(type), mRole(role), mModule(module), mFlags(0), mId(0)
+{
+    mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
+                    ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
+}
+
+void AudioPort::attach(const sp<HwModule>& module) {
+    mId = AudioPolicyManager::nextUniqueId();
+    mModule = module;
+}
+
+void AudioPort::toAudioPort(struct audio_port *port) const
+{
+    port->role = mRole;
+    port->type = mType;
+    strlcpy(port->name, mName, AUDIO_PORT_MAX_NAME_LEN);
+    unsigned int i;
+    for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) {
+        if (mSamplingRates[i] != 0) {
+            port->sample_rates[i] = mSamplingRates[i];
+        }
+    }
+    port->num_sample_rates = i;
+    for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) {
+        if (mChannelMasks[i] != 0) {
+            port->channel_masks[i] = mChannelMasks[i];
+        }
+    }
+    port->num_channel_masks = i;
+    for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) {
+        if (mFormats[i] != 0) {
+            port->formats[i] = mFormats[i];
+        }
+    }
+    port->num_formats = i;
+
+    ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
+
+    for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
+        port->gains[i] = mGains[i]->mGain;
+    }
+    port->num_gains = i;
+}
+
+void AudioPort::importAudioPort(const sp<AudioPort> port) {
+    for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) {
+        const uint32_t rate = port->mSamplingRates.itemAt(k);
+        if (rate != 0) { // skip "dynamic" rates
+            bool hasRate = false;
+            for (size_t l = 0 ; l < mSamplingRates.size() ; l++) {
+                if (rate == mSamplingRates.itemAt(l)) {
+                    hasRate = true;
+                    break;
+                }
+            }
+            if (!hasRate) { // never import a sampling rate twice
+                mSamplingRates.add(rate);
+            }
+        }
+    }
+    for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) {
+        const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k);
+        if (mask != 0) { // skip "dynamic" masks
+            bool hasMask = false;
+            for (size_t l = 0 ; l < mChannelMasks.size() ; l++) {
+                if (mask == mChannelMasks.itemAt(l)) {
+                    hasMask = true;
+                    break;
+                }
+            }
+            if (!hasMask) { // never import a channel mask twice
+                mChannelMasks.add(mask);
+            }
+        }
+    }
+    for (size_t k = 0 ; k < port->mFormats.size() ; k++) {
+        const audio_format_t format = port->mFormats.itemAt(k);
+        if (format != 0) { // skip "dynamic" formats
+            bool hasFormat = false;
+            for (size_t l = 0 ; l < mFormats.size() ; l++) {
+                if (format == mFormats.itemAt(l)) {
+                    hasFormat = true;
+                    break;
+                }
+            }
+            if (!hasFormat) { // never import a channel mask twice
+                mFormats.add(format);
+            }
+        }
+    }
+    for (size_t k = 0 ; k < port->mGains.size() ; k++) {
+        sp<AudioGain> gain = port->mGains.itemAt(k);
+        if (gain != 0) {
+            bool hasGain = false;
+            for (size_t l = 0 ; l < mGains.size() ; l++) {
+                if (gain == mGains.itemAt(l)) {
+                    hasGain = true;
+                    break;
+                }
+            }
+            if (!hasGain) { // never import a gain twice
+                mGains.add(gain);
+            }
+        }
+    }
+}
+
+void AudioPort::clearCapabilities() {
+    mChannelMasks.clear();
+    mFormats.clear();
+    mSamplingRates.clear();
+    mGains.clear();
+}
+
+void AudioPort::loadSamplingRates(char *name)
+{
+    char *str = strtok(name, "|");
+
+    // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
+    // rates should be read from the output stream after it is opened for the first time
+    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
+        mSamplingRates.add(0);
+        return;
+    }
+
+    while (str != NULL) {
+        uint32_t rate = atoi(str);
+        if (rate != 0) {
+            ALOGV("loadSamplingRates() adding rate %d", rate);
+            mSamplingRates.add(rate);
+        }
+        str = strtok(NULL, "|");
+    }
+}
+
+void AudioPort::loadFormats(char *name)
+{
+    char *str = strtok(name, "|");
+
+    // by convention, "0' in the first entry in mFormats indicates the supported formats
+    // should be read from the output stream after it is opened for the first time
+    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
+        mFormats.add(AUDIO_FORMAT_DEFAULT);
+        return;
+    }
+
+    while (str != NULL) {
+        audio_format_t format = (audio_format_t)ConfigParsingUtils::stringToEnum(sFormatNameToEnumTable,
+                                                             ARRAY_SIZE(sFormatNameToEnumTable),
+                                                             str);
+        if (format != AUDIO_FORMAT_DEFAULT) {
+            mFormats.add(format);
+        }
+        str = strtok(NULL, "|");
+    }
+}
+
+void AudioPort::loadInChannels(char *name)
+{
+    const char *str = strtok(name, "|");
+
+    ALOGV("loadInChannels() %s", name);
+
+    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
+        mChannelMasks.add(0);
+        return;
+    }
+
+    while (str != NULL) {
+        audio_channel_mask_t channelMask =
+                (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sInChannelsNameToEnumTable,
+                                                   ARRAY_SIZE(sInChannelsNameToEnumTable),
+                                                   str);
+        if (channelMask != 0) {
+            ALOGV("loadInChannels() adding channelMask %04x", channelMask);
+            mChannelMasks.add(channelMask);
+        }
+        str = strtok(NULL, "|");
+    }
+}
+
+void AudioPort::loadOutChannels(char *name)
+{
+    const char *str = strtok(name, "|");
+
+    ALOGV("loadOutChannels() %s", name);
+
+    // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
+    // masks should be read from the output stream after it is opened for the first time
+    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
+        mChannelMasks.add(0);
+        return;
+    }
+
+    while (str != NULL) {
+        audio_channel_mask_t channelMask =
+                (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sOutChannelsNameToEnumTable,
+                                                   ARRAY_SIZE(sOutChannelsNameToEnumTable),
+                                                   str);
+        if (channelMask != 0) {
+            mChannelMasks.add(channelMask);
+        }
+        str = strtok(NULL, "|");
+    }
+    return;
+}
+
+audio_gain_mode_t AudioPort::loadGainMode(char *name)
+{
+    const char *str = strtok(name, "|");
+
+    ALOGV("loadGainMode() %s", name);
+    audio_gain_mode_t mode = 0;
+    while (str != NULL) {
+        mode |= (audio_gain_mode_t)ConfigParsingUtils::stringToEnum(sGainModeNameToEnumTable,
+                                                ARRAY_SIZE(sGainModeNameToEnumTable),
+                                                str);
+        str = strtok(NULL, "|");
+    }
+    return mode;
+}
+
+void AudioPort::loadGain(cnode *root, int index)
+{
+    cnode *node = root->first_child;
+
+    sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask);
+
+    while (node) {
+        if (strcmp(node->name, GAIN_MODE) == 0) {
+            gain->mGain.mode = loadGainMode((char *)node->value);
+        } else if (strcmp(node->name, GAIN_CHANNELS) == 0) {
+            if (mUseInChannelMask) {
+                gain->mGain.channel_mask =
+                        (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sInChannelsNameToEnumTable,
+                                                           ARRAY_SIZE(sInChannelsNameToEnumTable),
+                                                           (char *)node->value);
+            } else {
+                gain->mGain.channel_mask =
+                        (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sOutChannelsNameToEnumTable,
+                                                           ARRAY_SIZE(sOutChannelsNameToEnumTable),
+                                                           (char *)node->value);
+            }
+        } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) {
+            gain->mGain.min_value = atoi((char *)node->value);
+        } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) {
+            gain->mGain.max_value = atoi((char *)node->value);
+        } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) {
+            gain->mGain.default_value = atoi((char *)node->value);
+        } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) {
+            gain->mGain.step_value = atoi((char *)node->value);
+        } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) {
+            gain->mGain.min_ramp_ms = atoi((char *)node->value);
+        } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) {
+            gain->mGain.max_ramp_ms = atoi((char *)node->value);
+        }
+        node = node->next;
+    }
+
+    ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d",
+          gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value);
+
+    if (gain->mGain.mode == 0) {
+        return;
+    }
+    mGains.add(gain);
+}
+
+void AudioPort::loadGains(cnode *root)
+{
+    cnode *node = root->first_child;
+    int index = 0;
+    while (node) {
+        ALOGV("loadGains() loading gain %s", node->name);
+        loadGain(node, index++);
+        node = node->next;
+    }
+}
+
+status_t AudioPort::checkExactSamplingRate(uint32_t samplingRate) const
+{
+    if (mSamplingRates.isEmpty()) {
+        return NO_ERROR;
+    }
+
+    for (size_t i = 0; i < mSamplingRates.size(); i ++) {
+        if (mSamplingRates[i] == samplingRate) {
+            return NO_ERROR;
+        }
+    }
+    return BAD_VALUE;
+}
+
+status_t AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate,
+        uint32_t *updatedSamplingRate) const
+{
+    if (mSamplingRates.isEmpty()) {
+        return NO_ERROR;
+    }
+
+    // Search for the closest supported sampling rate that is above (preferred)
+    // or below (acceptable) the desired sampling rate, within a permitted ratio.
+    // The sampling rates do not need to be sorted in ascending order.
+    ssize_t maxBelow = -1;
+    ssize_t minAbove = -1;
+    uint32_t candidate;
+    for (size_t i = 0; i < mSamplingRates.size(); i++) {
+        candidate = mSamplingRates[i];
+        if (candidate == samplingRate) {
+            if (updatedSamplingRate != NULL) {
+                *updatedSamplingRate = candidate;
+            }
+            return NO_ERROR;
+        }
+        // candidate < desired
+        if (candidate < samplingRate) {
+            if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) {
+                maxBelow = i;
+            }
+        // candidate > desired
+        } else {
+            if (minAbove < 0 || candidate < mSamplingRates[minAbove]) {
+                minAbove = i;
+            }
+        }
+    }
+    // This uses hard-coded knowledge about AudioFlinger resampling ratios.
+    // TODO Move these assumptions out.
+    static const uint32_t kMaxDownSampleRatio = 6;  // beyond this aliasing occurs
+    static const uint32_t kMaxUpSampleRatio = 256;  // beyond this sample rate inaccuracies occur
+                                                    // due to approximation by an int32_t of the
+                                                    // phase increments
+    // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum.
+    if (minAbove >= 0) {
+        candidate = mSamplingRates[minAbove];
+        if (candidate / kMaxDownSampleRatio <= samplingRate) {
+            if (updatedSamplingRate != NULL) {
+                *updatedSamplingRate = candidate;
+            }
+            return NO_ERROR;
+        }
+    }
+    // But if we have to up-sample from a lower sampling rate, that's OK.
+    if (maxBelow >= 0) {
+        candidate = mSamplingRates[maxBelow];
+        if (candidate * kMaxUpSampleRatio >= samplingRate) {
+            if (updatedSamplingRate != NULL) {
+                *updatedSamplingRate = candidate;
+            }
+            return NO_ERROR;
+        }
+    }
+    // leave updatedSamplingRate unmodified
+    return BAD_VALUE;
+}
+
+status_t AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const
+{
+    if (mChannelMasks.isEmpty()) {
+        return NO_ERROR;
+    }
+
+    for (size_t i = 0; i < mChannelMasks.size(); i++) {
+        if (mChannelMasks[i] == channelMask) {
+            return NO_ERROR;
+        }
+    }
+    return BAD_VALUE;
+}
+
+status_t AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask)
+        const
+{
+    if (mChannelMasks.isEmpty()) {
+        return NO_ERROR;
+    }
+
+    const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
+    for (size_t i = 0; i < mChannelMasks.size(); i ++) {
+        // FIXME Does not handle multi-channel automatic conversions yet
+        audio_channel_mask_t supported = mChannelMasks[i];
+        if (supported == channelMask) {
+            return NO_ERROR;
+        }
+        if (isRecordThread) {
+            // This uses hard-coded knowledge that AudioFlinger can silently down-mix and up-mix.
+            // FIXME Abstract this out to a table.
+            if (((supported == AUDIO_CHANNEL_IN_FRONT_BACK || supported == AUDIO_CHANNEL_IN_STEREO)
+                    && channelMask == AUDIO_CHANNEL_IN_MONO) ||
+                (supported == AUDIO_CHANNEL_IN_MONO && (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK
+                    || channelMask == AUDIO_CHANNEL_IN_STEREO))) {
+                return NO_ERROR;
+            }
+        }
+    }
+    return BAD_VALUE;
+}
+
+status_t AudioPort::checkFormat(audio_format_t format) const
+{
+    if (mFormats.isEmpty()) {
+        return NO_ERROR;
+    }
+
+    for (size_t i = 0; i < mFormats.size(); i ++) {
+        if (mFormats[i] == format) {
+            return NO_ERROR;
+        }
+    }
+    return BAD_VALUE;
+}
+
+
+uint32_t AudioPort::pickSamplingRate() const
+{
+    // special case for uninitialized dynamic profile
+    if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) {
+        return 0;
+    }
+
+    // For direct outputs, pick minimum sampling rate: this helps ensuring that the
+    // channel count / sampling rate combination chosen will be supported by the connected
+    // sink
+    if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
+            (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) {
+        uint32_t samplingRate = UINT_MAX;
+        for (size_t i = 0; i < mSamplingRates.size(); i ++) {
+            if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) {
+                samplingRate = mSamplingRates[i];
+            }
+        }
+        return (samplingRate == UINT_MAX) ? 0 : samplingRate;
+    }
+
+    uint32_t samplingRate = 0;
+    uint32_t maxRate = MAX_MIXER_SAMPLING_RATE;
+
+    // For mixed output and inputs, use max mixer sampling rates. Do not
+    // limit sampling rate otherwise
+    if (mType != AUDIO_PORT_TYPE_MIX) {
+        maxRate = UINT_MAX;
+    }
+    for (size_t i = 0; i < mSamplingRates.size(); i ++) {
+        if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) {
+            samplingRate = mSamplingRates[i];
+        }
+    }
+    return samplingRate;
+}
+
+audio_channel_mask_t AudioPort::pickChannelMask() const
+{
+    // special case for uninitialized dynamic profile
+    if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) {
+        return AUDIO_CHANNEL_NONE;
+    }
+    audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE;
+
+    // For direct outputs, pick minimum channel count: this helps ensuring that the
+    // channel count / sampling rate combination chosen will be supported by the connected
+    // sink
+    if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
+            (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) {
+        uint32_t channelCount = UINT_MAX;
+        for (size_t i = 0; i < mChannelMasks.size(); i ++) {
+            uint32_t cnlCount;
+            if (mUseInChannelMask) {
+                cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]);
+            } else {
+                cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]);
+            }
+            if ((cnlCount < channelCount) && (cnlCount > 0)) {
+                channelMask = mChannelMasks[i];
+                channelCount = cnlCount;
+            }
+        }
+        return channelMask;
+    }
+
+    uint32_t channelCount = 0;
+    uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT;
+
+    // For mixed output and inputs, use max mixer channel count. Do not
+    // limit channel count otherwise
+    if (mType != AUDIO_PORT_TYPE_MIX) {
+        maxCount = UINT_MAX;
+    }
+    for (size_t i = 0; i < mChannelMasks.size(); i ++) {
+        uint32_t cnlCount;
+        if (mUseInChannelMask) {
+            cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]);
+        } else {
+            cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]);
+        }
+        if ((cnlCount > channelCount) && (cnlCount <= maxCount)) {
+            channelMask = mChannelMasks[i];
+            channelCount = cnlCount;
+        }
+    }
+    return channelMask;
+}
+
+/* format in order of increasing preference */
+const audio_format_t AudioPort::sPcmFormatCompareTable[] = {
+        AUDIO_FORMAT_DEFAULT,
+        AUDIO_FORMAT_PCM_16_BIT,
+        AUDIO_FORMAT_PCM_8_24_BIT,
+        AUDIO_FORMAT_PCM_24_BIT_PACKED,
+        AUDIO_FORMAT_PCM_32_BIT,
+        AUDIO_FORMAT_PCM_FLOAT,
+};
+
+int AudioPort::compareFormats(audio_format_t format1,
+                                                  audio_format_t format2)
+{
+    // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any
+    // compressed format and better than any PCM format. This is by design of pickFormat()
+    if (!audio_is_linear_pcm(format1)) {
+        if (!audio_is_linear_pcm(format2)) {
+            return 0;
+        }
+        return 1;
+    }
+    if (!audio_is_linear_pcm(format2)) {
+        return -1;
+    }
+
+    int index1 = -1, index2 = -1;
+    for (size_t i = 0;
+            (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1));
+            i ++) {
+        if (sPcmFormatCompareTable[i] == format1) {
+            index1 = i;
+        }
+        if (sPcmFormatCompareTable[i] == format2) {
+            index2 = i;
+        }
+    }
+    // format1 not found => index1 < 0 => format2 > format1
+    // format2 not found => index2 < 0 => format2 < format1
+    return index1 - index2;
+}
+
+audio_format_t AudioPort::pickFormat() const
+{
+    // special case for uninitialized dynamic profile
+    if (mFormats.size() == 1 && mFormats[0] == 0) {
+        return AUDIO_FORMAT_DEFAULT;
+    }
+
+    audio_format_t format = AUDIO_FORMAT_DEFAULT;
+    audio_format_t bestFormat =
+            AudioPort::sPcmFormatCompareTable[
+                ARRAY_SIZE(AudioPort::sPcmFormatCompareTable) - 1];
+    // For mixed output and inputs, use best mixer output format. Do not
+    // limit format otherwise
+    if ((mType != AUDIO_PORT_TYPE_MIX) ||
+            ((mRole == AUDIO_PORT_ROLE_SOURCE) &&
+             (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) {
+        bestFormat = AUDIO_FORMAT_INVALID;
+    }
+
+    for (size_t i = 0; i < mFormats.size(); i ++) {
+        if ((compareFormats(mFormats[i], format) > 0) &&
+                (compareFormats(mFormats[i], bestFormat) <= 0)) {
+            format = mFormats[i];
+        }
+    }
+    return format;
+}
+
+status_t AudioPort::checkGain(const struct audio_gain_config *gainConfig,
+                                                  int index) const
+{
+    if (index < 0 || (size_t)index >= mGains.size()) {
+        return BAD_VALUE;
+    }
+    return mGains[index]->checkConfig(gainConfig);
+}
+
+void AudioPort::dump(int fd, int spaces) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    if (mName.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
+        result.append(buffer);
+    }
+
+    if (mSamplingRates.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, "");
+        result.append(buffer);
+        for (size_t i = 0; i < mSamplingRates.size(); i++) {
+            if (i == 0 && mSamplingRates[i] == 0) {
+                snprintf(buffer, SIZE, "Dynamic");
+            } else {
+                snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
+            }
+            result.append(buffer);
+            result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
+        }
+        result.append("\n");
+    }
+
+    if (mChannelMasks.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, "");
+        result.append(buffer);
+        for (size_t i = 0; i < mChannelMasks.size(); i++) {
+            ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]);
+
+            if (i == 0 && mChannelMasks[i] == 0) {
+                snprintf(buffer, SIZE, "Dynamic");
+            } else {
+                snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
+            }
+            result.append(buffer);
+            result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
+        }
+        result.append("\n");
+    }
+
+    if (mFormats.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- formats: ", spaces, "");
+        result.append(buffer);
+        for (size_t i = 0; i < mFormats.size(); i++) {
+            const char *formatStr = ConfigParsingUtils::enumToString(sFormatNameToEnumTable,
+                                                 ARRAY_SIZE(sFormatNameToEnumTable),
+                                                 mFormats[i]);
+            if (i == 0 && strcmp(formatStr, "") == 0) {
+                snprintf(buffer, SIZE, "Dynamic");
+            } else {
+                snprintf(buffer, SIZE, "%s", formatStr);
+            }
+            result.append(buffer);
+            result.append(i == (mFormats.size() - 1) ? "" : ", ");
+        }
+        result.append("\n");
+    }
+    write(fd, result.string(), result.size());
+    if (mGains.size() != 0) {
+        snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
+        write(fd, buffer, strlen(buffer) + 1);
+        result.append(buffer);
+        for (size_t i = 0; i < mGains.size(); i++) {
+            mGains[i]->dump(fd, spaces + 2, i);
+        }
+    }
+}
+
+
+// --- AudioPortConfig class implementation
+
+AudioPortConfig::AudioPortConfig()
+{
+    mSamplingRate = 0;
+    mChannelMask = AUDIO_CHANNEL_NONE;
+    mFormat = AUDIO_FORMAT_INVALID;
+    mGain.index = -1;
+}
+
+status_t AudioPortConfig::applyAudioPortConfig(
+                                                        const struct audio_port_config *config,
+                                                        struct audio_port_config *backupConfig)
+{
+    struct audio_port_config localBackupConfig;
+    status_t status = NO_ERROR;
+
+    localBackupConfig.config_mask = config->config_mask;
+    toAudioPortConfig(&localBackupConfig);
+
+    sp<AudioPort> audioport = getAudioPort();
+    if (audioport == 0) {
+        status = NO_INIT;
+        goto exit;
+    }
+    if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+        status = audioport->checkExactSamplingRate(config->sample_rate);
+        if (status != NO_ERROR) {
+            goto exit;
+        }
+        mSamplingRate = config->sample_rate;
+    }
+    if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+        status = audioport->checkExactChannelMask(config->channel_mask);
+        if (status != NO_ERROR) {
+            goto exit;
+        }
+        mChannelMask = config->channel_mask;
+    }
+    if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+        status = audioport->checkFormat(config->format);
+        if (status != NO_ERROR) {
+            goto exit;
+        }
+        mFormat = config->format;
+    }
+    if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
+        status = audioport->checkGain(&config->gain, config->gain.index);
+        if (status != NO_ERROR) {
+            goto exit;
+        }
+        mGain = config->gain;
+    }
+
+exit:
+    if (status != NO_ERROR) {
+        applyAudioPortConfig(&localBackupConfig);
+    }
+    if (backupConfig != NULL) {
+        *backupConfig = localBackupConfig;
+    }
+    return status;
+}
+
+void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig,
+                                        const struct audio_port_config *srcConfig) const
+{
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+        dstConfig->sample_rate = mSamplingRate;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) {
+            dstConfig->sample_rate = srcConfig->sample_rate;
+        }
+    } else {
+        dstConfig->sample_rate = 0;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+        dstConfig->channel_mask = mChannelMask;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) {
+            dstConfig->channel_mask = srcConfig->channel_mask;
+        }
+    } else {
+        dstConfig->channel_mask = AUDIO_CHANNEL_NONE;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+        dstConfig->format = mFormat;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
+            dstConfig->format = srcConfig->format;
+        }
+    } else {
+        dstConfig->format = AUDIO_FORMAT_INVALID;
+    }
+    if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
+        dstConfig->gain = mGain;
+        if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) {
+            dstConfig->gain = srcConfig->gain;
+        }
+    } else {
+        dstConfig->gain.index = -1;
+    }
+    if (dstConfig->gain.index != -1) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
+    } else {
+        dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
+    }
+}
+
+
+// --- AudioPatch class implementation
+
+AudioPatch::AudioPatch(audio_patch_handle_t handle,
+            const struct audio_patch *patch, uid_t uid) :
+                mHandle(handle), mPatch(*patch), mUid(uid), mAfPatchHandle(0)
+{}
+
+status_t AudioPatch::dump(int fd, int spaces, int index) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources);
+    result.append(buffer);
+    for (size_t i = 0; i < mPatch.num_sources; i++) {
+        if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
+            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
+                     mPatch.sources[i].id, ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
+                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
+                                                        mPatch.sources[i].ext.device.type));
+        } else {
+            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
+                     mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle);
+        }
+        result.append(buffer);
+    }
+    snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks);
+    result.append(buffer);
+    for (size_t i = 0; i < mPatch.num_sinks; i++) {
+        if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
+            snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
+                     mPatch.sinks[i].id, ConfigParsingUtils::enumToString(sDeviceNameToEnumTable,
+                                                        ARRAY_SIZE(sDeviceNameToEnumTable),
+                                                        mPatch.sinks[i].ext.device.type));
+        } else {
+            snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
+                     mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle);
+        }
+        result.append(buffer);
+    }
+
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+
+}; // namespace android
diff --git a/services/audiopolicy/managerdefault/Ports.h b/services/audiopolicy/managerdefault/Ports.h
new file mode 100644
index 0000000..f6e0e93
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Ports.h
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+namespace android {
+
+class HwModule;
+
+class AudioPort: public virtual RefBase
+{
+public:
+    AudioPort(const String8& name, audio_port_type_t type,
+            audio_port_role_t role, const sp<HwModule>& module);
+    virtual ~AudioPort() {}
+
+    audio_port_handle_t getHandle() { return mId; }
+
+    void attach(const sp<HwModule>& module);
+    bool isAttached() { return mId != 0; }
+
+    virtual void toAudioPort(struct audio_port *port) const;
+
+    void importAudioPort(const sp<AudioPort> port);
+    void clearCapabilities();
+
+    void loadSamplingRates(char *name);
+    void loadFormats(char *name);
+    void loadOutChannels(char *name);
+    void loadInChannels(char *name);
+
+    audio_gain_mode_t loadGainMode(char *name);
+    void loadGain(cnode *root, int index);
+    virtual void loadGains(cnode *root);
+
+    // searches for an exact match
+    status_t checkExactSamplingRate(uint32_t samplingRate) const;
+    // searches for a compatible match, and returns the best match via updatedSamplingRate
+    status_t checkCompatibleSamplingRate(uint32_t samplingRate,
+            uint32_t *updatedSamplingRate) const;
+    // searches for an exact match
+    status_t checkExactChannelMask(audio_channel_mask_t channelMask) const;
+    // searches for a compatible match, currently implemented for input channel masks only
+    status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask) const;
+    status_t checkFormat(audio_format_t format) const;
+    status_t checkGain(const struct audio_gain_config *gainConfig, int index) const;
+
+    uint32_t pickSamplingRate() const;
+    audio_channel_mask_t pickChannelMask() const;
+    audio_format_t pickFormat() const;
+
+    static const audio_format_t sPcmFormatCompareTable[];
+    static int compareFormats(audio_format_t format1, audio_format_t format2);
+
+    void dump(int fd, int spaces) const;
+
+    String8           mName;
+    audio_port_type_t mType;
+    audio_port_role_t mRole;
+    bool              mUseInChannelMask;
+    // by convention, "0' in the first entry in mSamplingRates, mChannelMasks or mFormats
+    // indicates the supported parameters should be read from the output stream
+    // after it is opened for the first time
+    Vector <uint32_t> mSamplingRates; // supported sampling rates
+    Vector <audio_channel_mask_t> mChannelMasks; // supported channel masks
+    Vector <audio_format_t> mFormats; // supported audio formats
+    Vector < sp<AudioGain> > mGains; // gain controllers
+    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
+    uint32_t mFlags; // attribute flags (e.g primary output,
+                     // direct output...).
+
+
+protected:
+    //TODO - clarify the role of mId in this case, both an "attached" indicator
+    // and a unique ID for identifying a port to the (upcoming) selection API,
+    // and its relationship to the mId in AudioOutputDescriptor and AudioInputDescriptor.
+    audio_port_handle_t mId;
+};
+
+class AudioPortConfig: public virtual RefBase
+{
+public:
+    AudioPortConfig();
+    virtual ~AudioPortConfig() {}
+
+    status_t applyAudioPortConfig(const struct audio_port_config *config,
+            struct audio_port_config *backupConfig = NULL);
+    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+            const struct audio_port_config *srcConfig = NULL) const = 0;
+    virtual sp<AudioPort> getAudioPort() const = 0;
+    uint32_t mSamplingRate;
+    audio_format_t mFormat;
+    audio_channel_mask_t mChannelMask;
+    struct audio_gain_config mGain;
+};
+
+
+class AudioPatch: public RefBase
+{
+public:
+    AudioPatch(audio_patch_handle_t handle, const struct audio_patch *patch, uid_t uid);
+
+    status_t dump(int fd, int spaces, int index) const;
+
+    audio_patch_handle_t mHandle;
+    struct audio_patch mPatch;
+    uid_t mUid;
+    audio_patch_handle_t mAfPatchHandle;
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/audio_policy_conf.h b/services/audiopolicy/managerdefault/audio_policy_conf.h
similarity index 100%
rename from services/audiopolicy/audio_policy_conf.h
rename to services/audiopolicy/managerdefault/audio_policy_conf.h
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyClientImpl.cpp
rename to services/audiopolicy/service/AudioPolicyClientImpl.cpp
diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyClientImplLegacy.cpp
rename to services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyEffects.cpp
rename to services/audiopolicy/service/AudioPolicyEffects.cpp
diff --git a/services/audiopolicy/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
similarity index 100%
rename from services/audiopolicy/AudioPolicyEffects.h
rename to services/audiopolicy/service/AudioPolicyEffects.h
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyInterfaceImpl.cpp
rename to services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
rename to services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
similarity index 100%
rename from services/audiopolicy/AudioPolicyService.cpp
rename to services/audiopolicy/service/AudioPolicyService.cpp
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
similarity index 99%
rename from services/audiopolicy/AudioPolicyService.h
rename to services/audiopolicy/service/AudioPolicyService.h
index 7c2b59d..0378384 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -35,7 +35,7 @@
 #include <hardware_legacy/AudioPolicyInterface.h>
 #endif
 #include "AudioPolicyEffects.h"
-#include "AudioPolicyManager.h"
+#include "managerdefault/AudioPolicyManager.h"
 
 
 namespace android {
