Merge "EffectModule: initialize all member variables in constructor"
diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
index faea008..4b4051d 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
@@ -95,7 +95,7 @@
 void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) {
     Mutex::Autolock lock(mSessionsLock);
 
-    for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
+    for (ssize_t index = (ssize_t)mIDToSessionMap.size() - 1; index >= 0; index--) {
         sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
         if (session->getPlugin() == plugin) {
             mIDToSessionMap.removeItemsAt(index);
diff --git a/include/media/AudioClient.h b/include/media/AudioClient.h
index feac9b9..a0530e4 120000
--- a/include/media/AudioClient.h
+++ b/include/media/AudioClient.h
@@ -1 +1 @@
-media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index 65f9b96..7937a29 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -23,6 +23,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/aac/exports.lds b/media/extractors/aac/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/aac/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index 01bbfa2..e5bbe31 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -23,6 +23,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/amr/exports.lds b/media/extractors/amr/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/amr/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 80a4125..84ba6d3 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -28,6 +28,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/flac/exports.lds b/media/extractors/flac/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/flac/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 68f8766..9af128e 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -27,6 +27,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/midi/exports.lds b/media/extractors/midi/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/midi/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 350c6fe..0301ffa 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -31,6 +31,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/mkv/exports.lds b/media/extractors/mkv/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/mkv/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index 6912ef1..d93562c 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -31,6 +31,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/mp3/exports.lds b/media/extractors/mp3/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/mp3/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index 49a3714..fce8dd6 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -33,6 +33,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/mp4/exports.lds b/media/extractors/mp4/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/mp4/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 50f740b..c6bb40d 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -41,6 +41,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/mpeg2/exports.lds b/media/extractors/mpeg2/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/mpeg2/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index 6bd8025..2c09a5f 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -28,6 +28,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/ogg/exports.lds b/media/extractors/ogg/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/ogg/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index f310892..65c71ef 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -27,6 +27,7 @@
         "-Wall",
         "-fvisibility=hidden",
     ],
+    version_script: "exports.lds",
 
     sanitize: {
         cfi: true,
diff --git a/media/extractors/wav/exports.lds b/media/extractors/wav/exports.lds
new file mode 100644
index 0000000..b1309ee
--- /dev/null
+++ b/media/extractors/wav/exports.lds
@@ -0,0 +1 @@
+{ global: GETEXTRACTORDEF; local: *; };
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 95e95de..d18f611 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -180,7 +180,6 @@
     ],
 
     shared_libs: [
-        "libui",
         "liblog",
         "libcutils",
         "libutils",
@@ -196,8 +195,6 @@
         "libdl",
         "libaudioutils",
         "libaudioclient",
-        "libhidlbase",
-        "libhidltransport",
         "libmedia_omx",
     ],
 
diff --git a/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp b/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
index 18207b0..d78a8e8 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Decoder.cpp
@@ -766,6 +766,8 @@
         reply->setInt32("eos", true);
     }
 
+    mNumFramesTotal += !mIsAudio;
+
     if (mSkipRenderingUntilMediaTimeUs >= 0) {
         if (timeUs < mSkipRenderingUntilMediaTimeUs) {
             ALOGV("[%s] dropping buffer at time %lld as requested.",
@@ -784,8 +786,6 @@
         mSkipRenderingUntilMediaTimeUs = -1;
     }
 
-    mNumFramesTotal += !mIsAudio;
-
     // wait until 1st frame comes out to signal resume complete
     notifyResumeCompleteIfNecessary();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index a84d0e5..1b02adb 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -752,6 +752,8 @@
         reply->setInt32("eos", true);
     }
 
+    mNumFramesTotal += !mIsAudio;
+
     if (mSkipRenderingUntilMediaTimeUs >= 0) {
         if (timeUs < mSkipRenderingUntilMediaTimeUs) {
             ALOGV("[%s] dropping buffer at time %lld as requested.",
@@ -770,8 +772,6 @@
         mSkipRenderingUntilMediaTimeUs = -1;
     }
 
-    mNumFramesTotal += !mIsAudio;
-
     // wait until 1st frame comes out to signal resume complete
     notifyResumeCompleteIfNecessary();
 
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 72917dd..f2bc6d0 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -24,7 +24,6 @@
     ],
     shared_libs: [
         "libbinder",
-        "libcutils",
         "liblog",
         "libutils",
         "libmemunreachable",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 92d98a8..43f6ed6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -39,14 +39,13 @@
                       DeviceVector &availableOutputDevices,
                       DeviceVector &availableInputDevices,
                       sp<DeviceDescriptor> &defaultOutputDevices,
-                      bool &isSpeakerDrcEnabled,
                       VolumeCurvesCollection *volumes = nullptr)
         : mHwModules(hwModules),
           mAvailableOutputDevices(availableOutputDevices),
           mAvailableInputDevices(availableInputDevices),
           mDefaultOutputDevices(defaultOutputDevices),
           mVolumeCurves(volumes),
-          mIsSpeakerDrcEnabled(isSpeakerDrcEnabled)
+          mIsSpeakerDrcEnabled(false)
     {}
 
     void setVolumes(const VolumeCurvesCollection &volumes)
@@ -80,6 +79,8 @@
         mAvailableOutputDevices.add(availableOutputDevices);
     }
 
+    bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
+
     void setSpeakerDrcEnabled(bool isSpeakerDrcEnabled)
     {
         mIsSpeakerDrcEnabled = isSpeakerDrcEnabled;
@@ -140,7 +141,10 @@
     DeviceVector &mAvailableInputDevices;
     sp<DeviceDescriptor> &mDefaultOutputDevices;
     VolumeCurvesCollection *mVolumeCurves;
-    bool &mIsSpeakerDrcEnabled;
+    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
+    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
+    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
+    bool mIsSpeakerDrcEnabled;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 0e11c5c..25c5e7a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3474,10 +3474,22 @@
 }
 #endif
 
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
+AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
+                                       bool /*forTesting*/)
     :
+    mUidCached(getuid()),
+    mpClientInterface(clientInterface),
     mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
     mA2dpSuspended(false),
+#ifdef USE_XML_AUDIO_POLICY_CONF
+    mVolumeCurves(new VolumeCurvesCollection()),
+    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
+            mDefaultOutputDevice, static_cast<VolumeCurvesCollection*>(mVolumeCurves)),
+#else
+    mVolumeCurves(new StreamDescriptorCollection()),
+    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
+            mDefaultOutputDevice),
+#endif
     mAudioPortGeneration(1),
     mBeaconMuteRefCount(0),
     mBeaconPlayingRefCount(0),
