Merge "AMR-NB: Enable building static libraries for amr-nb codecs"
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index 6697cb5..e33804d 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -40,21 +40,6 @@
 	frameworks/av/media/libmedia \
 	external/sonic \
 
-# If AUDIOSERVER_MULTILIB in device.mk is non-empty then it is used to control
-# the LOCAL_MULTILIB for all audioserver exclusive libraries.
-# This is relevant for 64 bit architectures where either or both
-# 32 and 64 bit libraries may be built.
-#
-# AUDIOSERVER_MULTILIB may be set as follows:
-#   32      to build 32 bit audioserver libraries and 32 bit audioserver.
-#   64      to build 64 bit audioserver libraries and 64 bit audioserver.
-#   both    to build both 32 bit and 64 bit libraries,
-#           and use primary target architecture (32 or 64) for audioserver.
-#   first   to build libraries and audioserver for the primary target architecture only.
-#   <empty> to build both 32 and 64 bit libraries and primary target audioserver.
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
 LOCAL_MODULE := audioserver
 
 LOCAL_INIT_RC := audioserver.rc
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 6665c43..cb9c7ba 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1525,6 +1525,35 @@
     return aps->setRttEnabled(enabled);
 }
 
+status_t AudioSystem::setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                    const AudioDeviceTypeAddr &device)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) {
+        return PERMISSION_DENIED;
+    }
+    return aps->setPreferredDeviceForStrategy(strategy, device);
+}
+
+status_t AudioSystem::removePreferredDeviceForStrategy(product_strategy_t strategy)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) {
+        return PERMISSION_DENIED;
+    }
+    return aps->removePreferredDeviceForStrategy(strategy);
+}
+
+status_t AudioSystem::getPreferredDeviceForStrategy(product_strategy_t strategy,
+        AudioDeviceTypeAddr &device)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) {
+        return PERMISSION_DENIED;
+    }
+    return aps->getPreferredDeviceForStrategy(strategy, device);
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 7cc95e5..0facaf8 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -104,7 +104,10 @@
     GET_VOLUME_GROUP_FOR_ATTRIBUTES,
     SET_ALLOWED_CAPTURE_POLICY,
     MOVE_EFFECTS_TO_IO,
-    SET_RTT_ENABLED
+    SET_RTT_ENABLED,
+    SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+    REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+    GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -1284,6 +1287,55 @@
         }
         return static_cast<status_t>(reply.readInt32());
     }
+
+    virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+            const AudioDeviceTypeAddr &device)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeUint32(static_cast<uint32_t>(strategy));
+        status_t status = device.writeToParcel(&data);
+        if (status != NO_ERROR) {
+            return BAD_VALUE;
+        }
+        status = remote()->transact(SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+                data, &reply);
+        if (status != NO_ERROR) {
+           return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
+
+    virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeUint32(static_cast<uint32_t>(strategy));
+        status_t status = remote()->transact(REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+                data, &reply);
+        if (status != NO_ERROR) {
+           return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
+
+    virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeUint32(static_cast<uint32_t>(strategy));
+        status_t status = remote()->transact(GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+                data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = device.readFromParcel(&reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1346,7 +1398,10 @@
         case GET_OFFLOAD_FORMATS_A2DP:
         case LIST_AUDIO_VOLUME_GROUPS:
         case GET_VOLUME_GROUP_FOR_ATTRIBUTES:
-        case SET_RTT_ENABLED: {
+        case SET_RTT_ENABLED:
+        case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+        case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+        case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2369,6 +2424,40 @@
             return NO_ERROR;
         }
 
+        case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            product_strategy_t strategy = (product_strategy_t) data.readUint32();
+            AudioDeviceTypeAddr device;
+            status_t status = device.readFromParcel((Parcel*)&data);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            status = setPreferredDeviceForStrategy(strategy, device);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
+        case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            product_strategy_t strategy = (product_strategy_t) data.readUint32();
+            status_t status = removePreferredDeviceForStrategy(strategy);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
+        case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            product_strategy_t strategy = (product_strategy_t) data.readUint32();
+            AudioDeviceTypeAddr device;
+            status_t status = getPreferredDeviceForStrategy(strategy, device);
+            status_t marshall_status = device.writeToParcel(reply);
+            if (marshall_status != NO_ERROR) {
+                return marshall_status;
+            }
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index f29a775..a86297d 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -403,6 +403,17 @@
      */
     static status_t setAudioHalPids(const std::vector<pid_t>& pids);
 
+    static status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+            const AudioDeviceTypeAddr &device);
+
+    static status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
+
+    static status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device);
+
+    static status_t getDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device);
+
     // ----------------------------------------------------------------------------
 
     class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 8669ee6..9b91d6d 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -223,6 +223,14 @@
                                                        volume_group_t &volumeGroup) = 0;
 
     virtual status_t setRttEnabled(bool enabled) = 0;
