Merge "Improve robustness when deleting abs volume device" into main
diff --git a/media/libaudioclient/PolicyAidlConversion.cpp b/media/libaudioclient/PolicyAidlConversion.cpp
index 441e329..163a359 100644
--- a/media/libaudioclient/PolicyAidlConversion.cpp
+++ b/media/libaudioclient/PolicyAidlConversion.cpp
@@ -379,6 +379,8 @@
return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
case media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL:
return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
+ case media::AudioPolicyForcedConfig::BT_BLE:
+ return AUDIO_POLICY_FORCE_BT_BLE;
}
return unexpected(BAD_VALUE);
}
@@ -418,6 +420,8 @@
return media::AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS;
case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
return media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL;
+ case AUDIO_POLICY_FORCE_BT_BLE:
+ return media::AudioPolicyForcedConfig::BT_BLE;
case AUDIO_POLICY_FORCE_CFG_CNT:
break;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
index 2255d4c..111bb2f 100644
--- a/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
@@ -36,4 +36,5 @@
ENCODED_SURROUND_NEVER = 13,
ENCODED_SURROUND_ALWAYS = 14,
ENCODED_SURROUND_MANUAL = 15,
+ BT_BLE = 16,
}
diff --git a/media/libaudioclient/tests/audioeffect_analyser.cpp b/media/libaudioclient/tests/audioeffect_analyser.cpp
index f4d37bc..199fb8b 100644
--- a/media/libaudioclient/tests/audioeffect_analyser.cpp
+++ b/media/libaudioclient/tests/audioeffect_analyser.cpp
@@ -62,6 +62,15 @@
constexpr int kNPointFFT = 16384;
constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
+// frequency used to generate testing tone
+constexpr uint32_t kTestFrequency = 1400;
+
+// Tolerance of audio gain difference in dB, which is 10^(0.1/20) (around 1.0116%) difference in
+// amplitude
+constexpr float kAudioGainDiffTolerancedB = .1f;
+
+const std::string kDataTempPath = "/data/local/tmp";
+
const char* gPackageName = "AudioEffectAnalyser";
static_assert(kPrimeDurationInSec + 2 * kNPointFFT / kSamplingFrequency < kCaptureDurationSec,
@@ -177,21 +186,30 @@
return effect;
}
-void computeFilterGainsAtTones(float captureDuration, int nPointFft, std::vector<int>& binOffsets,
- float* inputMag, float* gaindB, const char* res,
- audio_session_t sessionId) {
+void computeFilterGainsAtTones(float captureDuration, int nPointFft, std::vector<int> binOffsets,
+ float* inputMag, float* gaindB, const std::string res,
+ audio_session_t sessionId, const std::string res2 = "",
+ audio_session_t sessionId2 = AUDIO_SESSION_NONE) {
int totalFrameCount = captureDuration * kSamplingFrequency;
auto output = pffft::AlignedVector<float>(totalFrameCount);
auto fftOutput = pffft::AlignedVector<float>(nPointFft);
- PlaybackEnv argsP;
- argsP.mRes = std::string{res};
+ PlaybackEnv argsP, argsP2;
+ argsP.mRes = res;
argsP.mSessionId = sessionId;
CaptureEnv argsR;
argsR.mCaptureDuration = captureDuration;
std::thread playbackThread(&PlaybackEnv::play, &argsP);
+ std::optional<std::thread> playbackThread2;
+ if (res2 != "") {
+ argsP2 = {.mSessionId = sessionId2, .mRes = res2};
+ playbackThread2 = std::thread(&PlaybackEnv::play, &argsP2);
+ }
std::thread captureThread(&CaptureEnv::capture, &argsR);
captureThread.join();
playbackThread.join();
+ if (playbackThread2 != std::nullopt) {
+ playbackThread2->join();
+ }
ASSERT_EQ(OK, argsR.mStatus) << argsR.mMsg;
ASSERT_EQ(OK, argsP.mStatus) << argsP.mMsg;
ASSERT_FALSE(argsR.mDumpFileName.empty()) << "recorded not written to file";
@@ -210,7 +228,11 @@
auto k = binOffsets[i];
auto outputMag = sqrt((fftOutput[k * 2] * fftOutput[k * 2]) +
(fftOutput[k * 2 + 1] * fftOutput[k * 2 + 1]));
- gaindB[i] = 20 * log10(outputMag / inputMag[i]);
+ if (inputMag == nullptr) {
+ gaindB[i] = 20 * log10(outputMag);
+ } else {
+ gaindB[i] = 20 * log10(outputMag / inputMag[i]);
+ }
}
}
@@ -282,7 +304,7 @@
inputMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
(fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
}
- TemporaryFile tf("/data/local/tmp");
+ TemporaryFile tf(kDataTempPath);
close(tf.release());
std::ofstream fout(tf.path, std::ios::out | std::ios::binary);
fout.write((char*)input.data(), input.size() * sizeof(input[0]));
@@ -386,7 +408,7 @@
inputMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
(fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
}
- TemporaryFile tf("/data/local/tmp");
+ TemporaryFile tf(kDataTempPath);
close(tf.release());
std::ofstream fout(tf.path, std::ios::out | std::ios::binary);
fout.write((char*)input.data(), input.size() * sizeof(input[0]));
@@ -396,7 +418,7 @@
memset(gainWithOutFilter, 0, sizeof(gainWithOutFilter));
ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(kCaptureDurationSec, kNPointFFT, binOffsets,
inputMag, gainWithOutFilter, tf.path,
- AUDIO_SESSION_OUTPUT_MIX));
+ AUDIO_SESSION_NONE));
float diffA = gainWithOutFilter[0] - gainWithOutFilter[1];
float prevGain = -100.f;
for (auto strength = 150; strength < 1000; strength += strengthSupported ? 150 : 1000) {
@@ -421,6 +443,56 @@
}
}
+// assert the silent audio session with effect does not override the output audio
+TEST(AudioEffectTest, SilentAudioEffectSessionNotOverrideOutput) {
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffect> bassboost = createEffect(SL_IID_BASSBOOST, sessionId);
+ if ((bassboost->descriptor().flags & EFFECT_FLAG_HW_ACC_MASK) != 0) {
+ GTEST_SKIP() << "effect processed output inaccessible, skipping test";
+ }
+ ASSERT_EQ(OK, bassboost->initCheck());
+ ASSERT_EQ(NO_ERROR, bassboost->setEnabled(true));
+
+ const auto bin = roundToFreqCenteredToFftBin(kBinWidth, kTestFrequency);
+ const int binIndex = std::get<0 /* index */>(bin);
+ const int binFrequency = std::get<1 /* freq */>(bin);
+
+ const int totalFrameCount = kSamplingFrequency * kPlayBackDurationSec;
+ // input for effect module
+ auto silentAudio = pffft::AlignedVector<float>(totalFrameCount);
+ auto input = pffft::AlignedVector<float>(totalFrameCount);
+ generateMultiTone({binFrequency}, kSamplingFrequency, kPlayBackDurationSec, kDefAmplitude,
+ input.data(), totalFrameCount);
+ TemporaryFile tf(kDataTempPath);
+ close(tf.release());
+ std::ofstream fout(tf.path, std::ios::out | std::ios::binary);
+ fout.write((char*)input.data(), input.size() * sizeof(input[0]));
+ fout.close();
+
+ // play non-silent audio file on AUDIO_SESSION_NONE
+ float audioGain, audioPlusSilentEffectGain;
+ ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(kCaptureDurationSec, kNPointFFT, {binIndex},
+ nullptr, &audioGain, tf.path,
+ AUDIO_SESSION_NONE));
+ EXPECT_FALSE(std::isinf(audioGain)) << "output gain should not be -inf";
+
+ TemporaryFile silentFile(kDataTempPath);
+ close(silentFile.release());
+ std::ofstream fSilent(silentFile.path, std::ios::out | std::ios::binary);
+ fSilent.write((char*)silentAudio.data(), silentAudio.size() * sizeof(silentAudio[0]));
+ fSilent.close();
+ // play non-silent audio file on AUDIO_SESSION_NONE and silent audio on sessionId, expect
+ // the new output gain to be almost same as last playback
+ ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(
+ kCaptureDurationSec, kNPointFFT, {binIndex}, nullptr, &audioPlusSilentEffectGain,
+ tf.path, AUDIO_SESSION_NONE, silentFile.path, sessionId));
+ EXPECT_FALSE(std::isinf(audioPlusSilentEffectGain))
+ << "output might have been overwritten in effect accumulate mode";
+ EXPECT_NEAR(audioGain, audioPlusSilentEffectGain, kAudioGainDiffTolerancedB)
+ << " output gain should almost same with one more silent audio stream";
+}
+
int main(int argc, char** argv) {
android::ProcessState::self()->startThreadPool();
::testing::InitGoogleTest(&argc, argv);
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 740bf60..2753906 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -42,6 +42,8 @@
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Processing;
+using ::aidl::android::media::audio::common::AudioDevice;
+using ::aidl::android::media::audio::common::AudioDeviceAddress;
using ::aidl::android::media::audio::common::AudioSource;
using ::aidl::android::media::audio::common::AudioStreamType;
using ::aidl::android::media::audio::common::AudioUuid;
@@ -281,7 +283,8 @@
auto getConfigProcessingWithAidlProcessing =
[&](const auto& aidlProcess, std::vector<effectsConfig::InputStream>& preprocess,
- std::vector<effectsConfig::OutputStream>& postprocess) {
+ std::vector<effectsConfig::OutputStream>& postprocess,
+ std::vector<effectsConfig::DeviceEffects>& deviceprocess) {
if (aidlProcess.type.getTag() == Processing::Type::streamType) {
AudioStreamType aidlType =
aidlProcess.type.template get<Processing::Type::streamType>();
@@ -313,6 +316,25 @@
effectsConfig::InputStream stream = {.type = type.value(),
.effects = std::move(effects)};
preprocess.emplace_back(stream);
+ } else if (aidlProcess.type.getTag() == Processing::Type::device) {
+ AudioDevice aidlDevice =
+ aidlProcess.type.template get<Processing::Type::device>();
+ std::vector<std::shared_ptr<const effectsConfig::Effect>> effects;
+ std::transform(aidlProcess.ids.begin(), aidlProcess.ids.end(),
+ std::back_inserter(effects), getConfigEffectWithDescriptor);
+ audio_devices_t type;
+ char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+ status_t status = ::aidl::android::aidl2legacy_AudioDevice_audio_device(
+ aidlDevice, &type, address);
+ if (status != NO_ERROR) {
+ ALOGE("%s device effect has invalid device type / address", __func__);
+ return;
+ }
+ effectsConfig::DeviceEffects device = {
+ {.type = type, .effects = std::move(effects)},
+ .address = address,
+ };
+ deviceprocess.emplace_back(device);
}
};
@@ -320,17 +342,21 @@
[&]() -> std::shared_ptr<const effectsConfig::Processings> {
std::vector<effectsConfig::InputStream> preprocess;
std::vector<effectsConfig::OutputStream> postprocess;
+ std::vector<effectsConfig::DeviceEffects> deviceprocess;
for (const auto& processing : mAidlProcessings) {
- getConfigProcessingWithAidlProcessing(processing, preprocess, postprocess);
+ getConfigProcessingWithAidlProcessing(processing, preprocess, postprocess,
+ deviceprocess);
}
- if (0 == preprocess.size() && 0 == postprocess.size()) {
+ if (0 == preprocess.size() && 0 == postprocess.size() &&
+ 0 == deviceprocess.size()) {
return nullptr;
}
return std::make_shared<const effectsConfig::Processings>(
effectsConfig::Processings({.preprocess = std::move(preprocess),
- .postprocess = std::move(postprocess)}));
+ .postprocess = std::move(postprocess),
+ .deviceprocess = std::move(deviceprocess)}));
}());
return processings;
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 38e1ea4..030ee2b 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -800,6 +800,14 @@
}
status_t StreamOutHalAidl::drain(bool earlyNotify) {
+ if (!mStream) return NO_INIT;
+
+ if(const auto state = getState(); state == StreamDescriptor::State::IDLE) {
+ ALOGD("%p %s stream already in IDLE state", this, __func__);
+ if(mContext.isAsynchronous()) onDrainReady();
+ return OK;
+ }
+
return StreamHalAidl::drain(earlyNotify);
}
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 9cb2cff..0587640 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -215,6 +215,11 @@
~StreamHalAidl() override;
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State getState() {
+ std::lock_guard l(mLock);
+ return mLastReply.state;
+ }
+
status_t getLatency(uint32_t *latency);
// Always returns non-negative values.
@@ -268,10 +273,6 @@
result.format = config.format;
return result;
}
- ::aidl::android::hardware::audio::core::StreamDescriptor::State getState() {
- std::lock_guard l(mLock);
- return mLastReply.state;
- }
// Note: Since `sendCommand` takes mLock while holding mCommandReplyLock, never call
// it with `mLock` being held.
status_t sendCommand(
diff --git a/media/libstagefright/renderfright/gl/ProgramCache.cpp b/media/libstagefright/renderfright/gl/ProgramCache.cpp
index 350f0b7..ad6dd03 100644
--- a/media/libstagefright/renderfright/gl/ProgramCache.cpp
+++ b/media/libstagefright/renderfright/gl/ProgramCache.cpp
@@ -683,7 +683,7 @@
fs << "uniform mat4 inputTransformMatrix;";
fs << R"__SHADER__(
highp vec3 InputTransform(const highp vec3 color) {
- return clamp(vec3(inputTransformMatrix * vec4(color, 1.0)), 0.0, 1.0);
+ return vec3(inputTransformMatrix * vec4(color, 1.0));
}
)__SHADER__";
} else {
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index ca862b0..151ce7c 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -290,7 +290,7 @@
// Max file duration limit is set
if (mMaxFileDurationLimitUs != 0) {
if (bitRate > 0) {
- int64_t size2 = ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
+ int64_t size2 = ((mMaxFileDurationLimitUs / 1000) * bitRate * 6) / 8000000;
if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
// When both file size and duration limits are set,
// we use the smaller limit of the two.
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index a0ffcc0..711ad32 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1396,12 +1396,12 @@
((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
- status = setVolumeInternal(left, right, controller);
+ status = setVolumeInternal_ll(left, right, controller);
}
return status;
}
-status_t EffectModule::setVolumeInternal(
+status_t EffectModule::setVolumeInternal_ll(
uint32_t *left, uint32_t *right, bool controller) {
if (mVolume.has_value() && *left == mVolume.value()[0] && *right == mVolume.value()[1] &&
!controller) {
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index e67396e..9ecf89e 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -269,8 +269,9 @@
? EFFECT_BUFFER_ACCESS_WRITE : EFFECT_BUFFER_ACCESS_ACCUMULATE;
}
- status_t setVolumeInternal(uint32_t* left, uint32_t* right,
- bool controller /* the volume controller effect of the chain */);
+ status_t setVolumeInternal_ll(uint32_t* left, uint32_t* right,
+ bool controller /* the volume controller effect of the chain */)
+ REQUIRES(audio_utils::EffectChain_Mutex, audio_utils::EffectBase_Mutex);
effect_config_t mConfig; // input and output audio configuration
sp<EffectBufferHalInterface> mInBuffer; // Buffers for interacting with HAL
@@ -294,12 +295,12 @@
template <typename MUTEX>
class AutoLockReentrant {
public:
- AutoLockReentrant(MUTEX& mutex, pid_t allowedTid)
+ AutoLockReentrant(MUTEX& mutex, pid_t allowedTid) ACQUIRE(audio_utils::EffectBase_Mutex)
: mMutex(gettid() == allowedTid ? nullptr : &mutex)
{
if (mMutex != nullptr) mMutex->lock();
}
- ~AutoLockReentrant() {
+ ~AutoLockReentrant() RELEASE(audio_utils::EffectBase_Mutex) {
if (mMutex != nullptr) mMutex->unlock();
}
private:
@@ -316,7 +317,7 @@
// here is used to indicate the volume to apply before this effect.
std::optional<std::vector<uint32_t>> mReturnedVolume;
// TODO: b/315995877, remove this debugging string after root cause
- std::string mEffectInterfaceDebug;
+ std::string mEffectInterfaceDebug GUARDED_BY(audio_utils::EffectChain_Mutex);
};
class HwAccDeviceEffectModule : public EffectModule {
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index b92cd70..f7b9b33 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -99,21 +99,20 @@
* @return ioHandle if found, AUDIO_IO_HANDLE_NONE otherwise.
*/
audio_io_handle_t getIoForSession(audio_session_t sessionId,
- const effect_uuid_t *effectType = nullptr) const;
- bool hasOrphansForSession(audio_session_t sessionId) const;
- EffectDescriptorCollection getOrphanEffectsForSession(audio_session_t sessionId) const;
- void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
+ const effect_uuid_t* effectType = nullptr) const;
/**
- * @brief Checks if there is at least one orphan effect with given sessionId and effect type
- * uuid.
+ * @brief Checks if there is at least one orphan effect with given sessionId and optional effect
+ * type uuid.
* @param sessionId Session ID.
- * @param effectType Effect type UUID, the implementation will be same as hasOrphansForSession
- * if null.
+ * @param effectType Optional effect type UUID pointer to effect_uuid_t, nullptr by default.
* @return True if there is an orphan effect for given sessionId and type UUID, false otherwise.
*/
- bool hasOrphanEffectsForSessionAndType(audio_session_t sessionId,
- const effect_uuid_t* effectType) const;
+ bool hasOrphansForSession(audio_session_t sessionId,
+ const effect_uuid_t* effectType = nullptr) const;
+
+ EffectDescriptorCollection getOrphanEffectsForSession(audio_session_t sessionId) const;
+ void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
private:
status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 7971b61..090da6c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -210,27 +210,13 @@
}
}
-bool EffectDescriptorCollection::hasOrphansForSession(audio_session_t sessionId) const
-{
+bool EffectDescriptorCollection::hasOrphansForSession(audio_session_t sessionId,
+ const effect_uuid_t* effectType) const {
for (size_t i = 0; i < size(); ++i) {
sp<EffectDescriptor> effect = valueAt(i);
- if (effect->mSession == sessionId && effect->mIsOrphan) {
- return true;
- }
- }
- return false;
-}
-
-bool EffectDescriptorCollection::hasOrphanEffectsForSessionAndType(
- audio_session_t sessionId, const effect_uuid_t* effectType) const {
- if (effectType == nullptr) {
- return hasOrphansForSession(sessionId);
- }
-
- for (size_t i = 0; i < size(); ++i) {
- sp<EffectDescriptor> effect = valueAt(i);
- if (effect->mIsOrphan && effect->mSession == sessionId &&
- memcmp(&effect->mDesc.type, effectType, sizeof(effect_uuid_t)) == 0) {
+ if (effect->mSession == sessionId && effect->mIsOrphan &&
+ (effectType == nullptr ||
+ memcmp(&effect->mDesc.type, effectType, sizeof(effect_uuid_t)) == 0)) {
return true;
}
}
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 7666a2b..9fafe2e 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -143,7 +143,8 @@
}
break;
case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
- if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
+ if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_BT_BLE
+ && config != AUDIO_POLICY_FORCE_NONE) {
ALOGW("setForceUse() invalid config %d for VIBRATE_RINGING", config);
return BAD_VALUE;
}
@@ -402,6 +403,40 @@
}
}
}
+
+ // if LEA headset is connected and we are told to use it, play ringtone over
+ // speaker and BT LEA
+ if (!availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllBleSet()).isEmpty()) {
+ DeviceVector devices2;
+ devices2 = availableOutputDevices.getFirstDevicesFromTypes({
+ AUDIO_DEVICE_OUT_BLE_HEADSET, AUDIO_DEVICE_OUT_BLE_SPEAKER});
+ // Use ONLY Bluetooth LEA output when ringing in vibration mode
+ if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+ && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
+ if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
+ == AUDIO_POLICY_FORCE_BT_BLE) {
+ if (!devices2.isEmpty()) {
+ devices = devices2;
+ break;
+ }
+ }
+ }
+ // Use both Bluetooth LEA and phone default output when ringing in normal mode
+ if (audio_is_ble_out_device(getPreferredDeviceTypeForLegacyStrategy(
+ availableOutputDevices, STRATEGY_PHONE))) {
+ if (strategy == STRATEGY_SONIFICATION) {
+ devices.replaceDevicesByType(
+ AUDIO_DEVICE_OUT_SPEAKER,
+ availableOutputDevices.getDevicesFromType(
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE));
+ }
+ if (!devices2.isEmpty()) {
+ devices.add(devices2);
+ break;
+ }
+ }
+ }
+
// The second device used for sonification is the same as the device used by media strategy
FALLTHROUGH_INTENDED;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index e456e89..106f135 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2186,8 +2186,7 @@
// matching criteria values in priority order for best matching output so far
std::vector<uint32_t> bestMatchCriteria(8, 0);
- const bool hasOrphanHaptic =
- mEffects.hasOrphanEffectsForSessionAndType(sessionId, FX_IID_HAPTICGENERATOR);
+ const bool hasOrphanHaptic = mEffects.hasOrphansForSession(sessionId, FX_IID_HAPTICGENERATOR);
const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(
channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
@@ -6410,7 +6409,7 @@
// means haptic use cases (either the client channelmask includes haptic bits, or created a
// HapticGenerator effect for this session) are not supported.
return clientHapticChannel == 0 &&
- !mEffects.hasOrphanEffectsForSessionAndType(sessionId, FX_IID_HAPTICGENERATOR);
+ !mEffects.hasOrphansForSession(sessionId, FX_IID_HAPTICGENERATOR);
}
}
diff --git a/services/audiopolicy/permission/NativePermissionController.cpp b/services/audiopolicy/permission/NativePermissionController.cpp
index 8659f2c..07bb7e2 100644
--- a/services/audiopolicy/permission/NativePermissionController.cpp
+++ b/services/audiopolicy/permission/NativePermissionController.cpp
@@ -129,10 +129,12 @@
BinderResult<bool> NativePermissionController::validateUidPackagePair(
uid_t uid, const std::string& packageName) const {
+ if (uid == AID_ROOT || uid == AID_SYSTEM) return true;
uid = uid % AID_USER_OFFSET;
const auto fixed_package_opt = getFixedPackageName(uid);
if (fixed_package_opt.has_value()) {
- return packageName == fixed_package_opt.value();
+ return (uid == AID_ROOT || uid == AID_SYSTEM) ? true :
+ packageName == fixed_package_opt.value();
}
std::lock_guard l{m_};
if (!is_package_populated_) {
@@ -148,6 +150,7 @@
BinderResult<bool> NativePermissionController::checkPermission(PermissionEnum perm,
uid_t uid) const {
+ if (uid == AID_ROOT || uid == AID_SYSTEM || uid == getuid()) return true;
std::lock_guard l{m_};
const auto& uids = permission_map_[static_cast<size_t>(perm)];
if (!uids.empty()) {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 768cd07..f414862 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -23,6 +23,8 @@
#include <android/content/AttributionSourceState.h>
#include <android_media_audiopolicy.h>
+#include <com_android_media_audio.h>
+#include <error/expected_utils.h>
#include <media/AidlConversion.h>
#include <media/AudioPolicy.h>
#include <media/AudioValidator.h>
@@ -44,13 +46,30 @@
if (!_tmp.isOk()) return _tmp; \
}
+#define CHECK_PERM(expr1, expr2) \
+ VALUE_OR_RETURN_STATUS(getPermissionProvider().checkPermission((expr1), (expr2)))
+
#define MAX_ITEMS_PER_LIST 1024
namespace android {
namespace audiopolicy_flags = android::media::audiopolicy;
using binder::Status;
using aidl_utils::binderStatusFromStatusT;
+using com::android::media::audio::audioserver_permissions;
using com::android::media::permission::NativePermissionController;
+using com::android::media::permission::PermissionEnum::ACCESS_ULTRASOUND;
+using com::android::media::permission::PermissionEnum::CALL_AUDIO_INTERCEPTION;
+using com::android::media::permission::PermissionEnum::CAPTURE_AUDIO_HOTWORD;
+using com::android::media::permission::PermissionEnum::CAPTURE_VOICE_COMMUNICATION_OUTPUT;
+using com::android::media::permission::PermissionEnum::CAPTURE_AUDIO_OUTPUT;
+using com::android::media::permission::PermissionEnum::CAPTURE_MEDIA_OUTPUT;
+using com::android::media::permission::PermissionEnum::CAPTURE_TUNER_AUDIO_INPUT;
+using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_ROUTING;
+using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_SETTINGS;
+using com::android::media::permission::PermissionEnum::MODIFY_DEFAULT_AUDIO_EFFECTS;
+using com::android::media::permission::PermissionEnum::MODIFY_PHONE_STATE;
+using com::android::media::permission::PermissionEnum::RECORD_AUDIO;
+using com::android::media::permission::PermissionEnum::WRITE_SECURE_SETTINGS;
using content::AttributionSourceState;
using media::audio::common::AudioConfig;
using media::audio::common::AudioConfigBase;
@@ -86,31 +105,37 @@
!= std::end(mSupportedSystemUsages);
}
-status_t AudioPolicyService::validateUsage(const audio_attributes_t& attr) {
+Status AudioPolicyService::validateUsage(const audio_attributes_t& attr) {
return validateUsage(attr, getCallingAttributionSource());
}
-status_t AudioPolicyService::validateUsage(const audio_attributes_t& attr,
+Status AudioPolicyService::validateUsage(const audio_attributes_t& attr,
const AttributionSourceState& attributionSource) {
if (isSystemUsage(attr.usage)) {
if (isSupportedSystemUsage(attr.usage)) {
if (attr.usage == AUDIO_USAGE_CALL_ASSISTANT
&& ((attr.flags & AUDIO_FLAG_CALL_REDIRECTION) != 0)) {
- if (!callAudioInterceptionAllowed(attributionSource)) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(CALL_AUDIO_INTERCEPTION, attributionSource.uid)
+ : callAudioInterceptionAllowed(attributionSource))) {
ALOGE("%s: call audio interception not allowed for attribution source: %s",
__func__, attributionSource.toString().c_str());
- return PERMISSION_DENIED;
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "Call audio interception not allowed");
}
- } else if (!modifyAudioRoutingAllowed(attributionSource)) {
+ } else if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, attributionSource.uid)
+ : modifyAudioRoutingAllowed(attributionSource))) {
ALOGE("%s: modify audio routing not allowed for attribution source: %s",
__func__, attributionSource.toString().c_str());
- return PERMISSION_DENIED;
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "Modify audio routing not allowed");
}
} else {
- return BAD_VALUE;
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
}
- return NO_ERROR;
+ return Status::ok();
}
@@ -137,7 +162,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
@@ -191,7 +218,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -215,7 +244,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (uint32_t(state) >= AUDIO_MODE_CNT) {
@@ -265,7 +296,9 @@
return binderStatusFromStatusT(NO_INIT);
}
- if (!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -355,7 +388,7 @@
RETURN_IF_BINDER_ERROR(
binderStatusFromStatusT(AudioValidator::validateAudioAttributes(attr, "68953950")));
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr, attributionSource)));
+ RETURN_IF_BINDER_ERROR(validateUsage(attr, attributionSource));
ALOGV("%s()", __func__);
audio_utils::lock_guard _l(mMutex);
@@ -364,14 +397,22 @@
aidl2legacy_int32_t_uid_t(attributionSource.uid)))) {
attr.flags = static_cast<audio_flags_mask_t>(attr.flags | AUDIO_FLAG_NO_MEDIA_PROJECTION);
}
+ const bool bypassInterruptionAllowed = audioserver_permissions() ? (
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, attributionSource.uid) ||
+ CHECK_PERM(MODIFY_PHONE_STATE, attributionSource.uid) ||
+ CHECK_PERM(WRITE_SECURE_SETTINGS, attributionSource.uid))
+ : bypassInterruptionPolicyAllowed(attributionSource);
+
if (((attr.flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
- && !bypassInterruptionPolicyAllowed(attributionSource)) {
+ && !bypassInterruptionAllowed) {
attr.flags = static_cast<audio_flags_mask_t>(
attr.flags & ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE));
}
if (attr.content_type == AUDIO_CONTENT_TYPE_ULTRASOUND) {
- if (!accessUltrasoundAllowed(attributionSource)) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(ACCESS_ULTRASOUND, attributionSource.uid)
+ : accessUltrasoundAllowed(attributionSource))) {
ALOGE("%s: permission denied: ultrasound not allowed for uid %d pid %d",
__func__, attributionSource.uid, attributionSource.pid);
return binderStatusFromStatusT(PERMISSION_DENIED);
@@ -400,18 +441,24 @@
break;
case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
if (((attr.flags & AUDIO_FLAG_CALL_REDIRECTION) != 0)
- && !callAudioInterceptionAllowed(attributionSource)) {
+ && !(audioserver_permissions() ?
+ CHECK_PERM(CALL_AUDIO_INTERCEPTION, attributionSource.uid)
+ : callAudioInterceptionAllowed(attributionSource))) {
ALOGE("%s() permission denied: call redirection not allowed for uid %d",
__func__, attributionSource.uid);
result = PERMISSION_DENIED;
- } else if (!modifyPhoneStateAllowed(attributionSource)) {
+ } else if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_PHONE_STATE, attributionSource.uid)
+ : modifyPhoneStateAllowed(attributionSource))) {
ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
__func__, attributionSource.uid);
result = PERMISSION_DENIED;
}
break;
case AudioPolicyInterface::API_OUT_MIX_PLAYBACK:
- if (!modifyAudioRoutingAllowed(attributionSource)) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, attributionSource.uid)
+ : modifyAudioRoutingAllowed(attributionSource))) {
ALOGE("%s() permission denied: modify audio routing not allowed for uid %d",
__func__, attributionSource.uid);
result = PERMISSION_DENIED;
@@ -630,8 +677,7 @@
return binderStatusFromStatusT(BAD_VALUE);
}
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr,
- attributionSource)));
+ RETURN_IF_BINDER_ERROR(validateUsage(attr, attributionSource));
uint32_t virtualDeviceId = kDefaultVirtualDeviceId;
@@ -644,7 +690,10 @@
// type is API_INPUT_MIX_EXT_POLICY_REROUTE and by AudioService if a media projection
// is used and input type is API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK
// - ECHO_REFERENCE source is controlled by captureAudioOutputAllowed()
- if (!(recordingAllowed(attributionSource, inputSource)
+ const auto isRecordingAllowed = audioserver_permissions() ?
+ CHECK_PERM(RECORD_AUDIO, attributionSource.uid) :
+ recordingAllowed(attributionSource, inputSource);
+ if (!(isRecordingAllowed
|| inputSource == AUDIO_SOURCE_FM_TUNER
|| inputSource == AUDIO_SOURCE_REMOTE_SUBMIX
|| inputSource == AUDIO_SOURCE_ECHO_REFERENCE)) {
@@ -653,8 +702,12 @@
return binderStatusFromStatusT(PERMISSION_DENIED);
}
- bool canCaptureOutput = captureAudioOutputAllowed(attributionSource);
- bool canInterceptCallAudio = callAudioInterceptionAllowed(attributionSource);
+ bool canCaptureOutput = audioserver_permissions() ?
+ CHECK_PERM(CAPTURE_AUDIO_OUTPUT, attributionSource.uid)
+ : captureAudioOutputAllowed(attributionSource);
+ bool canInterceptCallAudio = audioserver_permissions() ?
+ CHECK_PERM(CALL_AUDIO_INTERCEPTION, attributionSource.uid)
+ : callAudioInterceptionAllowed(attributionSource);
bool isCallAudioSource = inputSource == AUDIO_SOURCE_VOICE_UPLINK
|| inputSource == AUDIO_SOURCE_VOICE_DOWNLINK
|| inputSource == AUDIO_SOURCE_VOICE_CALL;
@@ -668,11 +721,15 @@
}
if (inputSource == AUDIO_SOURCE_FM_TUNER
&& !canCaptureOutput
- && !captureTunerAudioInputAllowed(attributionSource)) {
+ && !(audioserver_permissions() ?
+ CHECK_PERM(CAPTURE_TUNER_AUDIO_INPUT, attributionSource.uid)
+ : captureTunerAudioInputAllowed(attributionSource))) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
- bool canCaptureHotword = captureHotwordAllowed(attributionSource);
+ bool canCaptureHotword = audioserver_permissions() ?
+ CHECK_PERM(CAPTURE_AUDIO_HOTWORD, attributionSource.uid)
+ : captureHotwordAllowed(attributionSource);
if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -687,7 +744,9 @@
}
if (attr.source == AUDIO_SOURCE_ULTRASOUND) {
- if (!accessUltrasoundAllowed(attributionSource)) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(ACCESS_ULTRASOUND, attributionSource.uid)
+ : accessUltrasoundAllowed(attributionSource))) {
ALOGE("%s: permission denied: ultrasound not allowed for uid %d pid %d",
__func__, attributionSource.uid, attributionSource.pid);
return binderStatusFromStatusT(PERMISSION_DENIED);
@@ -733,14 +792,29 @@
status = PERMISSION_DENIED;
}
break;
- case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
- if (!(modifyAudioRoutingAllowed(attributionSource)
+ case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE: {
+ bool modAudioRoutingAllowed;
+ if (audioserver_permissions()) {
+ auto result = getPermissionProvider().checkPermission(
+ MODIFY_AUDIO_ROUTING, attributionSource.uid);
+ if (!result.ok()) {
+ ALOGE("%s permission provider error: %s", __func__,
+ result.error().toString8().c_str());
+ status = aidl_utils::statusTFromBinderStatus(result.error());
+ break;
+ }
+ modAudioRoutingAllowed = result.value();
+ } else {
+ modAudioRoutingAllowed = modifyAudioRoutingAllowed(attributionSource);
+ }
+ if (!(modAudioRoutingAllowed
|| ((attr.flags & AUDIO_FLAG_CALL_REDIRECTION) != 0
&& canInterceptCallAudio))) {
ALOGE("%s permission denied for remote submix capture", __func__);
status = PERMISSION_DENIED;
}
break;
+ }
case AudioPolicyInterface::API_INPUT_INVALID:
default:
LOG_ALWAYS_FATAL("%s encountered an invalid input type %d",
@@ -1035,7 +1109,9 @@
if (mAudioPolicyManager == nullptr) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (uint32_t(streamToDriveAbs) >= AUDIO_STREAM_PUBLIC_CNT) {
@@ -1059,7 +1135,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
@@ -1083,7 +1161,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
@@ -1133,7 +1213,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
audio_utils::lock_guard _l(mMutex);
@@ -1439,7 +1521,9 @@
sp<AudioPolicyEffects>audioPolicyEffects;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(getAudioPolicyEffects(audioPolicyEffects)));
- if (!modifyDefaultAudioEffectsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_DEFAULT_AUDIO_EFFECTS, IPCThreadState::self()->getCallingUid())
+ : modifyDefaultAudioEffectsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(audioPolicyEffects->addSourceDefaultEffect(
@@ -1465,7 +1549,9 @@
sp<AudioPolicyEffects> audioPolicyEffects;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(getAudioPolicyEffects(audioPolicyEffects)));
- if (!modifyDefaultAudioEffectsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_DEFAULT_AUDIO_EFFECTS, IPCThreadState::self()->getCallingUid())
+ : modifyDefaultAudioEffectsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(audioPolicyEffects->addStreamDefaultEffect(
@@ -1480,7 +1566,9 @@
aidl2legacy_int32_t_audio_unique_id_t(idAidl));
sp<AudioPolicyEffects>audioPolicyEffects;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(getAudioPolicyEffects(audioPolicyEffects)));
- if (!modifyDefaultAudioEffectsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_DEFAULT_AUDIO_EFFECTS, IPCThreadState::self()->getCallingUid())
+ : modifyDefaultAudioEffectsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
return binderStatusFromStatusT(audioPolicyEffects->removeSourceDefaultEffect(id));
@@ -1492,7 +1580,9 @@
aidl2legacy_int32_t_audio_unique_id_t(idAidl));
sp<AudioPolicyEffects>audioPolicyEffects;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(getAudioPolicyEffects(audioPolicyEffects)));
- if (!modifyDefaultAudioEffectsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_DEFAULT_AUDIO_EFFECTS, IPCThreadState::self()->getCallingUid())
+ : modifyDefaultAudioEffectsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
return binderStatusFromStatusT(audioPolicyEffects->removeStreamDefaultEffect(id));
@@ -1510,7 +1600,9 @@
std::back_inserter(systemUsages), aidl2legacy_AudioUsage_audio_usage_t)));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -1569,7 +1661,7 @@
return binderStatusFromStatusT(NO_INIT);
}
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attributes)));
+ RETURN_IF_BINDER_ERROR(validateUsage(attributes));
audio_utils::lock_guard _l(mMutex);
*_aidl_return = mAudioPolicyManager->isDirectOutputSupported(config, attributes);
@@ -1644,7 +1736,9 @@
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(AudioValidator::validateAudioPatch(patch)));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1663,7 +1757,9 @@
audio_patch_handle_t handle = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_patch_handle_t(handleAidl));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1711,7 +1807,9 @@
binderStatusFromStatusT(AudioValidator::validateAudioPortConfig(config)));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1774,7 +1872,9 @@
// loopback|render only need a MediaProjection (checked in caller AudioService.java)
bool needModifyAudioRouting = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
return !is_mix_loopback_render(mix.mRouteFlags); });
- if (needModifyAudioRouting && !modifyAudioRoutingAllowed()) {
+ if (needModifyAudioRouting && !(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -1790,12 +1890,16 @@
const AttributionSourceState attributionSource = getCallingAttributionSource();
- if (needCaptureMediaOutput && !captureMediaOutputAllowed(attributionSource)) {
+ if (needCaptureMediaOutput && !(audioserver_permissions() ?
+ CHECK_PERM(CAPTURE_MEDIA_OUTPUT, attributionSource.uid)
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (needCaptureVoiceCommunicationOutput &&
- !captureVoiceCommunicationOutputAllowed(attributionSource)) {
+ !(audioserver_permissions() ?
+ CHECK_PERM(CAPTURE_VOICE_COMMUNICATION_OUTPUT, attributionSource.uid)
+ : captureVoiceCommunicationOutputAllowed(attributionSource))) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -1852,7 +1956,9 @@
aidl2legacy_AudioDeviceTypeAddress));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1866,7 +1972,9 @@
uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1885,7 +1993,9 @@
aidl2legacy_AudioDeviceTypeAddress));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1899,7 +2009,9 @@
int userId = VALUE_OR_RETURN_BINDER_STATUS(convertReinterpret<int>(userIdAidl));
audio_utils::lock_guard _l(mMutex);
- if(!modifyAudioRoutingAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, IPCThreadState::self()->getCallingUid())
+ : modifyAudioRoutingAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (mAudioPolicyManager == NULL) {
@@ -1927,7 +2039,7 @@
return binderStatusFromStatusT(NO_INIT);
}
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attributes)));
+ RETURN_IF_BINDER_ERROR(validateUsage(attributes));
// startAudioSource should be created as the calling uid
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1956,7 +2068,9 @@
if (mAudioPolicyManager == NULL) {
return binderStatusFromStatusT(NO_INIT);
}
- if (!settingsAllowed()) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS, IPCThreadState::self()->getCallingUid())
+ : settingsAllowed())) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
audio_utils::lock_guard _l(mMutex);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 699cacf..720ba84 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -452,8 +452,8 @@
app_state_t apmStatFromAmState(int amState);
bool isSupportedSystemUsage(audio_usage_t usage);
- status_t validateUsage(const audio_attributes_t& attr);
- status_t validateUsage(const audio_attributes_t& attr,
+ binder::Status validateUsage(const audio_attributes_t& attr);
+ binder::Status validateUsage(const audio_attributes_t& attr,
const AttributionSourceState& attributionSource);
void updateUidStates();