@@ -3487,49 +3499,48 @@
     mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
     mHasComputedSoundTriggerSupportsConcurrentCapture(false)
 {
-    mUidCached = getuid();
-    mpClientInterface = clientInterface;
+}
 
-    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
-    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
-    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
-    bool speakerDrcEnabled = false;
+AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
+        : AudioPolicyManager(clientInterface, false /*forTesting*/)
+{
+    loadConfig();
+    initialize();
+}
 
+void AudioPolicyManager::loadConfig() {
 #ifdef USE_XML_AUDIO_POLICY_CONF
-    mVolumeCurves = new VolumeCurvesCollection();
-    AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
-                             mDefaultOutputDevice, speakerDrcEnabled,
-                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
-    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
+    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
 #else
-    mVolumeCurves = new StreamDescriptorCollection();
-    AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
-                             mDefaultOutputDevice, speakerDrcEnabled);
-    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
-            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
+    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
+           && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
 #endif
         ALOGE("could not load audio policy configuration file, setting defaults");
-        config.setDefault();
+        getConfig().setDefault();
     }
-    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
-    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
+}
+
+status_t AudioPolicyManager::initialize() {
+    mVolumeCurves->initializeVolumeCurves(getConfig().isSpeakerDrcEnabled());
 
     // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
     audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
     if (!engineInstance) {
         ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
-        return;
+        return NO_INIT;
     }
     // Retrieve the Policy Manager Interface
     mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
     if (mEngine == NULL) {
         ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
-        return;
+        return NO_INIT;
     }
     mEngine->setObserver(this);
     status_t status = mEngine->initCheck();
-    (void) status;
-    ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
+    if (status != NO_ERROR) {
+        LOG_FATAL("Policy engine not initialized(err=%d)", status);
+        return status;
+    }
 
     // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
     // open all output streams needed to access attached devices
@@ -3692,11 +3703,16 @@
     // make sure default device is reachable
     if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
         ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
+        status = NO_INIT;
     }
 
