Merge "audio policy: add option to use new policy manager"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 94aac5c..b8a9711 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -49,6 +49,9 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libmedia_native.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudioflinger_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudioflinger.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libaudiopolicy_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libaudiopolicy.so)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 84565bb..f270bfc 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -3,9 +3,21 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    AudioPolicyService.cpp \
+    AudioPolicyService.cpp
+
+USE_LEGACY_AUDIO_POLICY = 1
+ifeq ($(USE_LEGACY_AUDIO_POLICY), 1)
+LOCAL_SRC_FILES += \
+    AudioPolicyInterfaceImplLegacy.cpp \
+    AudioPolicyClientImplLegacy.cpp
+
+    LOCAL_CFLAGS += -DUSE_LEGACY_AUDIO_POLICY
+else
+LOCAL_SRC_FILES += \
     AudioPolicyInterfaceImpl.cpp \
-    AudioPolicyClientImpl.cpp
+    AudioPolicyClientImpl.cpp \
+    AudioPolicyManager.cpp
+endif
 
 LOCAL_C_INCLUDES := \
     $(TOPDIR)frameworks/av/services/audioflinger \
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp
index 53f3e2d..44c47c3 100644
--- a/services/audiopolicy/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/AudioPolicyClientImpl.cpp
@@ -14,44 +14,17 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "AudioPolicyService"
+#define LOG_TAG "AudioPolicyClientImpl"
 //#define LOG_NDEBUG 0
 
-#include "Configuration.h"
-#undef __STRICT_ANSI__
-#define __STDINT_LIMITS
-#define __STDC_LIMIT_MACROS
-#include <stdint.h>
-
-#include <sys/time.h>
-#include <binder/IServiceManager.h>
 #include <utils/Log.h>
-#include <cutils/properties.h>
-#include <binder/IPCThreadState.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
 #include "AudioPolicyService.h"
-#include "ServiceUtilities.h"
-#include <hardware_legacy/power.h>
-#include <media/AudioEffect.h>
-#include <media/EffectsFactoryApi.h>
-//#include <media/IAudioFlinger.h>
-
-#include <hardware/hardware.h>
-#include <system/audio.h>
-#include <system/audio_policy.h>
-#include <hardware/audio_policy.h>
-#include <audio_effects/audio_effects_conf.h>
-#include <media/AudioParameter.h>
-
 
 namespace android {
 
-/* implementation of the interface to the policy manager */
-extern "C" {
+/* implementation of the client interface from the policy manager */
 
-audio_module_handle_t aps_load_hw_module(void *service __unused,
-                                             const char *name)
+audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -62,34 +35,14 @@
     return af->loadHwModule(name);
 }
 
-// deprecated: replaced by aps_open_output_on_module()
-audio_io_handle_t aps_open_output(void *service __unused,
-                                         audio_devices_t *pDevices,
-                                         uint32_t *pSamplingRate,
-                                         audio_format_t *pFormat,
-                                         audio_channel_mask_t *pChannelMask,
-                                         uint32_t *pLatencyMs,
-                                         audio_output_flags_t flags)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-
-    return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
-                          pLatencyMs, flags);
-}
-
-audio_io_handle_t aps_open_output_on_module(void *service __unused,
-                                                   audio_module_handle_t module,
-                                                   audio_devices_t *pDevices,
-                                                   uint32_t *pSamplingRate,
-                                                   audio_format_t *pFormat,
-                                                   audio_channel_mask_t *pChannelMask,
-                                                   uint32_t *pLatencyMs,
-                                                   audio_output_flags_t flags,
-                                                   const audio_offload_info_t *offloadInfo)
+audio_io_handle_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
+                               audio_devices_t *pDevices,
+                               uint32_t *pSamplingRate,
+                               audio_format_t *pFormat,
+                               audio_channel_mask_t *pChannelMask,
+                               uint32_t *pLatencyMs,
+                               audio_output_flags_t flags,
+                               const audio_offload_info_t *offloadInfo)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -100,9 +53,9 @@
                           pLatencyMs, flags, offloadInfo);
 }
 
-audio_io_handle_t aps_open_dup_output(void *service __unused,
-                                                 audio_io_handle_t output1,
-                                                 audio_io_handle_t output2)
+audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput(
+                                                                audio_io_handle_t output1,
+                                                                audio_io_handle_t output2)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -112,7 +65,7 @@
     return af->openDuplicateOutput(output1, output2);
 }
 
-int aps_close_output(void *service __unused, audio_io_handle_t output)
+status_t AudioPolicyService::AudioPolicyClient::closeOutput(audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -122,7 +75,7 @@
     return af->closeOutput(output);
 }
 
-int aps_suspend_output(void *service __unused, audio_io_handle_t output)
+status_t AudioPolicyService::AudioPolicyClient::suspendOutput(audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -133,7 +86,7 @@
     return af->suspendOutput(output);
 }
 