+
+    virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device) = 0;
+
+    virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+
+    virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device) = 0;
 };
 
 
diff --git a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
index 5e5e762..acc37ca 100644
--- a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
+++ b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
@@ -37,6 +37,8 @@
 
     bool equals(const AudioDeviceTypeAddr& other) const;
 
+    AudioDeviceTypeAddr& operator= (const AudioDeviceTypeAddr&) = default;
+
     void reset();
 
     status_t readFromParcel(const Parcel *parcel) override;
diff --git a/media/mtp/IMtpHandle.h b/media/mtp/IMtpHandle.h
index fd14b18..0435e82 100644
--- a/media/mtp/IMtpHandle.h
+++ b/media/mtp/IMtpHandle.h
@@ -16,7 +16,7 @@
 #ifndef _IMTP_HANDLE_H
 #define _IMTP_HANDLE_H
 
-#include <linux/usb/f_mtp.h>
+#include "f_mtp.h"
 
 namespace android {
 
diff --git a/media/mtp/f_mtp.h b/media/mtp/f_mtp.h
new file mode 100644
index 0000000..22ec771
--- /dev/null
+++ b/media/mtp/f_mtp.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USB_F_MTP_H
+#define _UAPI_LINUX_USB_F_MTP_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct mtp_file_range {
+  int fd;
+  loff_t offset;
+  int64_t length;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  uint16_t command;
+  uint32_t transaction_id;
+};
+struct mtp_event {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  size_t length;
+  void * data;
+};
+#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MTP_RECEIVE_FILE _IOW('M', 1, struct mtp_file_range)
+#define MTP_SEND_EVENT _IOW('M', 3, struct mtp_event)
+#define MTP_SEND_FILE_WITH_HEADER _IOW('M', 4, struct mtp_file_range)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 1823fbc..8fb6a87 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -268,6 +268,9 @@
         int64_t timeoutUs) __INTRODUCED_IN(21);
 
 /**
+ * Returns the format of the codec's output.
+ * The caller must free the returned format.
+ *
  * Available since API level 21.
  */
 AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*) __INTRODUCED_IN(21);
@@ -397,6 +400,7 @@
 /**
  * Get format of the buffer. The specified buffer index must have been previously obtained from
  * dequeueOutputBuffer.
+ * The caller must free the returned format.
  *
  * Available since API level 28.
  */
@@ -455,6 +459,7 @@
  * Call this after AMediaCodec_configure() returns successfully to get the input
  * format accepted by the codec. Do this to determine what optional configuration
  * parameters were supported by the codec.
+ * The caller must free the returned format.
  *
  * Available since API level 28.
  */
diff --git a/media/tests/benchmark/README.md b/media/tests/benchmark/README.md
index 520a2cf..6627462 100644
--- a/media/tests/benchmark/README.md
+++ b/media/tests/benchmark/README.md
@@ -14,11 +14,11 @@
 
 To run the test suite for measuring performance of the native layer, follow the following steps:
 
-The binaries will be created in the following path : ${OUT}/data/nativetest64/
+The binaries will be created in the following path : $OUT/data/nativetest64/
 