-    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
+    if (mPrimaryOutput == 0) {
+        ALOGE("Failed to open primary output");
+        status = NO_INIT;
+    }
 
     updateDevicesAndOutputs();
+    return status;
 }
 
 AudioPolicyManager::~AudioPolicyManager()
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 6038e33..3659e34 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -33,6 +33,7 @@
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyManagerObserver.h>
 #include <AudioGain.h>
+#include <AudioPolicyConfig.h>
 #include <AudioPort.h>
 #include <AudioPatch.h>
 #include <DeviceDescriptor.h>
@@ -234,6 +235,21 @@
         routing_strategy getStrategy(audio_stream_type_t stream) const;
 
 protected:
+        // A constructor that allows more fine-grained control over initialization process,
+        // used in automatic tests.
+        AudioPolicyManager(AudioPolicyClientInterface *clientInterface, bool forTesting);
+
+        // These methods should be used when finer control over APM initialization
+        // is needed, e.g. in tests. Must be used in conjunction with the constructor
+        // that only performs fields initialization. The public constructor comprises
+        // these steps in the following sequence:
+        //   - field initializing constructor;
+        //   - loadConfig;
+        //   - initialize.
+        AudioPolicyConfig& getConfig() { return mConfig; }
+        void loadConfig();
+        status_t initialize();
+
         // From AudioPolicyManagerObserver
         virtual const AudioPatchCollection &getAudioPatches() const
         {
@@ -526,18 +542,18 @@
         SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT);
         SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT);
 
-        IVolumeCurvesCollection *mVolumeCurves; // Volume Curves per use case and device category
-
         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
-
-        EffectDescriptorCollection mEffects;  // list of registered audio effects
         bool    mA2dpSuspended;  // true if A2DP output is suspended
+
+        IVolumeCurvesCollection *mVolumeCurves; // Volume Curves per use case and device category
+        EffectDescriptorCollection mEffects;  // list of registered audio effects
         sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
         HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
         HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
                                           // dumps
