Merge changes I42d7cbc5,I6eda8458
* changes:
Add mp2 container and codec support
Use header file for namespace functions
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index c1efa5f..69b9e7e 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -7608,6 +7608,13 @@
*/
ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
+ /**
+ * <p>The camera device is capable of writing image data into a region of memory
+ * inaccessible to Android userspace or the Android kernel, and only accessible to
+ * trusted execution environments (TEE).</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13,
+
} acamera_metadata_enum_android_request_available_capabilities_t;
diff --git a/include/media/AudioAttributes.h b/include/media/AudioAttributes.h
new file mode 120000
index 0000000..27ba471
--- /dev/null
+++ b/include/media/AudioAttributes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioAttributes.h
\ No newline at end of file
diff --git a/include/media/AudioCommonTypes.h b/include/media/AudioCommonTypes.h
new file mode 120000
index 0000000..ae7c99a
--- /dev/null
+++ b/include/media/AudioCommonTypes.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioCommonTypes.h
\ No newline at end of file
diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h
deleted file mode 120000
index 558657e..0000000
--- a/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioPolicyHelper.h
\ No newline at end of file
diff --git a/include/media/AudioProductStrategy.h b/include/media/AudioProductStrategy.h
new file mode 120000
index 0000000..6bfaf11
--- /dev/null
+++ b/include/media/AudioProductStrategy.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioProductStrategy.h
\ No newline at end of file
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index d02f541..78a444b 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -74,9 +74,6 @@
"signed-integer-overflow",
],
cfi: true,
- diag: {
- cfi: true,
- },
},
}
@@ -90,9 +87,6 @@
"signed-integer-overflow",
],
cfi: true,
- diag: {
- cfi: true,
- },
},
}
@@ -128,9 +122,6 @@
"signed-integer-overflow",
],
cfi: true,
- diag: {
- cfi: true,
- },
},
ldflags: ["-Wl,-Bsymbolic"],
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 1417aaf..bd10d67 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -5,6 +5,28 @@
}
cc_library_shared {
+ name: "libaudiopolicy",
+ srcs: [
+ "AudioAttributes.cpp",
+ "AudioPolicy.cpp",
+ "AudioProductStrategy.cpp",
+ ],
+ shared_libs: [
+ "libaudioutils",
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ include_dirs: ["system/media/audio_utils/include"],
+ export_include_dirs: ["include"],
+}
+
+cc_library_shared {
name: "libaudioclient",
aidl: {
@@ -23,7 +45,6 @@
":libaudioclient_aidl",
"AudioEffect.cpp",
- "AudioPolicy.cpp",
"AudioRecord.cpp",
"AudioSystem.cpp",
"AudioTrack.cpp",
@@ -41,6 +62,7 @@
],
shared_libs: [
"libaudioutils",
+ "libaudiopolicy",
"libaudiomanager",
"libbinder",
"libcutils",
diff --git a/media/libaudioclient/AudioAttributes.cpp b/media/libaudioclient/AudioAttributes.cpp
new file mode 100644
index 0000000..0f327cf
--- /dev/null
+++ b/media/libaudioclient/AudioAttributes.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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 "AudioAttributes"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+
+#include <media/AudioAttributes.h>
+
+namespace android {
+
+status_t AudioAttributes::readFromParcel(const Parcel *parcel)
+{
+ status_t ret = NO_ERROR;
+ mAttributes.content_type = static_cast<audio_content_type_t>(parcel->readInt32());
+ mAttributes.usage = static_cast<audio_usage_t>(parcel->readInt32());
+ mAttributes.source = static_cast<audio_source_t>(parcel->readInt32());
+ mAttributes.flags = static_cast<audio_flags_mask_t>(parcel->readInt32());
+ const bool hasFlattenedTag = (parcel->readInt32() == 1);
+ if (hasFlattenedTag) {
+ std::string tags;
+ ret = parcel->readUtf8FromUtf16(&tags);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+ std::strncpy(mAttributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+ } else {
+ strcpy(mAttributes.tags, "");
+ }
+ mStreamType = static_cast<audio_stream_type_t>(parcel->readInt32());
+ mGroupId = parcel->readUint32();
+ return NO_ERROR;
+}
+
+status_t AudioAttributes::writeToParcel(Parcel *parcel) const
+{
+ parcel->writeInt32(static_cast<int32_t>(mAttributes.content_type));
+ parcel->writeInt32(static_cast<int32_t>(mAttributes.usage));
+ parcel->writeInt32(static_cast<int32_t>(mAttributes.source));
+ parcel->writeInt32(static_cast<int32_t>(mAttributes.flags));
+ if (strlen(mAttributes.tags) == 0) {
+ parcel->writeInt32(0);
+ } else {
+ parcel->writeInt32(1);
+ parcel->writeUtf8AsUtf16(mAttributes.tags);
+ }
+ parcel->writeInt32(static_cast<int32_t>(mStreamType));
+ parcel->writeUint32(mGroupId);
+ return NO_ERROR;
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioProductStrategy.cpp b/media/libaudioclient/AudioProductStrategy.cpp
new file mode 100644
index 0000000..1da1114
--- /dev/null
+++ b/media/libaudioclient/AudioProductStrategy.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 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 "AudioProductStrategy"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <media/AudioProductStrategy.h>
+#include <media/AudioAttributes.h>
+#include <media/AudioSystem.h>
+
+namespace android {
+
+status_t AudioProductStrategy::readFromParcel(const Parcel *parcel)
+{
+ mId = static_cast<product_strategy_t>(parcel->readInt32());
+ status_t ret = parcel->readUtf8FromUtf16(&mName);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+ size_t size = static_cast<size_t>(parcel->readInt32());
+ for (size_t i = 0; i < size; i++) {
+ AudioAttributes attribute;
+ ret = attribute.readFromParcel(parcel);
+ if (ret != NO_ERROR) {
+ mAudioAttributes.clear();
+ return ret;
+ }
+ mAudioAttributes.push_back(attribute);
+ }
+ return NO_ERROR;
+}
+
+status_t AudioProductStrategy::writeToParcel(Parcel *parcel) const
+{
+ parcel->writeInt32(static_cast<int32_t>(mId));
+ parcel->writeUtf8AsUtf16(mName);
+ size_t size = mAudioAttributes.size();
+ size_t sizePosition = parcel->dataPosition();
+ parcel->writeInt32(size);
+ size_t finalSize = size;
+
+ for (size_t i = 0; i < size; i++) {
+ size_t position = parcel->dataPosition();
+ AudioAttributes attribute(mAudioAttributes[i]);
+ status_t ret = attribute.writeToParcel(parcel);
+ if (ret != NO_ERROR) {
+ parcel->setDataPosition(position);
+ finalSize--;
+ }
+ }
+ if (size != finalSize) {
+ size_t position = parcel->dataPosition();
+ parcel->setDataPosition(sizePosition);
+ parcel->writeInt32(finalSize);
+ parcel->setDataPosition(position);
+ }
+ return NO_ERROR;
+}
+
+bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
+ const audio_attributes_t clientAttritubes)
+{
+ if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
+ // The default product strategy is the strategy that holds default attributes by convention.
+ // All attributes that fail to match will follow the default strategy for routing.
+ // Choosing the default must be done as a fallback, the attributes match shall not
+ // select the default.
+ return false;
+ }
+ return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
+ (clientAttritubes.usage == refAttributes.usage)) &&
+ ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
+ (clientAttritubes.content_type == refAttributes.content_type)) &&
+ ((refAttributes.flags == AUDIO_FLAG_NONE) ||
+ (clientAttritubes.flags != AUDIO_FLAG_NONE &&
+ (clientAttritubes.flags & refAttributes.flags) == clientAttritubes.flags)) &&
+ ((strlen(refAttributes.tags) == 0) ||
+ (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
+}
+
+} // namespace android
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 896198b..b83a441e 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -25,6 +25,7 @@
#include <media/AudioSystem.h>
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
+#include <media/TypeConverter.h>
#include <math.h>
#include <system/audio.h>
@@ -970,7 +971,7 @@
uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return 0;
+ if (aps == 0) return PRODUCT_STRATEGY_NONE;
return aps->getStrategyForStream(stream);
}
@@ -1327,7 +1328,6 @@
return aps->setSurroundFormatEnabled(audioFormat, enabled);
}
-
status_t AudioSystem::setAssistantUid(uid_t uid)
{
const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -1352,11 +1352,62 @@
}
status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t> *formats)
+ std::vector<audio_format_t> *formats) {
+ const sp <IAudioPolicyService>
+ & aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
+status_t AudioSystem::listAudioProductStrategies(AudioProductStrategyVector &strategies)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+ return aps->listAudioProductStrategies(strategies);
+}
+
+audio_attributes_t AudioSystem::streamTypeToAttributes(audio_stream_type_t stream)
+{
+ AudioProductStrategyVector strategies;
+ listAudioProductStrategies(strategies);
+ for (const auto &strategy : strategies) {
+ auto attrVect = strategy.getAudioAttributes();
+ auto iter = std::find_if(begin(attrVect), end(attrVect), [&stream](const auto &attributes) {
+ return attributes.getStreamType() == stream; });
+ if (iter != end(attrVect)) {
+ return iter->getAttributes();
+ }
+ }
+ ALOGE("invalid stream type %s when converting to attributes", toString(stream).c_str());
+ return AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+audio_stream_type_t AudioSystem::attributesToStreamType(const audio_attributes_t &attr)
+{
+ product_strategy_t strategyId =
+ AudioSystem::getProductStrategyFromAudioAttributes(AudioAttributes(attr));
+ AudioProductStrategyVector strategies;
+ listAudioProductStrategies(strategies);
+ for (const auto &strategy : strategies) {
+ if (strategy.getId() == strategyId) {
+ auto attrVect = strategy.getAudioAttributes();
+ auto iter = std::find_if(begin(attrVect), end(attrVect), [&attr](const auto &refAttr) {
+ return AudioProductStrategy::attributesMatches(
+ refAttr.getAttributes(), attr); });
+ if (iter != end(attrVect)) {
+ return iter->getStreamType();
+ }
+ }
+ }
+ ALOGE("invalid attributes %s when converting to stream", toString(attr).c_str());
+ return AUDIO_STREAM_MUSIC;
+}
+
+product_strategy_t AudioSystem::getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PRODUCT_STRATEGY_NONE;
+ return aps->getProductStrategyFromAudioAttributes(aa);
}
// ---------------------------------------------------------------------------
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index c2ee2ee..79abea0 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -33,7 +33,6 @@
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
#include <media/MediaAnalyticsItem.h>
@@ -487,7 +486,7 @@
__func__,
mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
mStreamType = AUDIO_STREAM_DEFAULT;
- audio_attributes_flags_to_audio_output_flags(mAttributes.flags, flags);
+ audio_flags_to_audio_output_flags(mAttributes.flags, &flags);
}
// these below should probably come from the audioFlinger too...
@@ -1390,7 +1389,7 @@
audio_stream_type_t AudioTrack::streamType() const
{
if (mStreamType == AUDIO_STREAM_DEFAULT) {
- return audio_attributes_to_stream_type(&mAttributes);
+ return AudioSystem::attributesToStreamType(mAttributes);
}
return mStreamType;
}
@@ -1473,7 +1472,7 @@
IAudioFlinger::CreateTrackInput input;
if (mStreamType != AUDIO_STREAM_DEFAULT) {
- stream_type_to_audio_attributes(mStreamType, &input.attr);
+ input.attr = AudioSystem::streamTypeToAttributes(mStreamType);
} else {
input.attr = mAttributes;
}
@@ -2891,7 +2890,8 @@
mPortId, mStatus, mState, mSessionId, mFlags);
result.appendFormat(" stream type(%d), left - right volume(%f, %f)\n",
(mStreamType == AUDIO_STREAM_DEFAULT) ?
- audio_attributes_to_stream_type(&mAttributes) : mStreamType,
+ AudioSystem::attributesToStreamType(mAttributes) :
+ mStreamType,
mVolume[AUDIO_INTERLEAVE_LEFT], mVolume[AUDIO_INTERLEAVE_RIGHT]);
result.appendFormat(" format(%#x), channel mask(%#x), channel count(%u)\n",
mFormat, mChannelMask, mChannelCount);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 8c7fac5..0db56e8 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -92,7 +92,9 @@
IS_HAPTIC_PLAYBACK_SUPPORTED,
SET_UID_DEVICE_AFFINITY,
REMOVE_UID_DEVICE_AFFINITY,
- GET_OFFLOAD_FORMATS_A2DP
+ GET_OFFLOAD_FORMATS_A2DP,
+ LIST_AUDIO_PRODUCT_STRATEGIES,
+ GET_STRATEGY_FOR_ATTRIBUTES,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -412,7 +414,7 @@
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast <uint32_t>(stream));
remote()->transact(GET_STRATEGY_FOR_STREAM, data, &reply);
- return reply.readInt32();
+ return reply.readUint32();
}
virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream)
@@ -1051,19 +1053,61 @@
return status;
}
- virtual status_t removeUidDeviceAffinities(uid_t uid)
- {
+ virtual status_t removeUidDeviceAffinities(uid_t uid) {
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32((int32_t) uid);
- status_t status = remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
+ status_t status =
+ remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
+ status = (status_t) reply.readInt32();
}
return status;
}
+
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+ status_t status = remote()->transact(LIST_AUDIO_PRODUCT_STRATEGIES, data, &reply);
+ if (status != NO_ERROR) {
+ ALOGE("%s: permission denied", __func__);
+ return status;
+ }
+ status = static_cast<status_t>(reply.readInt32());
+ if (status == NO_ERROR) {
+ uint32_t numStrategies = static_cast<uint32_t>(reply.readInt32());
+ for (size_t i = 0; i < numStrategies; i++) {
+ AudioProductStrategy strategy;
+ status = strategy.readFromParcel(&reply);
+ if (status != NO_ERROR) {
+ ALOGE("%s: failed to read strategies", __FUNCTION__);
+ strategies.clear();
+ return status;
+ }
+ strategies.push_back(strategy);
+ }
+ }
+ return status;
+ }
+
+ virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ status_t status = aa.writeToParcel(&data);
+ if (status != NO_ERROR) {
+ return PRODUCT_STRATEGY_NONE;
+ }
+ status = remote()->transact(GET_STRATEGY_FOR_ATTRIBUTES, data, &reply);
+ if (status == NO_ERROR) {
+ return static_cast<product_strategy_t>(reply.readInt32());
+ }
+ return PRODUCT_STRATEGY_NONE;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1082,7 +1126,6 @@
case START_INPUT:
case STOP_INPUT:
case RELEASE_INPUT:
- case GET_STRATEGY_FOR_STREAM:
case GET_OUTPUT_FOR_EFFECT:
case REGISTER_EFFECT:
case UNREGISTER_EFFECT:
@@ -1378,7 +1421,7 @@
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_stream_type_t stream =
static_cast <audio_stream_type_t>(data.readInt32());
- reply->writeInt32(getStrategyForStream(stream));
+ reply->writeUint32(getStrategyForStream(stream));
return NO_ERROR;
} break;
@@ -1935,6 +1978,46 @@
return NO_ERROR;
}
+ case LIST_AUDIO_PRODUCT_STRATEGIES: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ AudioProductStrategyVector strategies;
+ status_t status = listAudioProductStrategies(strategies);
+ reply->writeInt32(status);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ size_t size = strategies.size();
+ size_t sizePosition = reply->dataPosition();
+ reply->writeInt32(size);
+ size_t finalSize = size;
+ for (size_t i = 0; i < size; i++) {
+ size_t position = reply->dataPosition();
+ if (strategies[i].writeToParcel(reply) != NO_ERROR) {
+ reply->setDataPosition(position);
+ finalSize--;
+ }
+ }
+ if (size != finalSize) {
+ size_t position = reply->dataPosition();
+ reply->setDataPosition(sizePosition);
+ reply->writeInt32(finalSize);
+ reply->setDataPosition(position);
+ }
+ return NO_ERROR;
+ }
+
+ case GET_STRATEGY_FOR_ATTRIBUTES: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ AudioAttributes attributes;
+ status_t status = attributes.readFromParcel(&data);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ product_strategy_t strategy = getProductStrategyFromAudioAttributes(attributes);
+ reply->writeUint32(static_cast<int>(strategy));
+ return NO_ERROR;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 5c5dbd6..536b00d 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -20,7 +20,6 @@
#include <math.h>
#include <utils/Log.h>
#include <cutils/properties.h>
-#include <media/AudioPolicyHelper.h>
#include "media/ToneGenerator.h"
@@ -1242,7 +1241,7 @@
if (mStreamType == AUDIO_STREAM_VOICE_CALL) {
streamType = AUDIO_STREAM_DTMF;
}
- stream_type_to_audio_attributes(streamType, &attr);
+ attr = AudioSystem::streamTypeToAttributes(streamType);
const size_t frameCount = mProcessSize;
status_t status = mpAudioTrack->set(
diff --git a/media/libaudioclient/include/media/AudioAttributes.h b/media/libaudioclient/include/media/AudioAttributes.h
new file mode 100644
index 0000000..edf26eb
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioAttributes.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioAttributes : public Parcelable
+{
+public:
+ AudioAttributes() = default;
+ AudioAttributes(const audio_attributes_t &attributes) : mAttributes(attributes) {}
+ AudioAttributes(uint32_t groupId,
+ audio_stream_type_t stream,
+ const audio_attributes_t &attributes) :
+ mAttributes(attributes), mStreamType(stream), mGroupId(groupId) {}
+
+ audio_attributes_t getAttributes() const { return mAttributes; }
+
+ status_t readFromParcel(const Parcel *parcel) override;
+ status_t writeToParcel(Parcel *parcel) const override;
+
+ audio_stream_type_t getStreamType() const { return mStreamType; }
+ uint32_t getGroupId() const { return mGroupId; }
+
+private:
+ audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ /**
+ * @brief mStreamType: for legacy volume management, we need to be able to convert an attribute
+ * to a given stream type.
+ */
+ audio_stream_type_t mStreamType = AUDIO_STREAM_DEFAULT;
+
+ /**
+ * @brief mGroupId: for future volume management, define groups within a strategy that follows
+ * the same curves of volume (extension of stream types to manage volume)
+ */
+ uint32_t mGroupId = 0;
+};
+
+} // namespace android
diff --git a/media/libaudioclient/include/media/AudioCommonTypes.h b/media/libaudioclient/include/media/AudioCommonTypes.h
new file mode 100644
index 0000000..5188da1
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioCommonTypes.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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 <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+enum product_strategy_t : uint32_t;
+const product_strategy_t PRODUCT_STRATEGY_NONE = static_cast<product_strategy_t>(-1);
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamTypes = std::vector<audio_stream_type_t>;
+
+constexpr bool operator==(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+ return lhs.usage == rhs.usage && lhs.content_type == rhs.content_type &&
+ lhs.flags == rhs.flags && (std::strcmp(lhs.tags, rhs.tags) == 0);
+}
+constexpr bool operator!=(const audio_attributes_t &lhs, const audio_attributes_t &rhs)
+{
+ return !(lhs==rhs);
+}
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioPolicyHelper.h b/media/libaudioclient/include/media/AudioPolicyHelper.h
deleted file mode 100644
index 46de6b3..0000000
--- a/media/libaudioclient/include/media/AudioPolicyHelper.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2014 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 AUDIO_POLICY_HELPER_H_
-#define AUDIO_POLICY_HELPER_H_
-
-#include <android-base/macros.h>
-#include <system/audio.h>
-
-static inline
-audio_stream_type_t audio_usage_to_stream_type(const audio_usage_t usage)
-{
- switch(usage) {
- case AUDIO_USAGE_MEDIA:
- case AUDIO_USAGE_GAME:
- case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
- case AUDIO_USAGE_ASSISTANT:
- return AUDIO_STREAM_MUSIC;
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
- return AUDIO_STREAM_ACCESSIBILITY;
- case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
- return AUDIO_STREAM_SYSTEM;
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- return AUDIO_STREAM_VOICE_CALL;
-
- case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
- return AUDIO_STREAM_DTMF;
-
- case AUDIO_USAGE_ALARM:
- return AUDIO_STREAM_ALARM;
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- return AUDIO_STREAM_RING;
-
- case AUDIO_USAGE_NOTIFICATION:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
- case AUDIO_USAGE_NOTIFICATION_EVENT:
- return AUDIO_STREAM_NOTIFICATION;
-
- case AUDIO_USAGE_UNKNOWN:
- default:
- return AUDIO_STREAM_MUSIC;
- }
-}
-
-static inline
-audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
-{
- // flags to stream type mapping
- if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
- return AUDIO_STREAM_ENFORCED_AUDIBLE;
- }
- if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
- return AUDIO_STREAM_BLUETOOTH_SCO;
- }
-
- // usage to stream type mapping
- return audio_usage_to_stream_type(attr->usage);
-}
-
-static inline
-void stream_type_to_audio_attributes(audio_stream_type_t streamType,
- audio_attributes_t *attr) {
- memset(attr, 0, sizeof(audio_attributes_t));
-
- switch (streamType) {
- case AUDIO_STREAM_DEFAULT:
- case AUDIO_STREAM_MUSIC:
- attr->content_type = AUDIO_CONTENT_TYPE_MUSIC;
- attr->usage = AUDIO_USAGE_MEDIA;
- break;
- case AUDIO_STREAM_VOICE_CALL:
- attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
- attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
- break;
- case AUDIO_STREAM_ENFORCED_AUDIBLE:
- attr->flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
- FALLTHROUGH_INTENDED; // attributes in common with STREAM_SYSTEM
- case AUDIO_STREAM_SYSTEM:
- attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
- break;
- case AUDIO_STREAM_RING:
- attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
- break;
- case AUDIO_STREAM_ALARM:
- attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- attr->usage = AUDIO_USAGE_ALARM;
- break;
- case AUDIO_STREAM_NOTIFICATION:
- attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- attr->usage = AUDIO_USAGE_NOTIFICATION;
- break;
- case AUDIO_STREAM_BLUETOOTH_SCO:
- attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
- attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
- attr->flags |= AUDIO_FLAG_SCO;
- break;
- case AUDIO_STREAM_DTMF:
- attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
- break;
- case AUDIO_STREAM_TTS:
- attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
- attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
- break;
- default:
- ALOGE("invalid stream type %d when converting to attributes", streamType);
- }
-}
-
-// Convert flags sent from Java AudioAttributes.getFlags() method to audio_output_flags_t
-static inline
-void audio_attributes_flags_to_audio_output_flags(const audio_flags_mask_t audioAttributeFlags,
- audio_output_flags_t &flags) {
- if ((audioAttributeFlags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
- flags = static_cast<audio_output_flags_t>(flags |
- AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_DIRECT);
- }
- if ((audioAttributeFlags & AUDIO_FLAG_LOW_LATENCY) != 0) {
- flags = static_cast<audio_output_flags_t>(flags | AUDIO_OUTPUT_FLAG_FAST);
- }
- // check deep buffer after flags have been modified above
- if (flags == AUDIO_OUTPUT_FLAG_NONE && (audioAttributeFlags & AUDIO_FLAG_DEEP_BUFFER) != 0) {
- flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
- }
-}
-
-#endif //AUDIO_POLICY_HELPER_H_
diff --git a/media/libaudioclient/include/media/AudioProductStrategy.h b/media/libaudioclient/include/media/AudioProductStrategy.h
new file mode 100644
index 0000000..7441095
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioProductStrategy.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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 <media/AudioCommonTypes.h>
+#include <media/AudioAttributes.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class AudioProductStrategy : public Parcelable
+{
+public:
+ AudioProductStrategy() {}
+ AudioProductStrategy(const std::string &name, const std::vector<AudioAttributes> &attributes,
+ product_strategy_t id) :
+ mName(name), mAudioAttributes(attributes), mId(id) {}
+
+ const std::string &getName() const { return mName; }
+ std::vector<AudioAttributes> getAudioAttributes() const { return mAudioAttributes; }
+ product_strategy_t getId() const { return mId; }
+
+ status_t readFromParcel(const Parcel *parcel) override;
+ status_t writeToParcel(Parcel *parcel) const override;
+
+ /**
+ * @brief attributesMatches: checks if client attributes matches with a reference attributes
+ * "matching" means the usage shall match if reference attributes has a defined usage, AND
+ * content type shall match if reference attributes has a defined content type AND
+ * flags shall match if reference attributes has defined flags AND
+ * tags shall match if reference attributes has defined tags.
+ * Reference attributes "default" shall not be considered as a "true" case. This convention
+ * is used to identify the default strategy.
+ * @param refAttributes to be considered
+ * @param clientAttritubes to be considered
+ * @return true if matching, false otherwise
+ */
+ static bool attributesMatches(const audio_attributes_t refAttributes,
+ const audio_attributes_t clientAttritubes);
+private:
+ std::string mName;
+ std::vector<AudioAttributes> mAudioAttributes;
+ product_strategy_t mId;
+};
+
+using AudioProductStrategyVector = std::vector<AudioProductStrategy>;
+
+} // namespace android
+
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 1fb7add..87a9919 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <media/AudioPolicy.h>
+#include <media/AudioProductStrategy.h>
#include <media/AudioIoDescriptor.h>
#include <media/IAudioFlingerClient.h>
#include <media/IAudioPolicyServiceClient.h>
@@ -364,6 +365,12 @@
static bool isHapticPlaybackSupported();
+ static status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+ static product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa);
+
+ static audio_attributes_t streamTypeToAttributes(audio_stream_type_t stream);
+ static audio_stream_type_t attributesToStreamType(const audio_attributes_t &attr);
+
// ----------------------------------------------------------------------------
class AudioPortCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 177adc2..b2cda32 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -196,6 +196,8 @@
virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) = 0;
virtual bool isHapticPlaybackSupported() = 0;
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+ virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa) = 0;
};
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index e7da488..4dece96 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -107,6 +107,7 @@
data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
status_t ret = remote()->transact(GETFORMAT, data, &reply);
if (ret == NO_ERROR) {
+ AutoMutex _l(mLock);
mMetaData = MetaData::createFromParcel(reply);
return mMetaData;
}
@@ -222,6 +223,8 @@
// NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
// XXX: could we use this for caching, or does metadata change on the fly?
sp<MetaData> mMetaData;
+ // ensure synchronize access to mMetaData
+ Mutex mLock;
// Cache all IMemory objects received from MediaExtractor.
// We gc IMemory objects that are no longer active (referenced by a MediaBuffer).
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
index 6dbc9b8..cbd64bb 100644
--- a/media/libmedia/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -57,6 +57,7 @@
AMEDIAFORMAT_KEY_COLOR_STANDARD,
AMEDIAFORMAT_KEY_COLOR_TRANSFER,
AMEDIAFORMAT_KEY_COMPLEXITY,
+ AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
AMEDIAFORMAT_KEY_CRYPTO_MODE,
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 00f537d..08519cd 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -123,9 +123,6 @@
"signed-integer-overflow",
],
cfi: true,
- diag: {
- cfi: true,
- },
},
}
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 98a3e75..4de92ad 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -22,7 +22,6 @@
#include <cutils/properties.h> // for property_get
#include <utils/Log.h>
-#include <media/AudioPolicyHelper.h>
#include <media/stagefright/foundation/ADebug.h>
namespace {
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 96f79e0..da95817 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -45,7 +45,6 @@
#include <utils/Timers.h>
#include <utils/Vector.h>
-#include <media/AudioPolicyHelper.h>
#include <media/IMediaHTTPService.h>
#include <media/IRemoteDisplay.h>
#include <media/IRemoteDisplayClient.h>
@@ -1627,7 +1626,7 @@
mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
if (mAttributes != NULL) {
memcpy(mAttributes, attr, sizeof(audio_attributes_t));
- mStreamType = audio_attributes_to_stream_type(attr);
+ mStreamType = AudioSystem::attributesToStreamType(*attr);
}
} else {
mAttributes = NULL;
@@ -1816,7 +1815,7 @@
mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
}
memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
- mStreamType = audio_attributes_to_stream_type(attributes);
+ mStreamType = AudioSystem::attributesToStreamType(*attributes);
}
}
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index c06c288..2dca5c3 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -752,6 +752,7 @@
constexpr char KEY_COLOR_STANDARD[] = "color-standard";
constexpr char KEY_COLOR_TRANSFER[] = "color-transfer";
constexpr char KEY_COMPLEXITY[] = "complexity";
+constexpr char KEY_CREATE_INPUT_SURFACE_SUSPENDED[] = "create-input-buffers-suspended";
constexpr char KEY_DURATION[] = "durationUs";
constexpr char KEY_FEATURE_[] = "feature-";
constexpr char KEY_FLAC_COMPRESSION_LEVEL[] = "flac-compression-level";
@@ -772,8 +773,10 @@
constexpr char KEY_LATENCY[] = "latency";
constexpr char KEY_LEVEL[] = "level";
constexpr char KEY_MAX_BIT_RATE[] = "max-bitrate";
+constexpr char KEY_MAX_FPS_TO_ENCODER[] = "max-fps-to-encoder";
constexpr char KEY_MAX_HEIGHT[] = "max-height";
constexpr char KEY_MAX_INPUT_SIZE[] = "max-input-size";
+constexpr char KEY_MAX_PTS_GAP_TO_ENCODER[] = "max-pts-gap-to-encoder";
constexpr char KEY_MAX_WIDTH[] = "max-width";
constexpr char KEY_MIME[] = "mime";
constexpr char KEY_OPERATING_RATE[] = "operating-rate";
@@ -828,8 +831,10 @@
constexpr int32_t INFO_TRY_AGAIN_LATER = -1;
constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
constexpr int32_t VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+constexpr char PARAMETER_KEY_OFFSET_TIME[] = "time-offset-us";
constexpr char PARAMETER_KEY_REQUEST_SYNC_FRAME[] = "request-sync";
constexpr char PARAMETER_KEY_SUSPEND[] = "drop-input-frames";
+constexpr char PARAMETER_KEY_SUSPEND_TIME[] = "drop-start-time-us";
constexpr char PARAMETER_KEY_VIDEO_BITRATE[] = "video-bitrate";
}
diff --git a/media/libstagefright/timedtext/Android.bp b/media/libstagefright/timedtext/Android.bp
index 97e1ec6..6935655 100644
--- a/media/libstagefright/timedtext/Android.bp
+++ b/media/libstagefright/timedtext/Android.bp
@@ -44,9 +44,6 @@
"signed-integer-overflow",
],
cfi: true,
- diag: {
- cfi: true,
- },
},
include_dirs: [
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index fcb706d..cd8ecb5 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -292,6 +292,7 @@
EXPORT const char* AMEDIAFORMAT_KEY_COMPILATION = "compilation";
EXPORT const char* AMEDIAFORMAT_KEY_COMPLEXITY = "complexity";
EXPORT const char* AMEDIAFORMAT_KEY_COMPOSER = "composer";
+EXPORT const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED = "create-input-buffers-suspended";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE = "crypto-default-iv-size";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK = "crypto-encrypted-byte-block";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES = "crypto-encrypted-sizes";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 2551228..cc1d9ef 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -188,6 +188,7 @@
extern const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_COMPILATION __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_COMPOSER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES __INTRODUCED_IN(29);
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index c50084e..171167d 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -56,6 +56,7 @@
AMEDIAFORMAT_KEY_COMPILATION; # var introduced=29
AMEDIAFORMAT_KEY_COMPLEXITY; # var introduced=28
AMEDIAFORMAT_KEY_COMPOSER; # var introduced=29
+ AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES; # var introduced=29
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 2d9bd8e..612855f 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -81,13 +81,16 @@
class Endpoint {
public:
Endpoint() = default;
- Endpoint(Endpoint&& other) { *this = std::move(other); }
- Endpoint& operator=(Endpoint&& other) {
+ Endpoint(const Endpoint&) = delete;
+ Endpoint& operator=(const Endpoint&) = delete;
+ Endpoint(Endpoint&& other) noexcept { swap(other); }
+ Endpoint& operator=(Endpoint&& other) noexcept {
+ swap(other);
+ return *this;
+ }
+ ~Endpoint() {
ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
"A non empty Patch Endpoint leaked, handle %d", mHandle);
- *this = other;
- other.mHandle = AUDIO_PATCH_HANDLE_NONE;
- return *this;
}
status_t checkTrack(TrackType *trackOrNull) const {
@@ -127,10 +130,19 @@
}
void stopTrack() { if (mTrack) mTrack->stop(); }
- private:
- Endpoint(const Endpoint&) = default;
- Endpoint& operator=(const Endpoint&) = default;
+ void swap(Endpoint &other) noexcept {
+ using std::swap;
+ swap(mThread, other.mThread);
+ swap(mCloseThread, other.mCloseThread);
+ swap(mHandle, other.mHandle);
+ swap(mTrack, other.mTrack);
+ }
+ friend void swap(Endpoint &a, Endpoint &b) noexcept {
+ a.swap(b);
+ }
+
+ private:
sp<ThreadType> mThread;
bool mCloseThread = true;
audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index ebb4f3b..f72f44a 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -11,8 +11,10 @@
LOCAL_C_INCLUDES := \
frameworks/av/services/audioflinger \
$(call include-path-for, audio-utils) \
- frameworks/av/services/audiopolicy/common/include \
- frameworks/av/services/audiopolicy/engine/interface \
+
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_interface_headers \
LOCAL_SHARED_LIBRARIES := \
libcutils \
@@ -51,7 +53,7 @@
libcutils \
libutils \
liblog \
- libaudioclient \
+ libaudiopolicy \
libsoundtrigger
ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
@@ -76,10 +78,12 @@
endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
LOCAL_C_INCLUDES += \
- frameworks/av/services/audiopolicy/common/include \
- frameworks/av/services/audiopolicy/engine/interface \
$(call include-path-for, audio-utils) \
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_interface_headers
+
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
@@ -114,10 +118,12 @@
libaudiopolicycomponents
LOCAL_C_INCLUDES += \
- frameworks/av/services/audiopolicy/common/include \
- frameworks/av/services/audiopolicy/engine/interface \
$(call include-path-for, audio-utils) \
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_interface_headers
+
LOCAL_CFLAGS := -Wall -Werror
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index cf2ce99..d7030f9 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -240,6 +240,10 @@
std::vector<audio_format_t> *formats) = 0;
virtual void setAppState(uid_t uid, app_state_t state);
+
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
+
+ virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa) = 0;
};
diff --git a/services/audiopolicy/common/include/RoutingStrategy.h b/services/audiopolicy/common/include/RoutingStrategy.h
deleted file mode 100644
index f8a1cd6..0000000
--- a/services/audiopolicy/common/include/RoutingStrategy.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace android {
-
-// Time in milliseconds after media stopped playing during which we consider that the
-// sonification should be as unobtrusive as during the time media was playing.
-#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
-
-enum routing_strategy {
- STRATEGY_NONE = -1,
- STRATEGY_MEDIA,
- STRATEGY_PHONE,
- STRATEGY_SONIFICATION,
- STRATEGY_SONIFICATION_RESPECTFUL,
- STRATEGY_DTMF,
- STRATEGY_ENFORCED_AUDIBLE,
- STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
- STRATEGY_ACCESSIBILITY,
- STRATEGY_REROUTING,
- NUM_STRATEGIES
-};
-
-}; //namespace android
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 837ca47..605fc1c 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -17,9 +17,20 @@
#pragma once
#include <system/audio.h>
+#include <vector>
+
+namespace android {
+
+using StreamTypeVector = std::vector<audio_stream_type_t>;
+
+static const audio_attributes_t defaultAttr = AUDIO_ATTRIBUTES_INITIALIZER;
+
+} // namespace android
static const audio_format_t gDynamicFormat = AUDIO_FORMAT_DEFAULT;
+static const uint32_t SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY = 5000;
+
// For mixed output and inputs, the policy will use max mixer sampling rates.
// Do not limit sampling rate otherwise
#define SAMPLE_RATE_HZ_MAX 192000
@@ -151,3 +162,25 @@
}
return format1 == format2;
}
+
+/**
+ * @brief hasStream checks if a given stream type is found in the list of streams
+ * @param streams collection of stream types to consider.
+ * @param streamType to consider
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasStream(const android::StreamTypeVector &streams,
+ audio_stream_type_t streamType)
+{
+ return std::find(begin(streams), end(streams), streamType) != end(streams);
+}
+
+/**
+ * @brief hasVoiceStream checks if a voice stream is found in the list of streams
+ * @param streams collection to consider.
+ * @return true if voice stream is found in the given streams, false otherwise
+ */
+static inline bool hasVoiceStream(const android::StreamTypeVector &streams)
+{
+ return hasStream(streams, AUDIO_STREAM_VOICE_CALL);
+}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 555412e..6e29632 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -16,6 +16,8 @@
#pragma once
+#include "DeviceDescriptor.h"
+
namespace android {
/**
@@ -34,4 +36,36 @@
virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};
+template <class IoDescriptor, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+ IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
+{
+ auto activeClients = desc->clientsList(true /*activeOnly*/);
+ auto activeClientsWithRoute =
+ desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
+ active = activeClients.size() > 0;
+ if (active && activeClients.size() == activeClientsWithRoute.size()) {
+ return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
+ }
+ return nullptr;
+}
+
+template <class IoCollection, class Filter>
+sp<DeviceDescriptor> findPreferredDevice(
+ IoCollection& ioCollection, Filter filter, const DeviceVector& devices)
+{
+ sp<DeviceDescriptor> device;
+ for (size_t i = 0; i < ioCollection.size(); i++) {
+ auto desc = ioCollection.valueAt(i);
+ bool active;
+ sp<DeviceDescriptor> curDevice = findPreferredDevice(desc, filter, active, devices);
+ if (active && curDevice == nullptr) {
+ return nullptr;
+ } else if (curDevice != nullptr) {
+ device = curDevice;
+ }
+ }
+ return device;
+}
+
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index e1ecc61..6132bb4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -16,18 +16,20 @@
#pragma once
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
+
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/Timers.h>
#include <utils/KeyedVector.h>
#include <system/audio.h>
-#include <RoutingStrategy.h>
#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "ClientDescriptor.h"
#include "DeviceDescriptor.h"
-#include <map>
+#include <vector>
namespace android {
@@ -35,6 +37,70 @@
class AudioMix;
class AudioPolicyClientInterface;
+class ActivityTracking
+{
+public:
+ virtual ~ActivityTracking() = default;
+ bool isActive(uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+ {
+ if (mActivityCount > 0) {
+ return true;
+ }
+ if (inPastMs == 0) {
+ return false;
+ }
+ if (sysTime == 0) {
+ sysTime = systemTime();
+ }
+ if (ns2ms(sysTime - mStopTime) < inPastMs) {
+ return true;
+ }
+ return false;
+ }
+ void changeActivityCount(int delta)
+ {
+ if ((delta + (int)mActivityCount) < 0) {
+ LOG_ALWAYS_FATAL("%s: invalid delta %d, refCount %d", __func__, delta, mActivityCount);
+ }
+ mActivityCount += delta;
+ if (!mActivityCount) {
+ setStopTime(systemTime());
+ }
+ }
+ uint32_t getActivityCount() const { return mActivityCount; }
+ nsecs_t getStopTime() const { return mStopTime; }
+ void setStopTime(nsecs_t stopTime) { mStopTime = stopTime; }
+
+ virtual void dump(String8 *dst, int spaces) const
+ {
+ dst->appendFormat("%*s- ActivityCount: %d, StopTime: %" PRId64 " \n", spaces, "",
+ getActivityCount(), getStopTime());
+ }
+private:
+ uint32_t mActivityCount = 0;
+ nsecs_t mStopTime = 0;
+};
+
+/**
+ * @brief The Activity class: it tracks the activity for volume policy (volume index, mute,
+ * memorize previous stop, and store mute if incompatible device with another strategy.
+ * Having this class prevents from looping on all attributes (legacy streams) of the strategy
+ */
+class RoutingActivity : public ActivityTracking
+{
+public:
+ void setMutedByDevice( bool isMuted) { mIsMutedByDevice = isMuted; }
+ bool isMutedByDevice() const { return mIsMutedByDevice; }
+
+private:
+ /**
+ * strategies muted because of incompatible device selection.
+ * See AudioPolicyManager::checkDeviceMuteStrategies()
+ */
+ bool mIsMutedByDevice = false;
+};
+using RoutingActivities = std::map<product_strategy_t, RoutingActivity>;
+
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
@@ -71,6 +137,14 @@
{ return mActiveCount[stream]; }
/**
+ * @brief setStopTime set the stop time due to the client stoppage or a re routing of this
+ * client
+ * @param client to be considered
+ * @param sysTime when the client stopped/was rerouted
+ */
+ void setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime);
+
+ /**
* Changes the client->active() state and the output descriptor's global active count,
* along with the stream active count and mActiveClients.
* The client must be previously added by the base class addClient().
@@ -82,6 +156,21 @@
uint32_t inPastMs = 0,
nsecs_t sysTime = 0) const;
+ bool isStrategyActive(product_strategy_t ps, uint32_t inPastMs = 0, nsecs_t sysTime = 0) const
+ {
+ return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+ mRoutingActivities.at(ps).isActive(inPastMs, sysTime) : false;
+ }
+ bool isStrategyMutedByDevice(product_strategy_t ps) const
+ {
+ return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
+ mRoutingActivities.at(ps).isMutedByDevice() : false;
+ }
+ void setStrategyMutedByDevice(product_strategy_t ps, bool isMuted)
+ {
+ mRoutingActivities[ps].setMutedByDevice(isMuted);
+ }
+
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
virtual sp<AudioPort> getAudioPort() const { return mPort; }
@@ -95,7 +184,8 @@
void setPatchHandle(audio_patch_handle_t handle) override;
TrackClientVector clientsList(bool activeOnly = false,
- routing_strategy strategy = STRATEGY_NONE, bool preferredDeviceOnly = false) const;
+ product_strategy_t strategy = PRODUCT_STRATEGY_NONE,
+ bool preferredDeviceOnly = false) const;
// override ClientMapHandler to abort when removing a client when active.
void removeClient(audio_port_handle_t portId) override {
@@ -121,8 +211,6 @@
DeviceVector mDevices; /**< current devices this output is routed to */
nsecs_t mStopTime[AUDIO_STREAM_CNT];
int mMuteCount[AUDIO_STREAM_CNT]; // mute request counter
- bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
- // device selection. See checkDeviceMuteStrategies()
AudioMix *mPolicyMix = nullptr; // non NULL when used by a dynamic policy
protected:
@@ -139,6 +227,8 @@
// Compare with the ClientMap (mClients) which are external AudioTrack clients of the
// output descriptor (and do not count internal PatchTracks).
ActiveClientMap mActiveClients;
+
+ RoutingActivities mRoutingActivities; /**< track routing activity on this ouput.*/
};
// Audio output driven by a software mixer in audio flinger.
@@ -275,6 +365,21 @@
bool isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
/**
+ * @brief isStrategyActiveOnSameModule checks if the given strategy is active (or was active
+ * in the past) on the given output and all the outputs belonging to the same HW Module
+ * the same module than the given output
+ * @param outputDesc to be considered
+ * @param ps product strategy to be checked upon activity status
+ * @param inPastMs if 0, check currently, otherwise, check in the past
+ * @param sysTime shall be set if request is done for the past activity.
+ * @return true if an output following the strategy is active on the same module than desc,
+ * false otherwise
+ */
+ bool isStrategyActiveOnSameModule(product_strategy_t ps,
+ const sp<SwAudioOutputDescriptor>& desc,
+ uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
+
+ /**
* returns the A2DP output handle if it is open or 0 otherwise
*/
audio_io_handle_t getA2dpOutput() const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 2932296..7296c95 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -78,7 +78,7 @@
sp<DeviceDescriptor> getDeviceAndMixForInputSource(audio_source_t inputSource,
const DeviceVector &availableDeviceTypes,
- AudioMix **policyMix);
+ AudioMix **policyMix) const;
/**
* @brief try to find a matching mix for a given output descriptor and returns the associated
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index a187029..4c069e4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -22,14 +22,14 @@
#include <sys/types.h>
#include <system/audio.h>
-#include <system/audio_policy.h>
+#include <media/AudioProductStrategy.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
+#include <policy.h>
#include "AudioPatch.h"
#include "EffectDescriptor.h"
-#include "RoutingStrategy.h"
namespace android {
@@ -41,10 +41,12 @@
{
public:
ClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
- audio_attributes_t attributes, audio_config_base_t config,
- audio_port_handle_t preferredDeviceId) :
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId,
+ bool isPreferredDeviceForExclusiveUse = false) :
mPortId(portId), mUid(uid), mSessionId(sessionId), mAttributes(attributes),
- mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false) {}
+ mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false),
+ mPreferredDeviceForExclusiveUse(isPreferredDeviceForExclusiveUse){}
~ClientDescriptor() override = default;
virtual void dump(String8 *dst, int spaces, int index) const;
@@ -58,7 +60,8 @@
audio_port_handle_t preferredDeviceId() const { return mPreferredDeviceId; };
void setPreferredDeviceId(audio_port_handle_t preferredDeviceId) {
mPreferredDeviceId = preferredDeviceId;
- };
+ }
+ bool isPreferredDeviceForExclusiveUse() const { return mPreferredDeviceForExclusiveUse; }
void setActive(bool active) { mActive = active; }
bool active() const { return mActive; }
bool hasPreferredDevice(bool activeOnly = false) const {
@@ -73,16 +76,19 @@
const audio_config_base_t mConfig;
audio_port_handle_t mPreferredDeviceId; // selected input device port ID
bool mActive;
+ bool mPreferredDeviceForExclusiveUse = false;
};
class TrackClientDescriptor: public ClientDescriptor
{
public:
TrackClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
- audio_attributes_t attributes, audio_config_base_t config,
- audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
- routing_strategy strategy, audio_output_flags_t flags) :
- ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId, audio_stream_type_t stream,
+ product_strategy_t strategy, audio_output_flags_t flags,
+ bool isPreferredDeviceForExclusiveUse) :
+ ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId,
+ isPreferredDeviceForExclusiveUse),
mStream(stream), mStrategy(strategy), mFlags(flags) {}
~TrackClientDescriptor() override = default;
@@ -92,11 +98,11 @@
audio_output_flags_t flags() const { return mFlags; }
audio_stream_type_t stream() const { return mStream; }
- routing_strategy strategy() const { return mStrategy; }
+ product_strategy_t strategy() const { return mStrategy; }
private:
const audio_stream_type_t mStream;
- const routing_strategy mStrategy;
+ const product_strategy_t mStrategy;
const audio_output_flags_t mFlags;
};
@@ -136,7 +142,7 @@
public:
SourceClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_attributes_t attributes,
const sp<AudioPatch>& patchDesc, const sp<DeviceDescriptor>& srcDevice,
- audio_stream_type_t stream, routing_strategy strategy);
+ audio_stream_type_t stream, product_strategy_t strategy);
~SourceClientDescriptor() override = default;
sp<AudioPatch> patchDesc() const { return mPatchDesc; }
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 2dc33ab..7f01dc5 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -16,7 +16,7 @@
#pragma once
-#include <RoutingStrategy.h>
+#include <policy.h>
#include <system/audio_effect.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
@@ -28,14 +28,26 @@
class EffectDescriptor : public RefBase
{
public:
+ EffectDescriptor(const effect_descriptor_t *desc, bool isMusicEffect,
+ int id, int io, int session) :
+ mId(id), mIo(io), mSession(session), mEnabled(false),
+ mIsMusicEffect(isMusicEffect)
+ {
+ memcpy (&mDesc, desc, sizeof(effect_descriptor_t));
+ }
+
void dump(String8 *dst, int spaces = 0) const;
int mId; // effect unique ID
int mIo; // io the effect is attached to
- routing_strategy mStrategy; // routing strategy the effect is associated to
int mSession; // audio session the effect is on
effect_descriptor_t mDesc; // effect descriptor
bool mEnabled; // enabled state: CPU load being used or not
+
+ bool isMusicEffect() const { return mIsMusicEffect; }
+
+private:
+ bool mIsMusicEffect;
};
class EffectDescriptorCollection : public KeyedVector<int, sp<EffectDescriptor> >
@@ -44,7 +56,7 @@
EffectDescriptorCollection();
status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io,
- uint32_t strategy, int session, int id);
+ int session, int id, bool isMusicEffect);
status_t unregisterEffect(int id);
sp<EffectDescriptor> getEffect(int id) const;
status_t setEffectEnabled(int id, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 78b3f45..1dfd88a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -44,9 +44,6 @@
mMuteCount[i] = 0;
mStopTime[i] = 0;
}
- for (int i = 0; i < NUM_STRATEGIES; i++) {
- mStrategyMutedByDevice[i] = false;
- }
if (mPort.get() != nullptr) {
mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
if (mPort->mGains.size() > 0) {
@@ -101,6 +98,7 @@
// return;
}
mActiveCount[stream] += delta;
+ mRoutingActivities[client->strategy()].changeActivityCount(delta);
if (delta > 0) {
mActiveClients[client] += delta;
@@ -122,6 +120,12 @@
ALOGV("%s stream %d, count %d", __FUNCTION__, stream, mActiveCount[stream]);
}
+void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
+{
+ mStopTime[client->stream()] = sysTime;
+ mRoutingActivities[client->strategy()].setStopTime(sysTime);
+}
+
void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
{
LOG_ALWAYS_FATAL_IF(getClient(client->portId()) == nullptr,
@@ -247,14 +251,15 @@
port->ext.mix.hw_module = getModuleHandle();
}
-TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, routing_strategy strategy,
+TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
bool preferredDeviceOnly) const
{
TrackClientVector clients;
for (const auto &client : getClientIterable()) {
if ((!activeOnly || client->active())
- && (strategy == STRATEGY_NONE || strategy == client->strategy())
- && (!preferredDeviceOnly || client->hasPreferredDevice())) {
+ && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
+ && (!preferredDeviceOnly ||
+ (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
clients.push_back(client);
}
}
@@ -698,6 +703,20 @@
return false;
}
+bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
+ const sp<SwAudioOutputDescriptor>& desc,
+ uint32_t inPastMs, nsecs_t sysTime) const
+{
+ for (size_t i = 0; i < size(); i++) {
+ const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
+ if (desc->sharesHwModuleWith(otherDesc) &&
+ otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
+ return true;
+ }
+ }
+ return false;
+}
+
audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
{
for (size_t i = 0; i < size(); i++) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index cd10c82..2489e76 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -302,7 +302,7 @@
}
sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
- audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix)
+ audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix) const
{
for (size_t i = 0; i < size(); i++) {
AudioMix *mix = valueAt(i)->getMix();
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 82d64c9..a6f6c3b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -82,10 +82,10 @@
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
audio_attributes_t attributes, const sp<AudioPatch>& patchDesc,
const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
- routing_strategy strategy) :
+ product_strategy_t strategy) :
TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
AUDIO_CONFIG_BASE_INITIALIZER, AUDIO_PORT_HANDLE_NONE,
- stream, strategy, AUDIO_OUTPUT_FLAG_NONE),
+ stream, strategy, AUDIO_OUTPUT_FLAG_NONE, false),
mPatchDesc(patchDesc), mSrcDevice(srcDevice)
{
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 4cb1e17..a3121d1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -215,11 +215,12 @@
sp<DeviceDescriptor> device;
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->type() == type) {
- // Assign device if address is empty or matches and
- // format is default or matches
+ // If format is specified, match it and ignore address
+ // Otherwise if address is specified match it
+ // Otherwise always match
if (((address == "" || itemAt(i)->address() == address) &&
format == AUDIO_FORMAT_DEFAULT) ||
- itemAt(i)->supportsFormat(format)) {
+ (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
device = itemAt(i);
if (itemAt(i)->address() == address) {
break;
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 40c49e7..89f9899 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -24,8 +24,9 @@
void EffectDescriptor::dump(String8 *dst, int spaces) const
{
+ dst->appendFormat("%*sID: %d\n", spaces, "", mId);
dst->appendFormat("%*sI/O: %d\n", spaces, "", mIo);
- dst->appendFormat("%*sStrategy: %d\n", spaces, "", mStrategy);
+ dst->appendFormat("%*sMusic Effect: %s\n", spaces, "", isMusicEffect()? "yes" : "no");
dst->appendFormat("%*sSession: %d\n", spaces, "", mSession);
dst->appendFormat("%*sName: %s\n", spaces, "", mDesc.name);
dst->appendFormat("%*s%s\n", spaces, "", mEnabled ? "Enabled" : "Disabled");
@@ -41,9 +42,8 @@
status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *desc,
audio_io_handle_t io,
- uint32_t strategy,
int session,
- int id)
+ int id, bool isMusicEffect)
{
if (getEffect(id) != nullptr) {
ALOGW("%s effect %s already registered", __FUNCTION__, desc->name);
@@ -59,18 +59,11 @@
if (mTotalEffectsMemory > mTotalEffectsMemoryMaxUsed) {
mTotalEffectsMemoryMaxUsed = mTotalEffectsMemory;
}
- ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
- desc->name, io, strategy, session, id);
+ ALOGV("registerEffect() effect %s, io %d, session %d id %d",
+ desc->name, io, session, id);
ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
- sp<EffectDescriptor> effectDesc = new EffectDescriptor();
- memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
- effectDesc->mId = id;
- effectDesc->mIo = io;
- effectDesc->mStrategy = static_cast<routing_strategy>(strategy);
- effectDesc->mSession = session;
- effectDesc->mEnabled = false;
-
+ sp<EffectDescriptor> effectDesc = new EffectDescriptor(desc, isMusicEffect, id, io, session);
add(id, effectDesc);
return NO_ERROR;
@@ -161,7 +154,7 @@
{
for (size_t i = 0; i < size(); i++) {
sp<EffectDescriptor> effectDesc = valueAt(i);
- if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
+ if (effectDesc->mEnabled && (effectDesc->isMusicEffect()) &&
((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
effectDesc->mDesc.name, effectDesc->mSession);
diff --git a/services/audiopolicy/engine/Android.mk b/services/audiopolicy/engine/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/engine/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
new file mode 100644
index 0000000..e6ede07
--- /dev/null
+++ b/services/audiopolicy/engine/common/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 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.
+
+cc_library_headers {
+ name: "libaudiopolicyengine_common_headers",
+ host_supported: true,
+ export_include_dirs: ["include"],
+}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
new file mode 100644
index 0000000..5c33fb3
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 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 <EngineConfig.h>
+#include <AudioPolicyManagerInterface.h>
+#include <ProductStrategy.h>
+
+namespace android {
+namespace audio_policy {
+
+class EngineBase : public AudioPolicyManagerInterface
+{
+public:
+ ///
+ /// from AudioPolicyManagerInterface
+ ///
+ android::status_t initCheck() override;
+
+ void setObserver(AudioPolicyManagerObserver *observer) override;
+
+ status_t setPhoneState(audio_mode_t mode) override;
+
+ audio_mode_t getPhoneState() const override { return mPhoneState; }
+
+ status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override
+ {
+ mForceUse[usage] = config;
+ return NO_ERROR;
+ }
+
+ audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override
+ {
+ return mForceUse[usage];
+ }
+ android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
+ audio_policy_dev_state_t /*state*/) override
+ {
+ return NO_ERROR;
+ }
+ product_strategy_t getProductStrategyForAttributes(
+ const audio_attributes_t &attr) const override;
+
+ audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const override;
+
+ audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const override;
+
+ StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const override;
+
+ AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const override;
+
+ StrategyVector getOrderedProductStrategies() const override;
+
+ status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const override;
+
+ void dump(String8 *dst) const override;
+
+
+ engineConfig::ParsingResult loadAudioPolicyEngineConfig();
+
+ const ProductStrategyMap &getProductStrategies() const { return mProductStrategies; }
+
+ ProductStrategyMap &getProductStrategies() { return mProductStrategies; }
+
+ product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+ product_strategy_t getProductStrategyByName(const std::string &name) const;
+
+ AudioPolicyManagerObserver *getApmObserver() const { return mApmObserver; }
+
+ inline bool isInCall() const
+ {
+ return is_state_in_call(getPhoneState());
+ }
+
+private:
+ AudioPolicyManagerObserver *mApmObserver = nullptr;
+
+ ProductStrategyMap mProductStrategies;
+ audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */
+
+ /** current forced use configuration. */
+ audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT] = {};
+};
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
new file mode 100644
index 0000000..72505b2
--- /dev/null
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2018 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 <system/audio.h>
+#include <AudioPolicyManagerInterface.h>
+#include <utils/RefBase.h>
+#include <HandleGenerator.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/**
+ * @brief The ProductStrategy class describes for each product_strategy_t identifier the
+ * associated audio attributes, the device types to use, the device address to use.
+ * The identifier is voluntarily not strongly typed in order to be extensible by OEM.
+ */
+class ProductStrategy : public virtual RefBase, private HandleGenerator<uint32_t>
+{
+private:
+ struct AudioAttributes {
+ audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
+ uint32_t mGroupId = 0;
+ audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ };
+
+ using AudioAttributesVector = std::vector<AudioAttributes>;
+
+public:
+ ProductStrategy(const std::string &name);
+
+ void addAttributes(const AudioAttributes &audioAttributes);
+
+ std::vector<android::AudioAttributes> listAudioAttributes() const;
+
+ std::string getName() const { return mName; }
+ AttributesVector getAudioAttributes() const;
+ product_strategy_t getId() const { return mId; }
+ StreamTypeVector getSupportedStreams() const;
+
+ /**
+ * @brief matches checks if the given audio attributes shall follow the strategy.
+ * Order of the attributes within a strategy matters.
+ * If only the usage is available, the check is performed on the usages of the given
+ * attributes, otherwise all fields must match.
+ * @param attributes to consider
+ * @return true if attributes matches with the strategy, false otherwise.
+ */
+ bool matches(const audio_attributes_t attributes) const;
+
+ bool supportStreamType(const audio_stream_type_t &streamType) const;
+
+ void setDeviceAddress(const std::string &address)
+ {
+ mDeviceAddress = address;
+ }
+
+ std::string getDeviceAddress() const { return mDeviceAddress; }
+
+ void setDeviceTypes(audio_devices_t devices)
+ {
+ mApplicableDevices = devices;
+ }
+
+ audio_devices_t getDeviceTypes() const { return mApplicableDevices; }
+
+ audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+ audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+ bool isDefault() const;
+
+ void dump(String8 *dst, int spaces = 0) const;
+
+private:
+ std::string mName;
+
+ AudioAttributesVector mAttributesVector;
+
+ product_strategy_t mId;
+
+ std::string mDeviceAddress; /**< Device address applicable for this strategy, maybe empty */
+
+ /**
+ * Applicable device(s) type mask for this strategy.
+ */
+ audio_devices_t mApplicableDevices = AUDIO_DEVICE_NONE;
+};
+
+class ProductStrategyMap : public std::map<product_strategy_t, sp<ProductStrategy> >
+{
+public:
+ /**
+ * @brief getProductStrategyForAttribute. The order of the vector is dimensionning.
+ * @param attr
+ * @return applicable product strategy for the given attribute, default if none applicable.
+ */
+ product_strategy_t getProductStrategyForAttributes(const audio_attributes_t &attr) const;
+
+ product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
+
+ audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const;
+
+ audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const;
+
+ /**
+ * @brief getAttributesForProductStrategy can be called from
+ * AudioManager: in this case, the product strategy IS the former routing strategy
+ * CarAudioManager: in this case, the product strategy IS the car usage
+ * [getAudioAttributesForCarUsage]
+ * OemExtension: in this case, the product strategy IS the Oem usage
+ *
+ * @param strategy
+ * @return audio attributes (or at least one of the attributes) following the given strategy.
+ */
+ audio_attributes_t getAttributesForProductStrategy(product_strategy_t strategy) const;
+
+ audio_devices_t getDeviceTypesForProductStrategy(product_strategy_t strategy) const;
+
+ std::string getDeviceAddressForProductStrategy(product_strategy_t strategy) const;
+
+ product_strategy_t getDefault() const;
+
+ 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
new file mode 100644
index 0000000..755f2a8
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2018 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/Base"
+#define LOG_NDEBUG 0
+
+#include "EngineBase.h"
+#include "EngineDefaultConfig.h"
+#include <TypeConverter.h>
+
+namespace android {
+namespace audio_policy {
+
+void EngineBase::setObserver(AudioPolicyManagerObserver *observer)
+{
+ ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
+ mApmObserver = observer;
+}
+
+status_t EngineBase::initCheck()
+{
+ return (mApmObserver != nullptr)? NO_ERROR : NO_INIT;
+}
+
+status_t EngineBase::setPhoneState(audio_mode_t state)
+{
+ ALOGV("setPhoneState() state %d", state);
+
+ if (state < 0 || state >= AUDIO_MODE_CNT) {
+ ALOGW("setPhoneState() invalid state %d", state);
+ return BAD_VALUE;
+ }
+
+ if (state == mPhoneState ) {
+ ALOGW("setPhoneState() setting same state %d", state);
+ return BAD_VALUE;
+ }
+
+ // store previous phone state for management of sonification strategy below
+ int oldState = mPhoneState;
+ mPhoneState = state;
+
+ if (!is_state_in_call(oldState) && is_state_in_call(state)) {
+ ALOGV(" Entering call in setPhoneState()");
+ } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
+ ALOGV(" Exiting call in setPhoneState()");
+ }
+ return NO_ERROR;
+}
+
+product_strategy_t EngineBase::getProductStrategyForAttributes(const audio_attributes_t &attr) const
+{
+ return mProductStrategies.getProductStrategyForAttributes(attr);
+}
+
+audio_stream_type_t EngineBase::getStreamTypeForAttributes(const audio_attributes_t &attr) const
+{
+ return mProductStrategies.getStreamTypeForAttributes(attr);
+}
+
+audio_attributes_t EngineBase::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+ return mProductStrategies.getAttributesForStreamType(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+ return mProductStrategies.getProductStrategyForStream(stream);
+}
+
+product_strategy_t EngineBase::getProductStrategyByName(const std::string &name) const
+{
+ for (const auto &iter : mProductStrategies) {
+ if (iter.second->getName() == name) {
+ return iter.second->getId();
+ }
+ }
+ return PRODUCT_STRATEGY_NONE;
+}
+
+engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
+{
+ auto loadProductStrategies =
+ [](auto& strategyConfigs, auto& productStrategies) {
+ uint32_t groupid = 0;
+ for (auto& strategyConfig : strategyConfigs) {
+ sp<ProductStrategy> strategy = new ProductStrategy(strategyConfig.name);
+ for (const auto &group : strategyConfig.attributesGroups) {
+ for (const auto &attr : group.attributesVect) {
+ strategy->addAttributes({group.stream, groupid, attr});
+ }
+ groupid += 1;
+ }
+ product_strategy_t strategyId = strategy->getId();
+ productStrategies[strategyId] = strategy;
+ }
+ };
+
+ auto result = engineConfig::parse();
+ if (result.parsedConfig == nullptr) {
+ ALOGW("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
+ result = {std::make_unique<engineConfig::Config>(gDefaultEngineConfig), 0};
+ }
+ ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+ loadProductStrategies(result.parsedConfig->productStrategies, mProductStrategies);
+ return result;
+}
+
+StrategyVector EngineBase::getOrderedProductStrategies() const
+{
+ auto findByFlag = [](const auto &productStrategies, auto flag) {
+ return std::find_if(begin(productStrategies), end(productStrategies),
+ [&](const auto &strategy) {
+ for (const auto &attributes : strategy.second->getAudioAttributes()) {
+ if ((attributes.flags & flag) == flag) {
+ return true;
+ }
+ }
+ return false;
+ });
+ };
+ auto strategies = mProductStrategies;
+ auto enforcedAudibleStrategyIter = findByFlag(strategies, AUDIO_FLAG_AUDIBILITY_ENFORCED);
+
+ if (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED &&
+ enforcedAudibleStrategyIter != strategies.end()) {
+ auto enforcedAudibleStrategy = *enforcedAudibleStrategyIter;
+ strategies.erase(enforcedAudibleStrategyIter);
+ strategies.insert(begin(strategies), enforcedAudibleStrategy);
+ }
+ StrategyVector orderedStrategies;
+ for (const auto &iter : strategies) {
+ orderedStrategies.push_back(iter.second->getId());
+ }
+ return orderedStrategies;
+}
+
+StreamTypeVector EngineBase::getStreamTypesForProductStrategy(product_strategy_t ps) const
+{
+ // @TODO default music stream to control volume if no group?
+ return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+ mProductStrategies.at(ps)->getSupportedStreams() :
+ StreamTypeVector(AUDIO_STREAM_MUSIC);
+}
+
+AttributesVector EngineBase::getAllAttributesForProductStrategy(product_strategy_t ps) const
+{
+ return (mProductStrategies.find(ps) != end(mProductStrategies)) ?
+ mProductStrategies.at(ps)->getAudioAttributes() : AttributesVector();
+}
+
+status_t EngineBase::listAudioProductStrategies(AudioProductStrategyVector &strategies) const
+{
+ for (const auto &iter : mProductStrategies) {
+ const auto &productStrategy = iter.second;
+ strategies.push_back(
+ {productStrategy->getName(), productStrategy->listAudioAttributes(),
+ productStrategy->getId()});
+ }
+ return NO_ERROR;
+}
+
+void EngineBase::dump(String8 *dst) const
+{
+ mProductStrategies.dump(dst, 2);
+}
+
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
new file mode 100644
index 0000000..3940c0c
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 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 <system/audio.h>
+
+namespace android {
+/**
+ * @brief AudioProductStrategies hard coded array of strategies to fill new engine API contract.
+ */
+const engineConfig::ProductStrategies gOrderedStrategies = {
+ {"STRATEGY_PHONE",
+ {
+ {"phone", AUDIO_STREAM_VOICE_CALL,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_SOURCE_DEFAULT, 0,
+ ""}},
+ },
+ {"sco", AUDIO_STREAM_BLUETOOTH_SCO,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_SCO,
+ ""}},
+ }
+ },
+ },
+ {"STRATEGY_SONIFICATION",
+ {
+ {"ring", AUDIO_STREAM_RING,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
+ AUDIO_SOURCE_DEFAULT, 0, ""}}
+ },
+ {"alarm", AUDIO_STREAM_ALARM,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, 0, ""}},
+ }
+ },
+ },
+ {"STRATEGY_ENFORCED_AUDIBLE",
+ {
+ {"", AUDIO_STREAM_ENFORCED_AUDIBLE,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+ AUDIO_FLAG_AUDIBILITY_ENFORCED, ""}}
+ }
+ },
+ },
+ {"STRATEGY_ACCESSIBILITY",
+ {
+ {"", AUDIO_STREAM_ACCESSIBILITY,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
+ AUDIO_SOURCE_DEFAULT, 0, ""}}
+ }
+ },
+ },
+ {"STRATEGY_SONIFICATION_RESPECTFUL",
+ {
+ {"", AUDIO_STREAM_NOTIFICATION,
+ {
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION, AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+ AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+ AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+ AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_EVENT,
+ AUDIO_SOURCE_DEFAULT, 0, ""}
+ }
+ }
+ },
+ },
+ {"STRATEGY_MEDIA",
+ {
+ {"music", AUDIO_STREAM_MUSIC,
+ {
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_GAME, AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANT, AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ AUDIO_SOURCE_DEFAULT, 0, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}
+ },
+ },
+ {"system", AUDIO_STREAM_SYSTEM,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_SONIFICATION,
+ AUDIO_SOURCE_DEFAULT, 0, ""}}
+ }
+ },
+ },
+ {"STRATEGY_DTMF",
+ {
+ {"", AUDIO_STREAM_DTMF,
+ {
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
+ AUDIO_SOURCE_DEFAULT, 0, ""}
+ }
+ }
+ },
+ },
+ {"STRATEGY_TRANSMITTED_THROUGH_SPEAKER",
+ {
+ {"", AUDIO_STREAM_TTS,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+ AUDIO_FLAG_BEACON, ""}}
+ }
+ },
+ },
+ {"STRATEGY_REROUTING",
+ {
+ {"", AUDIO_STREAM_REROUTING,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+ }
+ },
+ },
+ {"STRATEGY_PATCH",
+ {
+ {"", AUDIO_STREAM_PATCH,
+ {{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT, 0, ""}}
+ }
+ },
+ }
+};
+
+const engineConfig::Config gDefaultEngineConfig = {
+ 1.0,
+ gOrderedStrategies,
+ {},
+ {}
+};
+} // namespace android
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
new file mode 100644
index 0000000..71607d1
--- /dev/null
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2018 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/ProductStrategy"
+//#define LOG_NDEBUG 0
+
+#include "ProductStrategy.h"
+
+#include <media/TypeConverter.h>
+#include <utils/String8.h>
+#include <cstdint>
+#include <string>
+
+#include <log/log.h>
+
+
+namespace android {
+
+ProductStrategy::ProductStrategy(const std::string &name) :
+ mName(name),
+ mId(static_cast<product_strategy_t>(HandleGenerator<uint32_t>::getNextHandle()))
+{
+}
+
+void ProductStrategy::addAttributes(const AudioAttributes &audioAttributes)
+{
+ mAttributesVector.push_back(audioAttributes);
+}
+
+std::vector<android::AudioAttributes> ProductStrategy::listAudioAttributes() const
+{
+ std::vector<android::AudioAttributes> androidAa;
+ for (const auto &attr : mAttributesVector) {
+ androidAa.push_back({attr.mGroupId, attr.mStream, attr.mAttributes});
+ }
+ return androidAa;
+}
+
+AttributesVector ProductStrategy::getAudioAttributes() const
+{
+ AttributesVector attrVector;
+ for (const auto &attrGroup : mAttributesVector) {
+ attrVector.push_back(attrGroup.mAttributes);
+ }
+ if (not attrVector.empty()) {
+ return attrVector;
+ }
+ return { AUDIO_ATTRIBUTES_INITIALIZER };
+}
+
+bool ProductStrategy::matches(const audio_attributes_t attr) const
+{
+ return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+ [&attr](const auto &supportedAttr) {
+ return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr);
+ }) != end(mAttributesVector);
+}
+
+audio_stream_type_t ProductStrategy::getStreamTypeForAttributes(const audio_attributes_t &attr) const
+{
+ const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+ [&attr](const auto &supportedAttr) {
+ return AudioProductStrategy::attributesMatches(supportedAttr.mAttributes, attr); });
+ return iter != end(mAttributesVector) ? iter->mStream : AUDIO_STREAM_DEFAULT;
+}
+
+audio_attributes_t ProductStrategy::getAttributesForStreamType(audio_stream_type_t streamType) const
+{
+ const auto iter = std::find_if(begin(mAttributesVector), end(mAttributesVector),
+ [&streamType](const auto &supportedAttr) {
+ return supportedAttr.mStream == streamType; });
+ return iter != end(mAttributesVector) ? iter->mAttributes : AUDIO_ATTRIBUTES_INITIALIZER;
+}
+
+bool ProductStrategy::isDefault() const
+{
+ return std::find_if(begin(mAttributesVector), end(mAttributesVector), [](const auto &attr) {
+ return attr.mAttributes == defaultAttr; }) != end(mAttributesVector);
+}
+
+StreamTypeVector ProductStrategy::getSupportedStreams() const
+{
+ StreamTypeVector streams;
+ for (const auto &supportedAttr : mAttributesVector) {
+ if (std::find(begin(streams), end(streams), supportedAttr.mStream) == end(streams) &&
+ supportedAttr.mStream != AUDIO_STREAM_DEFAULT) {
+ streams.push_back(supportedAttr.mStream);
+ }
+ }
+ return streams;
+}
+
+bool ProductStrategy::supportStreamType(const audio_stream_type_t &streamType) const
+{
+ return std::find_if(begin(mAttributesVector), end(mAttributesVector),
+ [&streamType](const auto &supportedAttr) {
+ return supportedAttr.mStream == streamType; }) != end(mAttributesVector);
+}
+
+void ProductStrategy::dump(String8 *dst, int spaces) const
+{
+ dst->appendFormat("\n%*s-%s (id: %d)\n", spaces, "", mName.c_str(), mId);
+ std::string deviceLiteral;
+ if (!OutputDeviceConverter::toString(mApplicableDevices, deviceLiteral)) {
+ ALOGE("%s: failed to convert device %d", __FUNCTION__, mApplicableDevices);
+ }
+ dst->appendFormat("%*sSelected Device: {type:%s, @:%s}\n", spaces + 2, "",
+ deviceLiteral.c_str(), mDeviceAddress.c_str());
+
+ for (const auto &attr : mAttributesVector) {
+ dst->appendFormat("%*sGroup: %d stream: %s\n", spaces + 3, "", attr.mGroupId,
+ android::toString(attr.mStream).c_str());
+ dst->appendFormat("%*s Attributes: ", spaces + 3, "");
+ std::string attStr =
+ attr.mAttributes == defaultAttr ? "{ Any }" : android::toString(attr.mAttributes);
+ dst->appendFormat("%s\n", attStr.c_str());
+ }
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForAttributes(
+ const audio_attributes_t &attr) const
+{
+ for (const auto &iter : *this) {
+ if (iter.second->matches(attr)) {
+ return iter.second->getId();
+ }
+ }
+ ALOGV("%s: No matching product strategy for attributes %s, return default", __FUNCTION__,
+ toString(attr).c_str());
+ return getDefault();
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForStreamType(audio_stream_type_t stream) const
+{
+ for (const auto &iter : *this) {
+ const auto strategy = iter.second;
+ if (strategy->supportStreamType(stream)) {
+ return strategy->getAttributesForStreamType(stream);
+ }
+ }
+ ALOGV("%s: No product strategy for stream %s, using default", __FUNCTION__,
+ toString(stream).c_str());
+ return {};
+}
+
+audio_stream_type_t ProductStrategyMap::getStreamTypeForAttributes(
+ const audio_attributes_t &attr) const
+{
+ for (const auto &iter : *this) {
+ audio_stream_type_t stream = iter.second->getStreamTypeForAttributes(attr);
+ if (stream != AUDIO_STREAM_DEFAULT) {
+ return stream;
+ }
+ }
+ ALOGV("%s: No product strategy for attributes %s, using default (aka MUSIC)", __FUNCTION__,
+ toString(attr).c_str());
+ return AUDIO_STREAM_MUSIC;
+}
+
+product_strategy_t ProductStrategyMap::getDefault() const
+{
+ for (const auto &iter : *this) {
+ if (iter.second->isDefault()) {
+ ALOGV("%s: using default %s", __FUNCTION__, iter.second->getName().c_str());
+ return iter.second->getId();
+ }
+ }
+ ALOGE("%s: No default product strategy defined", __FUNCTION__);
+ return PRODUCT_STRATEGY_NONE;
+}
+
+audio_attributes_t ProductStrategyMap::getAttributesForProductStrategy(
+ product_strategy_t strategy) const
+{
+ if (find(strategy) == end()) {
+ ALOGE("Invalid %d strategy requested", strategy);
+ return AUDIO_ATTRIBUTES_INITIALIZER;
+ }
+ return at(strategy)->getAudioAttributes()[0];
+}
+
+product_strategy_t ProductStrategyMap::getProductStrategyForStream(audio_stream_type_t stream) const
+{
+ for (const auto &iter : *this) {
+ if (iter.second->supportStreamType(stream)) {
+ return iter.second->getId();
+ }
+ }
+ ALOGV("%s: No product strategy for stream %d, using default", __FUNCTION__, stream);
+ return getDefault();
+}
+
+
+audio_devices_t ProductStrategyMap::getDeviceTypesForProductStrategy(
+ product_strategy_t strategy) const
+{
+ if (find(strategy) == end()) {
+ ALOGE("Invalid %d strategy requested, returning device for default strategy", strategy);
+ product_strategy_t defaultStrategy = getDefault();
+ if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+ return AUDIO_DEVICE_NONE;
+ }
+ return at(getDefault())->getDeviceTypes();
+ }
+ return at(strategy)->getDeviceTypes();
+}
+
+std::string ProductStrategyMap::getDeviceAddressForProductStrategy(product_strategy_t psId) const
+{
+ if (find(psId) == end()) {
+ ALOGE("Invalid %d strategy requested, returning device for default strategy", psId);
+ product_strategy_t defaultStrategy = getDefault();
+ if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
+ return {};
+ }
+ return at(getDefault())->getDeviceAddress();
+ }
+ return at(psId)->getDeviceAddress();
+}
+
+void ProductStrategyMap::dump(String8 *dst, int spaces) const
+{
+ dst->appendFormat("%*sProduct Strategies dump:", spaces, "");
+ for (const auto &iter : *this) {
+ iter.second->dump(dst, spaces + 2);
+ }
+}
+
+}
+
diff --git a/services/audiopolicy/engine/config/Android.mk b/services/audiopolicy/engine/config/Android.mk
new file mode 100644
index 0000000..fe7d961
--- /dev/null
+++ b/services/audiopolicy/engine/config/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH := $(call my-dir)
+
+##################################################################
+# Component build
+##################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_EXPORT_C_INCLUDE_DIRS) \
+ external/libxml2/include \
+ external/icu/icu4c/source/common
+
+LOCAL_SRC_FILES := \
+ src/EngineConfig.cpp
+
+LOCAL_CFLAGS += -Wall -Werror -Wextra
+
+LOCAL_SHARED_LIBRARIES := \
+ libmedia_helper \
+ libandroidicu \
+ libxml2 \
+ libutils \
+ liblog
+
+LOCAL_STATIC_LIBRARIES := \
+ libaudiopolicycomponents
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE := libaudiopolicyengineconfig
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_HEADER_LIBRARIES := \
+ libaudio_system_headers \
+ libaudiopolicycommon
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
new file mode 100644
index 0000000..e18f687
--- /dev/null
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 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 <system/audio.h>
+
+#include <string>
+#include <vector>
+#include <utils/Errors.h>
+
+struct _xmlNode;
+struct _xmlDoc;
+
+namespace android {
+namespace engineConfig {
+
+/** Default path of audio policy usages configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
+
+using AttributesVector = std::vector<audio_attributes_t>;
+using StreamVector = std::vector<audio_stream_type_t>;
+
+struct AttributesGroup {
+ std::string name;
+ audio_stream_type_t stream;
+ AttributesVector attributesVect;
+};
+
+using AttributesGroups = std::vector<AttributesGroup>;
+
+struct ProductStrategy {
+ std::string name;
+ AttributesGroups attributesGroups;
+};
+
+using ProductStrategies = std::vector<ProductStrategy>;
+
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
+struct CriterionType
+{
+ std::string name;
+ bool isInclusive;
+ ValuePairs valuePairs;
+};
+
+using CriterionTypes = std::vector<CriterionType>;
+
+struct Criterion
+{
+ std::string name;
+ std::string typeName;
+ std::string defaultLiteralValue;
+};
+
+using Criteria = std::vector<Criterion>;
+
+struct Config {
+ float version;
+ ProductStrategies productStrategies;
+ Criteria criteria;
+ CriterionTypes criterionTypes;
+};
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+ /** Parsed config, nullptr if the xml lib could not load the file */
+ std::unique_ptr<Config> parsedConfig;
+ size_t nbSkippedElement; //< Number of skipped invalid product strategies
+};
+
+/** Parses the provided audio policy usage configuration.
+ * @return audio policy usage @see Config
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
new file mode 100644
index 0000000..3aa38cf
--- /dev/null
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2018 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/Config"
+//#define LOG_NDEBUG 0
+
+#include "EngineConfig.h"
+#include <policy.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/Log.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <istream>
+
+#include <cstdint>
+#include <string>
+
+
+namespace android {
+
+using utilities::convertTo;
+
+namespace engineConfig {
+
+static constexpr const char *gVersionAttribute = "version";
+static const char *const gReferenceElementName = "reference";
+static const char *const gReferenceAttributeName = "name";
+
+template<typename E, typename C>
+struct BaseSerializerTraits {
+ typedef E Element;
+ typedef C Collection;
+ typedef void* PtrSerializingCtx;
+};
+
+struct AttributesGroupTraits : public BaseSerializerTraits<AttributesGroup, AttributesGroups> {
+ static constexpr const char *tag = "AttributesGroup";
+ static constexpr const char *collectionTag = "AttributesGroups";
+
+ struct Attributes {
+ static constexpr const char *name = "name";
+ static constexpr const char *streamType = "streamType";
+ };
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+
+struct ProductStrategyTraits : public BaseSerializerTraits<ProductStrategy, ProductStrategies> {
+ static constexpr const char *tag = "ProductStrategy";
+ static constexpr const char *collectionTag = "ProductStrategies";
+
+ struct Attributes {
+ static constexpr const char *name = "name";
+ };
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root, Collection &ps);
+};
+struct ValueTraits : public BaseSerializerTraits<ValuePair, ValuePairs> {
+ static constexpr const char *tag = "value";
+ static constexpr const char *collectionTag = "values";
+
+ struct Attributes {
+ static constexpr const char *literal = "literal";
+ static constexpr const char *numerical = "numerical";
+ };
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+struct CriterionTypeTraits : public BaseSerializerTraits<CriterionType, CriterionTypes> {
+ static constexpr const char *tag = "criterion_type";
+ static constexpr const char *collectionTag = "criterion_types";
+
+ struct Attributes {
+ static constexpr const char *name = "name";
+ static constexpr const char *type = "type";
+ };
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+struct CriterionTraits : public BaseSerializerTraits<Criterion, Criteria> {
+ static constexpr const char *tag = "criterion";
+ static constexpr const char *collectionTag = "criteria";
+
+ struct Attributes {
+ static constexpr const char *name = "name";
+ static constexpr const char *type = "type";
+ static constexpr const char *defaultVal = "default";
+ };
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+
+using xmlCharUnique = std::unique_ptr<xmlChar, decltype(xmlFree)>;
+
+std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
+{
+ xmlCharUnique charPtr(xmlGetProp(cur, reinterpret_cast<const xmlChar *>(attribute)), xmlFree);
+ if (charPtr == NULL) {
+ return "";
+ }
+ std::string value(reinterpret_cast<const char*>(charPtr.get()));
+ return value;
+}
+
+static void getReference(const _xmlNode *root, const _xmlNode *&refNode, const std::string &refName,
+ const char *collectionTag)
+{
+ for (root = root->xmlChildrenNode; root != NULL; root = root->next) {
+ if (!xmlStrcmp(root->name, (const xmlChar *)collectionTag)) {
+ for (xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)gReferenceElementName))) {
+ std::string name = getXmlAttribute(cur, gReferenceAttributeName);
+ if (refName == name) {
+ refNode = cur;
+ return;
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+template <class Trait>
+static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
+ typename Trait::Collection &collection,
+ size_t &nbSkippedElement)
+{
+ for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+ if (xmlStrcmp(cur->name, (const xmlChar *)Trait::collectionTag) &&
+ xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+ continue;
+ }
+ const xmlNode *child = cur;
+ if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
+ child = child->xmlChildrenNode;
+ }
+ for (; child != NULL; child = child->next) {
+ if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
+ status_t status = Trait::deserialize(doc, child, collection);
+ if (status != NO_ERROR) {
+ nbSkippedElement += 1;
+ }
+ }
+ }
+ if (!xmlStrcmp(cur->name, (const xmlChar *)Trait::tag)) {
+ return NO_ERROR;
+ }
+ }
+ return NO_ERROR;
+}
+
+static constexpr const char *attributesAttributeRef = "attributesRef"; /**< for factorization. */
+
+static status_t parseAttributes(const _xmlNode *cur, audio_attributes_t &attributes)
+{
+ for (; cur != NULL; cur = cur->next) {
+ if (!xmlStrcmp(cur->name, (const xmlChar *)("ContentType"))) {
+ std::string contentTypeXml = getXmlAttribute(cur, "value");
+ audio_content_type_t contentType;
+ if (not AudioContentTypeConverter::fromString(contentTypeXml.c_str(), contentType)) {
+ ALOGE("Invalid content type %s", contentTypeXml.c_str());
+ return BAD_VALUE;
+ }
+ attributes.content_type = contentType;
+ ALOGV("%s content type %s", __FUNCTION__, contentTypeXml.c_str());
+ }
+ if (!xmlStrcmp(cur->name, (const xmlChar *)("Usage"))) {
+ std::string usageXml = getXmlAttribute(cur, "value");
+ audio_usage_t usage;
+ if (not UsageTypeConverter::fromString(usageXml.c_str(), usage)) {
+ ALOGE("Invalid usage %s", usageXml.c_str());
+ return BAD_VALUE;
+ }
+ attributes.usage = usage;
+ ALOGV("%s usage %s", __FUNCTION__, usageXml.c_str());
+ }
+ if (!xmlStrcmp(cur->name, (const xmlChar *)("Flags"))) {
+ std::string flags = getXmlAttribute(cur, "value");
+
+ ALOGV("%s flags %s", __FUNCTION__, flags.c_str());
+ attributes.flags = AudioFlagConverter::maskFromString(flags, " ");
+ }
+ if (!xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+ std::string bundleKey = getXmlAttribute(cur, "key");
+ std::string bundleValue = getXmlAttribute(cur, "value");
+
+ ALOGV("%s Bundle %s %s", __FUNCTION__, bundleKey.c_str(), bundleValue.c_str());
+
+ std::string tags(bundleKey + "=" + bundleValue);
+ std::strncpy(attributes.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
+ }
+ }
+ return NO_ERROR;
+}
+
+static status_t deserializeAttributes(_xmlDoc *doc, const _xmlNode *cur,
+ audio_attributes_t &attributes) {
+ // Retrieve content type, usage, flags, and bundle from xml
+ for (; cur != NULL; cur = cur->next) {
+ if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+ const xmlNode *attrNode = cur;
+ std::string attrRef = getXmlAttribute(cur, attributesAttributeRef);
+ if (!attrRef.empty()) {
+ getReference(xmlDocGetRootElement(doc), attrNode, attrRef, attributesAttributeRef);
+ if (attrNode == NULL) {
+ ALOGE("%s: No reference found for %s", __FUNCTION__, attrRef.c_str());
+ return BAD_VALUE;
+ }
+ return deserializeAttributes(doc, attrNode->xmlChildrenNode, attributes);
+ }
+ return parseAttributes(attrNode->xmlChildrenNode, attributes);
+ }
+ if (not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+ return parseAttributes(cur, attributes);
+ }
+ }
+ return BAD_VALUE;
+}
+
+static status_t deserializeAttributesCollection(_xmlDoc *doc, const _xmlNode *cur,
+ AttributesVector &collection)
+{
+ status_t ret = BAD_VALUE;
+ // Either we do provide only one attributes or a collection of supported attributes
+ for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+ if (not xmlStrcmp(cur->name, (const xmlChar *)("Attributes")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("ContentType")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Usage")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Flags")) ||
+ not xmlStrcmp(cur->name, (const xmlChar *)("Bundle"))) {
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ ret = deserializeAttributes(doc, cur, attributes);
+ if (ret == NO_ERROR) {
+ collection.push_back(attributes);
+ // We are done if the "Attributes" balise is omitted, only one Attributes is allowed
+ if (xmlStrcmp(cur->name, (const xmlChar *)("Attributes"))) {
+ return ret;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+status_t AttributesGroupTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+ Collection &attributesGroup)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGV("AttributesGroupTraits No attribute %s found", Attributes::name);
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+ audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
+ std::string streamTypeXml = getXmlAttribute(child, Attributes::streamType);
+ if (streamTypeXml.empty()) {
+ ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::streamType);
+ } else {
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::streamType, streamTypeXml.c_str());
+ if (not StreamTypeConverter::fromString(streamTypeXml.c_str(), streamType)) {
+ ALOGE("Invalid stream type %s", streamTypeXml.c_str());
+ return BAD_VALUE;
+ }
+ }
+ AttributesVector attributesVect;
+ deserializeAttributesCollection(doc, child, attributesVect);
+
+ attributesGroup.push_back({name, streamType, attributesVect});
+ return NO_ERROR;
+}
+
+status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
+{
+ std::string literal = getXmlAttribute(child, Attributes::literal);
+ if (literal.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+ return BAD_VALUE;
+ }
+ uint32_t numerical = 0;
+ std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
+ if (numericalTag.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+ return BAD_VALUE;
+ }
+ if (!convertTo(numericalTag, numerical)) {
+ ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
+ return BAD_VALUE;
+ }
+ values.push_back({numerical, literal});
+ return NO_ERROR;
+}
+
+status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+ Collection &criterionTypes)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
+
+ std::string type = getXmlAttribute(child, Attributes::type);
+ if (type.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
+ bool isInclusive(type == "inclusive");
+
+ ValuePairs pairs;
+ size_t nbSkippedElements = 0;
+ deserializeCollection<ValueTraits>(doc, child, pairs, nbSkippedElements);
+ criterionTypes.push_back({name, isInclusive, pairs});
+ return NO_ERROR;
+}
+
+status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child,
+ Collection &criteria)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+ std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
+ if (defaultValue.empty()) {
+ // Not mandatory to provide a default value for a criterion, even it is recommanded...
+ ALOGV("%s: No attribute %s found (but recommanded)", __FUNCTION__, Attributes::defaultVal);
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
+
+ std::string typeName = getXmlAttribute(child, Attributes::type);
+ if (typeName.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
+
+ criteria.push_back({name, typeName, defaultValue});
+ return NO_ERROR;
+}
+
+status_t ProductStrategyTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+ Collection &strategies)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGE("ProductStrategyTraits No attribute %s found", Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+ size_t skipped = 0;
+ AttributesGroups attrGroups;
+ deserializeCollection<AttributesGroupTraits>(doc, child, attrGroups, skipped);
+
+ strategies.push_back({name, attrGroups});
+ return NO_ERROR;
+}
+
+ParsingResult parse(const char* path) {
+ xmlDocPtr doc;
+ doc = xmlParseFile(path);
+ if (doc == NULL) {
+ ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
+ return {nullptr, 0};
+ }
+ xmlNodePtr cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
+ xmlFreeDoc(doc);
+ return {nullptr, 0};
+ }
+ if (xmlXIncludeProcess(doc) < 0) {
+ ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
+ return {nullptr, 0};
+ }
+ std::string version = getXmlAttribute(cur, gVersionAttribute);
+ if (version.empty()) {
+ ALOGE("%s: No version found", __func__);
+ return {nullptr, 0};
+ }
+ size_t nbSkippedElements = 0;
+ auto config = std::make_unique<Config>();
+ config->version = std::stof(version);
+ deserializeCollection<ProductStrategyTraits>(
+ doc, cur, config->productStrategies, nbSkippedElements);
+ deserializeCollection<CriterionTraits>(
+ doc, cur, config->criteria, nbSkippedElements);
+ deserializeCollection<CriterionTypeTraits>(
+ doc, cur, config->criterionTypes, nbSkippedElements);
+ return {std::move(config), nbSkippedElements};
+}
+
+} // namespace engineConfig
+} // namespace android
diff --git a/services/audiopolicy/engine/interface/Android.bp b/services/audiopolicy/engine/interface/Android.bp
new file mode 100644
index 0000000..2ea42b6
--- /dev/null
+++ b/services/audiopolicy/engine/interface/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 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.
+
+cc_library_headers {
+ name: "libaudiopolicyengine_interface_headers",
+ host_supported: true,
+ export_include_dirs: ["."],
+}
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 04594f5..498cc3b 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -17,7 +17,8 @@
#pragma once
#include <AudioPolicyManagerObserver.h>
-#include <RoutingStrategy.h>
+#include <media/AudioProductStrategy.h>
+#include <policy.h>
#include <Volume.h>
#include <HwModule.h>
#include <DeviceDescriptor.h>
@@ -28,6 +29,10 @@
namespace android {
+using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
+using StrategyVector = std::vector<product_strategy_t>;
+
+
/**
* This interface is dedicated to the policy manager that a Policy Engine shall implement.
*/
@@ -50,42 +55,6 @@
virtual void setObserver(AudioPolicyManagerObserver *observer) = 0;
/**
- * Get the input device selected for a given input source.
- *
- * @param[in] inputSource to get the selected input device associated to
- *
- * @return selected input device for the given input source, may be none if error.
- */
- virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const = 0;
-
- /**
- * Get the output device associated to a given strategy.
- *
- * @param[in] stream type for which the selected ouput device is requested.
- *
- * @return selected ouput device for the given strategy, may be none if error.
- */
- virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const = 0;
-
- /**
- * Get the strategy selected for a given stream type.
- *
- * @param[in] stream: for which the selected strategy followed by is requested.
- *
- * @return strategy to be followed.
- */
- virtual routing_strategy getStrategyForStream(audio_stream_type_t stream) = 0;
-
- /**
- * Get the strategy selected for a given usage.
- *
- * @param[in] usage to get the selected strategy followed by.
- *
- * @return strategy to be followed.
- */
- virtual routing_strategy getStrategyForUsage(audio_usage_t usage) = 0;
-
- /**
* Set the Telephony Mode.
*
* @param[in] mode: Android Phone state (normal, ringtone, csv, in communication)
@@ -133,6 +102,140 @@
virtual status_t setDeviceConnectionState(const android::sp<android::DeviceDescriptor> devDesc,
audio_policy_dev_state_t state) = 0;
+ /**
+ * Get the strategy selected for a given audio attributes.
+ *
+ * @param[in] audio attributes to get the selected @product_strategy_t followed by.
+ *
+ * @return @product_strategy_t to be followed.
+ */
+ virtual product_strategy_t getProductStrategyForAttributes(
+ const audio_attributes_t &attr) const = 0;
+
+ /**
+ * @brief getOutputDevicesForAttributes retrieves the devices to be used for given
+ * audio attributes.
+ * @param attributes of the output requesting Device(s) selection
+ * @param preferedDevice valid reference if a prefered device is requested, nullptr otherwise.
+ * @param fromCache if true, the device is returned from internal cache,
+ * otherwise it is determined by current state (device connected,phone state,
+ * force use, a2dp output...)
+ * @return vector of selected device descriptors.
+ * Appropriate device for streams handled by the specified audio attributes according
+ * to current phone state, forced states, connected devices...
+ * if fromCache is true, the device is returned from internal cache,
+ * otherwise it is determined by current state (device connected,phone state, force use,
+ * a2dp output...)
+ * This allows to:
+ * 1 speed up process when the state is stable (when starting or stopping an output)
+ * 2 access to either current device selection (fromCache == true) or
+ * "future" device selection (fromCache == false) when called from a context
+ * where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+ * before manager updates its outputs.
+ */
+ virtual DeviceVector getOutputDevicesForAttributes(
+ const audio_attributes_t &attributes,
+ const sp<DeviceDescriptor> &preferedDevice = nullptr,
+ bool fromCache = false) const = 0;
+
+ /**
+ * @brief getOutputDevicesForStream Legacy function retrieving devices from a stream type.
+ * @param stream type of the output requesting Device(s) selection
+ * @param fromCache if true, the device is returned from internal cache,
+ * otherwise it is determined by current state (device connected,phone state,
+ * force use, a2dp output...)
+ * @return appropriate device for streams handled by the specified audio attributes according
+ * to current phone state, forced states, connected devices...
+ * if fromCache is true, the device is returned from internal cache,
+ * otherwise it is determined by current state (device connected,phone state, force use,
+ * a2dp output...)
+ * This allows to:
+ * 1 speed up process when the state is stable (when starting or stopping an output)
+ * 2 access to either current device selection (fromCache == true) or
+ * "future" device selection (fromCache == false) when called from a context
+ * where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+ * before manager updates its outputs.
+ */
+ virtual DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+ bool fromCache = false) const = 0;
+
+ /**
+ * Get the input device selected for given audio attributes.
+ *
+ * @param[in] attr audio attributes to consider
+ * @param[out] mix to be used if a mix has been installed for the given audio attributes.
+ * @return selected input device for the audio attributes, may be null if error.
+ */
+ virtual sp<DeviceDescriptor> getInputDeviceForAttributes(
+ const audio_attributes_t &attr, AudioMix **mix = nullptr) const = 0;
+
+ /**
+ * Get the legacy stream type for a given audio attributes.
+ *
+ * @param[in] audio attributes to get the associated audio_stream_type_t.
+ *
+ * @return audio_stream_type_t associated to the attributes.
+ */
+ virtual audio_stream_type_t getStreamTypeForAttributes(
+ const audio_attributes_t &attr) const = 0;
+
+ /**
+ * @brief getAttributesForStream get the audio attributes from legacy stream type
+ * @param stream to consider
+ * @return audio attributes matching the legacy stream type
+ */
+ virtual audio_attributes_t getAttributesForStreamType(audio_stream_type_t stream) const = 0;
+
+ /**
+ * @brief getStreamTypesForProductStrategy retrieves the list of legacy stream type following
+ * the given product strategy
+ * @param ps product strategy to consider
+ * @return associated legacy Stream Types vector of the given product strategy
+ */
+ virtual StreamTypeVector getStreamTypesForProductStrategy(product_strategy_t ps) const = 0;
+
+ /**
+ * @brief getAllAttributesForProductStrategy retrieves all the attributes following the given
+ * product strategy. Any attributes that "matches" with this one will follow the product
+ * strategy.
+ * "matching" means the usage shall match if reference attributes has a defined usage, AND
+ * content type shall match if reference attributes has a defined content type AND
+ * flags shall match if reference attributes has defined flags AND
+ * tags shall match if reference attributes has defined tags.
+ * @param ps product strategy to consider
+ * @return vector of product strategy ids, empty if unknown strategy.
+ */
+ virtual AttributesVector getAllAttributesForProductStrategy(product_strategy_t ps) const = 0;
+
+ /**
+ * @brief getOrderedAudioProductStrategies
+ * @return priority ordered product strategies to help the AudioPolicyManager evaluating the
+ * device selection per output according to the prioritized strategies.
+ */
+ virtual StrategyVector getOrderedProductStrategies() const = 0;
+
+ /**
+ * @brief updateDeviceSelectionCache. Device selection for AudioAttribute / Streams is cached
+ * in the engine in order to speed up process when the audio system is stable.
+ * When a device is connected, the android mode is changed, engine is notified and can update
+ * the cache.
+ * When starting / stopping an output with a stream that can affect notification, the engine
+ * needs to update the cache upon this function call.
+ */
+ virtual void updateDeviceSelectionCache() = 0;
+
+ /**
+ * @brief listAudioProductStrategies. Introspection API to retrieve a collection of
+ * AudioProductStrategyVector that allows to build AudioAttributes according to a
+ * product_strategy which is just an index. It has also a human readable name to help the
+ * Car/Oem/AudioManager identiying the use case.
+ * @param strategies collection.
+ * @return OK if the list has been retrieved, error code otherwise
+ */
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) const = 0;
+
+ virtual void dump(String8 *dst) const = 0;
+
protected:
virtual ~AudioPolicyManagerInterface() {}
};
diff --git a/services/audiopolicy/engineconfigurable/Android.mk b/services/audiopolicy/engineconfigurable/Android.mk
index c2105e9..bbd9688 100644
--- a/services/audiopolicy/engineconfigurable/Android.mk
+++ b/services/audiopolicy/engineconfigurable/Android.mk
@@ -11,14 +11,13 @@
src/Engine.cpp \
src/EngineInstance.cpp \
src/Stream.cpp \
- src/Strategy.cpp \
- src/Usage.cpp \
src/InputSource.cpp \
+ ../engine/common/src/ProductStrategy.cpp \
+ ../engine/common/src/EngineBase.cpp
audio_policy_engine_includes_common := \
frameworks/av/services/audiopolicy/engineconfigurable/include \
- frameworks/av/services/audiopolicy/engineconfigurable/interface \
- frameworks/av/services/audiopolicy/engine/interface
+ frameworks/av/services/audiopolicy/engineconfigurable/interface
LOCAL_CFLAGS += \
-Wall \
@@ -32,8 +31,12 @@
$(audio_policy_engine_includes_common) \
$(TARGET_OUT_HEADERS)/hw \
$(call include-path-for, frameworks-av) \
- $(call include-path-for, audio-utils) \
- frameworks/av/services/audiopolicy/common/include
+ $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_common_headers \
+ libaudiopolicyengine_interface_headers
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
@@ -45,13 +48,14 @@
libaudiopolicycomponents
LOCAL_SHARED_LIBRARIES := \
+ libaudiopolicyengineconfig \
liblog \
- libcutils \
libutils \
liblog \
libaudioutils \
libparameter \
libmedia_helper \
+ libaudiopolicy \
libxml2
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/engineconfigurable/config/Android.mk b/services/audiopolicy/engineconfigurable/config/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
new file mode 100644
index 0000000..95a2ecc
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -0,0 +1,99 @@
+LOCAL_PATH := $(call my-dir)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+ audio_policy_engine_product_strategies_phone.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+##################################################################
+# AUTOMOTIVE CONFIGURATION TOP FILE
+##################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_automotive.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+ audio_policy_engine_product_strategies_automotive.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml
+
+include $(BUILD_PREBUILT)
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_automotive.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criteria.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := common/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_criterion_types.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+
+ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
+AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+CRITERION_TYPES_FILE := $(LOCAL_PATH)/common/$(LOCAL_MODULE).in
+
+include $(PROVISION_CRITERION_TYPES)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
similarity index 67%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
rename to services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
index 5d9193b..e2fb02b 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_configuration.xml
@@ -12,14 +12,13 @@
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.
--->
-<!--
- These are the minimum required criteria to be used by Audio HAL to ensure a basic
- user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+ -->
- <xi:include href="policy_criterion_types.xml"/>
- <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <xi:include href="audio_policy_engine_product_strategies.xml"/>
+ <xi:include href="audio_policy_engine_criterion_types.xml"/>
+ <xi:include href="audio_policy_engine_criteria.xml"/>
</configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..543a2f0
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,161 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<ProductStrategies>
+ <!-- OEM Usages -->
+ <!-- product_strategy will be defined according this order
+ product_strategy is oem_traffic_anouncement if all the conditions are satisfied for
+ AudioAttributes aa
+
+ int type = 0;
+ if (bundle != null) {
+ type = bundle.getInt(KEY_OEM_TYPE, 0);
+ }
+ if(
+ ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+ ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+ ( type == 1 ) )
+ -->
+
+ <ProductStrategy name="oem_traffic_anouncement">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <!-- traffic_annoucement = 1 -->
+ <Bundle key="oem" value="1"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="oem_strategy_1">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <Bundle key="oem" value="2"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="oem_strategy_2">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <Bundle key="oem" value="3"/>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Car Usages -->
+ <!-- Keep those lines only for car -->
+ <!-- Check car conditions if any OEM conditions matched -->
+ <!-- As defined by CarAudioAttributesUtil.java -->
+ <!-- product_strategy will be defined according this order
+ product_strategy is radio if all the conditions are satisfied for AudioAttributes aa
+
+ int type = CAR_AUDIO_TYPE_DEFAULT;
+ if (bundle != null) {
+ type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
+ }
+ if(
+ ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+ ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+ ( type == CAR_AUDIO_TYPE_RADIO ) )
+ -->
+ <ProductStrategy name="radio">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <Usage value="AUDIO_USAGE_MEDIA"/>
+ <Bundle key="car_audio_type" value="3"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="ext_audio_source">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <Usage value="AUDIO_USAGE_MEDIA"/>
+ <Bundle key="car_audio_type" value="7"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="voice_command">
+ <AttributesGroup>
+ <Attributes>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <!-- CAR_AUDIO_TYPE_VOICE_COMMAND = 1 -->
+ <Bundle key="car_audio_type" value="1"/>
+ </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="safety_alert">
+ <AttributesGroup>
+ <ContentType value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ <Usage value="AUDIO_USAGE_NOTIFICATION"/>
+ <!-- CAR_AUDIO_TYPE_SAFETY_ALERT = 2 -->
+ <Bundle key="car_audio_type" value="2"/>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- To be checked
+ CAR_AUDIO_TYPE_CARSERVICE_BOTTOM
+ CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY
+ CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE
+ -->
+
+ <!-- Generic Usages -->
+ <ProductStrategy name="music">
+ <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+ <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+ <!-- Default product strategy has empty attributes -->
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="nav_guidance">
+ <AttributesGroup>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="voice_call">
+ <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+ <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="alarm">
+ <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+ <Usage value="AUDIO_USAGE_ALARM"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="ring">
+ <AttributesGroup streamType="AUDIO_STREAM_RING">
+ <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="notification">
+ <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="system">
+ <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+ <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+ </AttributesGroup>
+ </ProductStrategy>
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
rename to services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criteria.xml
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
similarity index 100%
rename from services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
rename to services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types.xml.in
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
similarity index 67%
copy from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
copy to services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
index 5d9193b..ab61d8a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_configuration.xml
@@ -12,14 +12,11 @@
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.
--->
-<!--
- These are the minimum required criteria to be used by Audio HAL to ensure a basic
- user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+ -->
- <xi:include href="policy_criterion_types.xml"/>
- <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <xi:include href="audio_policy_engine_product_strategies.xml"/>
</configuration>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..f72e379
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 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.
+ -->
+
+<ProductStrategies>
+
+ <!-- "hidden strategies" like TTS, enforced audible:
+ Shall we expose them here or keep it hard coded -->
+
+ <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+ countries (e.g. camera in Japan)
+ This strategy will only have higher priority than phone if force for system is set to
+ enforced. -->
+
+ <ProductStrategy name="STRATEGY_PHONE">
+ <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO">
+ <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_SONIFICATION">
+ <AttributesGroup streamType="AUDIO_STREAM_RING">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+ <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+ <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE">
+ <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+ <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY">
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+ <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_MEDIA">
+ <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+ <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+ <Attributes></Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_DTMF">
+ <AttributesGroup streamType="AUDIO_STREAM_DTMF">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Used to identify the volume of audio streams exclusively transmitted through the speaker
+ (TTS) of the device -->
+ <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+ <AttributesGroup streamType="AUDIO_STREAM_TTS">
+ <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Routing Strategy rerouting may be removed as following media??? -->
+ <ProductStrategy name="STRATEGY_REROUTING">
+ <AttributesGroup streamType="AUDIO_STREAM_REROUTING">
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Default product strategy has empty attributes -->
+ <ProductStrategy name="STRATEGY_PATCH">
+ <AttributesGroup streamType="AUDIO_STREAM_PATCH">
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
index 2e29a9b..1fc2264 100644
--- a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
+++ b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
@@ -16,10 +16,11 @@
#pragma once
-#include <RoutingStrategy.h>
+#include <policy.h>
#include <EngineDefinition.h>
#include <Volume.h>
#include <system/audio.h>
+#include <media/AudioCommonTypes.h>
#include <utils/Errors.h>
#include <string>
#include <vector>
@@ -36,19 +37,6 @@
{
public:
/**
- * Add a strategy to the engine
- *
- * @param[in] name of the strategy to add
- * @param[in] identifier: the numerical value associated to this member. It MUST match either
- * system/audio.h or system/audio_policy.h enumration value in order to link the
- * parameter controled by the PFW and the policy manager component.
- *
- * @return NO_ERROR if the strategy has been added successfully, error code otherwise.
- *
- */
- virtual android::status_t addStrategy(const std::string &name, routing_strategy id) = 0;
-
- /**
* Add a streams to the engine.
*
* @param[in] name of the stream to add
@@ -62,19 +50,6 @@
virtual android::status_t addStream(const std::string &name, audio_stream_type_t id) = 0;
/**
- * Add a usage to the engine
- *
- * @param[in] name of the usage to add
- * @param[in] identifier: the numerical value associated to this member. It MUST match either
- * system/audio.h or system/audio_policy.h enumration value in order to link the
- * parameter controled by the PFW and the policy manager component.
- *
- * @return NO_ERROR if the usage has been added successfully, error code otherwise.
- *
- */
- virtual android::status_t addUsage(const std::string &name, audio_usage_t id) = 0;
-
- /**
* Add an input source to the engine
*
* @param[in] name of the input source to add
@@ -88,26 +63,6 @@
virtual android::status_t addInputSource(const std::string &name, audio_source_t id) = 0;
/**
- * Set the device to be used by a strategy.
- *
- * @param[in] strategy: name of the strategy for which the device to use has to be set
- * @param[in] devices; mask of devices to be used for the given strategy.
- *
- * @return true if the devices were set correclty for this strategy, false otherwise.
- */
- virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices) = 0;
-
- /**
- * Set the strategy to be followed by a stream.
- *
- * @param[in] stream: name of the stream for which the strategy to use has to be set
- * @param[in] strategy to follow for the given stream.
- *
- * @return true if the strategy were set correclty for this stream, false otherwise.
- */
- virtual bool setStrategyForStream(const audio_stream_type_t &stream, routing_strategy strategy) = 0;
-
- /**
* Set the strategy to be followed by a stream.
*
* @param[in] stream: name of the stream for which the strategy to use has to be set
@@ -119,16 +74,6 @@
const audio_stream_type_t &volumeProfile) = 0;
/**
- * Set the strategy to be followed by a usage.
- *
- * @param[in] usage: name of the usage for which the strategy to use has to be set
- * @param[in] strategy to follow for the given usage.
- *
- * @return true if the strategy were set correclty for this usage, false otherwise.
- */
- virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy) = 0;
-
- /**
* Set the input device to be used by an input source.
*
* @param[in] inputSource: name of the input source for which the device to use has to be set
@@ -139,6 +84,22 @@
virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
audio_devices_t device) = 0;
+ virtual void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+ const std::string &address) = 0;
+
+ /**
+ * Set the device to be used by a product strategy.
+ *
+ * @param[in] strategy: name of the product strategy for which the device to use has to be set
+ * @param[in] devices; mask of devices to be used for the given strategy.
+ *
+ * @return true if the devices were set correclty for this strategy, false otherwise.
+ */
+ virtual bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+ audio_devices_t devices) = 0;
+
+ virtual product_strategy_t getProductStrategyByName(const std::string &address) = 0;
+
protected:
virtual ~AudioPolicyPluginInterface() {}
};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index 7631976..060830b 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -9,7 +9,7 @@
LOCAL_PATH := $(call my-dir)
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable no-output_configurable no-input_configurable))
PFW_CORE := external/parameter-framework
#@TODO: upstream new domain generator
@@ -20,116 +20,79 @@
TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+endif
+
##################################################################
# CONFIGURATION FILES
##################################################################
######### Policy PFW top level file #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
include $(CLEAR_VARS)
LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework
LOCAL_SRC_FILES := $(LOCAL_MODULE).in
+# external/parameter-framework prevents from using debug interface
AUDIO_PATTERN = @TUNING_ALLOWED@
-ifeq ($(TARGET_BUILD_VARIANT),user)
+#ifeq ($(TARGET_BUILD_VARIANT),user)
AUDIO_VALUE = false
-else
-AUDIO_VALUE = true
-endif
+#else
+#AUDIO_VALUE = true
+#endif
-LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
+LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
-
-########## Policy PFW Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicyClass.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := \
- PolicySubsystem-CommonTypes.xml \
- libpolicy-subsystem
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
+########## Policy PFW Common Structures #########
include $(CLEAR_VARS)
LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
-######### Policy PFW Settings #########
include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE := PolicyClass.xml
+LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_REQUIRED_MODULES := \
- policy_criteria.xml \
- policy_criterion_types.xml \
- PolicySubsystem.xml \
- PolicyClass.xml \
- ParameterFrameworkConfigurationPolicy.xml
-
-ifeq ($(pfw_rebuild_settings),true)
-PFW_EDD_FILES := \
- $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
- $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
- $(LOCAL_PATH)/Settings/volumes.pfw
-
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- $(PFW_EDD_FILES)
-
-
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
-
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-include $(BUILD_PFW_SETTINGS)
-else
-# Use the existing file
-LOCAL_SRC_FILES := Settings/$(LOCAL_MODULE_STEM)
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
-endif # pfw_rebuild_settings
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 0)
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
+########## Policy PFW Example Structures #########
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.common
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem-CommonTypes.xml \
+ PolicySubsystem-Volume.xml \
+ libpolicy-subsystem \
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
######### Policy PFW Settings - No Output #########
-ifeq (0, 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-output
@@ -138,26 +101,24 @@
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
LOCAL_REQUIRED_MODULES := \
- policy_criteria.xml \
- policy_criterion_types.xml \
- PolicySubsystem.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml \
+ PolicySubsystem.xml.common \
PolicyClass.xml \
ParameterFrameworkConfigurationPolicy.xml
PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
PFW_EDD_FILES := \
$(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
$(LOCAL_PATH)/Settings/device_for_input_source.pfw \
$(LOCAL_PATH)/Settings/volumes.pfw
include $(BUILD_PFW_SETTINGS)
-endif # ifeq (0, 1)
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
######### Policy PFW Settings - No Input #########
-ifeq (0, 1)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-input
@@ -166,36 +127,26 @@
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
LOCAL_REQUIRED_MODULES := \
- policy_criteria.xml \
- policy_criterion_types.xml \
- PolicySubsystem.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml \
+ PolicySubsystem.xml.common \
PolicyClass.xml \
ParameterFrameworkConfigurationPolicy.xml
PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
PFW_EDD_FILES := \
- $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
- $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
- $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
$(LOCAL_PATH)/SettingsNoInput/device_for_input_source.pfw \
$(LOCAL_PATH)/Settings/volumes.pfw
include $(BUILD_PFW_SETTINGS)
-endif # ifeq (1, 0)
-
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
#######################################################################
# Recursive call sub-folder Android.mk
#######################################################################
include $(call all-makefiles-under,$(LOCAL_PATH))
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
new file mode 100644
index 0000000..ea4a58f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
@@ -0,0 +1,86 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+########## Policy PFW Structures #########
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.car
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+ ProductStrategies.xml.car \
+ PolicySubsystem-Volume.xml \
+ PolicySubsystem-CommonTypes.xml \
+ libpolicy-subsystem
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml.car
+LOCAL_MODULE_STEM := ProductStrategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.car
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+
+PFW_EDD_FILES := \
+ $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
+ $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+ $(LOCAL_PATH)/../Settings/volumes.pfw
+
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(PFW_EDD_FILES)
+
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem.xml.car \
+ PolicyClass.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml \
+ ParameterFrameworkConfigurationPolicy.xml
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
new file mode 100644
index 0000000..196d82c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
@@ -0,0 +1,717 @@
+supDomain: DeviceForProductStrategies
+ supDomain: OemTrafficAnouncement
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_traffic_anouncement/device_address = BUS08_OEM1
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ bus = 0
+
+ supDomain: OemStrategy1
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_strategy_1/device_address = BUS08_OEM1
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: OemStrategy2
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_strategy_2/device_address = BUS08_OEM1
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS08_OEM1
+
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: Radio
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/radio/device_address = BUS09_OEM2
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+ supDomain: ExtAudioSource
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/ext_audio_source/device_address = BUS09_OEM2
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS09_OEM2
+
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: VoiceCommand
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/voice_command/device_address = BUS02_VOICE_COMMAND
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS02_VOICE_COMMAND
+
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: SafetyAlert
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/safety_alert/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: Music
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/music/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+
+ supDomain: NavGuidance
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/nav_guidance/device_address = BUS01_NAV_GUIDANCE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: VoiceCall
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/voice_call/device_address = BUS04_CALL
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS04_CALL
+
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: Alarm
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/alarm/device_address = BUS05_ALARM
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS05_ALARM
+
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: Ring
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/ring/device_address = BUS03_CALL_RING
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS03_CALL_RING
+
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: Notification
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/notification/device_address = BUS06_NOTIFICATION
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS06_NOTIFICATION
+
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
+ supDomain: System
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ earpiece = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/system/device_address = BUS07_SYSTEM_SOUND
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS07_SYSTEM_SOUND
+
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ speaker = 0
+ bus = 1
+
+ conf: Speaker
+ AvailableOutputDevices Includes Speaker
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ speaker = 1
+ bus = 0
+
+ conf: Default
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ speaker = 0
+ bus = 0
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml
new file mode 100644
index 0000000..b55ce2c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+ Name="policy" Type="Policy">
+
+ <ComponentLibrary>
+ <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+ <!-- Common Types defintion -->
+ <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+ <xi:include href="ProductStrategies.xml"/>
+
+
+ <!--#################### GLOBAL COMPONENTS END ####################-->
+
+ <!--#################### STREAM BEGIN ####################-->
+
+ <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+ <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+ <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+ <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+ <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+ <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+ <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+ <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+ <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+ Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+ <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+ <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+ Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+ <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+ Description="For accessibility talk back prompts"/>
+ <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+ Description="For dynamic policy output mixes"/>
+ <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+ Description="For internal audio flinger tracks. Fixed volume"/>
+ </ComponentType>
+
+ <!--#################### STREAM END ####################-->
+
+ <!--#################### INPUT SOURCE BEGIN ####################-->
+
+ <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+ identifier mapping must match the value of the enum">
+ <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+ <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+ <Component Name="voice_uplink" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+ <Component Name="voice_downlink" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+ <Component Name="voice_call" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+ <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+ <Component Name="voice_recognition" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+ <Component Name="voice_communication" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+ <Component Name="remote_submix" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+ <Component Name="unprocessed" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+ <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+ <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+ </ComponentType>
+
+ <!--#################### INPUT SOURCE END ####################-->
+ </ComponentLibrary>
+
+ <InstanceDefinition>
+ <Component Name="streams" Type="Streams"/>
+ <Component Name="input_sources" Type="InputSources"/>
+ <Component Name="product_strategies" Type="ProductStrategies"/>
+ </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
new file mode 100644
index 0000000..53bba03
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+ <ComponentType Name="ProductStrategies" Description="">
+ <Component Name="oem_traffic_anouncement" Type="ProductStrategy"/>
+ <Component Name="oem_strategy_1" Type="ProductStrategy"/>
+ <Component Name="oem_strategy_2" Type="ProductStrategy"/>
+
+ <Component Name="radio" Type="ProductStrategy"/>
+ <Component Name="ext_audio_source" Type="ProductStrategy"/>
+ <Component Name="voice_command" Type="ProductStrategy"/>
+ <Component Name="safety_alert" Type="ProductStrategy"/>
+
+ <Component Name="music" Type="ProductStrategy"/>
+ <Component Name="nav_guidance" Type="ProductStrategy"/>
+ <Component Name="voice_call" Type="ProductStrategy"/>
+ <Component Name="alarm" Type="ProductStrategy"/>
+ <Component Name="ring" Type="ProductStrategy"/>
+ <Component Name="notification" Type="ProductStrategy"/>
+ <Component Name="system" Type="ProductStrategy"/>
+ </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
new file mode 100644
index 0000000..e9d67e9
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
@@ -0,0 +1,94 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
+
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+########## Policy PFW Structures #########
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml.phone
+LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem-CommonTypes.xml \
+ ProductStrategies.xml.phone \
+ PolicySubsystem-Volume.xml \
+ libpolicy-subsystem \
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml.phone
+LOCAL_MODULE_STEM := ProductStrategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.phone
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+
+PFW_EDD_FILES := \
+ $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+ $(LOCAL_PATH)/../Settings/volumes.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_media.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_accessibility.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_dtmf.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_enforced_audible.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_phone.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification_respectful.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_transmitted_through_speaker.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_unknown.pfw
+
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(PFW_EDD_FILES)
+
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem.xml.phone \
+ PolicyClass.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml \
+ ParameterFrameworkConfigurationPolicy.xml
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
similarity index 87%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
index 7c87c80..53e93de 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_accessibility.pfw
@@ -1,4 +1,4 @@
-supDomain: DeviceForStrategy
+supDomain: DeviceForProductStrategy
supDomain: Accessibility
#
@@ -9,7 +9,7 @@
#
domain: UnreachableDevices
conf: Calibration
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
hdmi_arc = 0
spdif = 0
aux_line = 0
@@ -18,6 +18,8 @@
telephony_tx = 0
ip = 0
bus = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
domain: Device
@@ -30,7 +32,7 @@
AvailableOutputDevices Includes RemoteSubmix
AvailableOutputDevicesAddresses Includes 0
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 1
earpiece = 0
bluetooth_a2dp = 0
@@ -58,7 +60,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dp
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 1
@@ -86,7 +88,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dpHeadphones
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -114,7 +116,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes BluetoothA2dpSpeaker
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -142,7 +144,7 @@
ForceUseForMedia Is ForceSpeaker
AvailableOutputDevices Includes Speaker
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -171,7 +173,7 @@
AvailableOutputDevices Includes BluetoothScoCarkit
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -200,7 +202,7 @@
AvailableOutputDevices Includes BluetoothScoHeadset
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -229,7 +231,7 @@
AvailableOutputDevices Includes BluetoothSco
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -266,7 +268,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes WiredHeadphone
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -302,7 +304,7 @@
#
AvailableOutputDevices Includes Line
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -339,7 +341,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes WiredHeadset
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -379,7 +381,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes UsbDevice
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -410,7 +412,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes UsbAccessory
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -440,7 +442,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes DgtlDockHeadset
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -470,7 +472,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes Hdmi
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -502,7 +504,7 @@
AvailableOutputDevices Includes AnlgDockHeadset
ForceUseForDock Is ForceAnalogDock
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -531,7 +533,7 @@
AvailableOutputDevices Includes Earpiece
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 1
bluetooth_a2dp = 0
@@ -553,7 +555,7 @@
conf: Speaker
AvailableOutputDevices Includes Speaker
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
@@ -573,7 +575,7 @@
hdmi = 0
conf: Default
- component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/accessibility/selected_output_devices/mask
remote_submix = 0
earpiece = 0
bluetooth_a2dp = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
index c830c42..b8426c6 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_dtmf.pfw
@@ -1,16 +1,17 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategies
supDomain: Dtmf
-
domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ conf: calibration
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
fm = 0
speaker_safe = 0
bluetooth_sco_carkit = 0
ip = 0
bus = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
+ /Policy/policy/product_strategies/dtmf/device_address =
domain: Device2
conf: RemoteSubmix
@@ -22,7 +23,7 @@
AvailableOutputDevices Includes RemoteSubmix
AvailableOutputDevicesAddresses Includes 0
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 1
earpiece = 0
wired_headset = 0
@@ -50,7 +51,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dp
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -78,7 +79,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dpHeadphones
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -106,7 +107,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dpSpeaker
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -135,7 +136,7 @@
ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
AvailableOutputDevices Includes Speaker
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -164,7 +165,7 @@
AvailableOutputDevices Includes BluetoothScoHeadset
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -193,7 +194,7 @@
AvailableOutputDevices Includes BluetoothSco
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -230,7 +231,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes WiredHeadphone
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -269,7 +270,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes Line
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -306,7 +307,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes WiredHeadset
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 1
@@ -346,7 +347,7 @@
ForceUseForCommunication Is ForceSpeaker
AvailableOutputDevices Includes UsbDevice
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -377,7 +378,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes UsbAccessory
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -407,7 +408,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes DgtlDockHeadset
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -437,7 +438,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes Hdmi
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -469,7 +470,7 @@
ForceUseForDock Is ForceAnalogDock
AvailableOutputDevices Includes AnlgDockHeadset
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -498,7 +499,7 @@
AvailableOutputDevices Includes Earpiece
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 1
wired_headset = 0
@@ -536,7 +537,7 @@
ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
AvailableOutputDevices Includes Speaker
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -556,7 +557,7 @@
speaker = 1
conf: Default
- component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/dtmf/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -586,10 +587,10 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes HdmiArc
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
conf: NotSelected
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
domain: Spdif
#
@@ -602,10 +603,10 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes Spdif
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 1
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 1
conf: NotSelected
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 0
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/spdif = 0
domain: AuxLine
#
@@ -618,7 +619,7 @@
TelephonyMode IsNot InCommunication
AvailableOutputDevices Includes AuxLine
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 1
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 1
conf: NotSelected
- /Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 0
+ /Policy/policy/product_strategies/dtmf/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
similarity index 83%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
index c641138..2daa9ac 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_enforced_audible.pfw
@@ -1,10 +1,10 @@
-supDomain: DeviceForStrategy
+supDomain: DeviceForProductStrategy
supDomain: EnforcedAudible
domain: UnreachableDevices
conf: Calibration
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
# no enforced_audible on remote submix (e.g. WFD)
hdmi_arc = 0
spdif = 0
@@ -13,6 +13,8 @@
ip = 0
bus = 0
fm = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
domain: Speaker
@@ -51,11 +53,11 @@
AvailableOutputDevices Excludes AnlgDockHeadset
ForceUseForDock IsNot ForceAnalogDock
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
speaker = 1
conf: NotSelected
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
speaker = 0
domain: Device2
@@ -63,7 +65,7 @@
AvailableOutputDevices Includes RemoteSubmix
AvailableOutputDevicesAddresses Includes 0
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 1
earpiece = 0
wired_headset = 0
@@ -86,7 +88,7 @@
AvailableOutputDevices Includes BluetoothA2dp
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -109,7 +111,7 @@
AvailableOutputDevices Includes BluetoothA2dpHeadphones
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -132,7 +134,7 @@
AvailableOutputDevices Includes BluetoothA2dpSpeaker
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -155,7 +157,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes WiredHeadphone
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -178,7 +180,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes Line
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -201,7 +203,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes WiredHeadset
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 1
@@ -224,7 +226,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes UsbAccessory
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -247,7 +249,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes UsbDevice
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -270,7 +272,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes DgtlDockHeadset
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -293,7 +295,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes Hdmi
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -317,7 +319,7 @@
ForceUseForDock Is ForceAnalogDock
AvailableOutputDevices Includes AnlgDockHeadset
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
@@ -337,7 +339,7 @@
line = 0
conf: NoDevice
- component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/enforced_audible/selected_output_devices/mask
remote_submix = 0
earpiece = 0
wired_headset = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
similarity index 77%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
index f8bab3d..d6d355c 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_media.pfw
@@ -1,10 +1,8 @@
-domainGroup: DeviceForStrategy
-
- domainGroup: Media
-
+supDomain: DeviceForProductStrategy
+ supDomain: Media
domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ conf: calibration
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
fm = 0
speaker_safe = 0
earpiece = 0
@@ -13,15 +11,18 @@
bluetooth_sco_carkit = 0
telephony_tx = 0
ip = 0
+ proxy = 0
+ usb_headset = 0
bus = 0
stub = 0
+ /Policy/policy/product_strategies/media/device_address =
domain: Device2
conf: RemoteSubmix
AvailableOutputDevices Includes RemoteSubmix
AvailableOutputDevicesAddresses Includes 0
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -41,7 +42,7 @@
ForceUseForCommunication IsNot ForceBtSco
AvailableOutputDevices Includes BluetoothA2dp
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -61,7 +62,7 @@
ForceUseForCommunication IsNot ForceBtSco
AvailableOutputDevices Includes BluetoothA2dpHeadphones
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -81,7 +82,7 @@
ForceUseForCommunication IsNot ForceBtSco
AvailableOutputDevices Includes BluetoothA2dpSpeaker
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -104,7 +105,7 @@
#
ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 1
hdmi = 0
dgtl_dock_headset = 0
@@ -122,7 +123,7 @@
conf: WiredHeadphone
AvailableOutputDevices Includes WiredHeadphone
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -140,7 +141,7 @@
conf: Line
AvailableOutputDevices Includes Line
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -158,7 +159,7 @@
conf: WiredHeadset
AvailableOutputDevices Includes WiredHeadset
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -176,7 +177,7 @@
conf: UsbAccessory
AvailableOutputDevices Includes UsbAccessory
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -194,7 +195,7 @@
conf: UsbDevice
AvailableOutputDevices Includes UsbDevice
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -212,7 +213,7 @@
conf: DgtlDockHeadset
AvailableOutputDevices Includes DgtlDockHeadset
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 1
@@ -230,7 +231,7 @@
conf: AuxDigital
AvailableOutputDevices Includes Hdmi
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 1
dgtl_dock_headset = 0
@@ -249,7 +250,7 @@
AvailableOutputDevices Includes AnlgDockHeadset
ForceUseForDock Is ForceAnalogDock
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -272,7 +273,7 @@
ForceUseForHdmiSystemAudio IsNot ForceHdmiSystemEnforced
ForceUseForCommunication IsNot ForceBtSco
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 1
hdmi = 0
dgtl_dock_headset = 0
@@ -288,7 +289,7 @@
line = 0
conf: Default
- component: /Policy/policy/strategies/media/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/media/selected_output_devices/mask
speaker = 0
hdmi = 0
dgtl_dock_headset = 0
@@ -311,10 +312,10 @@
conf: Selected
AvailableOutputDevices Includes HdmiArc
- /Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 1
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 1
conf: NotSelected
- /Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 0
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/hdmi_arc = 0
domain: Spdif
#
@@ -324,16 +325,16 @@
conf: Selected
AvailableOutputDevices Includes Spdif
- /Policy/policy/strategies/media/selected_output_devices/mask/spdif = 1
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 1
conf: NotSelected
- /Policy/policy/strategies/media/selected_output_devices/mask/spdif = 0
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/spdif = 0
domain: AuxLine
conf: Selected
AvailableOutputDevices Includes AuxLine
- /Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 1
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 1
conf: NotSelected
- /Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 0
+ /Policy/policy/product_strategies/media/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
index d371ad9..5693d4e 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_phone.pfw
@@ -1,10 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
supDomain: Phone
-
domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ conf: calibration
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
# no sonification on remote submix (e.g. WFD)
remote_submix = 0
hdmi_arc = 0
@@ -12,16 +10,18 @@
spdif = 0
fm = 0
speaker_safe = 0
- ip = 0
bus = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
+ /Policy/policy/product_strategies/phone/device_address =
domain: Device
conf: ScoCarkit
AvailableOutputDevices Includes BluetoothScoCarkit
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -44,7 +44,7 @@
AvailableOutputDevices Includes BluetoothScoHeadset
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -67,7 +67,7 @@
AvailableOutputDevices Includes BluetoothSco
ForceUseForCommunication Is ForceBtSco
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -97,7 +97,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
ForceUseForCommunication Is ForceNone
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -127,7 +127,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
ForceUseForCommunication Is ForceNone
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -157,7 +157,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
ForceUseForCommunication Is ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -184,7 +184,7 @@
AvailableOutputDevices Includes WiredHeadphone
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 1
@@ -211,7 +211,7 @@
AvailableOutputDevices Includes WiredHeadset
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 1
wired_headphone = 0
@@ -234,7 +234,7 @@
AvailableOutputDevices Includes Line
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -272,7 +272,7 @@
TelephonyMode IsNot InCall
TelephonyMode IsNot InCommunication
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -300,7 +300,7 @@
TelephonyMode IsNot InCommunication
TelephonyMode IsNot InCall
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -328,7 +328,7 @@
TelephonyMode IsNot InCall
TelephonyMode IsNot InCommunication
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -356,7 +356,7 @@
TelephonyMode IsNot InCall
TelephonyMode IsNot InCommunication
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -384,7 +384,7 @@
TelephonyMode IsNot InCall
TelephonyMode IsNot InCommunication
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -411,7 +411,7 @@
AvailableOutputDevices Includes Earpiece
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 1
wired_headset = 0
wired_headphone = 0
@@ -438,7 +438,7 @@
AvailableOutputDevices Includes Speaker
ForceUseForCommunication Is ForceSpeaker
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -461,7 +461,7 @@
#
# Fallback on default output device which can be speaker for example
#
- component: /Policy/policy/strategies/phone/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/phone/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
new file mode 100644
index 0000000..c064c18
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
@@ -0,0 +1,43 @@
+supDomain: DeviceForProductStrategy
+ supDomain: Rerouting
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/rerouting/device_address =
+
+ domain: SelectedDevice
+ conf: Bus
+ component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
+ bus = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
similarity index 86%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
index 70740d1..c4edeeb 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification.pfw
@@ -1,11 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
supDomain: Sonification
-
domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
- # no sonification on remote submix (e.g. WFD)
+ conf: calibration
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
remote_submix = 0
hdmi_arc = 0
spdif = 0
@@ -16,9 +13,12 @@
# Sonification follows phone strategy if in call but HDMI is not reachable
#
hdmi = 0
- ip = 0
bus = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
+ /Policy/policy/product_strategies/sonification/device_address =
domain: Speaker
@@ -41,11 +41,11 @@
TelephonyMode Is InCommunication
AvailableOutputDevices Excludes Line
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
speaker = 1
conf: NotSelected
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
speaker = 0
domain: Device2
@@ -59,7 +59,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -85,7 +85,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -111,7 +111,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceNoBtA2dp
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -138,7 +138,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothScoCarkit
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -165,7 +165,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothScoHeadset
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -192,7 +192,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothSco
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -228,7 +228,7 @@
TelephonyMode Is InCommunication
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 1
@@ -266,7 +266,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -302,7 +302,7 @@
TelephonyMode Is InCommunication
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 1
wired_headphone = 0
@@ -339,7 +339,7 @@
TelephonyMode Is InCommunication
ForceUseForCommunication IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -368,7 +368,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -397,7 +397,7 @@
TelephonyMode IsNot InCommunication
ForceUseForMedia IsNot ForceSpeaker
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -427,7 +427,7 @@
ForceUseForMedia IsNot ForceSpeaker
ForceUseForDock Is ForceAnalogDock
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
@@ -454,7 +454,7 @@
ForceUseForCommunication IsNot ForceSpeaker
AvailableOutputDevices Includes Earpiece
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 1
wired_headset = 0
wired_headphone = 0
@@ -472,7 +472,7 @@
line = 0
conf: None
- component: /Policy/policy/strategies/sonification/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification/selected_output_devices/mask
earpiece = 0
wired_headset = 0
wired_headphone = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
similarity index 85%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
index b673c4f..0a3dd5f 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_sonification_respectful.pfw
@@ -1,6 +1,5 @@
-domainGroup: DeviceForStrategy
-
- domainGroup: SonificationRespectful
+supDomain: DeviceForProductStrategy
+ supDomain: SonificationRespectful
#
# Sonificiation Respectful follows:
# - If in call: Strategy sonification (that follows phone strategy in call also...)
@@ -12,10 +11,9 @@
# selected.
#
# Case of stream active handled programmatically
-
domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ conf: calibration
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
remote_submix = 0
hdmi_arc = 0
aux_line = 0
@@ -23,8 +21,10 @@
fm = 0
telephony_tx = 0
ip = 0
- bus = 0
+ proxy = 0
+ usb_headset = 0
stub = 0
+ /Policy/policy/product_strategies/sonification_respectful/device_address =
domain: Speakers
@@ -38,7 +38,7 @@
TelephonyMode IsNot InCall
TelephonyMode IsNot InCommunication
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
speaker_safe = 1
speaker = 0
@@ -61,12 +61,12 @@
TelephonyMode Is InCommunication
AvailableOutputDevices Excludes Line
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
speaker_safe = 0
speaker = 1
conf: None
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
speaker_safe = 0
speaker = 0
@@ -81,7 +81,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dp
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -108,7 +108,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dpHeadphones
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -135,7 +135,7 @@
ForceUseForMedia IsNot ForceNoBtA2dp
AvailableOutputDevices Includes BluetoothA2dpSpeaker
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -162,7 +162,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothScoCarkit
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -189,7 +189,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothScoHeadset
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 1
@@ -216,7 +216,7 @@
ForceUseForCommunication Is ForceBtSco
AvailableOutputDevices Includes BluetoothSco
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 1
bluetooth_sco_headset = 0
@@ -253,7 +253,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes WiredHeadphone
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -294,7 +294,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes Line
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -331,7 +331,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes WiredHeadset
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -369,7 +369,7 @@
AvailableOutputDevices Excludes UsbAccessory
AvailableOutputDevices Includes UsbDevice
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -399,7 +399,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes UsbAccessory
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -429,7 +429,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes DgtlDockHeadset
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -459,7 +459,7 @@
ForceUseForMedia IsNot ForceSpeaker
AvailableOutputDevices Includes Hdmi
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -490,7 +490,7 @@
ForceUseForDock Is ForceAnalogDock
AvailableOutputDevices Includes AnlgDockHeadset
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -517,7 +517,7 @@
ForceUseForCommunication IsNot ForceSpeaker
AvailableOutputDevices Includes Earpiece
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/sonification_respectful/selected_output_devices/mask
earpiece = 1
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -534,20 +534,3 @@
usb_device = 0
hdmi = 0
- conf: None
- component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
- earpiece = 0
- bluetooth_sco = 0
- bluetooth_sco_headset = 0
- bluetooth_sco_carkit = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- bluetooth_a2dp = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
similarity index 61%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
index 9f9c211..3fc7670 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_transmitted_through_speaker.pfw
@@ -1,9 +1,8 @@
-supDomain: DeviceForStrategy
-
+supDomain: DeviceForProductStrategy
supDomain: TransmittedThroughSpeaker
domain: UnreacheableDevices
conf: Calibration
- component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
remote_submix = 0
hdmi_arc = 0
spdif = 0
@@ -11,7 +10,7 @@
fm = 0
speaker_safe = 0
earpiece = 0
- wired_headset = 1
+ wired_headset = 0
wired_headphone = 0
bluetooth_sco = 0
bluetooth_sco_headset = 0
@@ -29,15 +28,16 @@
ip = 0
bus = 0
stub = 0
+ /Policy/policy/product_strategies/transmitted_through_speaker/device_address =
domain: Speaker
conf: Selected
AvailableOutputDevices Includes Speaker
- component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
speaker = 1
conf: NotSelected
- component: /Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/transmitted_through_speaker/selected_output_devices/mask
speaker = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
new file mode 100644
index 0000000..c46cf56
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
@@ -0,0 +1,36 @@
+supDomain: DeviceForProductStrategy
+ supDomain: Unknown
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/unknown/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ bus = 0
+ stub = 0
+ /Policy/policy/product_strategies/unknown/device_address =
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
new file mode 100644
index 0000000..b55ce2c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
+ Name="policy" Type="Policy">
+
+ <ComponentLibrary>
+ <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
+ <!-- Common Types defintion -->
+ <xi:include href="PolicySubsystem-CommonTypes.xml"/>
+ <xi:include href="ProductStrategies.xml"/>
+
+
+ <!--#################### GLOBAL COMPONENTS END ####################-->
+
+ <!--#################### STREAM BEGIN ####################-->
+
+ <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+ <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+ <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+ <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+ <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+ <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+ <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+ <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+ <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+ Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+ <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+ <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+ Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+ <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
+ Description="For accessibility talk back prompts"/>
+ <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
+ Description="For dynamic policy output mixes"/>
+ <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
+ Description="For internal audio flinger tracks. Fixed volume"/>
+ </ComponentType>
+
+ <!--#################### STREAM END ####################-->
+
+ <!--#################### INPUT SOURCE BEGIN ####################-->
+
+ <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
+ identifier mapping must match the value of the enum">
+ <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+ <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
+ <Component Name="voice_uplink" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
+ <Component Name="voice_downlink" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
+ <Component Name="voice_call" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+ <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
+ <Component Name="voice_recognition" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
+ <Component Name="voice_communication" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+ <Component Name="remote_submix" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
+ <Component Name="unprocessed" Type="InputSource"
+ Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+ <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+ <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
+ </ComponentType>
+
+ <!--#################### INPUT SOURCE END ####################-->
+ </ComponentLibrary>
+
+ <InstanceDefinition>
+ <Component Name="streams" Type="Streams"/>
+ <Component Name="input_sources" Type="InputSources"/>
+ <Component Name="product_strategies" Type="ProductStrategies"/>
+ </InstanceDefinition>
+</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
new file mode 100644
index 0000000..4cbb3da
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+ <ComponentType Name="ProductStrategies" Description="">
+ <Component Name="accessibility" Type="ProductStrategy"/>
+ <Component Name="enforced_audible" Type="ProductStrategy"/>
+ <Component Name="transmitted_through_speaker" Type="ProductStrategy"/>
+
+ <Component Name="media" Type="ProductStrategy"/>
+ <Component Name="phone" Type="ProductStrategy"/>
+ <Component Name="dtmf" Type="ProductStrategy"/>
+
+ <Component Name="sonification" Type="ProductStrategy"/>
+ <Component Name="sonification_respectful" Type="ProductStrategy"/>
+ <Component Name="rerouting" Type="ProductStrategy"/>
+ <Component Name="unknown" Type="ProductStrategy"/>
+ </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
deleted file mode 100644
index 28a3629..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
+++ /dev/null
@@ -1,301 +0,0 @@
-domainGroup: DeviceForStrategy
-
- domainGroup: Rerouting
- #
- # Falls through media strategy
- #
- domain: UnreachableDevices
- conf: Calibration
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- hdmi_arc = 0
- spdif = 0
- aux_line = 0
- fm = 0
- speaker_safe = 0
- earpiece = 0
- bluetooth_sco = 0
- bluetooth_sco_headset = 0
- bluetooth_sco_carkit = 0
- telephony_tx = 0
- ip = 0
- bus = 0
- stub = 0
-
- domain: Device2
- conf: RemoteSubmix
- AvailableOutputDevices Includes RemoteSubmix
- AvailableOutputDevicesAddresses Includes 0
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 1
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: BluetoothA2dp
- ForceUseForMedia IsNot ForceNoBtA2dp
- AvailableOutputDevices Includes BluetoothA2dp
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 1
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: BluetoothA2dpHeadphone
- ForceUseForMedia IsNot ForceNoBtA2dp
- AvailableOutputDevices Includes BluetoothA2dpHeadphones
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 1
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: BluetoothA2dpSpeaker
- ForceUseForMedia IsNot ForceNoBtA2dp
- AvailableOutputDevices Includes BluetoothA2dpSpeaker
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 1
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: ForceSpeaker
- ForceUseForMedia Is ForceSpeaker
- AvailableOutputDevices Includes Speaker
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 1
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: WiredHeadphone
- AvailableOutputDevices Includes WiredHeadphone
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 1
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: Line
- AvailableOutputDevices Includes Line
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 1
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: WiredHeadset
- AvailableOutputDevices Includes WiredHeadset
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 1
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: UsbAccessory
- AvailableOutputDevices Includes UsbAccessory
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 1
- usb_device = 0
- hdmi = 0
-
- conf: UsbDevice
- AvailableOutputDevices Includes UsbDevice
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 1
- hdmi = 0
-
- conf: DgtlDockHeadset
- AvailableOutputDevices Includes DgtlDockHeadset
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 1
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: AuxDigital
- #
- # Rerouting is similar to media and sonification (exept here: sonification is not allowed on HDMI)
- #
- AvailableOutputDevices Includes Hdmi
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 1
-
- conf: AnlgDockHeadset
- AvailableOutputDevices Includes AnlgDockHeadset
- ForceUseForDock Is ForceAnalogDock
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 1
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: Speaker
- AvailableOutputDevices Includes Speaker
-
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 1
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
- conf: Default
- component: /Policy/policy/strategies/rerouting/selected_output_devices/mask
- remote_submix = 0
- bluetooth_a2dp = 0
- bluetooth_a2dp_headphones = 0
- bluetooth_a2dp_speaker = 0
- speaker = 0
- wired_headset = 0
- wired_headphone = 0
- line = 0
- angl_dock_headset = 0
- dgtl_dock_headset = 0
- usb_accessory = 0
- usb_device = 0
- hdmi = 0
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
deleted file mode 100644
index 3940b9d..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
+++ /dev/null
@@ -1,20 +0,0 @@
-domain: StrategyForStream
-
- conf: Calibration
- /Policy/policy/streams/voice_call/applicable_strategy/strategy = phone
- #
- # NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
- # while key clicks are played produces a poor result
- #
- /Policy/policy/streams/system/applicable_strategy/strategy = media
- /Policy/policy/streams/ring/applicable_strategy/strategy = sonification
- /Policy/policy/streams/music/applicable_strategy/strategy = media
- /Policy/policy/streams/alarm/applicable_strategy/strategy = sonification
- /Policy/policy/streams/notification/applicable_strategy/strategy = sonification_respectful
- /Policy/policy/streams/bluetooth_sco/applicable_strategy/strategy = phone
- /Policy/policy/streams/enforced_audible/applicable_strategy/strategy = enforced_audible
- /Policy/policy/streams/dtmf/applicable_strategy/strategy = dtmf
- /Policy/policy/streams/tts/applicable_strategy/strategy = transmitted_through_speaker
- /Policy/policy/streams/accessibility/applicable_strategy/strategy = accessibility
- /Policy/policy/streams/rerouting/applicable_strategy/strategy = rerouting
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
index daa7f68..56c5ed3 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
@@ -133,30 +133,6 @@
</BitParameterBlock>
</ComponentType>
- <!-- Routing Strategy definition as an enumeration. Numerical value must match the value
- of the routing strategy in policy header file. -->
- <ComponentType Name="Strategy">
- <EnumParameter Name="strategy" Size="32">
- <ValuePair Literal="media" Numerical="0"/>
- <ValuePair Literal="phone" Numerical="1"/>
- <ValuePair Literal="sonification" Numerical="2"/>
- <ValuePair Literal="sonification_respectful" Numerical="3"/>
- <ValuePair Literal="dtmf" Numerical="4"/>
- <ValuePair Literal="enforced_audible" Numerical="5"/>
- <ValuePair Literal="transmitted_through_speaker" Numerical="6"/>
- <ValuePair Literal="accessibility" Numerical="7"/>
- <ValuePair Literal="rerouting" Numerical="8"/>
- </EnumParameter>
- </ComponentType>
-
- <!--#################### STRATEGY COMMON TYPES BEGIN ####################-->
-
- <ComponentType Name="StrategyConfig" Mapping="Strategy">
- <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
- </ComponentType>
-
- <!--#################### STRATEGY COMMON TYPES END ####################-->
-
<!--#################### STREAM COMMON TYPES BEGIN ####################-->
<ComponentType Name="VolumeProfileType">
@@ -178,21 +154,12 @@
</ComponentType>
<ComponentType Name="Stream" Mapping="Stream">
- <Component Name="applicable_strategy" Type="Strategy"/>
<Component Name="applicable_volume_profile" Type="VolumeProfileType"
Description="Volume profile followed by a given stream type."/>
</ComponentType>
<!--#################### STREAM COMMON TYPES END ####################-->
- <!--#################### USAGE COMMON TYPES BEGIN ####################-->
-
- <ComponentType Name="Usage">
- <Component Name="applicable_strategy" Type="Strategy" Mapping="Usage"/>
- </ComponentType>
-
- <!--#################### USAGE COMMON TYPES END ####################-->
-
<!--#################### INPUT SOURCE COMMON TYPES BEGIN ####################-->
<ComponentType Name="InputSource">
@@ -202,4 +169,14 @@
<!--#################### INPUT SOURCE COMMON TYPES END ####################-->
+ <!--#################### PRODUCT STRATEGY COMMON TYPES BEGIN ####################-->
+
+ <ComponentType Name="ProductStrategy" Mapping="ProductStrategy">
+ <Component Name="selected_output_devices" Type="OutputDevicesMask"/>
+ <StringParameter Name="device_address" MaxLength="256"
+ Description="if any, device address associated"/>
+ </ComponentType>
+
+ <!--#################### PRODUCT STRATEGY COMMON TYPES END ####################-->
+
</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
index 45d1e8a..a4e7537 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
@@ -11,22 +11,6 @@
<!--#################### GLOBAL COMPONENTS END ####################-->
- <!--#################### STRATEGY BEGIN ####################-->
-
- <ComponentType Name="Strategies">
- <Component Name="media" Type="StrategyConfig" Mapping="Name:STRATEGY_MEDIA"/>
- <Component Name="phone" Type="StrategyConfig" Mapping="Name:STRATEGY_PHONE"/>
- <Component Name="sonification" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION"/>
- <Component Name="sonification_respectful" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION_RESPECTFUL"/>
- <Component Name="dtmf" Type="StrategyConfig" Mapping="Name:STRATEGY_DTMF"/>
- <Component Name="enforced_audible" Type="StrategyConfig" Mapping="Name:STRATEGY_ENFORCED_AUDIBLE"/>
- <Component Name="transmitted_through_speaker" Type="StrategyConfig" Mapping="Name:STRATEGY_TRANSMITTED_THROUGH_SPEAKER"/>
- <Component Name="accessibility" Type="StrategyConfig" Mapping="Name:STRATEGY_ACCESSIBILITY"/>
- <Component Name="rerouting" Type="StrategyConfig" Mapping=",Name:STRATEGY_REROUTING"/>
- </ComponentType>
-
- <!--#################### STRATEGY END ####################-->
-
<!--#################### STREAM BEGIN ####################-->
<ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
@@ -52,40 +36,6 @@
<!--#################### STREAM END ####################-->
- <!--#################### USAGE BEGIN ####################-->
-
- <ComponentType Name="Usages" Description="associated to audio_usage_t definition">
- <Component Name="unknown" Type="Usage" Mapping="Name:AUDIO_USAGE_UNKNOWN"/>
- <Component Name="media" Type="Usage" Mapping="Name:AUDIO_USAGE_MEDIA"/>
- <Component Name="voice_communication" Type="Usage"
- Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION"/>
- <Component Name="voice_communication_signalling" Type="Usage"
- Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
- <Component Name="alarm" Type="Usage" Mapping="Name:AUDIO_USAGE_ALARM"/>
- <Component Name="notification" Type="Usage" Mapping="Name:AUDIO_USAGE_NOTIFICATION"/>
- <Component Name="notification_telephony_ringtone" Type="Usage"
- Mapping="Name:AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
- <Component Name="notification_communication_request" Type="Usage"
- Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
- <Component Name="notification_communication_instant" Type="Usage"
- Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
- <Component Name="notification_communication_delayed" Type="Usage"
- Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
- <Component Name="notification_event" Type="Usage"
- Mapping="Name:AUDIO_USAGE_NOTIFICATION_EVENT"/>
- <Component Name="assistance_accessibility" Type="Usage"
- Mapping="Name:AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
- <Component Name="assistance_navigation_guidance" Type="Usage"
- Mapping="Name:AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
- <Component Name="assistance_sonification" Type="Usage"
- Mapping="Name:AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
- <Component Name="game" Type="Usage" Mapping="Name:AUDIO_USAGE_GAME"/>
- <Component Name="virtual_source" Type="Usage" Mapping="Name:AUDIO_USAGE_VIRTUAL_SOURCE"/>
- <Component Name="assistant" Type="Usage" Mapping="Name:AUDIO_USAGE_ASSISTANT"/>
- </ComponentType>
-
- <!--#################### USAGE END ####################-->
-
<!--#################### INPUT SOURCE BEGIN ####################-->
<ComponentType Name="InputSources" Description="associated to audio_source_t definition,
@@ -117,8 +67,6 @@
<InstanceDefinition>
<Component Name="streams" Type="Streams"/>
- <Component Name="strategies" Type="Strategies"/>
<Component Name="input_sources" Type="InputSources"/>
- <Component Name="usages" Type="Usages"/>
</InstanceDefinition>
</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
index db1f038..65dc9af 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
@@ -8,10 +8,9 @@
LOCAL_SRC_FILES := \
PolicySubsystemBuilder.cpp \
PolicySubsystem.cpp \
- Strategy.cpp \
InputSource.cpp \
Stream.cpp \
- Usage.cpp
+ ProductStrategy.cpp
LOCAL_CFLAGS += \
-Wall \
@@ -21,9 +20,8 @@
-fvisibility=hidden
LOCAL_C_INCLUDES := \
- frameworks/av/services/audiopolicy/common/include \
frameworks/av/services/audiopolicy/engineconfigurable/include \
- frameworks/av/services/audiopolicy/engineconfigurable/interface \
+ frameworks/av/services/audiopolicy/engineconfigurable/interface
LOCAL_SHARED_LIBRARIES := \
libaudiopolicyengineconfigurable \
@@ -31,6 +29,11 @@
libmedia_helper \
liblog \
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudioclient_headers \
+ libbase_headers
+
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
LOCAL_STATIC_LIBRARIES := libpfw_utility
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index 7374fc3..bfc1bca 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -17,10 +17,9 @@
#include "PolicySubsystem.h"
#include "SubsystemObjectFactory.h"
#include "PolicyMappingKeys.h"
-#include "Strategy.h"
#include "Stream.h"
#include "InputSource.h"
-#include "Usage.h"
+#include "ProductStrategy.h"
#include <AudioPolicyPluginInterface.h>
#include <AudioPolicyEngineInstance.h>
#include <utils/Log.h>
@@ -36,9 +35,8 @@
const char *const PolicySubsystem::mStreamComponentName = "Stream";
-const char *const PolicySubsystem::mStrategyComponentName = "Strategy";
const char *const PolicySubsystem::mInputSourceComponentName = "InputSource";
-const char *const PolicySubsystem::mUsageComponentName = "Usage";
+const char *const PolicySubsystem::mProductStrategyComponentName = "ProductStrategy";
PolicySubsystem::PolicySubsystem(const std::string &name, core::log::Logger &logger)
: CSubsystem(name, logger),
@@ -68,20 +66,14 @@
(1 << MappingKeyName))
);
addSubsystemObjectFactory(
- new TSubsystemObjectFactory<Strategy>(
- mStrategyComponentName,
- 0)
- );
- addSubsystemObjectFactory(
- new TSubsystemObjectFactory<Usage>(
- mUsageComponentName,
- (1 << MappingKeyName))
- );
- addSubsystemObjectFactory(
new TSubsystemObjectFactory<InputSource>(
mInputSourceComponentName,
(1 << MappingKeyName))
);
+ addSubsystemObjectFactory(
+ new TSubsystemObjectFactory<ProductStrategy>(
+ mProductStrategyComponentName, 0)
+ );
}
// Retrieve Route interface
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
index 822eeb9..9bf1c23 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
@@ -53,7 +53,6 @@
static const char *const mKeyAmend3; /**< amend3 key mapping string. */
static const char *const mStreamComponentName;
- static const char *const mStrategyComponentName;
static const char *const mInputSourceComponentName;
- static const char *const mUsageComponentName;
+ static const char *const mProductStrategyComponentName;
};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
new file mode 100644
index 0000000..bb29ef1
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 "ProductStrategy.h"
+#include "PolicyMappingKeys.h"
+#include "PolicySubsystem.h"
+
+using std::string;
+using android::product_strategy_t;
+
+ProductStrategy::ProductStrategy(const string &mappingValue,
+ CInstanceConfigurableElement *instanceConfigurableElement,
+ const CMappingContext &context,
+ core::log::Logger& logger)
+ : CFormattedSubsystemObject(instanceConfigurableElement,
+ logger,
+ mappingValue,
+ MappingKeyAmend1,
+ (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
+ context)
+{
+ ALOG_ASSERT(instanceConfigurableElement != nullptr, "Invalid Configurable Element");
+ mPolicySubsystem = static_cast<const PolicySubsystem *>(
+ instanceConfigurableElement->getBelongingSubsystem());
+ ALOG_ASSERT(mPolicySubsystem != nullptr, "Invalid Policy Subsystem");
+
+ mPolicyPluginInterface = mPolicySubsystem->getPolicyPluginInterface();
+ ALOG_ASSERT(mPolicyPluginInterface != nullptr, "Invalid Policy Plugin Interface");
+
+ std::string name(instanceConfigurableElement->getName());
+ mId = mPolicyPluginInterface->getProductStrategyByName(name);
+
+ ALOG_ASSERT(mId != PRODUCT_STRATEGY_INVALID, "Product Strategy %s not found", name.c_str());
+
+ ALOGE("Product Strategy %s added", name.c_str());
+}
+
+bool ProductStrategy::sendToHW(string & /*error*/)
+{
+ Device deviceParams;
+ blackboardRead(&deviceParams, sizeof(deviceParams));
+
+ mPolicyPluginInterface->setDeviceTypesForProductStrategy(mId, deviceParams.applicableDevice);
+ mPolicyPluginInterface->setDeviceAddressForProductStrategy(mId, deviceParams.deviceAddress);
+ return true;
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
similarity index 68%
rename from services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
rename to services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
index c02b82c..244f082 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -20,14 +20,24 @@
#include "InstanceConfigurableElement.h"
#include "MappingContext.h"
#include <AudioPolicyPluginInterface.h>
+#include <policy.h>
#include <string>
class PolicySubsystem;
-class Strategy : public CFormattedSubsystemObject
+class ProductStrategy : public CFormattedSubsystemObject
{
+private:
+ static const uint32_t mMaxStringSize = 257; /**< max string size (plus zero terminal). */
+
+ struct Device
+ {
+ uint32_t applicableDevice; /**< applicable device for this strategy. */
+ char deviceAddress[mMaxStringSize]; /**< device address associated with this strategy. */
+ } __attribute__((packed));
+
public:
- Strategy(const std::string &mappingValue,
+ ProductStrategy(const std::string &mappingValue,
CInstanceConfigurableElement *instanceConfigurableElement,
const CMappingContext &context,
core::log::Logger& logger);
@@ -38,10 +48,10 @@
private:
const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
+ android::product_strategy_t mId;
+
/**
* Interface to communicate with Audio Policy Engine.
*/
android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
- android::routing_strategy mId; /**< strategy identifier to link with audio.h.*/
};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
deleted file mode 100644
index 876bcb0..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Strategy.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-#include <RoutingStrategy.h>
-
-using std::string;
-using android::routing_strategy;
-
-namespace detail {
-
-constexpr std::pair<routing_strategy, const char*> routingStrategyMap[] = {
- {android::STRATEGY_MEDIA, "STRATEGY_MEDIA"},
- {android::STRATEGY_PHONE, "STRATEGY_PHONE"},
- {android::STRATEGY_SONIFICATION, "STRATEGY_SONIFICATION"},
- {android::STRATEGY_SONIFICATION_RESPECTFUL, "STRATEGY_SONIFICATION_RESPECTFUL"},
- {android::STRATEGY_DTMF, "STRATEGY_DTMF"},
- {android::STRATEGY_ENFORCED_AUDIBLE, "STRATEGY_ENFORCED_AUDIBLE"},
- {android::STRATEGY_TRANSMITTED_THROUGH_SPEAKER, "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"},
- {android::STRATEGY_ACCESSIBILITY, "STRATEGY_ACCESSIBILITY"},
- {android::STRATEGY_REROUTING, "STRATEGY_REROUTING"},
-};
-
-bool fromString(const char *literalName, routing_strategy &type)
-{
- for (auto& pair : routingStrategyMap) {
- if (strcmp(pair.second, literalName) == 0) {
- type = pair.first;
- return true;
- }
- }
- return false;
-}
-
-}
-
-Strategy::Strategy(const string &mappingValue,
- CInstanceConfigurableElement *instanceConfigurableElement,
- const CMappingContext &context,
- core::log::Logger& logger)
- : CFormattedSubsystemObject(instanceConfigurableElement,
- logger,
- mappingValue,
- MappingKeyAmend1,
- (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
- context),
- mPolicySubsystem(static_cast<const PolicySubsystem *>(
- instanceConfigurableElement->getBelongingSubsystem())),
- mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
- std::string name(context.getItem(MappingKeyName));
- if (not detail::fromString(name.c_str(), mId)) {
- LOG_ALWAYS_FATAL("Invalid Strategy %s, invalid XML structure file", name.c_str());
- }
- // Declares the strategy to audio policy engine
- mPolicyPluginInterface->addStrategy(instanceConfigurableElement->getName(), mId);
-}
-
-bool Strategy::sendToHW(string & /*error*/)
-{
- uint32_t applicableOutputDevice;
- blackboardRead(&applicableOutputDevice, sizeof(applicableOutputDevice));
- return mPolicyPluginInterface->setDeviceForStrategy(mId, applicableOutputDevice);
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
index 46c9e1c..5230e0e 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
@@ -20,7 +20,6 @@
#include <media/TypeConverter.h>
using std::string;
-using android::routing_strategy;
Stream::Stream(const string &/*mappingValue*/,
CInstanceConfigurableElement *instanceConfigurableElement,
@@ -45,11 +44,8 @@
Applicable params;
blackboardRead(¶ms, sizeof(params));
- mPolicyPluginInterface->setStrategyForStream(mId,
- static_cast<routing_strategy>(params.strategy));
-
- mPolicyPluginInterface->setVolumeProfileForStream(mId,
- static_cast<audio_stream_type_t>(params.volumeProfile));
+ mPolicyPluginInterface->setVolumeProfileForStream(
+ mId, static_cast<audio_stream_type_t>(params.volumeProfile));
return true;
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
index 4a875db..e0ce2fa 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
@@ -29,7 +29,6 @@
private:
struct Applicable
{
- uint32_t strategy; /**< applicable strategy for this stream. */
uint32_t volumeProfile; /**< applicable strategy for this stream. */
} __attribute__((packed));
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
deleted file mode 100644
index 925d631..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Usage.h"
-#include "PolicyMappingKeys.h"
-#include "PolicySubsystem.h"
-#include <media/TypeConverter.h>
-
-using std::string;
-using android::routing_strategy;
-
-Usage::Usage(const string &mappingValue,
- CInstanceConfigurableElement *instanceConfigurableElement,
- const CMappingContext &context, core::log::Logger &logger)
- : CFormattedSubsystemObject(instanceConfigurableElement,
- logger,
- mappingValue,
- MappingKeyAmend1,
- (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
- context),
- mPolicySubsystem(static_cast<const PolicySubsystem *>(
- instanceConfigurableElement->getBelongingSubsystem())),
- mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
-{
- std::string name(context.getItem(MappingKeyName));
-
- if (not android::UsageTypeConverter::fromString(name, mId)) {
- LOG_ALWAYS_FATAL("Invalid Usage name: %s, invalid XML structure file", name.c_str());
- }
- // Declares the strategy to audio policy engine
- mPolicyPluginInterface->addUsage(name, mId);
-}
-
-bool Usage::sendToHW(string & /*error*/)
-{
- uint32_t applicableStrategy;
- blackboardRead(&applicableStrategy, sizeof(applicableStrategy));
- return mPolicyPluginInterface->setStrategyForUsage(mId,
- static_cast<routing_strategy>(applicableStrategy));
-}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
deleted file mode 100644
index 860204f..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "FormattedSubsystemObject.h"
-#include "InstanceConfigurableElement.h"
-#include "MappingContext.h"
-#include <AudioPolicyPluginInterface.h>
-#include <string>
-
-class PolicySubsystem;
-
-class Usage : public CFormattedSubsystemObject
-{
-public:
- Usage(const std::string &mappingValue,
- CInstanceConfigurableElement *instanceConfigurableElement,
- const CMappingContext &context,
- core::log::Logger& logger);
-
-protected:
- virtual bool sendToHW(std::string &error);
-
-private:
- const PolicySubsystem *mPolicySubsystem; /**< Route subsytem plugin. */
-
- /**
- * Interface to communicate with Audio Policy Engine.
- */
- android::AudioPolicyPluginInterface *mPolicyPluginInterface;
-
- audio_usage_t mId; /**< usage identifier to link with audio.h. */
-};
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
index 1f8ed8d..02b41cb 100644
--- a/services/audiopolicy/engineconfigurable/src/Collection.h
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -18,8 +18,6 @@
#include "Element.h"
#include "Stream.h"
-#include "Strategy.h"
-#include "Usage.h"
#include "InputSource.h"
#include <utils/Errors.h>
#include <system/audio.h>
@@ -147,15 +145,9 @@
template <>
struct Collection<std::string>::collectionSupported {};
template <>
-struct Collection<audio_usage_t>::collectionSupported {};
-template <>
struct Collection<audio_source_t>::collectionSupported {};
-template <>
-struct Collection<routing_strategy>::collectionSupported {};
-typedef Collection<routing_strategy> StrategyCollection;
typedef Collection<audio_stream_type_t> StreamCollection;
-typedef Collection<audio_usage_t> UsageCollection;
typedef Collection<audio_source_t> InputSourceCollection;
} // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Element.h b/services/audiopolicy/engineconfigurable/src/Element.h
index 1b55c8c..97950d8 100644
--- a/services/audiopolicy/engineconfigurable/src/Element.h
+++ b/services/audiopolicy/engineconfigurable/src/Element.h
@@ -62,7 +62,7 @@
/**
* A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
* or a string.
*
* @tparam Property for which this policy element has setter / getter.
@@ -73,7 +73,7 @@
/**
* A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
* or a string.
*
* @tparam Property for which this policy element has setter / getter.
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 009cf90..f486dca 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -25,11 +25,12 @@
#endif
#include "Engine.h"
-#include "Strategy.h"
#include "Stream.h"
#include "InputSource.h"
-#include "Usage.h"
+
+#include <EngineConfig.h>
#include <policy.h>
+#include <AudioIODescriptorInterface.h>
#include <ParameterManagerWrapper.h>
using std::string;
@@ -39,77 +40,48 @@
namespace audio_policy {
template <>
-StrategyCollection &Engine::getCollection<routing_strategy>()
-{
- return mStrategyCollection;
-}
-template <>
StreamCollection &Engine::getCollection<audio_stream_type_t>()
{
return mStreamCollection;
}
template <>
-UsageCollection &Engine::getCollection<audio_usage_t>()
-{
- return mUsageCollection;
-}
-template <>
InputSourceCollection &Engine::getCollection<audio_source_t>()
{
return mInputSourceCollection;
}
template <>
-const StrategyCollection &Engine::getCollection<routing_strategy>() const
-{
- return mStrategyCollection;
-}
-template <>
const StreamCollection &Engine::getCollection<audio_stream_type_t>() const
{
return mStreamCollection;
}
template <>
-const UsageCollection &Engine::getCollection<audio_usage_t>() const
-{
- return mUsageCollection;
-}
-template <>
const InputSourceCollection &Engine::getCollection<audio_source_t>() const
{
return mInputSourceCollection;
}
-Engine::Engine()
- : mManagerInterface(this),
- mPluginInterface(this),
- mPolicyParameterMgr(new ParameterManagerWrapper()),
- mApmObserver(NULL)
+Engine::Engine() : mPolicyParameterMgr(new ParameterManagerWrapper())
{
+ status_t loadResult = loadAudioPolicyEngineConfig();
+ if (loadResult < 0) {
+ ALOGE("Policy Engine configuration is invalid.");
+ }
}
Engine::~Engine()
{
- mStrategyCollection.clear();
mStreamCollection.clear();
mInputSourceCollection.clear();
- mUsageCollection.clear();
-}
-
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
- ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
- mApmObserver = observer;
}
status_t Engine::initCheck()
{
- if (mPolicyParameterMgr == NULL || mPolicyParameterMgr->start() != NO_ERROR) {
+ if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start() != NO_ERROR) {
ALOGE("%s: could not start Policy PFW", __FUNCTION__);
return NO_INIT;
}
- return (mApmObserver != NULL)? NO_ERROR : NO_INIT;
+ return EngineBase::initCheck();
}
template <typename Key>
@@ -137,55 +109,16 @@
return element->template get<Property>();
}
-routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t usage)
+bool Engine::setVolumeProfileForStream(const audio_stream_type_t &stream,
+ const audio_stream_type_t &profile)
{
- return mPolicyEngine->getPropertyForKey<routing_strategy, audio_usage_t>(usage);
-}
-
-audio_devices_t Engine::ManagerInterfaceImpl::getDeviceForStrategy(routing_strategy strategy) const
-{
- const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs();
-
- /** This is the only case handled programmatically because the PFW is unable to know the
- * activity of streams.
- *
- * -While media is playing on a remote device, use the the sonification behavior.
- * Note that we test this usecase before testing if media is playing because
- * the isStreamActive() method only informs about the activity of a stream, not
- * if it's for local playback. Note also that we use the same delay between both tests
- *
- * -When media is not playing anymore, fall back on the sonification behavior
- */
- if (strategy == STRATEGY_SONIFICATION_RESPECTFUL &&
- !is_state_in_call(getPhoneState()) &&
- !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
- SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
- outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
- return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(STRATEGY_MEDIA);
- }
- if (strategy == STRATEGY_ACCESSIBILITY &&
- (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
- // do not route accessibility prompts to a digital output currently configured with a
- // compressed format as they would likely not be mixed and dropped.
- // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
- return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(
- STRATEGY_SONIFICATION);
- }
- return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
-}
-
-bool Engine::PluginInterfaceImpl::setVolumeProfileForStream(const audio_stream_type_t &stream,
- const audio_stream_type_t &profile)
-{
- if (mPolicyEngine->setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream,
- profile)) {
- mPolicyEngine->mApmObserver->getVolumeCurves().switchVolumeCurve(profile, stream);
+ if (setPropertyForKey<audio_stream_type_t, audio_stream_type_t>(stream, profile)) {
+ getApmObserver()->getVolumeCurves().switchVolumeCurve(profile, stream);
return true;
}
return false;
}
-
template <typename Property, typename Key>
bool Engine::setPropertyForKey(const Property &property, const Key &key)
{
@@ -199,7 +132,11 @@
status_t Engine::setPhoneState(audio_mode_t mode)
{
- return mPolicyParameterMgr->setPhoneState(mode);
+ status_t status = mPolicyParameterMgr->setPhoneState(mode);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return EngineBase::setPhoneState(mode);
}
audio_mode_t Engine::getPhoneState() const
@@ -210,7 +147,11 @@
status_t Engine::setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config)
{
- return mPolicyParameterMgr->setForceUse(usage, config);
+ status_t status = mPolicyParameterMgr->setForceUse(usage, config);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return EngineBase::setForceUse(usage, config);
}
audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) const
@@ -225,24 +166,210 @@
if (audio_is_output_device(devDesc->type())) {
return mPolicyParameterMgr->setAvailableOutputDevices(
- mApmObserver->getAvailableOutputDevices().types());
+ getApmObserver()->getAvailableOutputDevices().types());
} else if (audio_is_input_device(devDesc->type())) {
return mPolicyParameterMgr->setAvailableInputDevices(
- mApmObserver->getAvailableInputDevices().types());
+ getApmObserver()->getAvailableInputDevices().types());
}
return BAD_TYPE;
}
+status_t Engine::loadAudioPolicyEngineConfig()
+{
+ auto result = EngineBase::loadAudioPolicyEngineConfig();
+
+ // Custom XML Parsing
+ auto loadCriteria= [this](const auto& configCriteria, const auto& configCriterionTypes) {
+ for (auto& criterion : configCriteria) {
+ engineConfig::CriterionType criterionType;
+ for (auto &configCriterionType : configCriterionTypes) {
+ if (configCriterionType.name == criterion.typeName) {
+ criterionType = configCriterionType;
+ break;
+ }
+ }
+ ALOG_ASSERT(not criterionType.name.empty(), "Invalid criterion type for %s",
+ criterion.name.c_str());
+ mPolicyParameterMgr->addCriterion(criterion.name, criterionType.isInclusive,
+ criterionType.valuePairs,
+ criterion.defaultLiteralValue);
+ }
+ };
+
+ loadCriteria(result.parsedConfig->criteria, result.parsedConfig->criterionTypes);
+ return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const
+{
+ const auto productStrategies = getProductStrategies();
+ if (productStrategies.find(ps) == productStrategies.end()) {
+ ALOGE("%s: Trying to get device on invalid strategy %d", __FUNCTION__, ps);
+ return {};
+ }
+ const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+ uint32_t availableOutputDevicesType = availableOutputDevices.types();
+
+ /** This is the only case handled programmatically because the PFW is unable to know the
+ * activity of streams.
+ *
+ * -While media is playing on a remote device, use the the sonification behavior.
+ * Note that we test this usecase before testing if media is playing because
+ * the isStreamActive() method only informs about the activity of a stream, not
+ * if it's for local playback. Note also that we use the same delay between both tests
+ *
+ * -When media is not playing anymore, fall back on the sonification behavior
+ */
+ audio_devices_t devices = AUDIO_DEVICE_NONE;
+ if (ps == getProductStrategyForStream(AUDIO_STREAM_NOTIFICATION) &&
+ !is_state_in_call(getPhoneState()) &&
+ !outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
+ SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) &&
+ outputs.isStreamActive(AUDIO_STREAM_MUSIC,
+ SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+ product_strategy_t strategyForMedia =
+ getProductStrategyForStream(AUDIO_STREAM_MUSIC);
+ devices = productStrategies.getDeviceTypesForProductStrategy(strategyForMedia);
+ } else if (ps == getProductStrategyForStream(AUDIO_STREAM_ACCESSIBILITY) &&
+ (outputs.isStreamActive(AUDIO_STREAM_RING) ||
+ outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
+ // do not route accessibility prompts to a digital output currently configured with a
+ // compressed format as they would likely not be mixed and dropped.
+ // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
+ product_strategy_t strategyNotification = getProductStrategyForStream(AUDIO_STREAM_RING);
+ devices = productStrategies.getDeviceTypesForProductStrategy(strategyNotification);
+ } else {
+ devices = productStrategies.getDeviceTypesForProductStrategy(ps);
+ }
+ if (devices == AUDIO_DEVICE_NONE ||
+ (devices & availableOutputDevicesType) == AUDIO_DEVICE_NONE) {
+ devices = getApmObserver()->getDefaultOutputDevice()->type();
+ ALOGE_IF(devices == AUDIO_DEVICE_NONE, "%s: no valid default device defined", __FUNCTION__);
+ return DeviceVector(getApmObserver()->getDefaultOutputDevice());
+ }
+ if (/*device_distinguishes_on_address(devices)*/ devices == AUDIO_DEVICE_OUT_BUS) {
+ // We do expect only one device for these types of devices
+ // Criterion device address garantee this one is available
+ // If this criterion is not wished, need to ensure this device is available
+ const String8 address(productStrategies.getDeviceAddressForProductStrategy(ps).c_str());
+ ALOGV("%s:device 0x%x %s %d", __FUNCTION__, devices, address.c_str(), ps);
+ return DeviceVector(availableOutputDevices.getDevice(devices,
+ address,
+ AUDIO_FORMAT_DEFAULT));
+ }
+ ALOGV("%s:device 0x%x %d", __FUNCTION__, devices, ps);
+ return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+ const sp<DeviceDescriptor> &preferredDevice,
+ bool fromCache) const
+{
+ // First check for explict routing device
+ if (preferredDevice != nullptr) {
+ ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+ return DeviceVector(preferredDevice);
+ }
+ product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+ const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+ //
+ // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+ // be by APM?
+ //
+ // Honor explicit routing requests only if all active clients have a preferred route in which
+ // case the last active client route is used
+ sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+ if (device != nullptr) {
+ return DeviceVector(device);
+ }
+
+ return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+ auto attributes = EngineBase::getAttributesForStreamType(stream);
+ return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+ AudioMix **mix) const
+{
+ const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+ const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+ const auto &inputs = getApmObserver()->getInputs();
+ std::string address;
+ //
+ // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+ // first as it used to be by APM?
+ //
+ // Honor explicit routing requests only if all active clients have a preferred route in which
+ // case the last active client route is used
+ sp<DeviceDescriptor> device =
+ findPreferredDevice(inputs, attr.source, availableInputDevices);
+ if (device != nullptr) {
+ return device;
+ }
+
+ device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+ if (device != nullptr) {
+ return device;
+ }
+
+ audio_devices_t deviceType = getPropertyForKey<audio_devices_t, audio_source_t>(attr.source);
+
+ if (audio_is_remote_submix_device(deviceType)) {
+ address = "0";
+ std::size_t pos;
+ std::string tags { attr.tags };
+ if ((pos = tags.find("addr=")) != std::string::npos) {
+ address = tags.substr(pos + std::strlen("addr="));
+ }
+ }
+ return availableInputDevices.getDevice(deviceType, String8(address.c_str()), AUDIO_FORMAT_DEFAULT);
+}
+
+void Engine::updateDeviceSelectionCache()
+{
+ for (const auto &iter : getProductStrategies()) {
+ const auto &strategy = iter.second;
+ mDevicesForStrategies[strategy->getId()] = getDevicesForProductStrategy(strategy->getId());
+ }
+}
+
+void Engine::setDeviceAddressForProductStrategy(product_strategy_t strategy,
+ const std::string &address)
+{
+ if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+ ALOGE("%s: Trying to set address %s on invalid strategy %d", __FUNCTION__, address.c_str(),
+ strategy);
+ return;
+ }
+ getProductStrategies().at(strategy)->setDeviceAddress(address);
+}
+
+bool Engine::setDeviceTypesForProductStrategy(product_strategy_t strategy, audio_devices_t devices)
+{
+ if (getProductStrategies().find(strategy) == getProductStrategies().end()) {
+ ALOGE("%s: set device %d on invalid strategy %d", __FUNCTION__, devices, strategy);
+ return false;
+ }
+ getProductStrategies().at(strategy)->setDeviceTypes(devices);
+ return true;
+}
+
template <>
AudioPolicyManagerInterface *Engine::queryInterface()
{
- return &mManagerInterface;
+ return this;
}
template <>
AudioPolicyPluginInterface *Engine::queryInterface()
{
- return &mPluginInterface;
+ return this;
}
} // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index ba4f889..5553994 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -16,7 +16,7 @@
#pragma once
-
+#include "EngineBase.h"
#include <AudioPolicyManagerInterface.h>
#include <AudioPolicyPluginInterface.h>
#include "Collection.h"
@@ -29,7 +29,7 @@
class ParameterManagerWrapper;
class VolumeProfile;
-class Engine
+class Engine : public EngineBase, AudioPolicyPluginInterface
{
public:
Engine();
@@ -38,132 +38,69 @@
template <class RequestedInterface>
RequestedInterface *queryInterface();
-private:
- /// Interface members
- class ManagerInterfaceImpl : public AudioPolicyManagerInterface
+ ///
+ /// from EngineBase
+ ///
+ android::status_t initCheck() override;
+
+ status_t setPhoneState(audio_mode_t mode) override;
+
+ audio_mode_t getPhoneState() const override;
+
+ status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) override;
+
+ audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override;
+
+ android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state) override;
+
+ DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+ const sp<DeviceDescriptor> &preferedDevice = nullptr,
+ bool fromCache = false) const override;
+
+ DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+ bool fromCache = false) const override;
+
+ sp<DeviceDescriptor> getInputDeviceForAttributes(
+ const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
+
+ void updateDeviceSelectionCache() override;
+
+ ///
+ /// from AudioPolicyPluginInterface
+ ///
+ status_t addStream(const std::string &name, audio_stream_type_t stream) override
{
- public:
- ManagerInterfaceImpl(Engine *policyEngine)
- : mPolicyEngine(policyEngine) {}
-
- virtual android::status_t initCheck()
- {
- return mPolicyEngine->initCheck();
- }
- virtual void setObserver(AudioPolicyManagerObserver *observer)
- {
- mPolicyEngine->setObserver(observer);
- }
- virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
- {
- return mPolicyEngine->getPropertyForKey<audio_devices_t, audio_source_t>(inputSource);
- }
- virtual audio_devices_t getDeviceForStrategy(routing_strategy stategy) const;
- virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
- {
- return mPolicyEngine->getPropertyForKey<routing_strategy, audio_stream_type_t>(stream);
- }
- virtual routing_strategy getStrategyForUsage(audio_usage_t usage);
- virtual status_t setPhoneState(audio_mode_t mode)
- {
- return mPolicyEngine->setPhoneState(mode);
- }
- virtual audio_mode_t getPhoneState() const
- {
- return mPolicyEngine->getPhoneState();
- }
- virtual status_t setForceUse(audio_policy_force_use_t usage,
- audio_policy_forced_cfg_t config)
- {
- return mPolicyEngine->setForceUse(usage, config);
- }
- virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
- {
- return mPolicyEngine->getForceUse(usage);
- }
- virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
- audio_policy_dev_state_t state)
- {
- return mPolicyEngine->setDeviceConnectionState(devDesc, state);
- }
-
- private:
- Engine *mPolicyEngine;
- } mManagerInterface;
-
- class PluginInterfaceImpl : public AudioPolicyPluginInterface
+ return add<audio_stream_type_t>(name, stream);
+ }
+ status_t addInputSource(const std::string &name, audio_source_t source) override
{
- public:
- PluginInterfaceImpl(Engine *policyEngine)
- : mPolicyEngine(policyEngine) {}
+ return add<audio_source_t>(name, source);
+ }
+ bool setVolumeProfileForStream(const audio_stream_type_t &stream,
+ const audio_stream_type_t &volumeProfile) override;
- virtual status_t addStrategy(const std::string &name, routing_strategy strategy)
- {
- return mPolicyEngine->add<routing_strategy>(name, strategy);
- }
- virtual status_t addStream(const std::string &name, audio_stream_type_t stream)
- {
- return mPolicyEngine->add<audio_stream_type_t>(name, stream);
- }
- virtual status_t addUsage(const std::string &name, audio_usage_t usage)
- {
- return mPolicyEngine->add<audio_usage_t>(name, usage);
- }
- virtual status_t addInputSource(const std::string &name, audio_source_t source)
- {
- return mPolicyEngine->add<audio_source_t>(name, source);
- }
- virtual bool setDeviceForStrategy(const routing_strategy &strategy, audio_devices_t devices)
- {
- return mPolicyEngine->setPropertyForKey<audio_devices_t, routing_strategy>(devices,
- strategy);
- }
- virtual bool setStrategyForStream(const audio_stream_type_t &stream,
- routing_strategy strategy)
- {
- return mPolicyEngine->setPropertyForKey<routing_strategy, audio_stream_type_t>(strategy,
- stream);
- }
- virtual bool setVolumeProfileForStream(const audio_stream_type_t &stream,
- const audio_stream_type_t &volumeProfile);
+ bool setDeviceForInputSource(const audio_source_t &inputSource, audio_devices_t device) override
+ {
+ return setPropertyForKey<audio_devices_t, audio_source_t>(device, inputSource);
+ }
+ void setDeviceAddressForProductStrategy(product_strategy_t strategy,
+ const std::string &address) override;
- virtual bool setStrategyForUsage(const audio_usage_t &usage, routing_strategy strategy)
- {
- return mPolicyEngine->setPropertyForKey<routing_strategy, audio_usage_t>(strategy,
- usage);
- }
- virtual bool setDeviceForInputSource(const audio_source_t &inputSource,
- audio_devices_t device)
- {
- return mPolicyEngine->setPropertyForKey<audio_devices_t, audio_source_t>(device,
- inputSource);
- }
+ bool setDeviceTypesForProductStrategy(product_strategy_t strategy,
+ audio_devices_t devices) override;
- private:
- Engine *mPolicyEngine;
- } mPluginInterface;
+ product_strategy_t getProductStrategyByName(const std::string &name) override
+ {
+ return EngineBase::getProductStrategyByName(name);
+ }
private:
/* Copy facilities are put private to disable copy. */
Engine(const Engine &object);
Engine &operator=(const Engine &object);
- void setObserver(AudioPolicyManagerObserver *observer);
-
- bool setVolumeProfileForStream(const audio_stream_type_t &stream,
- device_category deviceCategory,
- const VolumeCurvePoints &points);
-
- status_t initCheck();
- status_t setPhoneState(audio_mode_t mode);
- audio_mode_t getPhoneState() const;
- status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
- audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
- status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
- audio_policy_dev_state_t state);
- StrategyCollection mStrategyCollection; /**< Strategies indexed by their enum id. */
StreamCollection mStreamCollection; /**< Streams indexed by their enum id. */
- UsageCollection mUsageCollection; /**< Usages indexed by their enum id. */
InputSourceCollection mInputSourceCollection; /**< Input sources indexed by their enum id. */
template <typename Key>
@@ -184,12 +121,16 @@
template <typename Property, typename Key>
bool setPropertyForKey(const Property &property, const Key &key);
+ status_t loadAudioPolicyEngineConfig();
+
+ DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
/**
* Policy Parameter Manager hidden through a wrapper.
*/
ParameterManagerWrapper *mPolicyParameterMgr;
- AudioPolicyManagerObserver *mApmObserver;
+ DeviceStrategyMap mDevicesForStrategies;
};
} // namespace audio_policy
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.h b/services/audiopolicy/engineconfigurable/src/InputSource.h
index 64b390e..e1865cc 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.h
@@ -59,7 +59,7 @@
/**
* A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
* or a string.
*/
template <typename Property>
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
deleted file mode 100644
index 310b35e..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Strategy"
-
-#include "Strategy.h"
-
-using std::string;
-
-namespace android {
-namespace audio_policy {
-
-status_t Element<routing_strategy>::setIdentifier(routing_strategy identifier)
-{
- if (identifier >= NUM_STRATEGIES) {
- return BAD_VALUE;
- }
- mIdentifier = identifier;
- ALOGD("%s: Strategy %s identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
- return NO_ERROR;
-}
-
-/**
- * Set the device associated to this strategy.
- * It checks if the output device is valid.
- *
- * @param[in] devices selected for the given strategy.
- *
- * @return NO_ERROR if the device is either valid or none, error code otherwise.
- */
-template <>
-status_t Element<routing_strategy>::set<audio_devices_t>(audio_devices_t devices)
-{
- if (!audio_is_output_devices(devices) || devices == AUDIO_DEVICE_NONE) {
- ALOGE("%s: trying to set an invalid device 0x%X for strategy %s",
- __FUNCTION__, devices, getName().c_str());
- return BAD_VALUE;
- }
- ALOGD("%s: 0x%X for strategy %s", __FUNCTION__, devices, getName().c_str());
- mApplicableDevices = devices;
- return NO_ERROR;
-}
-
-template <>
-audio_devices_t Element<routing_strategy>::get<audio_devices_t>() const
-{
- ALOGV("%s: 0x%X for strategy %s", __FUNCTION__, mApplicableDevices, getName().c_str());
- return mApplicableDevices;
-}
-
-} // namespace audio_policy
-} // namespace android
-
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.h b/services/audiopolicy/engineconfigurable/src/Strategy.h
deleted file mode 100644
index f2487fd..0000000
--- a/services/audiopolicy/engineconfigurable/src/Strategy.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android {
-namespace audio_policy {
-
-/**
- * @tparam audio_devices_t: Applicable output device(s) for this strategy.
- */
-template <>
-class Element<routing_strategy>
-{
-public:
- Element(const std::string &name)
- : mName(name),
- mApplicableDevices(AUDIO_DEVICE_NONE)
- {}
- ~Element() {}
-
- /**
- * Returns identifier of this policy element
- *
- * @returns string representing the name of this policy element
- */
- const std::string &getName() const { return mName; }
-
- /**
- * Set the unique identifier for this policy element.
- *
- * @tparam Key type of the unique identifier.
- * @param[in] identifier to be set.
- *
- * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
- */
- status_t setIdentifier(routing_strategy identifier);
-
- /**
- * @return the unique identifier of this policy element.
- */
- routing_strategy getIdentifier() const { return mIdentifier; }
-
- /**
- * A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
- * or a string.
- */
- template <typename Property>
- Property get() const;
-
- template <typename Property>
- status_t set(Property property);
-
-private:
- /* Copy facilities are put private to disable copy. */
- Element(const Element &object);
- Element &operator=(const Element &object);
-
- std::string mName; /**< Unique literal Identifier of a policy base element*/
- routing_strategy mIdentifier; /**< Unique numerical Identifier of a policy base element*/
-
- audio_devices_t mApplicableDevices; /**< Applicable output device(s) for this strategy. */
-};
-
-typedef Element<routing_strategy> Strategy;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
index 73fb94d..297eb02 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -34,32 +34,6 @@
return NO_ERROR;
}
-/**
-* Set the strategy to follow for this stream.
-* It checks if the strategy is valid.
-*
-* @param[in] strategy to be followed.
-*
-* @return NO_ERROR if the strategy is set correctly, error code otherwise.
-*/
-template <>
-status_t Element<audio_stream_type_t>::set<routing_strategy>(routing_strategy strategy)
-{
- if (strategy >= NUM_STRATEGIES) {
- return BAD_VALUE;
- }
- mApplicableStrategy = strategy;
- ALOGD("%s: 0x%X for Stream %s", __FUNCTION__, strategy, getName().c_str());
- return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_stream_type_t>::get<routing_strategy>() const
-{
- ALOGV("%s: 0x%X for Stream %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
- return mApplicableStrategy;
-}
-
template <>
status_t Element<audio_stream_type_t>::set<audio_stream_type_t>(audio_stream_type_t volumeProfile)
{
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
index 2bf70b3..a4fdd39 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.h
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -18,22 +18,20 @@
#include "Element.h"
#include "EngineDefinition.h"
-#include <RoutingStrategy.h>
#include <map>
namespace android {
namespace audio_policy {
/**
- * @tparam routing_strategy: Applicable strategy for this stream.
+ * @tparam product_strategy_t: Applicable strategy for this stream.
*/
template <>
class Element<audio_stream_type_t>
{
public:
Element(const std::string &name)
- : mName(name),
- mApplicableStrategy(STRATEGY_MEDIA)
+ : mName(name)
{}
~Element() {}
@@ -61,7 +59,7 @@
/**
* A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
+ * Property may be audio_stream_type_t, audio_usage_t, audio_source_t
* or a string.
*/
template <typename Property>
@@ -78,8 +76,6 @@
std::string mName; /**< Unique literal Identifier of a policy base element*/
audio_stream_type_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
- routing_strategy mApplicableStrategy; /**< Applicable strategy for this stream. */
-
audio_stream_type_t mVolumeProfile; /**< Volume Profile followed by this stream. */
};
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.cpp b/services/audiopolicy/engineconfigurable/src/Usage.cpp
deleted file mode 100644
index 8c0dfba..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APM::AudioPolicyEngine/Usage"
-
-#include "Usage.h"
-
-namespace android {
-namespace audio_policy {
-
-status_t Element<audio_usage_t>::setIdentifier(audio_usage_t identifier)
-{
- if (identifier > AUDIO_USAGE_MAX) {
- return BAD_VALUE;
- }
- mIdentifier = identifier;
- ALOGD("%s: Usage %s has identifier 0x%X", __FUNCTION__, getName().c_str(), identifier);
- return NO_ERROR;
-}
-
-template <>
-status_t Element<audio_usage_t>::set<routing_strategy>(routing_strategy strategy)
-{
- if (strategy >= NUM_STRATEGIES) {
- return BAD_VALUE;
- }
- ALOGD("%s: %d for Usage %s", __FUNCTION__, strategy, getName().c_str());
- mApplicableStrategy = strategy;
- return NO_ERROR;
-}
-
-template <>
-routing_strategy Element<audio_usage_t>::get<routing_strategy>() const
-{
- ALOGD("%s: %d for Usage %s", __FUNCTION__, mApplicableStrategy, getName().c_str());
- return mApplicableStrategy;
-}
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.h b/services/audiopolicy/engineconfigurable/src/Usage.h
deleted file mode 100644
index 72a452f..0000000
--- a/services/audiopolicy/engineconfigurable/src/Usage.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "Element.h"
-#include <RoutingStrategy.h>
-
-namespace android {
-namespace audio_policy {
-
-/**
- * @tparam routing_strategy: Applicable strategy for this usage.
- */
-template <>
-class Element<audio_usage_t>
-{
-public:
- Element(const std::string &name)
- : mName(name),
- mApplicableStrategy(STRATEGY_MEDIA)
- {}
- ~Element() {}
-
- /**
- * Returns identifier of this policy element
- *
- * @returns string representing the name of this policy element
- */
- const std::string &getName() const { return mName; }
-
- /**
- * Set the unique identifier for this policy element.
- *
- * @tparam Key type of the unique identifier.
- * @param[in] identifier to be set.
- *
- * @return NO_ERROR if the identifier is valid and set correctly, error code otherwise.
- */
- status_t setIdentifier(audio_usage_t identifier);
-
- /**
- * @return the unique identifier of this policy element.
- */
- audio_usage_t getIdentifier() const { return mIdentifier; }
-
- /**
- * A Policy element may implement getter/setter function for a given property.
- * Property may be routing_strategy, audio_stream_type_t, audio_usage_t, audio_source_t
- * or a string.
- */
- template <typename Property>
- Property get() const;
-
- template <typename Property>
- status_t set(Property property);
-
-private:
- /* Copy facilities are put private to disable copy. */
- Element(const Element &object);
- Element &operator=(const Element &object);
-
- std::string mName; /**< Unique literal Identifier of a policy base element*/
- audio_usage_t mIdentifier; /**< Unique numerical Identifier of a policy base element*/
- routing_strategy mApplicableStrategy; /**< Applicable strategy for this usage. */
-};
-
-typedef Element<audio_usage_t> Usage;
-
-} // namespace audio_policy
-} // namespace android
-
-
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
index 4814376..eebdfd6 100644
--- a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
+++ b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
@@ -8,7 +8,6 @@
$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_CONFIGURATION_FILE := $(AUDIO_POLICY_CONFIGURATION_FILE)
$(LOCAL_BUILT_MODULE): MY_CRITERION_TOOL := $(HOST_OUT)/bin/buildPolicyCriterionTypes.py
$(LOCAL_BUILT_MODULE): $(LOCAL_REQUIRED_MODULES) $(LOCAL_ADDITIONAL_DEPENDENCIES) \
- buildPolicyCriterionTypes.py \
$(CRITERION_TYPES_FILE) \
$(ANDROID_AUDIO_BASE_HEADER_FILE)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
index d19a364..c7d8d34 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
@@ -1,8 +1,5 @@
LOCAL_PATH:= $(call my-dir)
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
-
##################################################################
# WRAPPER LIBRARY
##################################################################
@@ -13,20 +10,20 @@
$(LOCAL_PATH)/include \
frameworks/av/services/audiopolicy/engineconfigurable/include \
frameworks/av/services/audiopolicy/engineconfigurable/interface \
- frameworks/av/services/audiopolicy/common/include \
external/libxml2/include \
external/icu/icu4c/source/common
LOCAL_SRC_FILES:= \
- ParameterManagerWrapper.cpp \
- ParameterManagerWrapperConfig.cpp
+ ParameterManagerWrapper.cpp
LOCAL_SHARED_LIBRARIES := \
libparameter \
libmedia_helper \
- libicuuc \
libxml2
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon
+
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
@@ -40,39 +37,3 @@
include $(BUILD_STATIC_LIBRARY)
-##################################################################
-# CONFIGURATION FILE
-##################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_wrapper_configuration.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_criteria.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := policy_criterion_types.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
-
-AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
-ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
-CRITERION_TYPES_FILE := $(LOCAL_PATH)/config/policy_criterion_types.xml.in
-
-include $(PROVISION_CRITERION_TYPES)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 09faa4c..4b57444 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,6 @@
//#define LOG_NDEBUG 0
#include "ParameterManagerWrapper.h"
-#include "ParameterManagerWrapperConfig.h"
#include <ParameterMgrPlatformConnector.h>
#include <SelectionCriterionTypeInterface.h>
#include <SelectionCriterionInterface.h>
@@ -38,7 +37,6 @@
using std::string;
using std::map;
using std::vector;
-using CriterionTypes = std::map<std::string, ISelectionCriterionTypeInterface *>;
/// PFW related definitions
// Logger
@@ -106,63 +104,35 @@
// Logger
mPfwConnector->setLogger(mPfwConnectorLogger);
-
- status_t loadResult = loadConfig();
- if (loadResult < 0) {
- ALOGE("Policy Wrapper configuration is partially invalid.");
- }
}
-status_t ParameterManagerWrapper::loadConfig()
+status_t ParameterManagerWrapper::addCriterion(const std::string &name, bool isInclusive,
+ ValuePairs pairs, const std::string &defaultValue)
{
- auto result = wrapper_config::parse();
- if (result.parsedConfig == nullptr) {
- return -ENOENT;
+ ALOG_ASSERT(not isStarted(), "Cannot add a criterion if PFW is already started");
+ auto criterionType = mPfwConnector->createSelectionCriterionType(isInclusive);
+
+ for (auto pair : pairs) {
+ std::string error;
+ ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
+ pair.second.c_str(), name.c_str());
+ criterionType->addValuePair(pair.first, pair.second, error);
}
- ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+ ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
+ "%s: Criterion %s already added", __FUNCTION__, name.c_str());
- CriterionTypes criterionTypes;
- for (auto criterionType : result.parsedConfig->criterionTypes) {
- ALOG_ASSERT(criterionTypes.find(criterionType.name) == criterionTypes.end(),
- "CriterionType %s already added", criterionType.name.c_str());
- ALOGV("%s: Adding new criterionType %s", __FUNCTION__, criterionType.name.c_str());
+ auto criterion = mPfwConnector->createSelectionCriterion(name, criterionType);
+ mPolicyCriteria[name] = criterion;
- auto criterionTypePfw =
- mPfwConnector->createSelectionCriterionType(criterionType.isInclusive);
-
- for (auto pair : criterionType.valuePairs) {
- std::string error;
- ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
- pair.second.c_str(), criterionType.name.c_str());
- criterionTypePfw->addValuePair(pair.first, pair.second, error);
+ if (not defaultValue.empty()) {
+ int numericalValue = 0;
+ if (not criterionType->getNumericalValue(defaultValue.c_str(), numericalValue)) {
+ ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
+ defaultValue.c_str());
}
- criterionTypes[criterionType.name] = criterionTypePfw;
+ criterion->setCriterionState(numericalValue);
}
-
- for (auto criterion : result.parsedConfig->criteria) {
- ALOG_ASSERT(mPolicyCriteria.find(criterion.name) == mPolicyCriteria.end(),
- "%s: Criterion %s already added", __FUNCTION__, criterion.name.c_str());
-
- auto criterionType =
- getElement<ISelectionCriterionTypeInterface>(criterion.typeName, criterionTypes);
- ALOG_ASSERT(criterionType != nullptr, "No %s Criterion type found for criterion %s",
- criterion.typeName.c_str(), criterion.name.c_str());
-
- auto criterionPfw = mPfwConnector->createSelectionCriterion(criterion.name, criterionType);
- mPolicyCriteria[criterion.name] = criterionPfw;
-
- if (not criterion.defaultLiteralValue.empty()) {
- int numericalValue = 0;
- if (not criterionType->getNumericalValue(criterion.defaultLiteralValue.c_str(),
- numericalValue)) {
- ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
- criterion.defaultLiteralValue.c_str());
- continue;
- }
- criterionPfw->setCriterionState(numericalValue);
- }
- }
- return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+ return NO_ERROR;
}
ParameterManagerWrapper::~ParameterManagerWrapper()
@@ -289,7 +259,7 @@
std::string criterionName = audio_is_output_device(devDesc->type()) ?
gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
- ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->mAddress.string(),
+ ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().string(),
state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
deleted file mode 100644
index bc6d046..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2018 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/PFWWrapperConfig"
-#define LOG_NDEBUG 0
-
-#include "ParameterManagerWrapperConfig.h"
-
-#include <media/convert.h>
-#include <utils/Log.h>
-#include <libxml/parser.h>
-#include <libxml/xinclude.h>
-#include <string>
-#include <vector>
-#include <sstream>
-#include <istream>
-
-
-namespace android {
-
-using utilities::convertTo;
-
-namespace audio_policy {
-namespace wrapper_config {
-namespace detail {
-
-std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
-{
- xmlChar *xmlValue = xmlGetProp(cur, (const xmlChar *)attribute);
- if (xmlValue == NULL) {
- return "";
- }
- std::string value((const char *)xmlValue);
- xmlFree(xmlValue);
- return value;
-}
-
-template <class Trait>
-static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
- typename Trait::Collection &collection,
- size_t &nbSkippedElement)
-{
- const xmlNode *root = cur->xmlChildrenNode;
- while (root != NULL) {
- if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) &&
- xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
- root = root->next;
- continue;
- }
- const xmlNode *child = root;
- if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
- child = child->xmlChildrenNode;
- }
- while (child != NULL) {
- if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
- status_t status = Trait::deserialize(doc, child, collection);
- if (status == NO_ERROR) {
- nbSkippedElement += 1;
- }
- }
- child = child->next;
- }
- if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
- return NO_ERROR;
- }
- root = root->next;
- }
- return NO_ERROR;
-}
-
-const char *const ValueTraits::tag = "value";
-const char *const ValueTraits::collectionTag = "values";
-
-const char ValueTraits::Attributes::literal[] = "literal";
-const char ValueTraits::Attributes::numerical[] = "numerical";
-
-status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
-{
- std::string literal = getXmlAttribute(child, Attributes::literal);
- if (literal.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
- return BAD_VALUE;
- }
- uint32_t numerical = 0;
- std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
- if (numericalTag.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
- return BAD_VALUE;
- }
- if (!convertTo(numericalTag, numerical)) {
- ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
- return BAD_VALUE;
- }
- values.push_back({numerical, literal});
- return NO_ERROR;
-}
-
-const char *const CriterionTypeTraits::tag = "criterion_type";
-const char *const CriterionTypeTraits::collectionTag = "criterion_types";
-
-const char CriterionTypeTraits::Attributes::name[] = "name";
-const char CriterionTypeTraits::Attributes::type[] = "type";
-
-status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
- Collection &criterionTypes)
-{
- std::string name = getXmlAttribute(child, Attributes::name);
- if (name.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
- return BAD_VALUE;
- }
- ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
-
- std::string type = getXmlAttribute(child, Attributes::type);
- if (type.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
- return BAD_VALUE;
- }
- ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
- bool isInclusive(type == "inclusive");
-
- ValuePairs pairs;
- size_t nbSkippedElements = 0;
- detail::deserializeCollection<detail::ValueTraits>(doc, child, pairs, nbSkippedElements);
-
- criterionTypes.push_back({name, isInclusive, pairs});
- return NO_ERROR;
-}
-
-const char *const CriterionTraits::tag = "criterion";
-const char *const CriterionTraits::collectionTag = "criteria";
-
-const char CriterionTraits::Attributes::name[] = "name";
-const char CriterionTraits::Attributes::type[] = "type";
-const char CriterionTraits::Attributes::defaultVal[] = "default";
-
-status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &criteria)
-{
- std::string name = getXmlAttribute(child, Attributes::name);
- if (name.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
- return BAD_VALUE;
- }
- ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
-
- std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
- if (defaultValue.empty()) {
- // Not mandatory to provide a default value for a criterion, even it is recommanded...
- ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::defaultVal);
- }
- ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
-
- std::string typeName = getXmlAttribute(child, Attributes::type);
- if (typeName.empty()) {
- ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
- return BAD_VALUE;
- }
- ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
-
- criteria.push_back({name, typeName, defaultValue});
- return NO_ERROR;
-}
-} // namespace detail
-
-ParsingResult parse(const char* path) {
- xmlDocPtr doc;
- doc = xmlParseFile(path);
- if (doc == NULL) {
- ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
- return {nullptr, 0};
- }
- xmlNodePtr cur = xmlDocGetRootElement(doc);
- if (cur == NULL) {
- ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
- xmlFreeDoc(doc);
- return {nullptr, 0};
- }
- if (xmlXIncludeProcess(doc) < 0) {
- ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
- return {nullptr, 0};
- }
- size_t nbSkippedElements = 0;
- auto config = std::make_unique<Config>();
-
- detail::deserializeCollection<detail::CriterionTraits>(
- doc, cur, config->criteria, nbSkippedElements);
- detail::deserializeCollection<detail::CriterionTypeTraits>(
- doc, cur, config->criterionTypes, nbSkippedElements);
-
- return {std::move(config), nbSkippedElements};
-}
-
-} // namespace wrapper_config
-} // namespace audio_policy
-} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
deleted file mode 100644
index 467d0e1..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 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 <stdint.h>
-#include <string>
-#include <vector>
-#include <utils/Errors.h>
-
-struct _xmlNode;
-struct _xmlDoc;
-
-namespace android {
-namespace audio_policy {
-namespace wrapper_config {
-
-/** Default path of audio policy usages configuration file. */
-constexpr char DEFAULT_PATH[] = "/vendor/etc/policy_wrapper_configuration.xml";
-
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
-using ValuePair = std::pair<uint32_t, std::string>;
-using ValuePairs = std::vector<ValuePair>;
-
-struct CriterionType
-{
- std::string name;
- bool isInclusive;
- ValuePairs valuePairs;
-};
-
-using CriterionTypes = std::vector<CriterionType>;
-
-struct Criterion
-{
- std::string name;
- std::string typeName;
- std::string defaultLiteralValue;
-};
-
-using Criteria = std::vector<Criterion>;
-
-struct Config {
- float version;
- Criteria criteria;
- CriterionTypes criterionTypes;
-};
-
-namespace detail
-{
-struct ValueTraits
-{
- static const char *const tag;
- static const char *const collectionTag;
-
- struct Attributes
- {
- static const char literal[];
- static const char numerical[];
- };
-
- typedef ValuePair Element;
- typedef ValuePair *PtrElement;
- typedef ValuePairs Collection;
-
- static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
- Collection &collection);
-};
-
-struct CriterionTypeTraits
-{
- static const char *const tag;
- static const char *const collectionTag;
-
- struct Attributes
- {
- static const char name[];
- static const char type[];
- };
-
- typedef CriterionType Element;
- typedef CriterionType *PtrElement;
- typedef CriterionTypes Collection;
-
- static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
- Collection &collection);
-};
-
-struct CriterionTraits
-{
- static const char *const tag;
- static const char *const collectionTag;
-
- struct Attributes
- {
- static const char name[];
- static const char type[];
- static const char defaultVal[];
- };
-
- typedef Criterion Element;
- typedef Criterion *PtrElement;
- typedef Criteria Collection;
-
- static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
- Collection &collection);
-};
-} // namespace detail
-
-/** Result of `parse(const char*)` */
-struct ParsingResult {
- /** Parsed config, nullptr if the xml lib could not load the file */
- std::unique_ptr<Config> parsedConfig;
- size_t nbSkippedElement; //< Number of skipped invalid product strategies
-};
-
-/** Parses the provided audio policy usage configuration.
- * @return audio policy usage @see Config
- */
-ParsingResult parse(const char* path = DEFAULT_PATH);
-
-} // namespace wrapper_config
-} // namespace audio_policy
-} // android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index cd39b6f..5bfad29 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -39,6 +39,9 @@
namespace android {
namespace audio_policy {
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
class ParameterManagerWrapper
{
private:
@@ -118,6 +121,17 @@
status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
audio_policy_dev_state_t state);
+ /**
+ * @brief addCriterion to the policy pfw
+ * @param name of the criterion
+ * @param isInclusive if true, inclusive, if false exclusive criterion type
+ * @param pairs of numerical/literal values of the criterion
+ * @param defaultValue provided as literal.
+ * @return
+ */
+ status_t addCriterion(const std::string &name, bool isInclusive, ValuePairs pairs,
+ const std::string &defaultValue);
+
private:
/**
* Apply the configuration of the platform on the policy parameter manager.
@@ -131,13 +145,6 @@
*/
void applyPlatformConfiguration();
- /**
- * Load the criterion configuration file.
- *
- * @return NO_ERROR is parsing successful, error code otherwise.
- */
- status_t loadConfig();
-
/**
* Retrieve an element from a map by its name.
*
diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk
index 837d5bb..95eac1c 100644
--- a/services/audiopolicy/enginedefault/Android.mk
+++ b/services/audiopolicy/enginedefault/Android.mk
@@ -8,10 +8,11 @@
LOCAL_SRC_FILES := \
src/Engine.cpp \
src/EngineInstance.cpp \
+ ../engine/common/src/ProductStrategy.cpp \
+ ../engine/common/src/EngineBase.cpp
audio_policy_engine_includes_common := \
- $(LOCAL_PATH)/include \
- frameworks/av/services/audiopolicy/engine/interface
+ $(LOCAL_PATH)/include
LOCAL_CFLAGS += \
-Wall \
@@ -26,8 +27,7 @@
$(TARGET_OUT_HEADERS)/hw \
$(call include-path-for, frameworks-av) \
$(call include-path-for, audio-utils) \
- $(call include-path-for, bionic) \
- frameworks/av/services/audiopolicy/common/include
+ $(call include-path-for, bionic)
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
@@ -37,12 +37,19 @@
LOCAL_HEADER_LIBRARIES := libbase_headers
LOCAL_STATIC_LIBRARIES := \
- libaudiopolicycomponents \
+ libaudiopolicycomponents
-LOCAL_SHARED_LIBRARIES += \
+LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
libutils \
- libmedia_helper
+ libmedia_helper \
+ libaudiopolicyengineconfig \
+ libaudiopolicy
+
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_common_headers \
+ libaudiopolicyengine_interface_headers
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/enginedefault/config/Android.mk b/services/audiopolicy/enginedefault/config/Android.mk
new file mode 100644
index 0000000..dcce8e3
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/Android.mk
@@ -0,0 +1,9 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
new file mode 100644
index 0000000..866466f
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH := $(call my-dir)
+
+##################################################################
+# CONFIGURATION TOP FILE
+##################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+
+LOCAL_REQUIRED_MODULES := \
+ audio_policy_engine_product_strategies_phone.xml
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
+LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+include $(BUILD_PREBUILT)
+
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
similarity index 67%
copy from services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
copy to services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
index 5d9193b..ab61d8a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_configuration.xml
@@ -12,14 +12,11 @@
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.
--->
-<!--
- These are the minimum required criteria to be used by Audio HAL to ensure a basic
- user experience on an Android device
--->
-<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+ -->
- <xi:include href="policy_criterion_types.xml"/>
- <xi:include href="policy_criteria.xml"/>
+<configuration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <xi:include href="audio_policy_engine_product_strategies.xml"/>
</configuration>
+
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..f72e379
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2018 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.
+ -->
+
+<ProductStrategies>
+
+ <!-- "hidden strategies" like TTS, enforced audible:
+ Shall we expose them here or keep it hard coded -->
+
+ <!-- Used to identify the volume of audio streams for enforced system sounds in certain
+ countries (e.g. camera in Japan)
+ This strategy will only have higher priority than phone if force for system is set to
+ enforced. -->
+
+ <ProductStrategy name="STRATEGY_PHONE">
+ <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO">
+ <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_SONIFICATION">
+ <AttributesGroup streamType="AUDIO_STREAM_RING">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/> </Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_ALARM">
+ <Attributes> <Usage value="AUDIO_USAGE_ALARM"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_ENFORCED_AUDIBLE">
+ <AttributesGroup streamType="AUDIO_STREAM_ENFORCED_AUDIBLE">
+ <Attributes> <Flags value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_ACCESSIBILITY">
+ <AttributesGroup streamType="AUDIO_STREAM_ACCESSIBILITY">
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
+ <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_MEDIA">
+ <AttributesGroup streamType="AUDIO_STREAM_MUSIC">
+ <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/> </Attributes>
+ <Attributes></Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_SYSTEM">
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="STRATEGY_DTMF">
+ <AttributesGroup streamType="AUDIO_STREAM_DTMF">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Used to identify the volume of audio streams exclusively transmitted through the speaker
+ (TTS) of the device -->
+ <ProductStrategy name="STRATEGY_TRANSMITTED_THROUGH_SPEAKER">
+ <AttributesGroup streamType="AUDIO_STREAM_TTS">
+ <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Routing Strategy rerouting may be removed as following media??? -->
+ <ProductStrategy name="STRATEGY_REROUTING">
+ <AttributesGroup streamType="AUDIO_STREAM_REROUTING">
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Default product strategy has empty attributes -->
+ <ProductStrategy name="STRATEGY_PATCH">
+ <AttributesGroup streamType="AUDIO_STREAM_PATCH">
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+
+</ProductStrategies>
+
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index cc5a025..93af8a6 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -29,6 +29,7 @@
#include <AudioPolicyManagerObserver.h>
#include <AudioPort.h>
#include <IOProfile.h>
+#include <AudioIODescriptorInterface.h>
#include <policy.h>
#include <utils/String8.h>
#include <utils/Log.h>
@@ -38,31 +39,33 @@
namespace audio_policy
{
+struct legacy_strategy_map { const char *name; legacy_strategy id; };
+static const std::vector<legacy_strategy_map> gLegacyStrategy = {
+ { "STRATEGY_NONE", STRATEGY_NONE },
+ { "STRATEGY_MEDIA", STRATEGY_MEDIA },
+ { "STRATEGY_PHONE", STRATEGY_PHONE },
+ { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
+ { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
+ { "STRATEGY_DTMF", STRATEGY_DTMF },
+ { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
+ { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
+ { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
+ { "STRATEGY_REROUTING", STRATEGY_REROUTING },
+ { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
+};
+
Engine::Engine()
- : mManagerInterface(this),
- mPhoneState(AUDIO_MODE_NORMAL),
- mApmObserver(NULL)
{
- for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
- mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
+ auto result = EngineBase::loadAudioPolicyEngineConfig();
+ ALOGE_IF(result.nbSkippedElement != 0,
+ "Policy Engine configuration is partially invalid, skipped %zu elements",
+ result.nbSkippedElement);
+
+ for (const auto &strategy : gLegacyStrategy) {
+ mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
}
}
-Engine::~Engine()
-{
-}
-
-void Engine::setObserver(AudioPolicyManagerObserver *observer)
-{
- ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
- mApmObserver = observer;
-}
-
-status_t Engine::initCheck()
-{
- return (mApmObserver != NULL) ? NO_ERROR : NO_INIT;
-}
-
status_t Engine::setPhoneState(audio_mode_t state)
{
ALOGV("setPhoneState() state %d", state);
@@ -72,22 +75,22 @@
return BAD_VALUE;
}
- if (state == mPhoneState ) {
+ if (state == getPhoneState()) {
ALOGW("setPhoneState() setting same state %d", state);
return BAD_VALUE;
}
// store previous phone state for management of sonification strategy below
- int oldState = mPhoneState;
- mPhoneState = state;
+ int oldState = getPhoneState();
+ EngineBase::setPhoneState(state);
if (!is_state_in_call(oldState) && is_state_in_call(state)) {
ALOGV(" Entering call in setPhoneState()");
- mApmObserver->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
+ getApmObserver()->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
AUDIO_STREAM_DTMF);
} else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
ALOGV(" Exiting call in setPhoneState()");
- mApmObserver->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
+ getApmObserver()->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
}
return NO_ERROR;
}
@@ -101,7 +104,6 @@
ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
return BAD_VALUE;
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_MEDIA:
if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
@@ -112,7 +114,6 @@
ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
return BAD_VALUE;
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_RECORD:
if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
@@ -120,7 +121,6 @@
ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
return BAD_VALUE;
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_DOCK:
if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
@@ -130,21 +130,18 @@
config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_SYSTEM:
if (config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
if (config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
if (config != AUDIO_POLICY_FORCE_NONE &&
@@ -154,109 +151,25 @@
ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
return BAD_VALUE;
}
- mForceUse[usage] = config;
break;
case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
return BAD_VALUE;
}
- mForceUse[usage] = config;
break;
default:
ALOGW("setForceUse() invalid usage %d", usage);
break; // TODO return BAD_VALUE?
}
- return NO_ERROR;
+ return EngineBase::setForceUse(usage, config);
}
-routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
-{
- // stream to strategy mapping
- switch (stream) {
- case AUDIO_STREAM_VOICE_CALL:
- case AUDIO_STREAM_BLUETOOTH_SCO:
- return STRATEGY_PHONE;
- case AUDIO_STREAM_RING:
- case AUDIO_STREAM_ALARM:
- return STRATEGY_SONIFICATION;
- case AUDIO_STREAM_NOTIFICATION:
- return STRATEGY_SONIFICATION_RESPECTFUL;
- case AUDIO_STREAM_DTMF:
- return STRATEGY_DTMF;
- default:
- ALOGE("unknown stream type %d", stream);
- FALLTHROUGH_INTENDED;
- case AUDIO_STREAM_SYSTEM:
- // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
- // while key clicks are played produces a poor result
- case AUDIO_STREAM_MUSIC:
- return STRATEGY_MEDIA;
- case AUDIO_STREAM_ENFORCED_AUDIBLE:
- return STRATEGY_ENFORCED_AUDIBLE;
- case AUDIO_STREAM_TTS:
- return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
- case AUDIO_STREAM_ACCESSIBILITY:
- return STRATEGY_ACCESSIBILITY;
- case AUDIO_STREAM_REROUTING:
- return STRATEGY_REROUTING;
- }
-}
-
-routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
-{
- // usage to strategy mapping
- switch (usage) {
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
- return STRATEGY_ACCESSIBILITY;
-
- case AUDIO_USAGE_MEDIA:
- case AUDIO_USAGE_GAME:
- case AUDIO_USAGE_ASSISTANT:
- case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
- case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
- return STRATEGY_MEDIA;
-
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- return STRATEGY_PHONE;
-
- case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
- return STRATEGY_DTMF;
-
- case AUDIO_USAGE_ALARM:
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- return STRATEGY_SONIFICATION;
-
- case AUDIO_USAGE_NOTIFICATION:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
- case AUDIO_USAGE_NOTIFICATION_EVENT:
- return STRATEGY_SONIFICATION_RESPECTFUL;
-
- case AUDIO_USAGE_UNKNOWN:
- default:
- return STRATEGY_MEDIA;
- }
-}
-
-audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
-{
- DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
- DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
-
- const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
-
- return getDeviceForStrategyInt(strategy, availableOutputDevices,
- availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
-}
-
-
-audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
- DeviceVector availableOutputDevices,
- DeviceVector availableInputDevices,
- const SwAudioOutputCollection &outputs,
- uint32_t outputDeviceTypesToIgnore) const
+audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
+ DeviceVector availableOutputDevices,
+ DeviceVector availableInputDevices,
+ const SwAudioOutputCollection &outputs,
+ uint32_t outputDeviceTypesToIgnore) const
{
uint32_t device = AUDIO_DEVICE_NONE;
uint32_t availableOutputDevicesType =
@@ -334,7 +247,7 @@
}
// for phone strategy, we first consider the forced use and then the available devices by
// order of priority
- switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+ switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
case AUDIO_POLICY_FORCE_BT_SCO:
if (!isInCall() || strategy != STRATEGY_DTMF) {
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
@@ -352,7 +265,7 @@
if (device) break;
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
if (!isInCall() &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
outputs.isA2dpSupported()) {
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
if (device) break;
@@ -386,7 +299,7 @@
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
// A2DP speaker when forcing to speaker output
if (!isInCall() &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
outputs.isA2dpSupported()) {
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
if (device) break;
@@ -426,7 +339,7 @@
// - in countries where not enforced in which case it follows STRATEGY_MEDIA
if ((strategy == STRATEGY_SONIFICATION) ||
- (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
}
@@ -442,9 +355,9 @@
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
}
// Use ONLY Bluetooth SCO output when ringing in vibration mode
- if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+ if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
&& (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
- if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
+ if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
== AUDIO_POLICY_FORCE_BT_SCO) {
if (device2 != AUDIO_DEVICE_NONE) {
device = device2;
@@ -453,7 +366,7 @@
}
}
// Use both Bluetooth SCO and phone default output when ringing in normal mode
- if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
if ((strategy == STRATEGY_SONIFICATION) &&
(device & AUDIO_DEVICE_OUT_SPEAKER) &&
(availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
@@ -520,7 +433,7 @@
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
}
if ((device2 == AUDIO_DEVICE_NONE) &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
outputs.isA2dpSupported()) {
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
if (device2 == AUDIO_DEVICE_NONE) {
@@ -531,7 +444,7 @@
}
}
if ((device2 == AUDIO_DEVICE_NONE) &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
}
if (device2 == AUDIO_DEVICE_NONE) {
@@ -560,7 +473,7 @@
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
}
if ((device2 == AUDIO_DEVICE_NONE) &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
}
if (device2 == AUDIO_DEVICE_NONE) {
@@ -581,7 +494,7 @@
// If hdmi system audio mode is on, remove speaker out of output list.
if ((strategy == STRATEGY_MEDIA) &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
+ (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
device &= ~AUDIO_DEVICE_OUT_SPEAKER;
}
@@ -603,7 +516,7 @@
if (device == AUDIO_DEVICE_NONE) {
ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
- device = mApmObserver->getDefaultOutputDevice()->type();
+ device = getApmObserver()->getDefaultOutputDevice()->type();
ALOGE_IF(device == AUDIO_DEVICE_NONE,
"getDeviceForStrategy() no default device defined");
}
@@ -614,9 +527,9 @@
audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
{
- const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
- const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
- const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
+ const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+ const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
uint32_t device = AUDIO_DEVICE_NONE;
@@ -651,7 +564,7 @@
case AUDIO_SOURCE_MIC:
if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
- } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
+ } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
(availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
} else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -675,7 +588,7 @@
primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
}
- switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
+ switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
case AUDIO_POLICY_FORCE_BT_SCO:
// if SCO device is requested but no SCO device is available, fall back to default case
if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
@@ -709,7 +622,7 @@
case AUDIO_SOURCE_VOICE_RECOGNITION:
case AUDIO_SOURCE_UNPROCESSED:
case AUDIO_SOURCE_HOTWORD:
- if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
+ if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
} else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -780,10 +693,107 @@
return device;
}
+void Engine::updateDeviceSelectionCache()
+{
+ for (const auto &iter : getProductStrategies()) {
+ const auto &strategy = iter.second;
+ auto devices = getDevicesForProductStrategy(strategy->getId());
+ mDevicesForStrategies[strategy->getId()] = devices;
+ strategy->setDeviceTypes(devices.types());
+ strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
+ }
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
+{
+ DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
+ const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+
+ auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
+ mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+ audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
+ availableOutputDevices,
+ availableInputDevices, outputs,
+ (uint32_t)AUDIO_DEVICE_NONE);
+ return availableOutputDevices.getDevicesFromTypeMask(devices);
+}
+
+DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
+ const sp<DeviceDescriptor> &preferredDevice,
+ bool fromCache) const
+{
+ // First check for explict routing device
+ if (preferredDevice != nullptr) {
+ ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
+ return DeviceVector(preferredDevice);
+ }
+ product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+ const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
+ //
+ // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+ // be by APM?
+ //
+ // Honor explicit routing requests only if all active clients have a preferred route in which
+ // case the last active client route is used
+ sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+ if (device != nullptr) {
+ return DeviceVector(device);
+ }
+
+ return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+}
+
+DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
+{
+ auto attributes = getAttributesForStreamType(stream);
+ return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
+}
+
+sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
+ AudioMix **mix) const
+{
+ const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+ const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+ const auto &inputs = getApmObserver()->getInputs();
+ std::string address;
+
+ //
+ // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+ // first as it used to be by APM?
+ //
+ // Honor explicit routing requests only if all active clients have a preferred route in which
+ // case the last active client route is used
+ sp<DeviceDescriptor> device =
+ findPreferredDevice(inputs, attr.source, availableInputDevices);
+ if (device != nullptr) {
+ return device;
+ }
+
+ device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+ if (device != nullptr) {
+ return device;
+ }
+ audio_devices_t deviceType = getDeviceForInputSource(attr.source);
+
+ if (audio_is_remote_submix_device(deviceType)) {
+ address = "0";
+ std::size_t pos;
+ std::string tags { attr.tags };
+ if ((pos = tags.find("addr=")) != std::string::npos) {
+ address = tags.substr(pos + std::strlen("addr="));
+ }
+ }
+ return availableInputDevices.getDevice(deviceType,
+ String8(address.c_str()),
+ AUDIO_FORMAT_DEFAULT);
+}
+
template <>
AudioPolicyManagerInterface *Engine::queryInterface()
{
- return &mManagerInterface;
+ return this;
}
} // namespace audio_policy
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 06186c1..15fc358 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -16,7 +16,7 @@
#pragma once
-
+#include "EngineBase.h"
#include "AudioPolicyManagerInterface.h"
#include <AudioGain.h>
#include <policy.h>
@@ -29,114 +29,69 @@
namespace audio_policy
{
-class Engine
+enum legacy_strategy {
+ STRATEGY_NONE = -1,
+ STRATEGY_MEDIA,
+ STRATEGY_PHONE,
+ STRATEGY_SONIFICATION,
+ STRATEGY_SONIFICATION_RESPECTFUL,
+ STRATEGY_DTMF,
+ STRATEGY_ENFORCED_AUDIBLE,
+ STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+ STRATEGY_ACCESSIBILITY,
+ STRATEGY_REROUTING,
+};
+
+class Engine : public EngineBase
{
public:
Engine();
- virtual ~Engine();
+ virtual ~Engine() = default;
template <class RequestedInterface>
RequestedInterface *queryInterface();
private:
- /// Interface members
- class ManagerInterfaceImpl : public AudioPolicyManagerInterface
- {
- public:
- explicit ManagerInterfaceImpl(Engine *policyEngine)
- : mPolicyEngine(policyEngine) {}
+ ///
+ /// from EngineBase, so from AudioPolicyManagerInterface
+ ///
+ status_t setPhoneState(audio_mode_t mode) override;
- virtual void setObserver(AudioPolicyManagerObserver *observer)
- {
- mPolicyEngine->setObserver(observer);
- }
- virtual status_t initCheck()
- {
- return mPolicyEngine->initCheck();
- }
- virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const
- {
- return mPolicyEngine->getDeviceForInputSource(inputSource);
- }
- virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy) const
- {
- return mPolicyEngine->getDeviceForStrategy(strategy);
- }
- virtual routing_strategy getStrategyForStream(audio_stream_type_t stream)
- {
- return mPolicyEngine->getStrategyForStream(stream);
- }
- virtual routing_strategy getStrategyForUsage(audio_usage_t usage)
- {
- return mPolicyEngine->getStrategyForUsage(usage);
- }
- virtual status_t setPhoneState(audio_mode_t mode)
- {
- return mPolicyEngine->setPhoneState(mode);
- }
- virtual audio_mode_t getPhoneState() const
- {
- return mPolicyEngine->getPhoneState();
- }
- virtual status_t setForceUse(audio_policy_force_use_t usage,
- audio_policy_forced_cfg_t config)
- {
- return mPolicyEngine->setForceUse(usage, config);
- }
- virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
- {
- return mPolicyEngine->getForceUse(usage);
- }
- virtual status_t setDeviceConnectionState(const sp<DeviceDescriptor> /*devDesc*/,
- audio_policy_dev_state_t /*state*/)
- {
- return NO_ERROR;
- }
- private:
- Engine *mPolicyEngine;
- } mManagerInterface;
+ status_t setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config) override;
+
+ DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
+ const sp<DeviceDescriptor> &preferedDevice = nullptr,
+ bool fromCache = false) const override;
+
+ DeviceVector getOutputDevicesForStream(audio_stream_type_t stream,
+ bool fromCache = false) const override;
+
+ sp<DeviceDescriptor> getInputDeviceForAttributes(
+ const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
+
+ void updateDeviceSelectionCache() override;
private:
/* Copy facilities are put private to disable copy. */
Engine(const Engine &object);
Engine &operator=(const Engine &object);
- void setObserver(AudioPolicyManagerObserver *observer);
-
- status_t initCheck();
-
- inline bool isInCall() const
- {
- return is_state_in_call(mPhoneState);
- }
-
- status_t setPhoneState(audio_mode_t mode);
- audio_mode_t getPhoneState() const
- {
- return mPhoneState;
- }
- status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
- audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
- {
- return mForceUse[usage];
- }
status_t setDefaultDevice(audio_devices_t device);
- routing_strategy getStrategyForStream(audio_stream_type_t stream);
- routing_strategy getStrategyForUsage(audio_usage_t usage);
- audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
- audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
- DeviceVector availableOutputDevices,
- DeviceVector availableInputDevices,
- const SwAudioOutputCollection &outputs,
- uint32_t outputDeviceTypesToIgnore) const;
+ audio_devices_t getDeviceForStrategyInt(legacy_strategy strategy,
+ DeviceVector availableOutputDevices,
+ DeviceVector availableInputDevices,
+ const SwAudioOutputCollection &outputs,
+ uint32_t outputDeviceTypesToIgnore) const;
+
+ DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+
audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
- audio_mode_t mPhoneState; /**< current phone state. */
- /** current forced use configuration. */
- audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];
+ DeviceStrategyMap mDevicesForStrategies;
- AudioPolicyManagerObserver *mApmObserver;
+ std::map<product_strategy_t, legacy_strategy> mLegacyStrategyMap;
};
} // namespace audio_policy
} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d7c7b4d..0eee3f2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -44,7 +44,6 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include <media/AudioParameter.h>
-#include <media/AudioPolicyHelper.h>
#include <private/android_filesystem_config.h>
#include <soundtrigger/SoundTrigger.h>
#include <system/audio.h>
@@ -495,9 +494,10 @@
ALOG_ASSERT(!rxDevices.isEmpty(), "updateCallRouting() no selected output device");
audio_attributes_t attr = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
- auto txSourceDevice = getDeviceAndMixForAttributes(attr);
+ auto txSourceDevice = mEngine->getInputDeviceForAttributes(attr);
ALOG_ASSERT(txSourceDevice != 0, "updateCallRouting() input selected device not available");
- ALOGV("updateCallRouting device rxDevice %s txDevice %s",
+
+ ALOGV("updateCallRouting device rxDevice %s txDevice %s",
rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());
// release existing RX patch if any
@@ -677,26 +677,27 @@
int delayMs = 0;
if (isStateInCall(state)) {
nsecs_t sysTime = systemTime();
+ auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+ auto sonificationStrategy = streamToStrategy(AUDIO_STREAM_ALARM);
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
// mute media and sonification strategies and delay device switch by the largest
// latency of any output where either strategy is active.
// This avoid sending the ring tone or music tail into the earpiece or headset.
- if ((isStrategyActive(desc, STRATEGY_MEDIA,
- SONIFICATION_HEADSET_MUSIC_DELAY,
- sysTime) ||
- isStrategyActive(desc, STRATEGY_SONIFICATION,
- SONIFICATION_HEADSET_MUSIC_DELAY,
- sysTime)) &&
+ if ((desc->isStrategyActive(musicStrategy, SONIFICATION_HEADSET_MUSIC_DELAY, sysTime) ||
+ desc->isStrategyActive(sonificationStrategy, SONIFICATION_HEADSET_MUSIC_DELAY,
+ sysTime)) &&
(delayMs < (int)desc->latency()*2)) {
delayMs = desc->latency()*2;
}
- setStrategyMute(STRATEGY_MEDIA, true, desc);
- setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
- setStrategyMute(STRATEGY_SONIFICATION, true, desc);
- setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+ setStrategyMute(musicStrategy, true, desc);
+ setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+ mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+ nullptr, true /*fromCache*/).types());
+ setStrategyMute(sonificationStrategy, true, desc);
+ setStrategyMute(sonificationStrategy, false, desc, MUTE_TIME_MS,
+ mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_ALARM),
+ nullptr, true /*fromCache*/).types());
}
}
@@ -743,12 +744,8 @@
}
// Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
- if (state == AUDIO_MODE_RINGTONE &&
- isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
- mLimitRingtoneVolume = true;
- } else {
- mLimitRingtoneVolume = false;
- }
+ mLimitRingtoneVolume = (state == AUDIO_MODE_RINGTONE &&
+ isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY));
}
audio_mode_t AudioPolicyManager::getPhoneState() {
@@ -871,8 +868,7 @@
audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream)
{
- routing_strategy strategy = getStrategy(stream);
- DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+ DeviceVector devices = mEngine->getOutputDevicesForStream(stream, false /*fromCache*/);
// Note that related method getOutputForAttr() uses getOutputForDevice() not selectOutput().
// We use selectOutput() here since we don't have the desired AudioTrack sample rate,
@@ -906,7 +902,7 @@
ALOGE("%s: invalid stream type", __func__);
return BAD_VALUE;
}
- stream_type_to_audio_attributes(srcStream, dstAttr);
+ *dstAttr = mEngine->getAttributesForStreamType(srcStream);
}
return NO_ERROR;
}
@@ -919,59 +915,55 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId)
+ audio_port_handle_t *selectedDeviceId,
+ bool *isRequestedDeviceForExclusiveUse)
{
- DeviceVector devices;
- routing_strategy strategy;
- audio_devices_t deviceType = AUDIO_DEVICE_NONE;
+ DeviceVector outputDevices;
const audio_port_handle_t requestedPortId = *selectedDeviceId;
DeviceVector msdDevices = getMsdAudioOutDevices();
+ const sp<DeviceDescriptor> requestedDevice =
+ mAvailableOutputDevices.getDeviceFromId(requestedPortId);
+
+
status_t status = getAudioAttributes(resultAttr, attr, *stream);
if (status != NO_ERROR) {
return status;
}
+ *stream = mEngine->getStreamTypeForAttributes(*resultAttr);
- ALOGV("%s usage=%d, content=%d, tag=%s flags=%08x"
- " session %d selectedDeviceId %d",
- __func__,
- resultAttr->usage, resultAttr->content_type, resultAttr->tags, resultAttr->flags,
- session, requestedPortId);
+ ALOGV("%s() attributes=%s stream=%s session %d selectedDeviceId %d", __func__,
+ toString(*resultAttr).c_str(), toString(*stream).c_str(), session, requestedPortId);
- *stream = streamTypefromAttributesInt(resultAttr);
-
- strategy = getStrategyForAttr(resultAttr);
-
- // First check for explicit routing (eg. setPreferredDevice)
- sp<DeviceDescriptor> requestedDevice = mAvailableOutputDevices.getDeviceFromId(requestedPortId);
- if (requestedDevice != nullptr) {
- deviceType = requestedDevice->type();
- } else {
- // If no explict route, is there a matching dynamic policy that applies?
- sp<SwAudioOutputDescriptor> desc;
- if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
- ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
- if (!audio_has_proportional_frames(config->format)) {
- return BAD_VALUE;
- }
- *stream = streamTypefromAttributesInt(resultAttr);
- *output = desc->mIoHandle;
- AudioMix *mix = desc->mPolicyMix;
- sp<DeviceDescriptor> deviceDesc =
- mAvailableOutputDevices.getDevice(
- mix->mDeviceType, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
- *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
- ALOGV("%s returns output %d", __func__, *output);
- return NO_ERROR;
- }
-
- // Virtual sources must always be dynamicaly or explicitly routed
- if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
- ALOGW("%s no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE", __func__);
+ // 1/ First check for explicit routing (eg. setPreferredDevice): NOTE: now handled by engine
+ // 2/ If no explict route, is there a matching dynamic policy that applies?
+ // NOTE: new engine product strategy does not make use of dynamic routing, keep it for
+ // remote-submix and legacy
+ sp<SwAudioOutputDescriptor> desc;
+ if (requestedDevice == nullptr &&
+ mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
+ ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
+ if (!audio_has_proportional_frames(config->format)) {
return BAD_VALUE;
}
- deviceType = getDeviceForStrategy(strategy, false /*fromCache*/);
+ *output = desc->mIoHandle;
+ AudioMix *mix = desc->mPolicyMix;
+ sp<DeviceDescriptor> deviceDesc =
+ mAvailableOutputDevices.getDevice(mix->mDeviceType,
+ mix->mDeviceAddress,
+ AUDIO_FORMAT_DEFAULT);
+ *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
+ ALOGV("getOutputForAttr() returns output %d", *output);
+ return NO_ERROR;
}
+ // Virtual sources must always be dynamicaly or explicitly routed
+ if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
+ ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
+ return BAD_VALUE;
+ }
+ // explicit routing managed by getDeviceForStrategy in APM is now handled by engine
+ // in order to let the choice of the order to future vendor engine
+ outputDevices = mEngine->getOutputDevicesForAttributes(*resultAttr, requestedDevice, false);
if ((resultAttr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
*flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
@@ -982,45 +974,40 @@
// FIXME: provide a more generic approach which is not device specific and move this back
// to getOutputForDevice.
// TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
- if (deviceType == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
- (*stream == AUDIO_STREAM_MUSIC || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
+ if (outputDevices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+ (*stream == AUDIO_STREAM_MUSIC || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
audio_is_linear_pcm(config->format) &&
isInCall()) {
if (requestedPortId != AUDIO_PORT_HANDLE_NONE) {
*flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
- } else {
- // Get the devce type directly from the engine to bypass preferred route logic
- deviceType = mEngine->getDeviceForStrategy(strategy);
+ *isRequestedDeviceForExclusiveUse = true;
}
}
- ALOGV("%s device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
- "flags %#x",
- __func__,
- deviceType, config->sample_rate, config->format, config->channel_mask, *flags);
+ ALOGV("%s() device %s, sampling rate %d, format %#x, channel mask %#x, flags %#x stream %s",
+ __func__, outputDevices.toString().c_str(), config->sample_rate, config->format,
+ config->channel_mask, *flags, toString(*stream).c_str());
*output = AUDIO_IO_HANDLE_NONE;
if (!msdDevices.isEmpty()) {
*output = getOutputForDevices(msdDevices, session, *stream, config, flags);
- sp<DeviceDescriptor> deviceDesc =
- mAvailableOutputDevices.getDevice(deviceType, String8(), AUDIO_FORMAT_DEFAULT);
- if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(deviceDesc) == NO_ERROR) {
- ALOGV("%s() Using MSD devices %s instead of device %s",
- __func__, msdDevices.toString().c_str(), deviceDesc->toString().c_str());
- deviceType = msdDevices.types();
+ sp<DeviceDescriptor> device = outputDevices.isEmpty() ? nullptr : outputDevices.itemAt(0);
+ if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(device) == NO_ERROR) {
+ ALOGV("%s() Using MSD devices %s instead of devices %s",
+ __func__, msdDevices.toString().c_str(), outputDevices.toString().c_str());
+ outputDevices = msdDevices;
} else {
*output = AUDIO_IO_HANDLE_NONE;
}
}
- devices = mAvailableOutputDevices.getDevicesFromTypeMask(deviceType);
if (*output == AUDIO_IO_HANDLE_NONE) {
- *output = getOutputForDevices(devices, session, *stream, config, flags);
+ *output = getOutputForDevices(outputDevices, session, *stream, config, flags);
}
if (*output == AUDIO_IO_HANDLE_NONE) {
return INVALID_OPERATION;
}
- *selectedDeviceId = getFirstDeviceId(devices);
+ *selectedDeviceId = getFirstDeviceId(outputDevices);
ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
@@ -1043,8 +1030,9 @@
}
const audio_port_handle_t requestedPortId = *selectedDeviceId;
audio_attributes_t resultAttr;
+ bool isRequestedDeviceForExclusiveUse = false;
status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
- config, flags, selectedDeviceId);
+ config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse);
if (status != NO_ERROR) {
return status;
}
@@ -1057,13 +1045,13 @@
sp<TrackClientDescriptor> clientDesc =
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
requestedPortId, *stream,
- getStrategyForAttr(&resultAttr),
- *flags);
+ mEngine->getProductStrategyForAttributes(resultAttr),
+ *flags, isRequestedDeviceForExclusiveUse);
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
outputDesc->addClient(clientDesc);
- ALOGV("%s returns output %d selectedDeviceId %d for port ID %d",
- __func__, *output, requestedPortId, *portId);
+ ALOGV("%s() returns output %d selectedDeviceId %d for port ID %d", __func__,
+ *output, *selectedDeviceId, *portId);
return NO_ERROR;
}
@@ -1368,7 +1356,8 @@
// Use media strategy for unspecified output device. This should only
// occur on checkForDeviceAndOutputChanges(). Device connection events may
// therefore invalidate explicit routing requests.
- DeviceVector devices = getDevicesForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
+ DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+ attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
LOG_ALWAYS_FATAL_IF(devices.isEmpty(), "no outpudevice to set Msd Patch");
device = devices.itemAt(0);
}
@@ -1547,6 +1536,8 @@
*delayMs = 0;
audio_stream_type_t stream = client->stream();
+ auto clientStrategy = client->strategy();
+ auto clientAttr = client->attributes();
if (stream == AUDIO_STREAM_TTS) {
ALOGV("\t found BEACON stream");
if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
@@ -1594,11 +1585,11 @@
if (client->hasPreferredDevice(true)) {
devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
if (devices != outputDesc->devices()) {
- checkStrategyRoute(getStrategy(stream), outputDesc->mIoHandle);
+ checkStrategyRoute(clientStrategy, outputDesc->mIoHandle);
}
}
- if (stream == AUDIO_STREAM_MUSIC) {
+ if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
selectOutputForMusicEffects();
}
@@ -1607,11 +1598,10 @@
if (devices.isEmpty()) {
devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
}
-
- routing_strategy strategy = getStrategy(stream);
- bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
- (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
- (beaconMuteLatency > 0);
+ bool shouldWait =
+ (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) ||
+ followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) ||
+ (beaconMuteLatency > 0));
uint32_t waitMs = beaconMuteLatency;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1666,7 +1656,7 @@
handleNotificationRoutingForStream(stream);
// force reevaluating accessibility routing when ringtone or alarm starts
- if (strategy == STRATEGY_SONIFICATION) {
+ if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
}
@@ -1685,7 +1675,7 @@
if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
- setStrategyMute(STRATEGY_SONIFICATION, true, outputDesc);
+ setStrategyMute(streamToStrategy(AUDIO_STREAM_ALARM), true, outputDesc);
}
// Automatically enable the remote submix input when output is started on a re routing mix
@@ -1747,7 +1737,7 @@
}
bool forceDeviceUpdate = false;
if (client->hasPreferredDevice(true)) {
- checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
+ checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE);
forceDeviceUpdate = true;
}
@@ -1756,7 +1746,7 @@
// store time at which the stream was stopped - see isStreamActive()
if (outputDesc->streamActiveCount(stream) == 0 || forceDeviceUpdate) {
- outputDesc->mStopTime[stream] = systemTime();
+ outputDesc->setStopTime(client, systemTime());
DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
// delay the device switch by twice the latency because stopOutput() is executed when
// the track stop() command is received and at that time the audio track buffer can
@@ -1791,10 +1781,10 @@
if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
- setStrategyMute(STRATEGY_SONIFICATION, false, outputDesc);
+ setStrategyMute(streamToStrategy(AUDIO_STREAM_RING), false, outputDesc);
}
- if (stream == AUDIO_STREAM_MUSIC) {
+ if (followsSameRouting(client->attributes(), attributes_initializer(AUDIO_USAGE_MEDIA))) {
selectOutputForMusicEffects();
}
return NO_ERROR;
@@ -1849,9 +1839,9 @@
input_type_t *inputType,
audio_port_handle_t *portId)
{
- ALOGV("getInputForAttr() source %d, sampling rate %d, format %#x, channel mask %#x,"
- "session %d, flags %#x",
- attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
+ ALOGV("%s() source %d, sampling rate %d, format %#x, channel mask %#x, session %d, "
+ "flags %#x attributes=%s", __func__, attr->source, config->sample_rate,
+ config->format, config->channel_mask, session, flags, toString(*attr).c_str());
status_t status = NO_ERROR;
audio_source_t halInputSource;
@@ -1940,7 +1930,7 @@
if (explicitRoutingDevice != nullptr) {
device = explicitRoutingDevice;
} else {
- device = getDeviceAndMixForAttributes(attributes, &policyMix);
+ device = mEngine->getInputDeviceForAttributes(attributes, &policyMix);
}
if (device == nullptr) {
ALOGW("getInputForAttr() could not find device for source %d", attributes.source);
@@ -1954,8 +1944,6 @@
// know about it and is therefore considered "legacy"
*inputType = API_INPUT_LEGACY;
} else if (audio_is_remote_submix_device(device->type())) {
- device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"),
- AUDIO_FORMAT_DEFAULT);
*inputType = API_INPUT_MIX_CAPTURE;
} else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
*inputType = API_INPUT_TELEPHONY_RX;
@@ -1965,9 +1953,7 @@
}
- *input = getInputForDevice(device, session, attributes.source,
- config, flags,
- policyMix);
+ *input = getInputForDevice(device, session, attributes, config, flags, policyMix);
if (*input == AUDIO_IO_HANDLE_NONE) {
status = INVALID_OPERATION;
goto error;
@@ -1975,8 +1961,8 @@
exit:
- *selectedDeviceId = mAvailableInputDevices.contains(device) ?
- device->getId() : AUDIO_PORT_HANDLE_NONE;
+ *selectedDeviceId = mAvailableInputDevices.contains(device) ?
+ device->getId() : AUDIO_PORT_HANDLE_NONE;
isSoundTrigger = attributes.source == AUDIO_SOURCE_HOTWORD &&
mSoundTriggerSessions.indexOfKey(session) > 0;
@@ -2000,16 +1986,16 @@
audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescriptor> &device,
audio_session_t session,
- audio_source_t inputSource,
+ const audio_attributes_t &attributes,
const audio_config_base_t *config,
audio_input_flags_t flags,
AudioMix *policyMix)
{
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
- audio_source_t halInputSource = inputSource;
+ audio_source_t halInputSource = attributes.source;
bool isSoundTrigger = false;
- if (inputSource == AUDIO_SOURCE_HOTWORD) {
+ if (attributes.source == AUDIO_SOURCE_HOTWORD) {
ssize_t index = mSoundTriggerSessions.indexOfKey(session);
if (index >= 0) {
input = mSoundTriggerSessions.valueFor(session);
@@ -2019,7 +2005,7 @@
} else {
halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
}
- } else if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+ } else if (attributes.source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
audio_is_linear_pcm(config->format)) {
flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_VOIP_TX);
}
@@ -2374,10 +2360,10 @@
// update volume on all outputs and streams matching the following:
// - The requested stream (or a stream matching for volume control) is active on the output
- // - The device (or devices) selected by the strategy corresponding to this stream includes
+ // - The device (or devices) selected by the engine for this stream includes
// the requested device
// - For non default requested device, currently selected device on the output is either the
- // requested device or one of the devices selected by the strategy
+ // requested device or one of the devices selected by the engine for this stream
// - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
// no specific device volume value exists for currently selected device.
status_t status = NO_ERROR;
@@ -2391,9 +2377,9 @@
if (!(desc->isStreamActive((audio_stream_type_t)curStream) || isInCall())) {
continue;
}
- routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
- audio_devices_t curStreamDevice = Volume::getDeviceForVolume(getDeviceForStrategy(
- curStrategy, false /*fromCache*/));
+ audio_devices_t curStreamDevice = Volume::getDeviceForVolume(
+ mEngine->getOutputDevicesForStream((audio_stream_type_t)curStream,
+ false /*fromCache*/).types());
if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
((curStreamDevice & device) == 0)) {
continue;
@@ -2435,10 +2421,10 @@
if (!audio_is_output_device(device)) {
return BAD_VALUE;
}
- // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
- // the strategy the stream belongs to.
+ // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
+ // stream by the engine.
if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
- device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
+ device = mEngine->getOutputDevicesForStream(stream, true /*fromCache*/).types();
}
device = Volume::getDeviceForVolume(device);
@@ -2458,8 +2444,8 @@
// 3: The primary output
// 4: the first output in the list
- routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
- DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+ DeviceVector devices = mEngine->getOutputDevicesForAttributes(
+ attributes_initializer(AUDIO_USAGE_MEDIA), nullptr, false /*fromCache*/);
SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
if (outputs.size() == 0) {
@@ -2531,7 +2517,9 @@
return INVALID_OPERATION;
}
}
- return mEffects.registerEffect(desc, io, strategy, session, id);
+ return mEffects.registerEffect(desc, io, session, id,
+ (strategy == streamToStrategy(AUDIO_STREAM_MUSIC) ||
+ strategy == PRODUCT_STRATEGY_NONE));
}
status_t AudioPolicyManager::unregisterEffect(int id)
@@ -2870,6 +2858,9 @@
mAudioPatches.dump(dst);
mPolicyMixes.dump(dst);
mAudioSources.dump(dst);
+
+ dst->appendFormat("\nPolicy Engine dump:\n");
+ mEngine->dump(dst);
}
status_t AudioPolicyManager::dump(int fd)
@@ -2956,7 +2947,7 @@
bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) {
audio_output_flags_t output_flags = AUDIO_OUTPUT_FLAG_NONE;
- audio_attributes_flags_to_audio_output_flags(attributes.flags, output_flags);
+ audio_flags_to_audio_output_flags(attributes.flags, &output_flags);
sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
config.sample_rate,
config.format,
@@ -3461,27 +3452,27 @@
}
}
-void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
- audio_io_handle_t ouptutToSkip)
+void AudioPolicyManager::checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip)
{
- DeviceVector devices = getDevicesForStrategy(strategy, false /*fromCache*/);
+ // Take the first attributes following the product strategy as it is used to retrieve the routed
+ // device. All attributes wihin a strategy follows the same "routing strategy"
+ auto attributes = mEngine->getAllAttributesForProductStrategy(ps).front();
+ DeviceVector devices = mEngine->getOutputDevicesForAttributes(attributes, nullptr, false);
SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
for (size_t j = 0; j < mOutputs.size(); j++) {
if (mOutputs.keyAt(j) == ouptutToSkip) {
continue;
}
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
- if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
+ if (!outputDesc->isStrategyActive(ps)) {
continue;
}
// If the default device for this strategy is on another output mix,
// invalidate all tracks in this strategy to force re connection.
// Otherwise select new device on the output mix.
if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
- for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
- if (getStrategy((audio_stream_type_t)stream) == strategy) {
- mpClientInterface->invalidateStream((audio_stream_type_t)stream);
- }
+ for (auto stream : mEngine->getStreamTypesForProductStrategy(ps)) {
+ mpClientInterface->invalidateStream(stream);
}
} else {
setOutputDevices(
@@ -3493,13 +3484,18 @@
void AudioPolicyManager::clearSessionRoutes(uid_t uid)
{
// remove output routes associated with this uid
- SortedVector<routing_strategy> affectedStrategies;
+ std::vector<product_strategy_t> affectedStrategies;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
for (const auto& client : outputDesc->getClientIterable()) {
if (client->hasPreferredDevice() && client->uid() == uid) {
client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
- affectedStrategies.add(getStrategy(client->stream()));
+ auto clientStrategy = client->strategy();
+ if (std::find(begin(affectedStrategies), end(affectedStrategies), clientStrategy) !=
+ end(affectedStrategies)) {
+ continue;
+ }
+ affectedStrategies.push_back(client->strategy());
}
}
}
@@ -3549,7 +3545,7 @@
*session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
*ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
audio_attributes_t attr = { .source = AUDIO_SOURCE_HOTWORD };
- *device = getDeviceAndMixForAttributes(attr)->type();
+ *device = mEngine->getInputDeviceForAttributes(attr)->type();
return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
}
@@ -3591,8 +3587,8 @@
sp<SourceClientDescriptor> sourceDesc =
new SourceClientDescriptor(*portId, uid, *attributes, patchDesc, srcDevice,
- streamTypefromAttributesInt(attributes),
- getStrategyForAttr(attributes));
+ mEngine->getStreamTypeForAttributes(*attributes),
+ mEngine->getProductStrategyForAttributes(*attributes));
status_t status = connectAudioSource(sourceDesc);
if (status == NO_ERROR) {
@@ -3609,12 +3605,12 @@
disconnectAudioSource(sourceDesc);
audio_attributes_t attributes = sourceDesc->attributes();
- routing_strategy strategy = getStrategyForAttr(&attributes);
audio_stream_type_t stream = sourceDesc->stream();
sp<DeviceDescriptor> srcDevice = sourceDesc->srcDevice();
- DeviceVector sinkDevices = getDevicesForStrategy(strategy, true);
- ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for strategy");
+ DeviceVector sinkDevices =
+ mEngine->getOutputDevicesForAttributes(attributes, nullptr, true);
+ ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for attributes");
sp<DeviceDescriptor> sinkDevice = sinkDevices.itemAt(0);
ALOG_ASSERT(mAvailableOutputDevices.contains(sinkDevice), "%s: Device %s not available",
__FUNCTION__, sinkDevice->toString().c_str());
@@ -3638,8 +3634,10 @@
config.format = sourceDesc->config().format;
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ bool isRequestedDeviceForExclusiveUse = false;
getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
- &attributes, &stream, sourceDesc->uid(), &config, &flags, &selectedDeviceId);
+ &attributes, &stream, sourceDesc->uid(), &config, &flags,
+ &selectedDeviceId, &isRequestedDeviceForExclusiveUse);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevices.types());
return INVALID_OPERATION;
@@ -3968,16 +3966,15 @@
return NO_ERROR;
}
-sp<SourceClientDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
- audio_io_handle_t output, routing_strategy strategy)
+sp<SourceClientDescriptor> AudioPolicyManager::getSourceForAttributesOnOutput(
+ audio_io_handle_t output, const audio_attributes_t &attr)
{
sp<SourceClientDescriptor> source;
for (size_t i = 0; i < mAudioSources.size(); i++) {
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
- audio_attributes_t attributes = sourceDesc->attributes();
- routing_strategy sourceStrategy = getStrategyForAttr(&attributes);
sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->swOutput().promote();
- if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
+ if (followsSameRouting(attr, sourceDesc->attributes()) &&
+ outputDesc != 0 && outputDesc->mIoHandle == output) {
source = sourceDesc;
break;
}
@@ -4792,16 +4789,25 @@
}
}
-void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
+bool AudioPolicyManager::followsSameRouting(const audio_attributes_t &lAttr,
+ const audio_attributes_t &rAttr) const
{
- DeviceVector oldDevices = getDevicesForStrategy(strategy, true /*fromCache*/);
- DeviceVector newDevices = getDevicesForStrategy(strategy, false /*fromCache*/);
+ return mEngine->getProductStrategyForAttributes(lAttr) ==
+ mEngine->getProductStrategyForAttributes(rAttr);
+}
+
+void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
+{
+ auto psId = mEngine->getProductStrategyForAttributes(attr);
+
+ 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);
// also take into account external policy-related changes: add all outputs which are
// associated with policies in the "before" and "after" output vectors
- ALOGVV("checkOutputForStrategy(): policy related outputs");
+ ALOGVV("%s(): policy related outputs", __func__);
for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
if (desc != 0 && desc->mPolicyMix != NULL) {
@@ -4817,7 +4823,7 @@
}
}
- if (!dstOutputs.isEmpty() && srcOutputs != dstOutputs) {
+ if (srcOutputs != dstOutputs) {
// get maximum latency of all source outputs to determine the minimum mute time guaranteeing
// audio from invalidated tracks will be rendered when unmuting
uint32_t maxLatency = 0;
@@ -4828,50 +4834,40 @@
}
}
ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
- "%s: strategy %d, moving from output %s to output %s", __func__, strategy,
+ "%s: strategy %d, moving from output %s to output %s", __func__, psId,
std::to_string(srcOutputs[0]).c_str(),
std::to_string(dstOutputs[0]).c_str());
// mute strategy while moving tracks from one output to another
for (audio_io_handle_t srcOut : srcOutputs) {
sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
- if (desc != 0 && isStrategyActive(desc, strategy)) {
- setStrategyMute(strategy, true, desc);
- setStrategyMute(strategy, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
+ if (desc != 0 && desc->isStrategyActive(psId)) {
+ setStrategyMute(psId, true, desc);
+ setStrategyMute(psId, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
newDevices.types());
}
- sp<SourceClientDescriptor> source =
- getSourceForStrategyOnOutput(srcOut, strategy);
+ sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
if (source != 0){
connectAudioSource(source);
}
}
- // Move effects associated to this strategy from previous output to new output
- if (strategy == STRATEGY_MEDIA) {
+ // Move effects associated to this stream from previous output to new output
+ if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
selectOutputForMusicEffects();
}
- // Move tracks associated to this strategy from previous output to new output
- for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
- if (getStrategy((audio_stream_type_t)i) == strategy) {
- mpClientInterface->invalidateStream((audio_stream_type_t)i);
- }
+ // Move tracks associated to this stream (and linked) from previous output to new output
+ for (auto stream : mEngine->getStreamTypesForProductStrategy(psId)) {
+ mpClientInterface->invalidateStream(stream);
}
}
}
void AudioPolicyManager::checkOutputForAllStrategies()
{
- if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
- checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
- checkOutputForStrategy(STRATEGY_PHONE);
- if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
- checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
- checkOutputForStrategy(STRATEGY_SONIFICATION);
- checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
- checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
- checkOutputForStrategy(STRATEGY_MEDIA);
- checkOutputForStrategy(STRATEGY_DTMF);
- checkOutputForStrategy(STRATEGY_REROUTING);
+ for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
+ auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
+ checkOutputForAttributes(attributes);
+ }
}
void AudioPolicyManager::checkA2dpSuspend()
@@ -4924,38 +4920,6 @@
}
}
-template <class IoDescriptor, class Filter>
-sp<DeviceDescriptor> AudioPolicyManager::findPreferredDevice(
- IoDescriptor& desc, Filter filter, bool& active, const DeviceVector& devices)
-{
- auto activeClients = desc->clientsList(true /*activeOnly*/);
- auto activeClientsWithRoute =
- desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
- active = activeClients.size() > 0;
- if (active && activeClients.size() == activeClientsWithRoute.size()) {
- return devices.getDeviceFromId(activeClientsWithRoute[0]->preferredDeviceId());
- }
- return nullptr;
-}
-
-template <class IoCollection, class Filter>
-sp<DeviceDescriptor> AudioPolicyManager::findPreferredDevice(
- IoCollection& ioCollection, Filter filter, const DeviceVector& devices)
-{
- sp<DeviceDescriptor> device;
- for (size_t i = 0; i < ioCollection.size(); i++) {
- auto desc = ioCollection.valueAt(i);
- bool active;
- sp<DeviceDescriptor> curDevice = findPreferredDevice(desc, filter, active, devices);
- if (active && curDevice == nullptr) {
- return nullptr;
- } else if (curDevice != nullptr) {
- device = curDevice;
- }
- }
- return device;
-}
-
DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
bool fromCache)
{
@@ -4975,7 +4939,7 @@
// input: a specific app can not force routing for other apps by setting a preferred device.
bool active; // unused
sp<DeviceDescriptor> device =
- findPreferredDevice(outputDesc, STRATEGY_NONE, active, mAvailableOutputDevices);
+ findPreferredDevice(outputDesc, PRODUCT_STRATEGY_NONE, active, mAvailableOutputDevices);
if (device != nullptr) {
return DeviceVector(device);
}
@@ -4987,54 +4951,22 @@
return DeviceVector(device);
}
- // check the following by order of priority to request a routing change if necessary:
- // 1: the strategy enforced audible is active and enforced on the output:
- // use device for strategy enforced audible
- // 2: we are in call or the strategy phone is active on the output:
- // use device for strategy phone
- // 3: the strategy sonification is active on the output:
- // use device for strategy sonification
- // 4: the strategy for enforced audible is active but not enforced on the output:
- // use the device for strategy enforced audible
- // 5: the strategy accessibility is active on the output:
- // use device for strategy accessibility
- // 6: the strategy "respectful" sonification is active on the output:
- // use device for strategy "respectful" sonification
- // 7: the strategy media is active on the output:
- // use device for strategy media
- // 8: the strategy DTMF is active on the output:
- // use device for strategy DTMF
- // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
- // use device for strategy t-t-s
+ for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
+ StreamTypeVector streams = mEngine->getStreamTypesForProductStrategy(productStrategy);
+ auto attr = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
- // FIXME: extend use of isStrategyActiveOnSameModule() to all strategies
- // with a refined rule considering mutually exclusive devices (using same backend)
- // as opposed to all streams on the same audio HAL module.
- if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
- mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
- devices = getDevicesForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
- } else if (isInCall() ||
- isStrategyActiveOnSameModule(outputDesc, STRATEGY_PHONE)) {
- devices = getDevicesForStrategy(STRATEGY_PHONE, fromCache);
- } else if (isStrategyActiveOnSameModule(outputDesc, STRATEGY_SONIFICATION)) {
- devices = getDevicesForStrategy(STRATEGY_SONIFICATION, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
- devices = getDevicesForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
- devices = getDevicesForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
- devices = getDevicesForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
- devices = getDevicesForStrategy(STRATEGY_MEDIA, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
- devices = getDevicesForStrategy(STRATEGY_DTMF, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
- devices = getDevicesForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
- } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
- devices = getDevicesForStrategy(STRATEGY_REROUTING, fromCache);
+ if ((hasVoiceStream(streams) &&
+ (isInCall() || mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc))) ||
+ (hasStream(streams, AUDIO_STREAM_ALARM) &&
+ mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) ||
+ outputDesc->isStrategyActive(productStrategy)) {
+ // Retrieval of devices for voice DL is done on primary output profile, cannot
+ // check the route (would force modifying configuration file for this profile)
+ devices = mEngine->getOutputDevicesForAttributes(attr, nullptr, fromCache);
+ break;
+ }
}
-
- ALOGV("getNewOutputDevice() selected devices %s", devices.toString().c_str());
+ ALOGV("%s selected devices %s", __func__, devices.toString().c_str());
return devices;
}
@@ -5068,7 +5000,7 @@
attributes.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
}
if (attributes.source != AUDIO_SOURCE_DEFAULT) {
- device = getDeviceAndMixForAttributes(attributes);
+ device = mEngine->getInputDeviceForAttributes(attributes);
}
return device;
@@ -5079,26 +5011,22 @@
return (stream1 == stream2);
}
-uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
- return (uint32_t)getStrategy(stream);
-}
-
audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
// By checking the range of stream before calling getStrategy, we avoid
- // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
- // and then return STRATEGY_MEDIA, but we want to return the empty set.
- if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
+ // getOutputDevicesForStream's behavior for invalid streams.
+ // engine's getOutputDevicesForStream would fallback on its default behavior (most probably
+ // device for music stream), but we want to return the empty set.
+ if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_DEVICE_NONE;
}
DeviceVector activeDevices;
DeviceVector devices;
- for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
- if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
+ for (audio_stream_type_t curStream = AUDIO_STREAM_MIN; curStream < AUDIO_STREAM_PUBLIC_CNT;
+ curStream = (audio_stream_type_t) (curStream + 1)) {
+ if (!streamsMatchForvolume(stream, curStream)) {
continue;
}
- routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
- DeviceVector curDevices =
- getDevicesForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
+ DeviceVector curDevices = mEngine->getOutputDevicesForStream(curStream, false/*fromCache*/);
devices.merge(curDevices);
for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
@@ -5123,28 +5051,10 @@
return devices.types();
}
-routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
-{
- ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
- return mEngine->getStrategyForStream(stream);
-}
-
-routing_strategy AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
- // flags to strategy mapping
- if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
- return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
- }
- if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
- return STRATEGY_ENFORCED_AUDIBLE;
- }
- // usage to strategy mapping
- return mEngine->getStrategyForUsage(attr->usage);
-}
-
void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
switch(stream) {
case AUDIO_STREAM_MUSIC:
- checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+ checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION));
updateDevicesAndOutputs();
break;
default:
@@ -5211,33 +5121,14 @@
return 0;
}
-DeviceVector AudioPolicyManager::getDevicesForStrategy(routing_strategy strategy, bool fromCache)
-{
- // Honor explicit routing requests only if all active clients have a preferred route in which
- // case the last active client route is used
- sp<DeviceDescriptor> device = findPreferredDevice(mOutputs, strategy, mAvailableOutputDevices);
- if (device != nullptr) {
- return DeviceVector(device);
- }
-
- if (fromCache) {
- ALOGVV("%s from cache strategy %d, device %s", __func__, strategy,
- mDevicesForStrategy[strategy].toString().c_str());
- return mDevicesForStrategy[strategy];
- }
- return mAvailableOutputDevices.getDevicesFromTypeMask(mEngine->getDeviceForStrategy(strategy));
-}
-
void AudioPolicyManager::updateDevicesAndOutputs()
{
- for (int i = 0; i < NUM_STRATEGIES; i++) {
- mDevicesForStrategy[i] = getDevicesForStrategy((routing_strategy)i, false /*fromCache*/);
- }
+ mEngine->updateDeviceSelectionCache();
mPreviousOutputs = mOutputs;
}
uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
- audio_devices_t prevDeviceType,
+ const DeviceVector &prevDevices,
uint32_t delayMs)
{
// mute/unmute strategies using an incompatible device combination
@@ -5248,22 +5139,24 @@
}
uint32_t muteWaitMs = 0;
- audio_devices_t deviceType = outputDesc->devices().types();
- bool shouldMute = outputDesc->isActive() && (popcount(deviceType) >= 2);
+ DeviceVector devices = outputDesc->devices();
+ bool shouldMute = outputDesc->isActive() && (devices.size() >= 2);
- for (size_t i = 0; i < NUM_STRATEGIES; i++) {
- audio_devices_t curDeviceType =
- getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
- curDeviceType = curDeviceType & outputDesc->supportedDevices().types();
- bool mute = shouldMute && (curDeviceType & deviceType) && (curDeviceType != deviceType);
+ auto productStrategies = mEngine->getOrderedProductStrategies();
+ for (const auto &productStrategy : productStrategies) {
+ auto attributes = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
+ DeviceVector curDevices =
+ mEngine->getOutputDevicesForAttributes(attributes, nullptr, false/*fromCache*/);
+ curDevices = curDevices.filter(outputDesc->supportedDevices());
+ bool mute = shouldMute && curDevices.containsAtLeastOne(devices) && curDevices != devices;
bool doMute = false;
- if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
+ if (mute && !outputDesc->isStrategyMutedByDevice(productStrategy)) {
doMute = true;
- outputDesc->mStrategyMutedByDevice[i] = true;
- } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
+ outputDesc->setStrategyMutedByDevice(productStrategy, true);
+ } else if (!mute && outputDesc->isStrategyMutedByDevice(productStrategy)) {
doMute = true;
- outputDesc->mStrategyMutedByDevice[i] = false;
+ outputDesc->setStrategyMutedByDevice(productStrategy, false);
}
if (doMute) {
for (size_t j = 0; j < mOutputs.size(); j++) {
@@ -5272,10 +5165,10 @@
if (!desc->supportedDevices().containsAtLeastOne(outputDesc->supportedDevices())) {
continue;
}
- ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
- mute ? "muting" : "unmuting", i, curDeviceType);
- setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
- if (isStrategyActive(desc, (routing_strategy)i)) {
+ ALOGVV("%s() %s (curDevice %s)", __func__,
+ mute ? "muting" : "unmuting", curDevices.toString().c_str());
+ setStrategyMute(productStrategy, mute, desc, mute ? 0 : delayMs);
+ if (desc->isStrategyActive(productStrategy)) {
if (mute) {
// FIXME: should not need to double latency if volume could be applied
// immediately by the audioflinger mixer. We must account for the delay
@@ -5293,7 +5186,7 @@
// temporary mute output if device selection changes to avoid volume bursts due to
// different per device volumes
- if (outputDesc->isActive() && (deviceType != prevDeviceType)) {
+ if (outputDesc->isActive() && (devices != prevDevices)) {
uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
// temporary mute duration is conservatively set to 4 times the reported latency
uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
@@ -5301,13 +5194,13 @@
muteWaitMs = tempMuteWaitMs;
}
- for (size_t i = 0; i < NUM_STRATEGIES; i++) {
- if (isStrategyActive(outputDesc, (routing_strategy)i)) {
+ for (const auto &productStrategy : productStrategies) {
+ if (outputDesc->isStrategyActive(productStrategy)) {
// make sure that we do not start the temporary mute period too early in case of
// delayed device change
- setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
- setStrategyMute((routing_strategy)i, false, outputDesc,
- delayMs + tempMuteDurationMs, deviceType);
+ setStrategyMute(productStrategy, true, outputDesc, delayMs);
+ setStrategyMute(productStrategy, false, outputDesc, delayMs + tempMuteDurationMs,
+ devices.types());
}
}
}
@@ -5359,7 +5252,7 @@
// if the outputs are not materially active, there is no need to mute.
if (requiresMuteCheck) {
- muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevices.types(), delayMs);
+ muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevices, delayMs);
} else {
ALOGV("%s: suppressing checkDeviceMuteStrategies", __func__);
muteWaitMs = 0;
@@ -5531,36 +5424,6 @@
return NULL;
}
-sp<DeviceDescriptor> AudioPolicyManager::getDeviceAndMixForAttributes(
- const audio_attributes_t &attributes, AudioMix **policyMix)
-{
- // Honor explicit routing requests only if all active clients have a preferred route in which
- // case the last active client route is used
- sp<DeviceDescriptor> device =
- findPreferredDevice(mInputs, attributes.source, mAvailableInputDevices);
- if (device != nullptr) {
- return device;
- }
-
- sp<DeviceDescriptor> selectedDeviceFromMix =
- mPolicyMixes.getDeviceAndMixForInputSource(attributes.source, mAvailableInputDevices,
- policyMix);
- return (selectedDeviceFromMix != nullptr) ?
- selectedDeviceFromMix : getDeviceForAttributes(attributes);
-}
-
-sp<DeviceDescriptor> AudioPolicyManager::getDeviceForAttributes(const audio_attributes_t &attributes)
-{
- audio_devices_t device = mEngine->getDeviceForInputSource(attributes.source);
- if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
- strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
- return mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- String8(attributes.tags + strlen("addr=")),
- AUDIO_FORMAT_DEFAULT);
- }
- return mAvailableInputDevices.getDevice(device, String8(), AUDIO_FORMAT_DEFAULT);
-}
-
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
int index,
audio_devices_t device)
@@ -5613,18 +5476,18 @@
// speaker is part of the select devices
// - if music is playing, always limit the volume to current music volume,
// with a minimum threshold at -36dB so that notification is always perceived.
- const routing_strategy stream_strategy = getStrategy(stream);
if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
AUDIO_DEVICE_OUT_USB_HEADSET |
AUDIO_DEVICE_OUT_HEARING_AID)) &&
- ((stream_strategy == STRATEGY_SONIFICATION)
- || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
+ ((stream == AUDIO_STREAM_ALARM || stream == AUDIO_STREAM_RING)
+ || (stream == AUDIO_STREAM_NOTIFICATION)
|| (stream == AUDIO_STREAM_SYSTEM)
- || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
- (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
+ || ((stream == AUDIO_STREAM_ENFORCED_AUDIBLE) &&
+ (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
+ AUDIO_POLICY_FORCE_NONE))) &&
mVolumeCurves->canBeMuted(stream)) {
// when the phone is ringing we must consider that music could have been paused just before
// by the music application and behave as if music was active if the last music track was
@@ -5632,7 +5495,9 @@
if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
mLimitRingtoneVolume) {
volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
- audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
+ audio_devices_t musicDevice =
+ mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+ nullptr, true /*fromCache*/).types();
float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
musicDevice),
@@ -5656,7 +5521,7 @@
}
}
} else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
- stream_strategy != STRATEGY_SONIFICATION) {
+ (stream != AUDIO_STREAM_ALARM && stream != AUDIO_STREAM_RING)) {
volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
}
}
@@ -5761,18 +5626,16 @@
}
}
-void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
- bool on,
- const sp<AudioOutputDescriptor>& outputDesc,
- int delayMs,
- audio_devices_t device)
+void AudioPolicyManager::setStrategyMute(product_strategy_t strategy,
+ bool on,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ int delayMs,
+ audio_devices_t device)
{
- ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
- strategy, on, outputDesc->getId());
- for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
- if (getStrategy((audio_stream_type_t)stream) == strategy) {
- setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
- }
+ for (auto stream: mEngine->getStreamTypesForProductStrategy(strategy)) {
+ ALOGVV("%s() stream %d, mute %d, output ID %d", __FUNCTION__, stream, on,
+ outputDesc->getId());
+ setStreamMute(stream, on, outputDesc, delayMs, device);
}
}
@@ -5814,25 +5677,9 @@
}
}
-audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
-{
- // flags to stream type mapping
- if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
- return AUDIO_STREAM_ENFORCED_AUDIBLE;
- }
- if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
- return AUDIO_STREAM_BLUETOOTH_SCO;
- }
- if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
- return AUDIO_STREAM_TTS;
- }
-
- return audio_usage_to_stream_type(attr->usage);
-}
-
bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
{
- // has flags that map to a strategy?
+ // has flags that map to a stream type?
if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
return true;
}
@@ -5863,37 +5710,6 @@
return true;
}
-bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
- routing_strategy strategy, uint32_t inPastMs,
- nsecs_t sysTime) const
-{
- if ((sysTime == 0) && (inPastMs != 0)) {
- sysTime = systemTime();
- }
- for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
- if (((getStrategy((audio_stream_type_t)i) == strategy) ||
- (STRATEGY_NONE == strategy)) &&
- outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
- return true;
- }
- }
- return false;
-}
-
-bool AudioPolicyManager::isStrategyActiveOnSameModule(const sp<SwAudioOutputDescriptor>& outputDesc,
- routing_strategy strategy, uint32_t inPastMs,
- nsecs_t sysTime) const
-{
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (outputDesc->sharesHwModuleWith(desc)
- && isStrategyActive(desc, strategy, inPastMs, sysTime)) {
- return true;
- }
- }
- return false;
-}
-
audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
{
return mEngine->getForceUse(usage);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index de6d489..73c3b56 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -153,9 +153,15 @@
audio_devices_t device);
// return the strategy corresponding to a given stream type
- virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
- // return the strategy corresponding to the given audio attributes
- virtual routing_strategy getStrategyForAttr(const audio_attributes_t *attr);
+ virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
+ {
+ return streamToStrategy(stream);
+ }
+ product_strategy_t streamToStrategy(audio_stream_type_t stream) const
+ {
+ auto attributes = mEngine->getAttributesForStreamType(stream);
+ return mEngine->getProductStrategyForAttributes(attributes);
+ }
// return the enabled output devices for the given stream type
virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
@@ -244,13 +250,20 @@
virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
std::vector<audio_format_t> *formats);
- // return the strategy corresponding to a given stream type
- routing_strategy getStrategy(audio_stream_type_t stream) const;
-
virtual void setAppState(uid_t uid, app_state_t state);
virtual bool isHapticPlaybackSupported();
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
+ {
+ return mEngine->listAudioProductStrategies(strategies);
+ }
+
+ virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa)
+ {
+ return mEngine->getProductStrategyForAttributes(aa.getAttributes());
+ }
+
protected:
// A constructor that allows more fine-grained control over initialization process,
// used in automatic tests.
@@ -306,32 +319,6 @@
void removeOutput(audio_io_handle_t output);
void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
- // return appropriate device for streams handled by the specified strategy according to current
- // phone state, connected devices...
- // if fromCache is true, the device is returned from mDeviceForStrategy[],
- // otherwise it is determine by current state
- // (device connected,phone state, force use, a2dp output...)
- // This allows to:
- // 1 speed up process when the state is stable (when starting or stopping an output)
- // 2 access to either current device selection (fromCache == true) or
- // "future" device selection (fromCache == false) when called from a context
- // where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
- // before updateDevicesAndOutputs() is called.
- virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy,
- bool fromCache)
- {
- return getDevicesForStrategy(strategy, fromCache).types();
- }
-
- DeviceVector getDevicesForStrategy(routing_strategy strategy, bool fromCache);
-
- bool isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc, routing_strategy strategy,
- uint32_t inPastMs = 0, nsecs_t sysTime = 0) const;
-
- bool isStrategyActiveOnSameModule(const sp<SwAudioOutputDescriptor>& outputDesc,
- routing_strategy strategy, uint32_t inPastMs = 0,
- nsecs_t sysTime = 0) const;
-
// change the route of the specified output. Returns the number of ms we have slept to
// allow new routing to take effect in certain cases.
uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
@@ -350,9 +337,6 @@
status_t resetInputDevice(audio_io_handle_t input,
audio_patch_handle_t *patchHandle = NULL);
- // select input device corresponding to requested audio source
- sp<DeviceDescriptor> getDeviceForAttributes(const audio_attributes_t &attributes);
-
// compute the actual volume for a given stream according to the requested index and a particular
// device
virtual float computeVolume(audio_stream_type_t stream,
@@ -373,8 +357,16 @@
void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device, int delayMs = 0, bool force = false);
- // Mute or unmute all streams handled by the specified strategy on the specified output
- void setStrategyMute(routing_strategy strategy,
+ /**
+ * @brief setStrategyMute Mute or unmute all active clients on the considered output
+ * following the given strategy.
+ * @param strategy to be considered
+ * @param on true for mute, false for unmute
+ * @param outputDesc to be considered
+ * @param delayMs
+ * @param device
+ */
+ void setStrategyMute(product_strategy_t strategy,
bool on,
const sp<AudioOutputDescriptor>& outputDesc,
int delayMs = 0,
@@ -420,26 +412,28 @@
// A2DP suspend status is rechecked.
void checkForDeviceAndOutputChanges(std::function<bool()> onOutputsChecked = nullptr);
- // checks and if necessary changes outputs used for all strategies.
- // must be called every time a condition that affects the output choice for a given strategy
- // changes: connected device, phone state, force use...
- // Must be called before updateDevicesAndOutputs()
- void checkOutputForStrategy(routing_strategy strategy);
+ /**
+ * @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
+ * attributes changes: connected device, phone state, force use...
+ * Must be called before updateDevicesAndOutputs()
+ * @param attr to be considered
+ */
+ void checkOutputForAttributes(const audio_attributes_t &attr);
- // Same as checkOutputForStrategy() but for a all strategies in order of priority
+ bool followsSameRouting(const audio_attributes_t &lAttr,
+ const audio_attributes_t &rAttr) const;
+
+ /**
+ * @brief checkOutputForAllStrategies Same as @see checkOutputForAttributes()
+ * but for a all product strategies in order of priority
+ */
void checkOutputForAllStrategies();
// manages A2DP output suspend/restore according to phone state and BT SCO usage
void checkA2dpSuspend();
- template <class IoDescriptor, class Filter>
- sp<DeviceDescriptor> findPreferredDevice(IoDescriptor& desc, Filter filter,
- bool& active, const DeviceVector& devices);
-
- template <class IoCollection, class Filter>
- sp<DeviceDescriptor> findPreferredDevice(IoCollection& ioCollection, Filter filter,
- const DeviceVector& devices);
-
// selects the most appropriate device on output for current state
// must be called every time a condition that affects the device choice for a given output is
// changed: connected device, phone state, force use, output start, output stop..
@@ -447,11 +441,14 @@
DeviceVector getNewOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
bool fromCache);
- // updates cache of device used by all strategies (mDeviceForStrategy[])
- // must be called every time a condition that affects the device choice for a given strategy is
- // changed: connected device, phone state, force use...
- // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
- // Must be called after checkOutputForAllStrategies()
+ /**
+ * @brief updateDevicesAndOutputs: updates cache of devices of the engine
+ * must be called every time a condition that affects the device choice is changed:
+ * connected device, phone state, force use...
+ * cached values are used by getOutputDevicesForStream()/getDevicesForAttributes if
+ * parameter fromCache is true.
+ * Must be called after checkOutputForAllStrategies()
+ */
void updateDevicesAndOutputs();
// selects the most appropriate device on input for current state
@@ -470,13 +467,19 @@
SortedVector<audio_io_handle_t> getOutputsForDevices(
const DeviceVector &devices, const SwAudioOutputCollection& openOutputs);
- // mute/unmute strategies using an incompatible device combination
- // if muting, wait for the audio in pcm buffer to be drained before proceeding
- // if unmuting, unmute only after the specified delay
- // Returns the number of ms waited
- virtual uint32_t checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
- audio_devices_t prevDeviceType,
- uint32_t delayMs);
+ /**
+ * @brief checkDeviceMuteStrategies mute/unmute strategies
+ * using an incompatible device combination.
+ * if muting, wait for the audio in pcm buffer to be drained before proceeding
+ * if unmuting, unmute only after the specified delay
+ * @param outputDesc
+ * @param prevDevice
+ * @param delayMs
+ * @return the number of ms waited
+ */
+ virtual uint32_t checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
+ const DeviceVector &prevDevices,
+ uint32_t delayMs);
audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
@@ -570,15 +573,22 @@
void clearAudioPatches(uid_t uid);
void clearSessionRoutes(uid_t uid);
- void checkStrategyRoute(routing_strategy strategy, audio_io_handle_t ouptutToSkip);
+
+ /**
+ * @brief checkStrategyRoute: when an output is beeing rerouted, reconsider each output
+ * that may host a strategy playing on the considered output.
+ * @param ps product strategy that initiated the rerouting
+ * @param ouptutToSkip output that initiated the rerouting
+ */
+ void checkStrategyRoute(product_strategy_t ps, audio_io_handle_t ouptutToSkip);
status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
- sp<SourceClientDescriptor> getSourceForStrategyOnOutput(audio_io_handle_t output,
- routing_strategy strategy);
+ sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
+ const audio_attributes_t &attr);
void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
@@ -606,15 +616,6 @@
bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
- /**
- * @brief mDevicesForStrategy vector of devices that are assigned for a given strategy.
- * Note: in case of removal of device (@see setDeviceConnectionState), the device descriptor
- * will be removed from the @see mAvailableOutputDevices or @see mAvailableInputDevices
- * but the devices for strategies will be reevaluated within the
- * @see setDeviceConnectionState function.
- */
- DeviceVector mDevicesForStrategy[NUM_STRATEGIES];
-
float mLastVoiceVolume; // last voice volume value sent to audio HAL
bool mA2dpSuspended; // true if A2DP output is suspended
@@ -709,7 +710,8 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId);
+ audio_port_handle_t *selectedDeviceId,
+ bool *isRequestedDeviceForExclusiveUse);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevices(
const DeviceVector &devices,
@@ -717,16 +719,26 @@
audio_stream_type_t stream,
const audio_config_t *config,
audio_output_flags_t *flags);
- // internal method to return the input handle for the given device and format
+
+ /**
+ * @brief getInputForDevice selects an input handle for a given input device and
+ * requester context
+ * @param device to be used by requester, selected by policy mix rules or engine
+ * @param session requester session id
+ * @param uid requester uid
+ * @param attributes requester audio attributes (e.g. input source and tags matter)
+ * @param config requester audio configuration (e.g. sample rate, format, channel mask).
+ * @param flags requester input flags
+ * @param policyMix may be null, policy rules to be followed by the requester
+ * @return input io handle aka unique input identifier selected for this device.
+ */
audio_io_handle_t getInputForDevice(const sp<DeviceDescriptor> &device,
audio_session_t session,
- audio_source_t inputSource,
+ const audio_attributes_t &attributes,
const audio_config_base_t *config,
audio_input_flags_t flags,
AudioMix *policyMix);
- // internal function to derive a stream type value from audio attributes
- audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
// event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
// returns 0 if no mute/unmute event happened, the largest latency of the device where
// the mute/unmute happened
@@ -734,11 +746,6 @@
uint32_t setBeaconMute(bool mute);
bool isValidAttributes(const audio_attributes_t *paa);
- // select input device corresponding to requested audio source and return associated policy
- // mix if any. Calls getDeviceForInputSource().
- sp<DeviceDescriptor> getDeviceAndMixForAttributes(const audio_attributes_t &attributes,
- AudioMix **policyMix = NULL);
-
// Called by setDeviceConnectionState().
status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 919a90d..4947714 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -23,7 +23,6 @@
#include <memory>
#include <cutils/misc.h>
#include <media/AudioEffect.h>
-#include <media/AudioPolicyHelper.h>
#include <media/EffectsConfig.h>
#include <mediautils/ServiceUtilities.h>
#include <system/audio.h>
@@ -398,8 +397,7 @@
ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
return BAD_VALUE;
}
-
- audio_stream_type_t stream = audio_usage_to_stream_type(usage);
+ audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 45fb174..7768ea3 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -19,7 +19,6 @@
#include "AudioPolicyService.h"
#include "TypeConverter.h"
-#include <media/AudioPolicyHelper.h>
#include <media/MediaAnalyticsItem.h>
#include <mediautils/ServiceUtilities.h>
#include <utils/Log.h>
@@ -703,11 +702,12 @@
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
- return 0;
+ return PRODUCT_STRATEGY_NONE;
}
if (mAudioPolicyManager == NULL) {
- return 0;
+ return PRODUCT_STRATEGY_NONE;
}
+ // DO NOT LOCK, may be called from AudioFlinger with lock held, reaching deadlock
AutoCallerClear acc;
return mAudioPolicyManager->getStrategyForStream(stream);
}
@@ -1186,4 +1186,22 @@
return mAudioPolicyManager->isHapticPlaybackSupported();
}
+status_t AudioPolicyService::listAudioProductStrategies(AudioProductStrategyVector &strategies)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->listAudioProductStrategies(strategies);
+}
+
+product_strategy_t AudioPolicyService::getProductStrategyFromAudioAttributes(
+ const AudioAttributes &aa)
+{
+ if (mAudioPolicyManager == NULL) {
+ return PRODUCT_STRATEGY_NONE;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->getProductStrategyFromAudioAttributes(aa);
+}
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c073b7c..ee293a7 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -229,6 +229,9 @@
virtual bool isHapticPlaybackSupported();
+ virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
+ virtual product_strategy_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa);
+
status_t doStopOutput(audio_port_handle_t portId);
void doReleaseOutput(audio_port_handle_t portId);
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
index e4fba0f..97be44c 100644
--- a/services/audiopolicy/tests/Android.mk
+++ b/services/audiopolicy/tests/Android.mk
@@ -4,8 +4,6 @@
LOCAL_C_INCLUDES := \
frameworks/av/services/audiopolicy \
- frameworks/av/services/audiopolicy/common/include \
- frameworks/av/services/audiopolicy/engine/interface \
$(call include-path-for, audio-utils) \
LOCAL_SHARED_LIBRARIES := \
@@ -18,6 +16,10 @@
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents \
+LOCAL_HEADER_LIBRARIES := \
+ libaudiopolicycommon \
+ libaudiopolicyengine_interface_headers
+
LOCAL_SRC_FILES := \
audiopolicymanager_tests.cpp \
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c3113bf..ee8d7e1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -49,6 +49,7 @@
#include <hardware/hardware.h>
#include "hidl/HidlCameraService.h"
#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
#include <memunreachable/memunreachable.h>
#include <media/AudioSystem.h>
#include <media/IMediaHTTPService.h>
@@ -226,7 +227,7 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto& i : mListenerList) {
- i->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
+ i.second->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
}
}
@@ -1287,6 +1288,18 @@
return ret;
}
+bool CameraService::shouldRejectHiddenCameraConnection(const String8 & cameraId) {
+ // If the thread serving this call is not a hwbinder thread and the caller
+ // isn't the cameraserver itself, and the camera id being requested is to be
+ // publically hidden, we should reject the connection.
+ if (!hardware::IPCThreadState::self()->isServingCall() &&
+ CameraThreadState::getCallingPid() != getpid() &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+ return true;
+ }
+ return false;
+}
+
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
@@ -1299,6 +1312,7 @@
Status ret = Status::ok();
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
+
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
@@ -1330,6 +1344,14 @@
(halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
static_cast<int>(effectiveApiLevel));
+ if (shouldRejectHiddenCameraConnection(cameraId)) {
+ ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
+ cameraId.c_str());
+ return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
+ "No camera device with ID \"%s\" currently available",
+ cameraId.string());
+
+ }
sp<CLIENT> client = nullptr;
{
// Acquire mServiceLock and prevent other clients from connecting
@@ -1635,6 +1657,14 @@
Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
/*out*/
std::vector<hardware::CameraStatus> *cameraStatuses) {
+ return addListenerHelper(listener, cameraStatuses);
+}
+
+Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener,
+ /*out*/
+ std::vector<hardware::CameraStatus> *cameraStatuses,
+ bool isVendorListener) {
+
ATRACE_CALL();
ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
@@ -1649,20 +1679,26 @@
{
Mutex::Autolock lock(mStatusListenerLock);
for (auto& it : mListenerList) {
- if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
+ if (IInterface::asBinder(it.second) == IInterface::asBinder(listener)) {
ALOGW("%s: Tried to add listener %p which was already subscribed",
__FUNCTION__, listener.get());
return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
}
}
- mListenerList.push_back(listener);
+ mListenerList.emplace_back(isVendorListener, listener);
}
/* Collect current devices and status */
{
Mutex::Autolock lock(mCameraStatesLock);
for (auto& i : mCameraStates) {
+ if (!isVendorListener &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(i.first.c_str())) {
+ ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
+ i.first.c_str(), CameraThreadState::getCallingPid());
+ continue;
+ }
cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
}
}
@@ -1697,7 +1733,7 @@
{
Mutex::Autolock lock(mStatusListenerLock);
for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
- if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
+ if (IInterface::asBinder(it->second) == IInterface::asBinder(listener)) {
mListenerList.erase(it);
return Status::ok();
}
@@ -3033,7 +3069,13 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto& listener : mListenerList) {
- listener->onStatusChanged(mapToInterface(status), String16(cameraId));
+ if (!listener.first &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+ ALOGV("Skipping camera discovery callback for system-only camera %s",
+ cameraId.c_str());
+ continue;
+ }
+ listener.second->onStatusChanged(mapToInterface(status), String16(cameraId));
}
});
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a296198..3af52fa 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -173,6 +173,10 @@
virtual status_t shellCommand(int in, int out, int err, const Vector<String16>& args);
+ binder::Status addListenerHelper(const sp<hardware::ICameraServiceListener>& listener,
+ /*out*/
+ std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false);
+
/////////////////////////////////////////////////////////////////////
// Client functionality
@@ -615,6 +619,10 @@
sp<BasicClient>* client,
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
+ // Should an operation attempt on a cameraId be rejected, if the camera id is
+ // advertised as a publically hidden secure camera, by the camera HAL ?
+ bool shouldRejectHiddenCameraConnection(const String8 & cameraId);
+
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
@@ -781,7 +789,8 @@
sp<CameraProviderManager> mCameraProviderManager;
// Guarded by mStatusListenerMutex
- std::vector<sp<hardware::ICameraServiceListener>> mListenerList;
+ std::vector<std::pair<bool, sp<hardware::ICameraServiceListener>>> mListenerList;
+
Mutex mStatusListenerLock;
/**
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 7c32e84..8ee3298 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -499,6 +499,17 @@
}
}
+bool CameraProviderManager::ProviderInfo::DeviceInfo3::isPublicallyHiddenSecureCamera() {
+ camera_metadata_entry_t entryCap;
+ entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ if (entryCap.count != 1) {
+ // Do NOT hide this camera device if the capabilities specify anything more
+ // than ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA.
+ return false;
+ }
+ return entryCap.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+}
+
void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedSizes(
const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
std::vector<std::tuple<size_t, size_t>> *sizes/*out*/) {
@@ -643,7 +654,7 @@
bool isDepthExclusivePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
depthExclTag) != (chTags.data.i32 + chTags.count);
bool isDepthSizePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
- depthExclTag) != (chTags.data.i32 + chTags.count);
+ depthSizesTag) != (chTags.data.i32 + chTags.count);
if (!(isDepthExclusivePresent && isDepthSizePresent)) {
// No depth support, nothing more to do.
return OK;
@@ -671,7 +682,6 @@
getSupportedDynamicDepthSizes(supportedBlobSizes, supportedDepthSizes,
&supportedDynamicDepthSizes, &internalDepthSizes);
if (supportedDynamicDepthSizes.empty()) {
- ALOGE("%s: No dynamic depth size matched!", __func__);
// Nothing more to do.
return OK;
}
@@ -877,6 +887,16 @@
return deviceInfo->mIsLogicalCamera;
}
+bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) {
+ return false;
+ }
+ return deviceInfo->mIsPublicallyHiddenSecureCamera;
+}
+
bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
for (auto& provider : mProviders) {
for (auto& deviceInfo : provider->mDevices) {
@@ -1704,17 +1724,19 @@
__FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
return;
}
+
+ mIsPublicallyHiddenSecureCamera = isPublicallyHiddenSecureCamera();
+
status_t res = fixupMonochromeTags();
if (OK != res) {
ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
__FUNCTION__, strerror(-res), res);
return;
}
- res = addDynamicDepthTags();
- if (OK != res) {
- ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-res),
- res);
- return;
+ auto stat = addDynamicDepthTags();
+ if (OK != stat) {
+ ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
+ stat);
}
camera_metadata_entry flashAvailable =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
@@ -1726,6 +1748,7 @@
}
queryPhysicalCameraIds();
+
// Get physical camera characteristics if applicable
auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
if (!castResult.isOk()) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index fbd7d2e..18869f5 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -264,6 +264,7 @@
*/
bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);
+ bool isPublicallyHiddenSecureCamera(const std::string& id);
bool isHiddenPhysicalCamera(const std::string& cameraId);
static const float kDepthARTolerance;
@@ -354,6 +355,7 @@
std::vector<std::string> mPhysicalIds;
hardware::CameraInfo mInfo;
sp<IBase> mSavedInterface;
+ bool mIsPublicallyHiddenSecureCamera = false;
const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
@@ -471,6 +473,7 @@
CameraMetadata mCameraCharacteristics;
std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics;
void queryPhysicalCameraIds();
+ bool isPublicallyHiddenSecureCamera();
status_t fixupMonochromeTags();
status_t addDynamicDepthTags();
static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 48f1d37..74cfe42 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -182,7 +182,8 @@
}
}
std::vector<hardware::CameraStatus> cameraStatusAndIds{};
- binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
+ binder::Status serviceRet =
+ mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index ae832ba..4f3ac1b 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -51,7 +51,6 @@
#include <utils/Timers.h>
#include <utils/Vector.h>
-#include <media/AudioPolicyHelper.h>
#include <media/IMediaHTTPService.h>
#include <media/IRemoteDisplay.h>
#include <media/IRemoteDisplayClient.h>