-adb push $(OUT)/data/nativetest64/* /data/local/tmp/
+adb push $OUT/data/nativetest64/* /data/local/tmp/
 
-Eg. adb push $(OUT)/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
+Eg. adb push $OUT/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
 
 To run the binary, follow the commands mentioned below under each module.
 
@@ -78,13 +78,13 @@
 To run the test suite for measuring performance of the SDK APIs, follow the following steps:
 
 The apk will be created at the following path:
-${OUT}/testcases/MediaBenchmarkApp/arm64/
+$OUT/testcases/MediaBenchmarkTest/arm64/
 
 To get the resorce files for the test follow instructions given in [NDK](#NDK)
 
 For installing the apk, run the command:
 ```
-adb install -f -r ${OUT}/testcases/MediaBenchmarkApp/arm64/MediaBenchmarkApp.apk
+adb install -f -r $OUT/testcases/MediaBenchmarkTest/arm64/MediaBenchmarkTest.apk
 ```
 
 For running all the tests, run the command:
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 06ba8b0..b5592e3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5735,7 +5735,7 @@
                 int64_t framesWritten = mBytesWritten / mFrameSize;
                 if (mStandby || !last ||
                         track->presentationComplete(framesWritten, audioHALFrames) ||
-                        track->isPaused()) {
+                        track->isPaused() || mHwPaused) {
                     if (track->isStopping_2()) {
                         track->mState = TrackBase::STOPPED;
                     }
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 1155987..1fe60d4 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -271,6 +271,14 @@
 
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup) = 0;
+
+    virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device) = 0;
+
+    virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+
+    virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device) = 0;
 };
 
 
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
old mode 100644
new mode 100755
index b87c71d..a1c69f2
--- a/services/audiopolicy/engine/common/Android.bp
+++ b/services/audiopolicy/engine/common/Android.bp
@@ -25,6 +25,7 @@
         "src/ProductStrategy.cpp",
         "src/VolumeCurve.cpp",
         "src/VolumeGroup.cpp",
+        "src/LastRemovableMediaDevices.cpp",
     ],
     cflags: [
         "-Wall",
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
old mode 100644
new mode 100755
index fca9a60..7f339dc
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -20,6 +20,7 @@
 #include <EngineInterface.h>
 #include <ProductStrategy.h>
 #include <VolumeGroup.h>
+#include <LastRemovableMediaDevices.h>
 
 namespace android {
 namespace audio_policy {
@@ -49,10 +50,8 @@
         return mForceUse[usage];
     }
     android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
-                                               audio_policy_dev_state_t /*state*/) override
-    {
-        return NO_ERROR;
-    }
+                                               audio_policy_dev_state_t /*state*/) override;
+
     product_strategy_t getProductStrategyForAttributes(
             const audio_attributes_t &attr) const override;
 
@@ -86,8 +85,21 @@
 
     status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;
 
+    std::vector<audio_devices_t> getLastRemovableMediaDevices(
+            device_out_group_t group = GROUP_NONE) const
+    {
+        return mLastRemovableMediaDevices.getLastRemovableMediaDevices(group);
+    }
+
     void dump(String8 *dst) const override;
 
+    status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+            const AudioDeviceTypeAddr &device) override;
+
+    status_t removePreferredDeviceForStrategy(product_strategy_t strategy) override;
+
+    status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device) const override;
 
     engineConfig::ParsingResult loadAudioPolicyEngineConfig();
 
@@ -115,11 +127,13 @@
 
     status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
 
- private:
+private:
     AudioPolicyManagerObserver *mApmObserver = nullptr;
 
     ProductStrategyMap mProductStrategies;
+    ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices;
     VolumeGroupMap mVolumeGroups;
+    LastRemovableMediaDevices mLastRemovableMediaDevices;
     audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
 
     /** current forced use configuration. */
diff --git a/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h b/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
new file mode 100755
index 0000000..a3053a4
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LAST_REMOVABLE_MEDIA_DEVICES_H
+#define ANDROID_LAST_REMOVABLE_MEDIA_DEVICES_H
+
+#include <vector>
+#include <HwModule.h>
+#include <system/audio_policy.h>
+
+namespace android {
+
+typedef enum {
+    GROUP_NONE = -1,
+    GROUP_WIRED,
+    GROUP_BT_A2DP,
+    NUM_GROUP
+} device_out_group_t;
+
+class LastRemovableMediaDevices
+{
+public:
+    void setRemovableMediaDevices(sp<DeviceDescriptor> desc, audio_policy_dev_state_t state);
+    std::vector<audio_devices_t> getLastRemovableMediaDevices(
+            device_out_group_t group = GROUP_NONE) const;
+
+private:
+    struct DeviceGroupDescriptor {
+        sp<DeviceDescriptor> desc;
+        device_out_group_t group;
+    };
+    std::vector<DeviceGroupDescriptor> mMediaDevices;
+
+    device_out_group_t getDeviceOutGroup(audio_devices_t device) const;
+};
+
+} // namespace android
+
+#endif // ANDROID_LAST_REMOVABLE_MEDIA_DEVICES_H
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index ab8eff3..3ebe7d1 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -28,6 +28,7 @@
 #include <utils/String8.h>
 #include <media/AudioAttributes.h>
 #include <media/AudioContainers.h>