+        AudioPolicyConfig mConfig;
 
         std::atomic<uint32_t> mAudioPortGeneration;
 
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
new file mode 100644
index 0000000..62869a4
--- /dev/null
+++ b/services/audiopolicy/tests/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES := \
+  frameworks/av/services/audiopolicy \
+  frameworks/av/services/audiopolicy/common/include \
+  frameworks/av/services/audiopolicy/engine/interface \
+  frameworks/av/services/audiopolicy/utilities
+
+LOCAL_SHARED_LIBRARIES := \
+  libaudiopolicymanagerdefault \
+  libbase \
+  liblog \
+  libmedia_helper \
+  libutils \
+
+LOCAL_STATIC_LIBRARIES := \
+  libaudiopolicycomponents \
+
+LOCAL_SRC_FILES := \
+  audiopolicymanager_tests.cpp \
+
+LOCAL_MODULE := audiopolicy_tests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -Werror -Wall
+
+include $(BUILD_NATIVE_TEST)
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
new file mode 100644
index 0000000..c4da98a
--- /dev/null
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "AudioPolicyInterface.h"
+
+namespace android {
+
+class AudioPolicyTestClient : public AudioPolicyClientInterface
+{
+public:
+    virtual ~AudioPolicyTestClient() {}
+
+    // AudioPolicyClientInterface Implementation
+    audio_module_handle_t loadHwModule(const char* /*name*/) override { return 0; }
+    status_t openOutput(audio_module_handle_t /*module*/,
+                        audio_io_handle_t* /*output*/,
+                        audio_config_t* /*config*/,
+                        audio_devices_t* /*devices*/,
+                        const String8& /*address*/,
+                        uint32_t* /*latencyMs*/,
+                        audio_output_flags_t /*flags*/) override { return 0; }
+    audio_io_handle_t openDuplicateOutput(audio_io_handle_t /*output1*/,
+                                          audio_io_handle_t /*output2*/) override { return 0; }
+    status_t closeOutput(audio_io_handle_t /*output*/) override { return 0; }
+    status_t suspendOutput(audio_io_handle_t /*output*/) override { return 0; }
+    status_t restoreOutput(audio_io_handle_t /*output*/) override { return 0; }
+    status_t openInput(audio_module_handle_t /*module*/,
+                       audio_io_handle_t* /*input*/,
+                       audio_config_t* /*config*/,
+                       audio_devices_t* /*device*/,
+                       const String8& /*address*/,
+                       audio_source_t /*source*/,
+                       audio_input_flags_t /*flags*/) override { return 0; }
+    status_t closeInput(audio_io_handle_t /*input*/) override { return 0; }
+    status_t setStreamVolume(audio_stream_type_t /*stream*/,
+                             float /*volume*/,
+                             audio_io_handle_t /*output*/,
+                             int /*delayMs*/) override { return 0; }
+    status_t invalidateStream(audio_stream_type_t /*stream*/) override { return 0; }
+    void setParameters(audio_io_handle_t /*ioHandle*/,
+                       const String8& /*keyValuePairs*/,
+                       int /*delayMs*/) override { }
+    String8 getParameters(audio_io_handle_t /*ioHandle*/,
+                          const String8& /*keys*/) override { return String8(); }
+    status_t startTone(audio_policy_tone_t /*tone*/,
+                       audio_stream_type_t /*stream*/) override { return 0; }
+    status_t stopTone() override { return 0; }
+    status_t setVoiceVolume(float /*volume*/, int /*delayMs*/) override { return 0; }
+    status_t moveEffects(audio_session_t /*session*/,
+                         audio_io_handle_t /*srcOutput*/,
+                         audio_io_handle_t /*dstOutput*/) override { return 0; }
+    status_t createAudioPatch(const struct audio_patch* /*patch*/,
+                              audio_patch_handle_t* /*handle*/,
+                              int /*delayMs*/) override { return 0; }
+    status_t releaseAudioPatch(audio_patch_handle_t /*handle*/,
+                               int /*delayMs*/) override { return 0; }
+    status_t setAudioPortConfig(const struct audio_port_config* /*config*/,
+                                int /*delayMs*/) override { return 0; }
+    void onAudioPortListUpdate() override { }
+    void onAudioPatchListUpdate() override { }
+    audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t /*use*/) override { return 0; }
+    void onDynamicPolicyMixStateUpdate(String8 /*regId*/, int32_t /*state*/) override { }
+    void onRecordingConfigurationUpdate(int /*event*/,
+                                        const record_client_info_t* /*clientInfo*/,
+                                        const struct audio_config_base* /*clientConfig*/,
+                                        const struct audio_config_base* /*deviceConfig*/,
+                                        audio_patch_handle_t /*patchHandle*/) override { }
+};
+
+} // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
new file mode 100644
index 0000000..fe543a6
--- /dev/null
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "managerdefault/AudioPolicyManager.h"
+
+namespace android {
+
+class AudioPolicyTestManager : public AudioPolicyManager {
+  public:
+    explicit AudioPolicyTestManager(AudioPolicyClientInterface *clientInterface)
+            : AudioPolicyManager(clientInterface, true /*forTesting*/) { }
+    using AudioPolicyManager::getConfig;
+    using AudioPolicyManager::initialize;
+};
+
+}  // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
new file mode 100644
index 0000000..33b15c7
--- /dev/null
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 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 <gtest/gtest.h>
+
+#include "AudioPolicyTestClient.h"
+#include "AudioPolicyTestManager.h"
+
+using namespace android;
+
+TEST(AudioPolicyManager, CreateWithDummyClient) {
+    AudioPolicyTestClient client;
+    AudioPolicyTestManager manager(&client);
+    manager.getConfig().setDefault();
+    ASSERT_EQ(NO_INIT, manager.initialize());
+}