-int aps_restore_output(void *service __unused, audio_io_handle_t output)
+status_t AudioPolicyService::AudioPolicyClient::restoreOutput(audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -144,29 +97,11 @@
     return af->restoreOutput(output);
 }
 
-// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
-audio_io_handle_t aps_open_input(void *service __unused,
-                                        audio_devices_t *pDevices,
-                                        uint32_t *pSamplingRate,
-                                        audio_format_t *pFormat,
-                                        audio_channel_mask_t *pChannelMask,
-                                        audio_in_acoustics_t acoustics __unused)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        ALOGW("%s: could not get AudioFlinger", __func__);
-        return 0;
-    }
-
-    return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask);
-}
-
-audio_io_handle_t aps_open_input_on_module(void *service __unused,
-                                                  audio_module_handle_t module,
-                                                  audio_devices_t *pDevices,
-                                                  uint32_t *pSamplingRate,
-                                                  audio_format_t *pFormat,
-                                                  audio_channel_mask_t *pChannelMask)
+audio_io_handle_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
+                              audio_devices_t *pDevices,
+                              uint32_t *pSamplingRate,
+                              audio_format_t *pFormat,
+                              audio_channel_mask_t *pChannelMask)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -177,7 +112,7 @@
     return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask);
 }
 
-int aps_close_input(void *service __unused, audio_io_handle_t input)
+status_t AudioPolicyService::AudioPolicyClient::closeInput(audio_io_handle_t input)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -187,7 +122,15 @@
     return af->closeInput(input);
 }
 
-int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream)
+status_t AudioPolicyService::AudioPolicyClient::setStreamVolume(audio_stream_type_t stream,
+                     float volume, audio_io_handle_t output,
+                     int delay_ms)
+{
+    return mAudioPolicyService->setStreamVolume(stream, volume, output,
+                                               delay_ms);
+}
+
+status_t AudioPolicyService::AudioPolicyClient::invalidateStream(audio_stream_type_t stream)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -197,9 +140,39 @@
     return af->invalidateStream(stream);
 }
 
-int aps_move_effects(void *service __unused, int session,
-                                audio_io_handle_t src_output,
-                                audio_io_handle_t dst_output)
+void AudioPolicyService::AudioPolicyClient::setParameters(audio_io_handle_t io_handle,
+                   const String8& keyValuePairs,
+                   int delay_ms)
+{
+    mAudioPolicyService->setParameters(io_handle, keyValuePairs.string(), delay_ms);
+}
+
+String8 AudioPolicyService::AudioPolicyClient::getParameters(audio_io_handle_t io_handle,
+                      const String8& keys)
+{
+    String8 result = AudioSystem::getParameters(io_handle, keys);
+    return result;
+}
+
+status_t AudioPolicyService::AudioPolicyClient::startTone(audio_policy_tone_t tone,
+              audio_stream_type_t stream)
+{
+    return mAudioPolicyService->startTone(tone, stream);
+}
+
+status_t AudioPolicyService::AudioPolicyClient::stopTone()
+{
+    return mAudioPolicyService->stopTone();
+}
+
+status_t AudioPolicyService::AudioPolicyClient::setVoiceVolume(float volume, int delay_ms)
+{
+    return mAudioPolicyService->setVoiceVolume(volume, delay_ms);
+}
+
+status_t AudioPolicyService::AudioPolicyClient::moveEffects(int session,
+                        audio_io_handle_t src_output,
+                        audio_io_handle_t dst_output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
     if (af == 0) {
@@ -209,53 +182,6 @@
     return af->moveEffects(session, src_output, dst_output);
 }
 
-char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
-                                     const char *keys)
-{
-    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
-    return strdup(result.string());
-}
 
-void aps_set_parameters(void *service, audio_io_handle_t io_handle,
-                                   const char *kv_pairs, int delay_ms)
-{
-    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
-
-    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
-}
-
-int aps_set_stream_volume(void *service, audio_stream_type_t stream,
-                                     float volume, audio_io_handle_t output,
-                                     int delay_ms)
-{
-    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
-
-    return audioPolicyService->setStreamVolume(stream, volume, output,
-                                               delay_ms);
-}
-
-int aps_start_tone(void *service, audio_policy_tone_t tone,
-                              audio_stream_type_t stream)
-{
-    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
-
-    return audioPolicyService->startTone(tone, stream);
-}
-
-int aps_stop_tone(void *service)
-{
-    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
-
-    return audioPolicyService->stopTone();
-}
-
-int aps_set_voice_volume(void *service, float volume, int delay_ms)
-{
-    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
-
-    return audioPolicyService->setVoiceVolume(volume, delay_ms);
-}
-
-}; // extern "C"
 
 }; // namespace android
diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
new file mode 100644
index 0000000..53f3e2d
--- /dev/null
+++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
@@ -0,0 +1,261 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AudioPolicyService"
+//#define LOG_NDEBUG 0
+
+#include "Configuration.h"
+#undef __STRICT_ANSI__
+#define __STDINT_LIMITS
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
+#include <sys/time.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include <cutils/properties.h>
+#include <binder/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+#include "AudioPolicyService.h"
+#include "ServiceUtilities.h"
+#include <hardware_legacy/power.h>
+#include <media/AudioEffect.h>
+#include <media/EffectsFactoryApi.h>
+//#include <media/IAudioFlinger.h>
+
+#include <hardware/hardware.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <hardware/audio_policy.h>
+#include <audio_effects/audio_effects_conf.h>
+#include <media/AudioParameter.h>
+
+
+namespace android {
+
+/* implementation of the interface to the policy manager */
+extern "C" {
+
+audio_module_handle_t aps_load_hw_module(void *service __unused,
+                                             const char *name)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+
+    return af->loadHwModule(name);
+}
+
+// deprecated: replaced by aps_open_output_on_module()
+audio_io_handle_t aps_open_output(void *service __unused,
+                                         audio_devices_t *pDevices,
+                                         uint32_t *pSamplingRate,
+                                         audio_format_t *pFormat,
+                                         audio_channel_mask_t *pChannelMask,
+                                         uint32_t *pLatencyMs,
+                                         audio_output_flags_t flags)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+
+    return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
+                          pLatencyMs, flags);
+}
+
+audio_io_handle_t aps_open_output_on_module(void *service __unused,
+                                                   audio_module_handle_t module,
+                                                   audio_devices_t *pDevices,
+                                                   uint32_t *pSamplingRate,
+                                                   audio_format_t *pFormat,
+                                                   audio_channel_mask_t *pChannelMask,
+                                                   uint32_t *pLatencyMs,
+                                                   audio_output_flags_t flags,
+                                                   const audio_offload_info_t *offloadInfo)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+    return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
+                          pLatencyMs, flags, offloadInfo);
+}
+
+audio_io_handle_t aps_open_dup_output(void *service __unused,
+                                                 audio_io_handle_t output1,
+                                                 audio_io_handle_t output2)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+    return af->openDuplicateOutput(output1, output2);
+}
+
+int aps_close_output(void *service __unused, audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    return af->closeOutput(output);
+}
+
+int aps_suspend_output(void *service __unused, audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return PERMISSION_DENIED;
+    }
+
+    return af->suspendOutput(output);
+}
+
+int aps_restore_output(void *service __unused, audio_io_handle_t output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return PERMISSION_DENIED;
+    }
+
+    return af->restoreOutput(output);
+}
+
+// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
+audio_io_handle_t aps_open_input(void *service __unused,
+                                        audio_devices_t *pDevices,
+                                        uint32_t *pSamplingRate,
+                                        audio_format_t *pFormat,
+                                        audio_channel_mask_t *pChannelMask,
+                                        audio_in_acoustics_t acoustics __unused)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+
+    return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask);
+}
+
+audio_io_handle_t aps_open_input_on_module(void *service __unused,
+                                                  audio_module_handle_t module,
+                                                  audio_devices_t *pDevices,
+                                                  uint32_t *pSamplingRate,
+                                                  audio_format_t *pFormat,
+                                                  audio_channel_mask_t *pChannelMask)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        ALOGW("%s: could not get AudioFlinger", __func__);
+        return 0;
+    }
+
+    return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask);
+}
+
+int aps_close_input(void *service __unused, audio_io_handle_t input)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    return af->closeInput(input);
+}
+
+int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    return af->invalidateStream(stream);
+}
+
+int aps_move_effects(void *service __unused, int session,
+                                audio_io_handle_t src_output,
+                                audio_io_handle_t dst_output)
+{
+    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+    if (af == 0) {
+        return PERMISSION_DENIED;
+    }
+
+    return af->moveEffects(session, src_output, dst_output);
+}
+
+char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
+                                     const char *keys)
+{
+    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
+    return strdup(result.string());
+}
+
+void aps_set_parameters(void *service, audio_io_handle_t io_handle,
+                                   const char *kv_pairs, int delay_ms)
+{
+    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
+}
+
+int aps_set_stream_volume(void *service, audio_stream_type_t stream,
+                                     float volume, audio_io_handle_t output,
+                                     int delay_ms)
+{
+    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+    return audioPolicyService->setStreamVolume(stream, volume, output,
+                                               delay_ms);
+}
+
+int aps_start_tone(void *service, audio_policy_tone_t tone,
+                              audio_stream_type_t stream)
+{
+    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+    return audioPolicyService->startTone(tone, stream);
+}
+
+int aps_stop_tone(void *service)
+{
+    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+    return audioPolicyService->stopTone();
+}
+
+int aps_set_voice_volume(void *service, float volume, int delay_ms)
+{
+    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
+
+    return audioPolicyService->setVoiceVolume(volume, delay_ms);
+}
+
+}; // extern "C"
+
+}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 768b13e..66260e3 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_AUDIOPOLICYINTERFACE_H
-#define ANDROID_AUDIOPOLICYINTERFACE_H
+#ifndef ANDROID_AUDIOPOLICY_INTERFACE_H
+#define ANDROID_AUDIOPOLICY_INTERFACE_H
 
 #include <media/AudioSystem.h>
 #include <utils/String8.h>