+#include <media/AudioPolicy.h>
 
 namespace android {
 
@@ -163,4 +164,10 @@
     product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
 };
 
+class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t, AudioDeviceTypeAddr>
+{
+public:
+    void dump(String8 *dst, int spaces = 0) const;
+};
+
 } // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 840eb34..01efc7a 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -63,6 +63,17 @@
     return NO_ERROR;
 }
 
+status_t EngineBase::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                              audio_policy_dev_state_t state)
+{
+    audio_devices_t deviceType = devDesc->type();
+    if ((deviceType != AUDIO_DEVICE_NONE) && audio_is_output_device(deviceType)) {
+        mLastRemovableMediaDevices.setRemovableMediaDevices(devDesc, state);
+    }
+
+    return NO_ERROR;
+}
+
 product_strategy_t EngineBase::getProductStrategyForAttributes(const audio_attributes_t &attr) const
 {
     return mProductStrategies.getProductStrategyForAttributes(attr);
@@ -272,9 +283,57 @@
     return NO_ERROR;
 }
 
+status_t EngineBase::setPreferredDeviceForStrategy(product_strategy_t strategy,
+            const AudioDeviceTypeAddr &device)
+{
+    // verify strategy exists
+    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
+        ALOGE("%s invalid strategy %u", __func__, strategy);
+        return BAD_VALUE;
+    }
+
+    mProductStrategyPreferredDevices[strategy] = device;
+    return NO_ERROR;
+}
+
+status_t EngineBase::removePreferredDeviceForStrategy(product_strategy_t strategy)
+{
+    // verify strategy exists
+    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
+        ALOGE("%s invalid strategy %u", __func__, strategy);
+        return BAD_VALUE;
+    }
+
+    if (mProductStrategyPreferredDevices.erase(strategy) == 0) {
+        // no preferred device was set
+        return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t EngineBase::getPreferredDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device) const
+{
+    // verify strategy exists
+    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
+        ALOGE("%s unknown strategy %u", __func__, strategy);
+        return BAD_VALUE;
+    }
+    // preferred device for this strategy?
+    auto devIt = mProductStrategyPreferredDevices.find(strategy);
+    if (devIt == mProductStrategyPreferredDevices.end()) {
+        ALOGV("%s no preferred device for strategy %u", __func__, strategy);
+        return NAME_NOT_FOUND;
+    }
+
+    device = devIt->second;
+    return NO_ERROR;
+}
+
 void EngineBase::dump(String8 *dst) const
 {
     mProductStrategies.dump(dst, 2);
+    mProductStrategyPreferredDevices.dump(dst, 2);
     mVolumeGroups.dump(dst, 2);
 }
 
diff --git a/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
new file mode 100755
index 0000000..87b6aaf
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioPolicyEngine/LastRemovableMediaDevices"
+//#define LOG_NDEBUG 0
+
+#include "LastRemovableMediaDevices.h"
+#include <log/log.h>
+
+namespace android {
+
+void LastRemovableMediaDevices::setRemovableMediaDevices(sp<DeviceDescriptor> desc,
+                                                         audio_policy_dev_state_t state)
+{
+    if (desc == nullptr) {
+        return;
+    } else {
+        if ((state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) &&
+                (getDeviceOutGroup(desc->type()) != GROUP_NONE)) {
+            setRemovableMediaDevices(desc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
+            mMediaDevices.insert(mMediaDevices.begin(), {desc, getDeviceOutGroup(desc->type())});
+        } else if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
+            for (auto iter = mMediaDevices.begin(); iter != mMediaDevices.end(); ++iter) {
+                if ((iter->desc)->equals(desc)) {
+                    mMediaDevices.erase(iter);
+                    break;
+                }
+            }
+        }
+    }
+}
+
+std::vector<audio_devices_t> LastRemovableMediaDevices::getLastRemovableMediaDevices(
+        device_out_group_t group) const
+{
+    std::vector<audio_devices_t> ret;
+    for (auto iter = mMediaDevices.begin(); iter != mMediaDevices.end(); ++iter) {
+        if ((group == GROUP_NONE) || (group == getDeviceOutGroup((iter->desc)->type()))) {
+            ret.push_back((iter->desc)->type());
+        }
+    }
+    return ret;
+}
+
+device_out_group_t LastRemovableMediaDevices::getDeviceOutGroup(audio_devices_t device) const
+{
+    switch (device) {
+    case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+    case AUDIO_DEVICE_OUT_LINE:
+    case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+    case AUDIO_DEVICE_OUT_USB_HEADSET:
+    case AUDIO_DEVICE_OUT_USB_ACCESSORY:
+    case AUDIO_DEVICE_OUT_USB_DEVICE:
+    case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+        return GROUP_WIRED;
+    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+        return GROUP_BT_A2DP;
+    default:
+        return GROUP_NONE;
+    }
+}
+
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index 14c9dd1..fe15ff6 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -310,5 +310,15 @@
     }
 }
 
