You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
6.2 KiB
212 lines
6.2 KiB
/*
|
|
* 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.
|
|
*/
|
|
|
|
#define LOG_TAG "AudioPolicy"
|
|
//#define LOG_NDEBUG 0
|
|
#include <utils/Log.h>
|
|
#include <media/AudioPolicy.h>
|
|
|
|
namespace android {
|
|
|
|
//
|
|
// AudioMixMatchCriterion implementation
|
|
//
|
|
AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
|
|
audio_source_t source,
|
|
uint32_t rule)
|
|
: mRule(rule)
|
|
{
|
|
if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
|
|
mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
|
|
mValue.mUsage = usage;
|
|
} else {
|
|
mValue.mSource = source;
|
|
}
|
|
}
|
|
|
|
status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
|
|
{
|
|
mRule = parcel->readInt32();
|
|
switch (mRule) {
|
|
case RULE_MATCH_ATTRIBUTE_USAGE:
|
|
case RULE_EXCLUDE_ATTRIBUTE_USAGE:
|
|
mValue.mUsage = (audio_usage_t) parcel->readInt32();
|
|
break;
|
|
case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
|
|
case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
|
|
mValue.mSource = (audio_source_t) parcel->readInt32();
|
|
break;
|
|
case RULE_MATCH_UID:
|
|
case RULE_EXCLUDE_UID:
|
|
mValue.mUid = (uid_t) parcel->readInt32();
|
|
break;
|
|
case RULE_MATCH_USERID:
|
|
case RULE_EXCLUDE_USERID:
|
|
mValue.mUserId = (int) parcel->readInt32();
|
|
break;
|
|
default:
|
|
ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
|
|
return BAD_VALUE;
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
status_t AudioMixMatchCriterion::writeToParcel(Parcel *parcel) const
|
|
{
|
|
parcel->writeInt32(mRule);
|
|
parcel->writeInt32(mValue.mUsage);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// AudioMix implementation
|
|
//
|
|
|
|
status_t AudioMix::readFromParcel(Parcel *parcel)
|
|
{
|
|
mMixType = parcel->readInt32();
|
|
mFormat.sample_rate = (uint32_t)parcel->readInt32();
|
|
mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32();
|
|
mFormat.format = (audio_format_t)parcel->readInt32();
|
|
mRouteFlags = parcel->readInt32();
|
|
mDeviceType = (audio_devices_t) parcel->readInt32();
|
|
mDeviceAddress = parcel->readString8();
|
|
mCbFlags = (uint32_t)parcel->readInt32();
|
|
mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
|
|
mVoiceCommunicationCaptureAllowed = parcel->readBool();
|
|
size_t size = (size_t)parcel->readInt32();
|
|
if (size > MAX_CRITERIA_PER_MIX) {
|
|
size = MAX_CRITERIA_PER_MIX;
|
|
}
|
|
for (size_t i = 0; i < size; i++) {
|
|
AudioMixMatchCriterion criterion;
|
|
if (criterion.readFromParcel(parcel) == NO_ERROR) {
|
|
mCriteria.add(criterion);
|
|
}
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
status_t AudioMix::writeToParcel(Parcel *parcel) const
|
|
{
|
|
parcel->writeInt32(mMixType);
|
|
parcel->writeInt32(mFormat.sample_rate);
|
|
parcel->writeInt32(mFormat.channel_mask);
|
|
parcel->writeInt32(mFormat.format);
|
|
parcel->writeInt32(mRouteFlags);
|
|
parcel->writeInt32(mDeviceType);
|
|
parcel->writeString8(mDeviceAddress);
|
|
parcel->writeInt32(mCbFlags);
|
|
parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
|
|
parcel->writeBool(mVoiceCommunicationCaptureAllowed);
|
|
size_t size = mCriteria.size();
|
|
if (size > MAX_CRITERIA_PER_MIX) {
|
|
size = MAX_CRITERIA_PER_MIX;
|
|
}
|
|
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();
|
|
if (mCriteria[i].writeToParcel(parcel) != 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;
|
|
}
|
|
|
|
void AudioMix::setExcludeUid(uid_t uid) const {
|
|
AudioMixMatchCriterion crit;
|
|
crit.mRule = RULE_EXCLUDE_UID;
|
|
crit.mValue.mUid = uid;
|
|
mCriteria.add(crit);
|
|
}
|
|
|
|
void AudioMix::setMatchUid(uid_t uid) const {
|
|
AudioMixMatchCriterion crit;
|
|
crit.mRule = RULE_MATCH_UID;
|
|
crit.mValue.mUid = uid;
|
|
mCriteria.add(crit);
|
|
}
|
|
|
|
bool AudioMix::hasUidRule(bool match, uid_t uid) const {
|
|
const uint32_t rule = match ? RULE_MATCH_UID : RULE_EXCLUDE_UID;
|
|
for (size_t i = 0; i < mCriteria.size(); i++) {
|
|
if (mCriteria[i].mRule == rule
|
|
&& mCriteria[i].mValue.mUid == uid) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AudioMix::hasMatchUidRule() const {
|
|
for (size_t i = 0; i < mCriteria.size(); i++) {
|
|
if (mCriteria[i].mRule == RULE_MATCH_UID) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void AudioMix::setExcludeUserId(int userId) const {
|
|
AudioMixMatchCriterion crit;
|
|
crit.mRule = RULE_EXCLUDE_USERID;
|
|
crit.mValue.mUserId = userId;
|
|
mCriteria.add(crit);
|
|
}
|
|
|
|
void AudioMix::setMatchUserId(int userId) const {
|
|
AudioMixMatchCriterion crit;
|
|
crit.mRule = RULE_MATCH_USERID;
|
|
crit.mValue.mUserId = userId;
|
|
mCriteria.add(crit);
|
|
}
|
|
|
|
bool AudioMix::hasUserIdRule(bool match, int userId) const {
|
|
const uint32_t rule = match ? RULE_MATCH_USERID : RULE_EXCLUDE_USERID;
|
|
for (size_t i = 0; i < mCriteria.size(); i++) {
|
|
if (mCriteria[i].mRule == rule
|
|
&& mCriteria[i].mValue.mUserId == userId) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AudioMix::hasMatchUserIdRule() const {
|
|
for (size_t i = 0; i < mCriteria.size(); i++) {
|
|
if (mCriteria[i].mRule == RULE_MATCH_USERID) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AudioMix::isDeviceAffinityCompatible() const {
|
|
return ((mMixType == MIX_TYPE_PLAYERS)
|
|
&& (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
|
|
}
|
|
|
|
} // namespace android
|