@@ -254,4 +254,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_AUDIOPOLICYINTERFACE_H
+#endif // ANDROID_AUDIOPOLICY_INTERFACE_H
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index bb62ab3..c57c4fa 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -14,17 +14,13 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "AudioPolicyService"
+#define LOG_TAG "AudioPolicyIntefaceImpl"
 //#define LOG_NDEBUG 0
 
 #include <utils/Log.h>
 #include "AudioPolicyService.h"
 #include "ServiceUtilities.h"
 
-#include <system/audio.h>
-#include <system/audio_policy.h>
-#include <hardware/audio_policy.h>
-
 namespace android {
 
 
@@ -34,7 +30,7 @@
                                                   audio_policy_dev_state_t state,
                                                   const char *device_address)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (!settingsAllowed()) {
@@ -50,7 +46,7 @@
 
     ALOGV("setDeviceConnectionState()");
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
+    return mAudioPolicyManager->setDeviceConnectionState(device,
                                                       state, device_address);
 }
 
@@ -58,16 +54,16 @@
                                                               audio_devices_t device,
                                                               const char *device_address)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
     }
-    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
+    return mAudioPolicyManager->getDeviceConnectionState(device,
                                                       device_address);
 }
 
 status_t AudioPolicyService::setPhoneState(audio_mode_t state)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (!settingsAllowed()) {
@@ -83,14 +79,14 @@
     AudioSystem::setMode(state);
 
     Mutex::Autolock _l(mLock);
-    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
+    mAudioPolicyManager->setPhoneState(state);
     return NO_ERROR;
 }
 
 status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
                                          audio_policy_forced_cfg_t config)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (!settingsAllowed()) {
@@ -104,19 +100,19 @@
     }
     ALOGV("setForceUse()");
     Mutex::Autolock _l(mLock);
-    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
+    mAudioPolicyManager->setForceUse(usage, config);
     return NO_ERROR;
 }
 
 audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return AUDIO_POLICY_FORCE_NONE;
     }
     if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
         return AUDIO_POLICY_FORCE_NONE;
     }
-    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
+    return mAudioPolicyManager->getForceUse(usage);
 }
 
 audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
@@ -126,12 +122,12 @@
                                     audio_output_flags_t flags,
                                     const audio_offload_info_t *offloadInfo)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
     ALOGV("getOutput()");
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate,
+    return mAudioPolicyManager->getOutput(stream, samplingRate,
                                     format, channelMask, flags, offloadInfo);
 }
 
@@ -139,19 +135,19 @@
                                          audio_stream_type_t stream,
                                          int session)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     ALOGV("startOutput()");
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
+    return mAudioPolicyManager->startOutput(output, stream, session);
 }
 
 status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
                                         audio_stream_type_t stream,
                                         int session)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     ALOGV("stopOutput()");
@@ -165,12 +161,12 @@
 {
     ALOGV("doStopOutput from tid %d", gettid());
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
+    return mAudioPolicyManager->stopOutput(output, stream, session);
 }
 
 void AudioPolicyService::releaseOutput(audio_io_handle_t output)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return;
     }
     ALOGV("releaseOutput()");
@@ -181,7 +177,7 @@
 {
     ALOGV("doReleaseOutput from tid %d", gettid());
     Mutex::Autolock _l(mLock);
-    mpAudioPolicy->release_output(mpAudioPolicy, output);
+    mAudioPolicyManager->releaseOutput(output);
 }
 
 audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
@@ -190,7 +186,7 @@
                                     audio_channel_mask_t channelMask,
                                     int audioSession)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
     // already checked by client, but double-check in case the client wrapper is bypassed
@@ -204,7 +200,7 @@
 
     Mutex::Autolock _l(mLock);
     // the audio_in_acoustics_t parameter is ignored by get_input()
-    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
+    audio_io_handle_t input = mAudioPolicyManager->getInput(inputSource, samplingRate,
                                                    format, channelMask, (audio_in_acoustics_t) 0);
 
     if (input == 0) {
@@ -248,31 +244,31 @@
 
 status_t AudioPolicyService::startInput(audio_io_handle_t input)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mpAudioPolicy->start_input(mpAudioPolicy, input);
+    return mAudioPolicyManager->startInput(input);
 }
 
 status_t AudioPolicyService::stopInput(audio_io_handle_t input)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
+    return mAudioPolicyManager->stopInput(input);
 }
 
 void AudioPolicyService::releaseInput(audio_io_handle_t input)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return;
     }
     Mutex::Autolock _l(mLock);