+void ProductStrategyPreferredRoutingMap::dump(android::String8* dst, int spaces) const {
+    dst->appendFormat("\n%*sPreferred devices per product strategy dump:", spaces, "");
+    for (const auto& iter : *this) {
+        dst->appendFormat("\n%*sStrategy %u dev:%08x addr:%s",
+                          spaces + 2, "",
+                          (uint32_t) iter.first,
+                          iter.second.mType, iter.second.mAddress.c_str());
+    }
+    dst->appendFormat("\n");
+}
 }
 
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index 0c58a7c..dfb20b5 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -292,6 +292,39 @@
      */
     virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const = 0;
 
+    /**
+     * @brief setPreferredDeviceForStrategy sets the default device to be used for a
+     * strategy when available
+     * @param strategy the audio strategy whose routing will be affected
+     * @param device the audio device to route to when available
+     * @return BAD_VALUE if the strategy is invalid,
+     *     or NO_ERROR if the preferred device was set
+     */
+    virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+            const AudioDeviceTypeAddr &device) = 0;
+
+    /**
+     * @brief removePreferredDeviceForStrategy removes the preferred device previously set
+     * for the given strategy
+     * @param strategy the audio strategy whose routing will be affected
+     * @return BAD_VALUE if the strategy is invalid,
+     *     or NO_ERROR if the preferred device was removed
+     */
+    virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+
+    /**
+     * @brief getPreferredDeviceForStrategy queries which device is set as the
+     * preferred device for the given strategy
+     * @param strategy the strategy to query
+     * @param device returns configured as the preferred device if one was set
+     * @return BAD_VALUE if the strategy is invalid,
+     *     or NAME_NOT_FOUND if no preferred device was set
+     *     or NO_ERROR if the device parameter was initialized to the preferred device
+     */
+    virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+            AudioDeviceTypeAddr &device) const = 0;
+
+
     virtual void dump(String8 *dst) const = 0;
 
 protected:
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 0a88685..752ba92 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -176,7 +176,7 @@
         return mPolicyParameterMgr->setAvailableInputDevices(
                     deviceTypesToBitMask(getApmObserver()->getAvailableInputDevices().types()));
     }
