Add last connected device concept

When connecting multiple audio devices,
Media and Sonification sounds comes out of the last connected device,
not a high-priority device.

Test: play music
Test: connect wired earphone // sound : wired earphone
Test: connect usb earphone // sound : usb earphone, not the wired earphone(high-priority)
Test: connect bluetooth headset // sound : bluetooth headset
Test: disconnect bluetooth headset // sound : usb earphone, not the wired earphone(high-priority)
Bug: 135749685

Change-Id: I579a04a04c97cc846b88e54fa83cdf3dad0b5cee
Signed-off-by: Baekgyeong Kim <baek.kim@samsung.com>
gugelfrei
Baekgyeong Kim 5 years ago committed by Mikhail Naganov
parent b20ae2f7f7
commit 0845152be4

@ -25,6 +25,7 @@ cc_library_static {
"src/ProductStrategy.cpp",
"src/VolumeCurve.cpp",
"src/VolumeGroup.cpp",
"src/LastRemovableMediaDevices.cpp",
],
cflags: [
"-Wall",

@ -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 @@ public:
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,6 +85,12 @@ public:
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;
@ -115,11 +120,12 @@ public:
status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
private:
private:
AudioPolicyManagerObserver *mApmObserver = nullptr;
ProductStrategyMap mProductStrategies;
VolumeGroupMap mVolumeGroups;
LastRemovableMediaDevices mLastRemovableMediaDevices;
audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */
/** current forced use configuration. */

@ -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

@ -63,6 +63,17 @@ status_t EngineBase::setPhoneState(audio_mode_t state)
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);

@ -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

@ -176,7 +176,7 @@ status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
return mPolicyParameterMgr->setAvailableInputDevices(
deviceTypesToBitMask(getApmObserver()->getAvailableInputDevices().types()));
}
return BAD_TYPE;
return EngineBase::setDeviceConnectionState(devDesc, state);
}
status_t Engine::loadAudioPolicyEngineConfig()

@ -385,23 +385,21 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
(getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
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)

Loading…
Cancel
Save