-    mpAudioPolicy->release_input(mpAudioPolicy, input);
+    mAudioPolicyManager->releaseInput(input);
 
     ssize_t index = mInputs.indexOfKey(input);
     if (index < 0) {
@@ -288,7 +284,7 @@
                                             int indexMin,
                                             int indexMax)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (!settingsAllowed()) {
@@ -298,7 +294,7 @@
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
-    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
+    mAudioPolicyManager->initStreamVolume(stream, indexMin, indexMax);
     return NO_ERROR;
 }
 
@@ -306,7 +302,7 @@
                                                   int index,
                                                   audio_devices_t device)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (!settingsAllowed()) {
@@ -316,63 +312,53 @@
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
-    if (mpAudioPolicy->set_stream_volume_index_for_device) {
-        return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
-                                                                stream,
-                                                                index,
-                                                                device);
-    } else {
-        return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
-    }
+    return mAudioPolicyManager->setStreamVolumeIndex(stream,
+                                                    index,
+                                                    device);
 }
 
 status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
                                                   int *index,
                                                   audio_devices_t device)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
-    if (mpAudioPolicy->get_stream_volume_index_for_device) {
-        return mpAudioPolicy->get_stream_volume_index_for_device(mpAudioPolicy,
-                                                                stream,
-                                                                index,
-                                                                device);
-    } else {
-        return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
-    }
+    return mAudioPolicyManager->getStreamVolumeIndex(stream,
+                                                    index,
+                                                    device);
 }
 
 uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
-    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
+    return mAudioPolicyManager->getStrategyForStream(stream);
 }
 
 //audio policy: use audio_device_t appropriately
 
 audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return (audio_devices_t)0;
     }
-    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
+    return mAudioPolicyManager->getDevicesForStream(stream);
 }
 
 audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
 {
     // FIXME change return type to status_t, and return NO_INIT here
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
+    return mAudioPolicyManager->getOutputForEffect(desc);
 }
 
 status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
@@ -381,56 +367,53 @@
                                 int session,
                                 int id)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
+    return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
 }
 
 status_t AudioPolicyService::unregisterEffect(int id)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
+    return mAudioPolicyManager->unregisterEffect(id);
 }
 
 status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
-    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
+    return mAudioPolicyManager->setEffectEnabled(id, enabled);
 }
 
 bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