-    return BAD_TYPE;
+    return EngineBase::setDeviceConnectionState(devDesc, state);
 }
 
 status_t Engine::loadAudioPolicyEngineConfig()
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
old mode 100644
new mode 100755
index 9dc0d64..02b99d0
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -386,22 +386,20 @@
             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
         }
         if ((devices2.isEmpty()) &&
-                (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
-                 outputs.isA2dpSupported()) {
-            devices2 = availableOutputDevices.getFirstDevicesFromTypes({
-                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
-                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER});
-        }
-        if ((devices2.isEmpty()) &&
             (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
         }
-        if (devices2.isEmpty()) {
-            devices2 = availableOutputDevices.getFirstDevicesFromTypes({
-                    AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_LINE,
-                    AUDIO_DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_USB_HEADSET,
-                    AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE,
-                    AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET});
+        if (devices2.isEmpty() && (getLastRemovableMediaDevices().size() > 0)) {
+            if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+                    outputs.isA2dpSupported()) {
+                // Get the last connected device of wired and bluetooth a2dp
+                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
+                        getLastRemovableMediaDevices());
+            } else {
+                // Get the last connected device of wired except bluetooth a2dp
+                devices2 = availableOutputDevices.getFirstDevicesFromTypes(
+                        getLastRemovableMediaDevices(GROUP_WIRED));
+            }
         }
         if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {
             // no sonification on aux digital (e.g. HDMI)
@@ -606,7 +604,7 @@
 void Engine::updateDeviceSelectionCache()
 {
     for (const auto &iter : getProductStrategies()) {
-        const auto &strategy = iter.second;
+        const auto& strategy = iter.second;
         auto devices = getDevicesForProductStrategy(strategy->getId());
         mDevicesForStrategies[strategy->getId()] = devices;
         strategy->setDeviceTypes(devices.types());
@@ -614,14 +612,30 @@
     }
 }
 
-DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
-{
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const {
     DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
-    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
-    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
 
+    // check if this strategy has a preferred device that is available,
+    // if yes, give priority to it
+    AudioDeviceTypeAddr preferredStrategyDevice;
+    const status_t status = getPreferredDeviceForStrategy(strategy, preferredStrategyDevice);
+    if (status == NO_ERROR) {
+        // there is a preferred device, is it available?
+        sp<DeviceDescriptor> preferredAvailableDevDescr = availableOutputDevices.getDevice(
+                preferredStrategyDevice.mType,
+                String8(preferredStrategyDevice.mAddress.c_str()),
+                AUDIO_FORMAT_DEFAULT);
+        if (preferredAvailableDevDescr != nullptr) {
+            ALOGVV("%s using pref device 0x%08x/%s for strategy %u", __FUNCTION__,
+                   preferredStrategyDevice.mType, preferredStrategyDevice.mAddress, strategy);
+            return DeviceVector(preferredAvailableDevDescr);
+        }
+    }
+
+    DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();
     auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
-                mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+                          mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
     return getDevicesForStrategyInt(legacyStrategy,
                                     availableOutputDevices,
                                     availableInputDevices, outputs);
diff --git a/services/audiopolicy/manager/Android.mk b/services/audiopolicy/manager/Android.mk
index d6ca2f2..cae6cfa 100644
--- a/services/audiopolicy/manager/Android.mk
+++ b/services/audiopolicy/manager/Android.mk
@@ -23,8 +23,6 @@
 
 LOCAL_CFLAGS := -Wall -Werror
 
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
 LOCAL_MODULE:= libaudiopolicymanager
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 718142f..23c0a12 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -794,27 +794,11 @@
     //FIXME: workaround for truncated touch sounds
     // to be removed when the problem is handled by system UI
     uint32_t delayMs = 0;
-    uint32_t waitMs = 0;
     if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) {
         delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
     }
-    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-        DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
-        waitMs = updateCallRouting(newDevices, delayMs);
-    }
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
-        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
-        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
-            // As done in setDeviceConnectionState, we could also fix default device issue by
-            // preventing the force re-routing in case of default dev that distinguishes on address.
-            // Let's give back to engine full device choice decision however.
-            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs);
-        }
-        if (forceVolumeReeval && !newDevices.isEmpty()) {
-            applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true);
-        }
-    }
+
+    updateCallAndOutputRouting(forceVolumeReeval, delayMs);
 
     for (const auto& activeDesc : mInputs.getActiveInputs()) {
         auto newDevice = getNewInputDevice(activeDesc);
@@ -3084,6 +3068,72 @@
     return res;
 }
 