+    return mAudioPolicyManager->isStreamActive(stream, inPastMs);
 }
 
 bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
 {
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         return 0;
     }
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs);
+    return mAudioPolicyManager->isStreamActiveRemotely(stream, inPastMs);
 }
 
 bool AudioPolicyService::isSourceActive(audio_source_t source) const
 {
-    if (mpAudioPolicy == NULL) {
-        return false;
-    }
-    if (mpAudioPolicy->is_source_active == 0) {
+    if (mAudioPolicyManager == NULL) {
         return false;
     }
     Mutex::Autolock _l(mLock);
-    return mpAudioPolicy->is_source_active(mpAudioPolicy, source);
+    return mAudioPolicyManager->isSourceActive(source);
 }
 
 status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
@@ -438,7 +421,7 @@
                                                        uint32_t *count)
 {
 
-    if (mpAudioPolicy == NULL) {
+    if (mAudioPolicyManager == NULL) {
         *count = 0;
         return NO_INIT;
     }
@@ -472,17 +455,12 @@
 
 bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
 {
-    if (mpAudioPolicy == NULL) {
-        ALOGV("mpAudioPolicy == NULL");
+    if (mAudioPolicyManager == NULL) {
+        ALOGV("mAudioPolicyManager == NULL");
         return false;
     }
 
-    if (mpAudioPolicy->is_offload_supported == NULL) {
-        ALOGV("HAL does not implement is_offload_supported");
-        return false;
-    }
-
-    return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info);
+    return mAudioPolicyManager->isOffloadSupported(info);
 }
 
 
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
new file mode 100644
index 0000000..bb62ab3
--- /dev/null
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AudioPolicyService"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include "AudioPolicyService.h"
+#include "ServiceUtilities.h"
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <hardware/audio_policy.h>
+
+namespace android {
+
+
+// ----------------------------------------------------------------------------
+
+status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
+                                                  audio_policy_dev_state_t state,
+                                                  const char *device_address)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
+        return BAD_VALUE;
+    }
+    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
+            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
+        return BAD_VALUE;
+    }
+
+    ALOGV("setDeviceConnectionState()");
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
+                                                      state, device_address);
+}
+
+audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
+                                                              audio_devices_t device,
+                                                              const char *device_address)
+{
+    if (mpAudioPolicy == NULL) {
+        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+    }
+    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
+                                                      device_address);
+}
+
+status_t AudioPolicyService::setPhoneState(audio_mode_t state)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (uint32_t(state) >= AUDIO_MODE_CNT) {
+        return BAD_VALUE;
+    }
+
+    ALOGV("setPhoneState()");
+
+    // TODO: check if it is more appropriate to do it in platform specific policy manager
+    AudioSystem::setMode(state);
+
+    Mutex::Autolock _l(mLock);
+    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
+                                         audio_policy_forced_cfg_t config)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
+        return BAD_VALUE;
+    }
+    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
+        return BAD_VALUE;
+    }
+    ALOGV("setForceUse()");
+    Mutex::Autolock _l(mLock);
+    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
+    return NO_ERROR;
+}
+
+audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
+{
+    if (mpAudioPolicy == NULL) {
+        return AUDIO_POLICY_FORCE_NONE;
+    }
+    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
+        return AUDIO_POLICY_FORCE_NONE;
+    }
+    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
+}
+
+audio_io_handle_t AudioPolicyService::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)
+{
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    ALOGV("getOutput()");
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate,
+                                    format, channelMask, flags, offloadInfo);
+}
+
+status_t AudioPolicyService::startOutput(audio_io_handle_t output,
+                                         audio_stream_type_t stream,
+                                         int session)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    ALOGV("startOutput()");
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
+}
+
+status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
+                                        audio_stream_type_t stream,
+                                        int session)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    ALOGV("stopOutput()");
+    mOutputCommandThread->stopOutputCommand(output, stream, session);
+    return NO_ERROR;
+}
+
+status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
+                                      audio_stream_type_t stream,
+                                      int session)
+{
+    ALOGV("doStopOutput from tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
+}
+
+void AudioPolicyService::releaseOutput(audio_io_handle_t output)
+{
+    if (mpAudioPolicy == NULL) {
+        return;
+    }
+    ALOGV("releaseOutput()");
+    mOutputCommandThread->releaseOutputCommand(output);
+}
+
+void AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
+{
+    ALOGV("doReleaseOutput from tid %d", gettid());
+    Mutex::Autolock _l(mLock);
+    mpAudioPolicy->release_output(mpAudioPolicy, output);
+}
+
+audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
+                                    uint32_t samplingRate,
+                                    audio_format_t format,
+                                    audio_channel_mask_t channelMask,
+                                    int audioSession)
+{
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    // already checked by client, but double-check in case the client wrapper is bypassed
+    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD) {
+        return 0;
+    }
+
+    if ((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
+        return 0;
+    }
+
+    Mutex::Autolock _l(mLock);
+    // the audio_in_acoustics_t parameter is ignored by get_input()
+    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
+                                                   format, channelMask, (audio_in_acoustics_t) 0);
+
+    if (input == 0) {
+        return input;
+    }
+    // create audio pre processors according to input source
+    audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
+                                    AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
+
+    ssize_t index = mInputSources.indexOfKey(aliasSource);
+    if (index < 0) {
+        return input;
+    }
+    ssize_t idx = mInputs.indexOfKey(input);
+    InputDesc *inputDesc;
+    if (idx < 0) {
+        inputDesc = new InputDesc(audioSession);
+        mInputs.add(input, inputDesc);
+    } else {
+        inputDesc = mInputs.valueAt(idx);
+    }
+
+    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
+    for (size_t i = 0; i < effects.size(); i++) {
+        EffectDesc *effect = effects[i];
+        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
+        status_t status = fx->initCheck();
+        if (status != NO_ERROR && status != ALREADY_EXISTS) {
+            ALOGW("Failed to create Fx %s on input %d", effect->mName, input);
+            // fx goes out of scope and strong ref on AudioEffect is released
+            continue;
+        }
+        for (size_t j = 0; j < effect->mParams.size(); j++) {
+            fx->setParameter(effect->mParams[j]);
+        }
+        inputDesc->mEffects.add(fx);
+    }
+    setPreProcessorEnabled(inputDesc, true);
+    return input;
+}
+
+status_t AudioPolicyService::startInput(audio_io_handle_t input)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+
+    return mpAudioPolicy->start_input(mpAudioPolicy, input);
+}
+
+status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+
+    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
+}
+
+void AudioPolicyService::releaseInput(audio_io_handle_t input)
+{
+    if (mpAudioPolicy == NULL) {
+        return;
+    }
+    Mutex::Autolock _l(mLock);
+    mpAudioPolicy->release_input(mpAudioPolicy, input);
+
+    ssize_t index = mInputs.indexOfKey(input);
+    if (index < 0) {
+        return;
+    }
+    InputDesc *inputDesc = mInputs.valueAt(index);
+    setPreProcessorEnabled(inputDesc, false);
+    delete inputDesc;
+    mInputs.removeItemsAt(index);
+}
+
+status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
+                                            int indexMin,
+                                            int indexMax)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+        return BAD_VALUE;
+    }
+    Mutex::Autolock _l(mLock);
+    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
+    return NO_ERROR;
+}
+
+status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
+                                                  int index,
+                                                  audio_devices_t device)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+        return BAD_VALUE;
+    }
+    Mutex::Autolock _l(mLock);
+    if (mpAudioPolicy->set_stream_volume_index_for_device) {
+        return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
+                                                                stream,
+                                                                index,
+                                                                device);
+    } else {
+        return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
+    }
+}
+
+status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
+                                                  int *index,
+                                                  audio_devices_t device)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+        return BAD_VALUE;
+    }
+    Mutex::Autolock _l(mLock);
+    if (mpAudioPolicy->get_stream_volume_index_for_device) {
+        return mpAudioPolicy->get_stream_volume_index_for_device(mpAudioPolicy,
+                                                                stream,
+                                                                index,
+                                                                device);
+    } else {
+        return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
+    }
+}
+
+uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
+{
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
+}
+
+//audio policy: use audio_device_t appropriately
+
+audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
+{
+    if (mpAudioPolicy == NULL) {
+        return (audio_devices_t)0;
+    }
+    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
+}
+
+audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
+{
+    // FIXME change return type to status_t, and return NO_INIT here
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
+}
+
+status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
+                                audio_io_handle_t io,
+                                uint32_t strategy,
+                                int session,
+                                int id)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
+}
+
+status_t AudioPolicyService::unregisterEffect(int id)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
+}
+
+status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
+{
+    if (mpAudioPolicy == NULL) {
+        return NO_INIT;
+    }
+    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
+}
+
+bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
+{
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
+}
+
+bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
+{
+    if (mpAudioPolicy == NULL) {
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs);
+}
+
+bool AudioPolicyService::isSourceActive(audio_source_t source) const
+{
+    if (mpAudioPolicy == NULL) {
+        return false;
+    }
+    if (mpAudioPolicy->is_source_active == 0) {
+        return false;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->is_source_active(mpAudioPolicy, source);
+}
+
+status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
+                                                       effect_descriptor_t *descriptors,
+                                                       uint32_t *count)
+{
+
+    if (mpAudioPolicy == NULL) {
+        *count = 0;
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    status_t status = NO_ERROR;
+
+    size_t index;
+    for (index = 0; index < mInputs.size(); index++) {
+        if (mInputs.valueAt(index)->mSessionId == audioSession) {
+            break;
+        }
+    }
+    if (index == mInputs.size()) {
+        *count = 0;
+        return BAD_VALUE;
+    }
+    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
+
+    for (size_t i = 0; i < effects.size(); i++) {
+        effect_descriptor_t desc = effects[i]->descriptor();
+        if (i < *count) {
+            descriptors[i] = desc;
+        }
+    }
+    if (effects.size() > *count) {
+        status = NO_MEMORY;
+    }
+    *count = effects.size();
+    return status;
+}
+
+bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
+{
+    if (mpAudioPolicy == NULL) {
+        ALOGV("mpAudioPolicy == NULL");
+        return false;
+    }
+
+    if (mpAudioPolicy->is_offload_supported == NULL) {
+        ALOGV("HAL does not implement is_offload_supported");
+        return false;
+    }
+
+    return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info);
+}
+
+
+}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index a052e04..4a708a0 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -60,7 +60,8 @@
 // ----------------------------------------------------------------------------
 
 AudioPolicyService::AudioPolicyService()
-    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL)
+    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
+      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL)
 {
     char value[PROPERTY_VALUE_MAX];
     const struct hw_module_t *module;
@@ -75,12 +76,15 @@
     mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
     // start output activity command thread
     mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
+
+#ifdef USE_LEGACY_AUDIO_POLICY
+    ALOGI("AudioPolicyService CSTOR in legacy mode");
+
     /* instantiate the audio policy manager */
     rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
     if (rc) {
         return;
     }
-
     rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
     ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
     if (rc) {
@@ -99,8 +103,13 @@
     if (rc) {
         return;
     }
-
     ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
+#else
+    ALOGI("AudioPolicyService CSTOR in new mode");
+
+    mAudioPolicyClient = new AudioPolicyClient(this);
+    mAudioPolicyManager = new AudioPolicyManager(mAudioPolicyClient);
+#endif
 
     // load audio pre processing modules
     if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
@@ -130,12 +139,17 @@
     }
     mInputs.clear();
 
+#ifdef USE_LEGACY_AUDIO_POLICY
     if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) {
         mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
     }
     if (mpAudioPolicyDev != NULL) {
         audio_policy_dev_close(mpAudioPolicyDev);
     }
+#else
+    delete mAudioPolicyManager;
+    delete mAudioPolicyClient;
+#endif
 }
 
 
@@ -163,7 +177,11 @@
     char buffer[SIZE];
     String8 result;
 
+#ifdef USE_LEGACY_AUDIO_POLICY
     snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
+#else
+    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
+#endif
     result.append(buffer);
     snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
     result.append(buffer);
@@ -193,9 +211,15 @@
             mTonePlaybackThread->dump(fd);
         }
 