+status_t AudioPolicyManager::setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device) {
+    ALOGI("%s() strategy=%d device=%08x addr=%s", __FUNCTION__,
+            strategy, device.mType, device.mAddress.c_str());
+    // strategy preferred device is only for output devices
+    if (!audio_is_output_device(device.mType)) {
+        ALOGE("%s() device=%08x is NOT an output device", __FUNCTION__, device.mType);
+        return BAD_VALUE;
+    }
+
+    status_t status = mEngine->setPreferredDeviceForStrategy(strategy, device);
+    if (status != NO_ERROR) {
+        ALOGW("Engine could not set preferred device %08x %s for strategy %d",
+                device.mType, device.mAddress.c_str(), strategy);
+        return status;
+    }
+
+    checkForDeviceAndOutputChanges();
+    updateCallAndOutputRouting();
+
+    return NO_ERROR;
+}
+
+void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint32_t delayMs)
+{
+    uint32_t waitMs = 0;
+    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
+        DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
+        waitMs = updateCallRouting(newDevices, delayMs);
+    }
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
+        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
+        if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
+            // As done in setDeviceConnectionState, we could also fix default device issue by
+            // preventing the force re-routing in case of default dev that distinguishes on address.
+            // Let's give back to engine full device choice decision however.
+            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs);
+        }
+        if (forceVolumeReeval && !newDevices.isEmpty()) {
+            applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true);
+        }
+    }
+}
+
+status_t AudioPolicyManager::removePreferredDeviceForStrategy(product_strategy_t strategy)
+{
+    ALOGI("%s() strategy=%d", __FUNCTION__, strategy);
+
+    status_t status = mEngine->removePreferredDeviceForStrategy(strategy);
+    if (status != NO_ERROR) {
+        ALOGW("Engine could not remove preferred device for strategy %d", strategy);
+        return status;
+    }
+
+    checkForDeviceAndOutputChanges();
+    updateCallAndOutputRouting();
+
+    return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device) {
+    return mEngine->getPreferredDeviceForStrategy(strategy, device);
+}
+
 void AudioPolicyManager::dump(String8 *dst) const
 {
     dst->appendFormat("\nAudioPolicyManager Dump: %p\n", this);
@@ -5056,6 +5106,7 @@
 
     DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
     DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
+
     SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
     SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index cff6983..d516d7b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -258,6 +258,12 @@
                 const Vector<AudioDeviceTypeAddr>& devices);
         virtual status_t removeUidDeviceAffinities(uid_t uid);
 
+        virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device);
+        virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
+        virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device);
+
         virtual status_t startAudioSource(const struct audio_port_config *source,
                                           const audio_attributes_t *attributes,
                                           audio_port_handle_t *portId,
@@ -496,13 +502,19 @@
         // close an input.
         void closeInput(audio_io_handle_t input);
 
-        // runs all the checks required for accomodating changes in devices and outputs
+        // runs all the checks required for accommodating changes in devices and outputs
         // if 'onOutputsChecked' callback is provided, it is executed after the outputs
         // check via 'checkOutputForAllStrategies'. If the callback returns 'true',
         // A2DP suspend status is rechecked.
         void checkForDeviceAndOutputChanges(std::function<bool()> onOutputsChecked = nullptr);
 
         /**
+         * @brief updates routing for all outputs (including call if call in progress).
+         * @param delayMs delay for unmuting if required
+         */
+        void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);
+
+        /**
          * @brief checkOutputForAttributes checks and if necessary changes outputs used for the
          * given audio attributes.
          * must be called every time a condition that affects the output choice for a given
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
index c4f4c56..1144970 100644
--- a/services/audiopolicy/service/Android.mk
+++ b/services/audiopolicy/service/Android.mk
@@ -38,8 +38,6 @@
 LOCAL_STATIC_LIBRARIES := \
     libaudiopolicycomponents
 
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
 LOCAL_MODULE:= libaudiopolicyservice
 
 LOCAL_CFLAGS += -fvisibility=hidden
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index fa8da89..47a103b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1325,4 +1325,33 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyService::setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->setPreferredDeviceForStrategy(strategy, device);
+}
+
+status_t AudioPolicyService::removePreferredDeviceForStrategy(product_strategy_t strategy)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->removePreferredDeviceForStrategy(strategy);
+}
+
+status_t AudioPolicyService::getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device)
+{
+    if (mAudioPolicyManager == NULL) {
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    return mAudioPolicyManager->getPreferredDeviceForStrategy(strategy, device);
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index bed1b04..7b72dc1 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -224,6 +224,15 @@
 
     virtual status_t removeUidDeviceAffinities(uid_t uid);
 
+    virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   const AudioDeviceTypeAddr &device);
+
+    virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
+
+
+    virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
+                                                   AudioDeviceTypeAddr &device);
+
     virtual status_t startAudioSource(const struct audio_port_config *source,
                                       const audio_attributes_t *attributes,
                                       audio_port_handle_t *portId);
diff --git a/services/oboeservice/Android.mk b/services/oboeservice/Android.mk
index 5e4cd39..96ccebc 100644
--- a/services/oboeservice/Android.mk
+++ b/services/oboeservice/Android.mk
@@ -39,8 +39,6 @@
     TimestampScheduler.cpp \
     AAudioThread.cpp
 
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
 # LOCAL_CFLAGS += -fvisibility=hidden
 LOCAL_CFLAGS += -Wno-unused-parameter
 LOCAL_CFLAGS += -Wall -Werror