+#ifdef USE_LEGACY_AUDIO_POLICY
         if (mpAudioPolicy) {
             mpAudioPolicy->dump(mpAudioPolicy, fd);
         }
+#else
+        if (mAudioPolicyManager) {
+            mAudioPolicyManager->dump(fd);
+        }
+#endif
 
         if (locked) mLock.unlock();
     }
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index ae053a9..cdc90d0 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -30,6 +30,8 @@
 #include <media/IAudioPolicyService.h>
 #include <media/ToneGenerator.h>
 #include <media/AudioEffect.h>
+#include <hardware_legacy/AudioPolicyInterface.h>
+#include "AudioPolicyManager.h"
 
 namespace android {
 
@@ -38,7 +40,6 @@
 class AudioPolicyService :
     public BinderService<AudioPolicyService>,
     public BnAudioPolicyService,
-//    public AudioPolicyClientInterface,
     public IBinder::DeathRecipient
 {
     friend class BinderService<AudioPolicyService>;
@@ -313,6 +314,91 @@
         Vector< sp<AudioEffect> >mEffects;
     };
 
+    class AudioPolicyClient : public AudioPolicyClientInterface
+    {
+     public:
+        AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {}
+        virtual ~AudioPolicyClient() {}
+
+        //
+        // Audio HW module functions
+        //
+
+        // loads a HW module.
+        virtual audio_module_handle_t loadHwModule(const char *name);
+
+        //
+        // Audio output Control functions
+        //
+
+        // opens an audio output with the requested parameters. The parameter values can indicate to use the default values
+        // in case the audio policy manager has no specific requirements for the output being opened.
+        // When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
+        // The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
+        virtual audio_io_handle_t openOutput(audio_module_handle_t module,
+                                             audio_devices_t *pDevices,
+                                             uint32_t *pSamplingRate,
+                                             audio_format_t *pFormat,
+                                             audio_channel_mask_t *pChannelMask,
+                                             uint32_t *pLatencyMs,
+                                             audio_output_flags_t flags,
+                                             const audio_offload_info_t *offloadInfo = NULL);
+        // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
+        // a special mixer thread in the AudioFlinger.
+        virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2);
+        // closes the output stream
+        virtual status_t closeOutput(audio_io_handle_t output);
+        // suspends the output. When an output is suspended, the corresponding audio hardware output stream is placed in
+        // standby and the AudioTracks attached to the mixer thread are still processed but the output mix is discarded.
+        virtual status_t suspendOutput(audio_io_handle_t output);
+        // restores a suspended output.
+        virtual status_t restoreOutput(audio_io_handle_t output);
+
+        //
+        // Audio input Control functions
+        //
+
+        // opens an audio input
+        virtual audio_io_handle_t openInput(audio_module_handle_t module,
+                                            audio_devices_t *pDevices,
+                                            uint32_t *pSamplingRate,
+                                            audio_format_t *pFormat,
+                                            audio_channel_mask_t *pChannelMask);
+        // closes an audio input
+        virtual status_t closeInput(audio_io_handle_t input);
+        //
+        // misc control functions
+        //
+
+        // set a stream volume for a particular output. For the same user setting, a given stream type can have different volumes
+        // for each output (destination device) it is attached to.
+        virtual status_t setStreamVolume(audio_stream_type_t stream, float volume, audio_io_handle_t output, int delayMs = 0);
+
+        // invalidate a stream type, causing a reroute to an unspecified new output
+        virtual status_t invalidateStream(audio_stream_type_t stream);
+
+        // function enabling to send proprietary informations directly from audio policy manager to audio hardware interface.
+        virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs = 0);
+        // function enabling to receive proprietary informations directly from audio hardware interface to audio policy manager.
+        virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
+
+        // request the playback of a tone on the specified stream: used for instance to replace notification sounds when playing
+        // over a telephony device during a phone call.
+        virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream);
+        virtual status_t stopTone();
+
+        // set down link audio volume.
+        virtual status_t setVoiceVolume(float volume, int delayMs = 0);
+
+        // move effect to the specified output
+        virtual status_t moveEffects(int session,
+                                         audio_io_handle_t srcOutput,
+                                         audio_io_handle_t dstOutput);
+
+     private:
+        AudioPolicyService *mAudioPolicyService;
+    };
+
     static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
 
     void setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled);
@@ -344,6 +430,9 @@
     sp<AudioCommandThread> mOutputCommandThread;    // process stop and release output
     struct audio_policy_device *mpAudioPolicyDev;
     struct audio_policy *mpAudioPolicy;
+    AudioPolicyManager *mAudioPolicyManager;
+    AudioPolicyClient *mAudioPolicyClient;
+
     KeyedVector< audio_source_t, InputSourceDesc* > mInputSources;
     KeyedVector< audio_io_handle_t, InputDesc* > mInputs;
 };