summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-12 15:01:24 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-12 15:01:24 +0100
commite15fd68c5dc4089690b5d3086776c3851e504bb7 (patch)
tree2c75274dee02b07463c9164efdf6888e1a9c75dc /services
parent185e2110a53feb7720d91b6f8366ad27402f21cc (diff)
parent26c5fa31d17a638bf314de6e12e86bb8a86db44b (diff)
downloadframeworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.zip
frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.gz
frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.bz2
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_av into replicant-6.0
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/Android.mk11
-rw-r--r--services/audioflinger/AudioMixer.cpp3
-rw-r--r--services/audioflinger/AudioResamplerQTI.cpp21
-rw-r--r--services/audioflinger/AudioResamplerQTI.h2
-rw-r--r--services/audioflinger/Effects.cpp29
-rw-r--r--services/audioflinger/FastCapture.cpp1
-rw-r--r--services/audioflinger/FastCaptureDumpState.cpp2
-rw-r--r--services/audioflinger/FastMixer.cpp18
-rw-r--r--services/audioflinger/ServiceUtilities.cpp8
-rw-r--r--services/audioflinger/ServiceUtilities.h1
-rw-r--r--services/audioflinger/Threads.cpp52
-rw-r--r--services/audioflinger/Threads.h4
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h4
-rw-r--r--services/audiopolicy/engineconfigurable/parameter-framework/Android.mk2
-rw-r--r--services/audiopolicy/service/AudioPolicyClientImpl.cpp4
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.cpp132
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.h19
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp71
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp9
-rw-r--r--services/audiopolicy/service/AudioPolicyService.cpp95
-rw-r--r--services/audiopolicy/service/AudioPolicyService.h41
-rw-r--r--services/camera/libcameraservice/CameraFlashlight.cpp14
-rw-r--r--services/camera/libcameraservice/CameraService.cpp4
-rw-r--r--services/camera/libcameraservice/CameraService.h2
-rw-r--r--services/camera/libcameraservice/api1/CameraClient.cpp8
-rw-r--r--services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp8
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp8
-rw-r--r--services/soundtrigger/SoundTriggerHwService.cpp69
28 files changed, 430 insertions, 212 deletions
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 0dd2af6..8ea26d3 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -160,12 +160,19 @@ LOCAL_SHARED_LIBRARIES := \
libaudioutils
#QTI Resampler
-ifeq ($(call is-vendor-board-platform,QCOM), true)
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true)
+ifdef TARGET_2ND_ARCH
LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += AudioResamplerQTI.cpp.arm
LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH) += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH) += libqct_resampler
LOCAL_CFLAGS_$(TARGET_2ND_ARCH) += -DQTI_RESAMPLER
+else
+LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
+LOCAL_SHARED_LIBRARIES += libqct_resampler
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
endif
endif
#QTI Resampler
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 806eaf1..bb9d4e5 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -781,7 +781,8 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam
#ifdef QTI_RESAMPLER
if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) &&
(trackSampleRate > devSampleRate * 2) &&
- ((devSampleRate == 48000)||(devSampleRate == 44100))) {
+ ((devSampleRate == 48000)||(devSampleRate == 44100)) &&
+ (resamplerChannelCount <= 2)) {
quality = AudioResampler::QTI_QUALITY;
}
#endif
diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp
index 44b741e..0d57e09 100644
--- a/services/audioflinger/AudioResamplerQTI.cpp
+++ b/services/audioflinger/AudioResamplerQTI.cpp
@@ -51,8 +51,9 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
{
int16_t vl = mVolume[0];
int16_t vr = mVolume[1];
- int16_t *pBuf;
+ int32_t *pBuf;
+ int64_t tempL, tempR;
size_t inFrameRequest;
size_t inFrameCount = getNumInSample(outFrameCount);
size_t index = 0;
@@ -74,7 +75,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
if(mResamplerOutBuf) {
delete [] mResamplerOutBuf;
}
- mTmpBuf = new int16_t[inFrameRequest + 16];
+ mTmpBuf = new int32_t[inFrameRequest + 16];
mResamplerOutBuf = new int32_t[out_count];
}
@@ -95,7 +96,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
goto resample_exit;
}
- mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+ mTmpBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++));
if (frameIndex >= mBuffer.frameCount) {
provider->releaseBuffer(&mBuffer);
@@ -121,8 +122,8 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
goto resample_exit;
}
- mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
- pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+ mTmpBuf[index] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++));
+ pBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++));
if (frameIndex >= mBuffer.frameCount * 2) {
provider->releaseBuffer(&mBuffer);
}
@@ -133,8 +134,12 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
resample_exit:
for (int i = 0; i < out_count; i += 2) {
- fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl);
- fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr);
+ // Multiplying q4.27 data with u4.12 gain could result in 39 fractional bit data(27+12)
+ // To get back the 27 fractional bit format output data, do right shift by 12
+ tempL = (int64_t)mResamplerOutBuf[i] * vl;
+ tempR = (int64_t)mResamplerOutBuf[i+1] * vr;
+ fout[i] += float_from_q4_27((int32_t)(tempL>>12));
+ fout[i+1] += float_from_q4_27((int32_t)(tempR>>12));
}
mFrameIndex = frameIndex;
@@ -151,7 +156,7 @@ void AudioResamplerQTI::setSampleRate(int32_t inSampleRate)
void AudioResamplerQTI::init()
{
- QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate);
+ QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate, 1/*32bit in*/);
}
size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount)
diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h
index 0b30a9f..1cf93fc 100644
--- a/services/audioflinger/AudioResamplerQTI.h
+++ b/services/audioflinger/AudioResamplerQTI.h
@@ -35,7 +35,7 @@ public:
size_t getNumInSample(size_t outFrameCount);
int16_t *mState;
- int16_t *mTmpBuf;
+ int32_t *mTmpBuf;
int32_t *mResamplerOutBuf;
size_t mFrameIndex;
size_t stateSize;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 879b6c9..5505d2e 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -543,6 +543,13 @@ status_t AudioFlinger::EffectModule::remove_effect_from_hal_l()
return NO_ERROR;
}
+// round up delta valid if value and divisor are positive.
+template <typename T>
+static T roundUpDelta(const T &value, const T &divisor) {
+ T remainder = value % divisor;
+ return remainder == 0 ? 0 : divisor - remainder;
+}
+
status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
@@ -558,6 +565,28 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
if (mStatus != NO_ERROR) {
return mStatus;
}
+ if (cmdCode == EFFECT_CMD_GET_PARAM &&
+ (*replySize < sizeof(effect_param_t) ||
+ ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t))) {
+ android_errorWriteLog(0x534e4554, "29251553");
+ return -EINVAL;
+ }
+ if ((cmdCode == EFFECT_CMD_SET_PARAM
+ || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used
+ (sizeof(effect_param_t) > cmdSize
+ || ((effect_param_t *)pCmdData)->psize > cmdSize
+ - sizeof(effect_param_t)
+ || ((effect_param_t *)pCmdData)->vsize > cmdSize
+ - sizeof(effect_param_t)
+ - ((effect_param_t *)pCmdData)->psize
+ || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) >
+ cmdSize
+ - sizeof(effect_param_t)
+ - ((effect_param_t *)pCmdData)->psize
+ - ((effect_param_t *)pCmdData)->vsize)) {
+ android_errorWriteLog(0x534e4554, "30204301");
+ return -EINVAL;
+ }
status_t status = (*mEffectInterface)->command(mEffectInterface,
cmdCode,
cmdSize,
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index 2493fb7..7c8a25f 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -25,6 +25,7 @@
#include <media/AudioBufferProvider.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include "AudioFlinger.h"
#include "FastCapture.h"
namespace android {
diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/FastCaptureDumpState.cpp
index 53eeba5..de4a6db 100644
--- a/services/audioflinger/FastCaptureDumpState.cpp
+++ b/services/audioflinger/FastCaptureDumpState.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "FastCaptureDumpState"
-//define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include "Configuration.h"
#include <utils/Log.h>
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 45c68b5..2bc8066 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -334,6 +334,11 @@ void FastMixer::onWork()
if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
ALOG_ASSERT(mMixerBuffer != NULL);
+
+ // AudioMixer::mState.enabledTracks is undefined if mState.hook == process__validate,
+ // so we keep a side copy of enabledTracks
+ bool anyEnabledTracks = false;
+
// for each track, update volume and check for underrun
unsigned currentTrackMask = current->mTrackMask;
while (currentTrackMask != 0) {
@@ -392,11 +397,13 @@ void FastMixer::onWork()
underruns.mBitFields.mPartial++;
underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
mMixer->enable(name);
+ anyEnabledTracks = true;
}
} else {
underruns.mBitFields.mFull++;
underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
mMixer->enable(name);
+ anyEnabledTracks = true;
}
ftDump->mUnderruns = underruns;
ftDump->mFramesReady = framesReady;
@@ -407,9 +414,14 @@ void FastMixer::onWork()
pts = AudioBufferProvider::kInvalidPTS;
}
- // process() is CPU-bound
- mMixer->process(pts);
- mMixerBufferState = MIXED;
+ if (anyEnabledTracks) {
+ // process() is CPU-bound
+ mMixer->process(pts);
+ mMixerBufferState = MIXED;
+ } else if (mMixerBufferState != ZEROED) {
+ mMixerBufferState = UNDEFINED;
+ }
+
} else if (mMixerBufferState == MIXED) {
mMixerBufferState = UNDEFINED;
}
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index 2e68dad..031ff05 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -106,6 +106,14 @@ bool captureAudioOutputAllowed() {
return ok;
}
+bool accessFmRadioAllowed() {
+ static const String16 sAccessFmRadio("android.permission.ACCESS_FM_RADIO");
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkCallingPermission(sAccessFmRadio);
+ if (!ok) ALOGE("Request requires android.permission.ACCESS_FM_RADIO");
+ return ok;
+}
+
bool captureHotwordAllowed() {
static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index fba6dce..dffb114 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,6 +21,7 @@ namespace android {
extern pid_t getpid_cached;
bool recordingAllowed(const String16& opPackageName);
+bool accessFmRadioAllowed();
bool captureAudioOutputAllowed();
bool captureHotwordAllowed();
bool settingsAllowed();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c3ee6c2..e5e8bdb 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2574,11 +2574,10 @@ void AudioFlinger::PlaybackThread::cacheParameters_l()
}
}
-void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
+void AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType)
{
ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
this, streamType, mTracks.size());
- Mutex::Autolock _l(mLock);
size_t size = mTracks.size();
for (size_t i = 0; i < size; i++) {
@@ -2589,6 +2588,12 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy
}
}
+void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
+{
+ Mutex::Autolock _l(mLock);
+ invalidateTracks_l(streamType);
+}
+
status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
{
int session = chain->sessionId();
@@ -4470,8 +4475,12 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar
dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
// Make a non-atomic copy of fast mixer dump state so it won't change underneath us
- const FastMixerDumpState copy(mFastMixerDumpState);
- copy.dump(fd);
+ // while we are dumping it. It may be inconsistent, but it won't mutate!
+ // This is a large object so we place it on the heap.
+ // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
+ const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState);
+ copy->dump(fd);
+ delete copy;
#ifdef STATE_QUEUE_DUMP
// Similar for state queue
@@ -4863,6 +4872,10 @@ bool AudioFlinger::DirectOutputThread::shouldStandby_l()
bool trackPaused = false;
bool trackStopped = false;
+ if ((mType == DIRECT) && audio_is_linear_pcm(mFormat) && !usesHwAvSync()) {
+ return !mStandby;
+ }
+
// do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack
// after a timeout and we will enter standby then.
if (mTracks.size() > 0) {
@@ -4983,6 +4996,8 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l()
mStandbyDelayNs = 0;
} else if ((mType == OFFLOAD) && !audio_is_linear_pcm(mFormat)) {
mStandbyDelayNs = kOffloadStandbyDelayNs;
+ } else if (mType == DIRECT && mIsDirectPcm) {
+ mStandbyDelayNs = kOffloadStandbyDelayNs;
} else {
mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2);
}
@@ -5154,15 +5169,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
if (track->isInvalid()) {
ALOGW("An invalidated track shouldn't be in active list");
tracksToRemove->add(track);
- continue;
- }
-
- if (track->mState == TrackBase::IDLE) {
+ } else if (track->mState == TrackBase::IDLE) {
ALOGW("An idle track shouldn't be in active list");
- continue;
- }
-
- if (track->isPausing()) {
+ } else if (track->isPausing()) {
track->setPaused();
if (last) {
if (mHwSupportsPause && !mHwPaused) {
@@ -5185,7 +5194,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
if (last) {
mFlushPending = true;
}
- } else if (track->isResumePending()){
+ } else if (track->isResumePending()) {
track->resumeAck();
if (last) {
if (mPausedBytesRemaining) {
@@ -5361,6 +5370,13 @@ void AudioFlinger::OffloadThread::flushHw_l()
}
}
+void AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType)
+{
+ Mutex::Autolock _l(mLock);
+ mFlushPending = true;
+ PlaybackThread::invalidateTracks_l(streamType);
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
@@ -6454,9 +6470,13 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no");
dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no");
- // Make a non-atomic copy of fast capture dump state so it won't change underneath us
- const FastCaptureDumpState copy(mFastCaptureDumpState);
- copy.dump(fd);
+ // Make a non-atomic copy of fast capture dump state so it won't change underneath us
+ // while we are dumping it. It may be inconsistent, but it won't mutate!
+ // This is a large object so we place it on the heap.
+ // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
+ const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState);
+ copy->dump(fd);
+ delete copy;
}
void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 48ff77d..8fab1e4 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -617,7 +617,8 @@ public:
virtual bool isValidSyncEvent(const sp<SyncEvent>& event) const;
// called with AudioFlinger lock held
- void invalidateTracks(audio_stream_type_t streamType);
+ void invalidateTracks_l(audio_stream_type_t streamType);
+ virtual void invalidateTracks(audio_stream_type_t streamType);
virtual size_t frameCount() const { return mNormalFrameCount; }
@@ -1000,6 +1001,7 @@ protected:
virtual bool waitingAsyncCallback();
virtual bool waitingAsyncCallback_l();
+ virtual void invalidateTracks(audio_stream_type_t streamType);
private:
size_t mPausedWriteLength; // length in bytes of write interrupted by pause
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index a5edc14..93e6266 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -332,8 +332,8 @@ public:
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
- virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added) = 0;
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& streamInfo, bool added) = 0;
+
};
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
index c402fd5..be86231 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
@@ -4,4 +4,4 @@ LOCAL_PATH := $(call my-dir)
# Recursive call sub-folder Android.mk
#######################################################################
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(LOCAL_PATH)/plugin/Android.mk
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index d71daa4..82720f4 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -220,9 +220,9 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate(
}
void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ sp<AudioSessionInfo>& info, bool added)
{
- mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, added);
}
audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId()
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index f2d7f6f..d6fabfe 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -228,6 +228,8 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
{
status_t status = NO_ERROR;
+ ALOGV("addOutputSessionEffects %d", audioSession);
+
Mutex::Autolock _l(mLock);
// create audio processors according to stream
// FIXME: should we have specific post processing settings for internal streams?
@@ -235,6 +237,22 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
stream = AUDIO_STREAM_MUSIC;
}
+
+ // send the streaminfo notification only once
+ ssize_t sidx = mOutputAudioSessionInfo.indexOfKey(audioSession);
+ if (sidx >= 0) {
+ // AudioSessionInfo is existing and we just need to increase ref count
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(sidx);
+ info->mRefCount++;
+
+ if (info->mRefCount == 1) {
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, true);
+ }
+ ALOGV("addOutputSessionEffects(): session info %d refCount=%d", audioSession, info->mRefCount);
+ } else {
+ ALOGV("addOutputSessionEffects(): no output stream info found for stream");
+ }
+
ssize_t index = mOutputStreams.indexOfKey(stream);
if (index < 0) {
ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
@@ -246,8 +264,6 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
if (idx < 0) {
procDesc = new EffectVector(audioSession);
mOutputSessions.add(audioSession, procDesc);
-
- mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, true);
} else {
// EffectVector is existing and we just need to increase ref count
procDesc = mOutputSessions.valueAt(idx);
@@ -279,65 +295,123 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
return status;
}
-status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
- audio_stream_type_t stream,
- int audioSession)
+status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */,
+ audio_stream_type_t stream,
+ int session)
{
- status_t status = NO_ERROR;
- (void) output; // argument not used for now
- (void) stream; // argument not used for now
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
Mutex::Autolock _l(mLock);
- ssize_t index = mOutputSessions.indexOfKey(audioSession);
- if (index < 0) {
- ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
- return NO_ERROR;
+
+ ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+ if (idx >= 0) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(idx);
+ if (info->mRefCount == 0) {
+ mOutputAudioSessionInfo.removeItemsAt(idx);
+ }
+ ALOGV("releaseOutputAudioSessionInfo() sessionId=%d refcount=%d",
+ session, info->mRefCount);
+ } else {
+ ALOGV("releaseOutputAudioSessionInfo() no session info found");
}
+ return NO_ERROR;
+}
- EffectVector *procDesc = mOutputSessions.valueAt(index);
+status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* output */,
+ audio_stream_type_t stream,
+ int session,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask, uid_t uid)
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
- // just in case it already has a death wish
- if (procDesc->mRefCount == 0) {
+ Mutex::Autolock _l(mLock);
+
+ // TODO: Handle other stream types based on client registration
+ if (stream != AUDIO_STREAM_MUSIC) {
return NO_ERROR;
}
- procDesc->mRefCount--;
- ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
- audioSession, procDesc->mRefCount);
+ // update AudioSessionInfo. This is used in the stream open/close path
+ // to notify userspace applications about session creation and
+ // teardown, allowing the app to make decisions about effects for
+ // a particular stream. This is independent of the current
+ // output_session_processing feature which forcibly attaches a
+ // static list of effects to a stream.
+ ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+ sp<AudioSessionInfo> info;
+ if (idx < 0) {
+ info = new AudioSessionInfo(session, stream, flags, channelMask, uid);
+ mOutputAudioSessionInfo.add(session, info);
+ } else {
+ // the streaminfo may actually change
+ info = mOutputAudioSessionInfo.valueAt(idx);
+ info->mFlags = flags;
+ info->mChannelMask = channelMask;
+ }
- if (procDesc->mRefCount == 0) {
- mAudioPolicyService->releaseOutputSessionEffectsDelayed(
- output, stream, audioSession, 10000);
+ ALOGV("updateOutputAudioSessionInfo() sessionId=%d, flags=0x%x, channelMask=0x%x uid=%d refCount=%d",
+ info->mSessionId, info->mFlags, info->mChannelMask, info->mUid, info->mRefCount);
+
+ return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ ALOGV("listAudioSessions() streams %d", streams);
+
+ for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(i);
+ if (streams == -1 || info->mStream == streams) {
+ sessions.push_back(info);
+ }
}
- return status;
+ return NO_ERROR;
}
-status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t output,
+status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
int audioSession)
{
status_t status = NO_ERROR;
(void) output; // argument not used for now
+ (void) stream; // argument not used for now
Mutex::Autolock _l(mLock);
- ssize_t index = mOutputSessions.indexOfKey(audioSession);
+ ssize_t index = mOutputAudioSessionInfo.indexOfKey(audioSession);
+ if (index >= 0) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(index);
+ info->mRefCount--;
+ if (info->mRefCount == 0) {
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, false);
+ }
+ ALOGV("releaseOutputSessionEffects(): session=%d refCount=%d", info->mSessionId, info->mRefCount);
+ } else {
+ ALOGV("releaseOutputSessionEffects: no stream info was attached to this stream");
+ }
+
+ index = mOutputSessions.indexOfKey(audioSession);
if (index < 0) {
- ALOGV("doReleaseOutputSessionEffects: no output processing was attached to this stream");
+ ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
return NO_ERROR;
}
EffectVector *procDesc = mOutputSessions.valueAt(index);
- ALOGV("doReleaseOutputSessionEffects(): session: %d, refCount: %d",
+ procDesc->mRefCount--;
+ ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
audioSession, procDesc->mRefCount);
-
if (procDesc->mRefCount == 0) {
procDesc->setProcessorEnabled(false);
procDesc->mEffects.clear();
delete procDesc;
mOutputSessions.removeItemsAt(index);
- mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false);
- ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d",
+ ALOGV("releaseOutputSessionEffects(): output processing released from session: %d",
audioSession);
}
return status;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 7988515..a95d49f 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -46,7 +46,7 @@ public:
// The constructor will parse audio_effects.conf
// First it will look whether vendor specific file exists,
// otherwise it will parse the system default file.
- AudioPolicyEffects(AudioPolicyService *audioPolicyService);
+ AudioPolicyEffects(AudioPolicyService *audioPolicyService);
virtual ~AudioPolicyEffects();
// NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService
@@ -86,11 +86,18 @@ public:
audio_stream_type_t stream,
int audioSession);
- // For deferred release
- status_t doReleaseOutputSessionEffects(audio_io_handle_t output,
- audio_stream_type_t stream,
- int audioSession);
+ status_t updateOutputAudioSessionInfo(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ int audioSession,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask, uid_t uid);
+
+ status_t releaseOutputAudioSessionInfo(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ int audioSession);
+ status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions);
private:
@@ -200,6 +207,8 @@ private:
KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
// Automatic output effects are unique for audiosession ID
KeyedVector< int32_t, EffectVector* > mOutputSessions;
+ // Stream info for session events
+ KeyedVector< int32_t, sp<AudioSessionInfo> > mOutputAudioSessionInfo;
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index c0d3866..b23c35e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -161,19 +161,32 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
- ALOGV("getOutput()");
- Mutex::Autolock _l(mLock);
+ ALOGV("getOutputForAttr()");
+ status_t status = NO_ERROR;
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
- // if the caller is us, trust the specified uid
- if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
- uid_t newclientUid = IPCThreadState::self()->getCallingUid();
- if (uid != (uid_t)-1 && uid != newclientUid) {
- ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
+ // if the caller is us, trust the specified uid
+ if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
+ uid_t newclientUid = IPCThreadState::self()->getCallingUid();
+ if (uid != (uid_t)-1 && uid != newclientUid) {
+ ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
+ }
+ uid = newclientUid;
}
- uid = newclientUid;
+ status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
+ format, channelMask, flags, selectedDeviceId, offloadInfo);
+
+ audioPolicyEffects = mAudioPolicyEffects;
}
- return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
- format, channelMask, flags, selectedDeviceId, offloadInfo);
+
+ if (status == NO_ERROR && audioPolicyEffects != 0) {
+ audioPolicyEffects->updateOutputAudioSessionInfo(*output,
+ *stream, session, flags, channelMask, uid);
+ }
+
+ return status;
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -269,8 +282,16 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
audio_session_t session)
{
ALOGV("doReleaseOutput from tid %d", gettid());
- Mutex::Autolock _l(mLock);
- mAudioPolicyManager->releaseOutput(output, stream, session);
+ sp<AudioPolicyEffects>audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
+ audioPolicyEffects = mAudioPolicyEffects;
+ mAudioPolicyManager->releaseOutput(output, stream, session);
+ }
+ if (audioPolicyEffects != 0) {
+ audioPolicyEffects->releaseOutputAudioSessionInfo(output,
+ stream, session);
+ }
}
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
@@ -295,6 +316,11 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
return BAD_VALUE;
}
+
+ if ((attr->source == AUDIO_SOURCE_FM_TUNER) && !accessFmRadioAllowed()) {
+ return BAD_VALUE;
+ }
+
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status;
AudioPolicyInterface::input_type_t inputType;
@@ -717,4 +743,25 @@ status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle)
return mAudioPolicyManager->stopAudioSource(handle);
}
+status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ audioPolicyEffects = mAudioPolicyEffects;
+ }
+
+ if (audioPolicyEffects != 0) {
+ return audioPolicyEffects->listAudioSessions(streams, sessions);
+ }
+
+ // no errors here if effects are not available
+ return NO_ERROR;
+}
+
+
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index 318c6d2..da7f45d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -275,6 +275,10 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
return BAD_VALUE;
}
+ if ((inputSource == AUDIO_SOURCE_FM_TUNER) && !accessFmRadioAllowed()) {
+ return BAD_VALUE;
+ }
+
#ifdef HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB
if (inputSource == AUDIO_SOURCE_HOTWORD)
inputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
@@ -642,4 +646,9 @@ status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle)
return INVALID_OPERATION;
}
+status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ return INVALID_OPERATION;
+}
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 58cfe37..79370f4 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -177,23 +177,6 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
}
-status_t AudioPolicyService::setEffectSessionCallbacksEnabled(bool enabled)
-{
- Mutex::Autolock _l(mNotificationClientsLock);
-
- uid_t uid = IPCThreadState::self()->getCallingUid();
- if (mNotificationClients.indexOfKey(uid) < 0) {
- return NO_INIT;
- }
- if (!modifyAudioRoutingAllowed()) {
- ALOGE("setEffectSessionCallbacksEnabled requires MODIFY_AUDIO_ROUTING");
- return PERMISSION_DENIED;
- }
- mNotificationClients.valueFor(uid)->setEffectSessionCallbacksEnabled(enabled);
- return OK;
-}
-
-
// removeNotificationClient() is called when the client process dies.
void AudioPolicyService::removeNotificationClient(uid_t uid)
{
@@ -271,22 +254,18 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co
return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
}
-void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- bool added)
+void AudioPolicyService::onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
{
ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)",
- stream, sessionId, added);
- mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, added);
+ info->mStream, info->mSessionId, added);
+ mOutputCommandThread->effectSessionUpdateCommand(info, added);
}
-void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- bool added)
+void AudioPolicyService::doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
{
Mutex::Autolock _l(mNotificationClientsLock);
for (size_t i = 0; i < mNotificationClients.size(); i++) {
- mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(info, added);
}
}
@@ -294,8 +273,7 @@ AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyS
const sp<IAudioPolicyServiceClient>& client,
uid_t uid)
: mService(service), mUid(uid), mAudioPolicyServiceClient(client),
- mAudioPortCallbacksEnabled(false),
- mEffectSessionCallbacksEnabled(false)
+ mAudioPortCallbacksEnabled(false)
{
}
@@ -327,10 +305,10 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
}
void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ sp<AudioSessionInfo>& info, bool added)
{
- if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) {
- mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ if (mAudioPolicyServiceClient != 0) {
+ mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(info, added);
}
}
@@ -347,23 +325,12 @@ void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool e
mAudioPortCallbacksEnabled = enabled;
}
-void AudioPolicyService::NotificationClient::setEffectSessionCallbacksEnabled(bool enabled)
-{
- mEffectSessionCallbacksEnabled = enabled;
-}
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
IPCThreadState::self()->getCallingPid());
}
-void AudioPolicyService::releaseOutputSessionEffectsDelayed(
- audio_io_handle_t output, audio_stream_type_t stream,
- audio_unique_id_t sessionId, int delayMs)
-{
- mAudioCommandThread->releaseOutputSessionEffectsCommand(output, stream, sessionId, delayMs);
-}
-
static bool tryLock(Mutex& mutex)
{
bool locked = false;
@@ -639,30 +606,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
EffectSessionUpdateData *data =
(EffectSessionUpdateData *)command->mParam.get();
ALOGV("AudioCommandThread() processing effect session update %d %d %d",
- data->mStream, data->mSessionId, data->mAdded);
+ data->mAudioSessionInfo->mStream, data->mAudioSessionInfo->mSessionId,
+ data->mAdded);
svc = mService.promote();
if (svc == 0) {
break;
}
mLock.unlock();
- svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded);
+ svc->doOnOutputSessionEffectsUpdate(data->mAudioSessionInfo, data->mAdded);
mLock.lock();
} break;
- case RELEASE_OUTPUT_SESSION_EFFECTS: {
- ReleaseOutputSessionEffectsData *data =
- (ReleaseOutputSessionEffectsData *)command->mParam.get();
- ALOGV("AudioCommandThread() processing release output session effects %d %d %d",
- data->mOutput, data->mStream, data->mSessionId);
- svc = mService.promote();
- if (svc == 0) {
- break;
- }
- mLock.unlock();
- svc->mAudioPolicyEffects->doReleaseOutputSessionEffects(
- data->mOutput, data->mStream, data->mSessionId);
- mLock.lock();
- } break;
-
default:
ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
@@ -937,37 +890,19 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
}
void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ sp<AudioSessionInfo>& streamInfo, bool added)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = EFFECT_SESSION_UPDATE;
EffectSessionUpdateData *data = new EffectSessionUpdateData();
- data->mStream = stream;
- data->mSessionId = sessionId;
+ data->mAudioSessionInfo = streamInfo;
data->mAdded = added;
command->mParam = data;
ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)",
- stream, sessionId, added);
+ streamInfo->mStream, streamInfo->mSessionId, added);
sendCommand(command);
}
-void AudioPolicyService::AudioCommandThread::releaseOutputSessionEffectsCommand(
- audio_io_handle_t output, audio_stream_type_t stream,
- audio_unique_id_t sessionId, int delayMs)
-{
- sp<AudioCommand> command = new AudioCommand();
- command->mCommand = RELEASE_OUTPUT_SESSION_EFFECTS;
- ReleaseOutputSessionEffectsData *data = new ReleaseOutputSessionEffectsData();
- data->mOutput = output;
- data->mStream = stream;
- data->mSessionId = sessionId;
- command->mParam = data;
- ALOGV("AudioCommandThread() sending release output session effects (id=%d) for stream %d",
- sessionId, stream);
- sendCommand(command, delayMs);
-}
-
-
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 9b17a26..b7f55ae 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -202,7 +202,8 @@ public:
audio_io_handle_t *handle);
virtual status_t stopAudioSource(audio_io_handle_t handle);
- virtual status_t setEffectSessionCallbacksEnabled(bool enabled);
+ virtual status_t listAudioSessions(audio_stream_type_t stream,
+ Vector< sp<AudioSessionInfo>>& sessions);
status_t doStartOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -231,14 +232,8 @@ public:
void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
- void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
- void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
- void releaseOutputSessionEffectsDelayed(audio_io_handle_t output,
- audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- int delayMs);
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+ void doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
private:
AudioPolicyService() ANDROID_API;
@@ -273,7 +268,6 @@ private:
SET_AUDIOPORT_CONFIG,
DYN_POLICY_MIX_STATE_UPDATE,
EFFECT_SESSION_UPDATE,
- RELEASE_OUTPUT_SESSION_EFFECTS,
};
AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -316,12 +310,7 @@ private:
int delayMs);
void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state);
void insertCommand_l(AudioCommand *command, int delayMs = 0);
- void effectSessionUpdateCommand(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
- void releaseOutputSessionEffectsCommand(audio_io_handle_t output,
- audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- int delayMs = 0);
+ void effectSessionUpdateCommand(sp<AudioSessionInfo>& info, bool added);
private:
class AudioCommandData;
@@ -420,18 +409,10 @@ private:
class EffectSessionUpdateData : public AudioCommandData {
public:
- audio_stream_type_t mStream;
- audio_unique_id_t mSessionId;
+ sp<AudioSessionInfo> mAudioSessionInfo;
bool mAdded;
};
- class ReleaseOutputSessionEffectsData : public AudioCommandData {
- public:
- audio_io_handle_t mOutput;
- audio_stream_type_t mStream;
- audio_unique_id_t mSessionId;
- };
-
Mutex mLock;
Condition mWaitWorkCV;
Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands
@@ -541,8 +522,8 @@ private:
virtual audio_unique_id_t newAudioUniqueId();
- virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+
private:
AudioPolicyService *mAudioPolicyService;
@@ -560,9 +541,8 @@ private:
void onAudioPatchListUpdate();
void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
void setAudioPortCallbacksEnabled(bool enabled);
- void setEffectSessionCallbacksEnabled(bool enabled);
- void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info,
+ bool added);
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
@@ -574,7 +554,6 @@ private:
const uid_t mUid;
const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient;
bool mAudioPortCallbacksEnabled;
- bool mEffectSessionCallbacksEnabled;
};
// Internal dump utilities.
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 406c1c4..62ce610 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -828,6 +828,18 @@ status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
return device->setPreviewWindow(mSurface);
}
+static void notifyCallback(int32_t, int32_t, int32_t, void*) {
+ /* Empty */
+}
+
+static void dataCallback(int32_t, const sp<IMemory>&, camera_frame_metadata_t*, void*) {
+ /* Empty */
+}
+
+static void dataCallbackTimestamp(nsecs_t, int32_t, const sp<IMemory>&, void*) {
+ /* Empty */
+}
+
status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
const String8& cameraId) {
sp<CameraHardwareInterface> device =
@@ -841,7 +853,7 @@ status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
}
// need to set __get_memory in set_callbacks().
- device->setCallbacks(NULL, NULL, NULL, NULL);
+ device->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, this);
mParameters = device->getParameters();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a560b93..3c9fd16 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -81,7 +81,7 @@ static void camera_device_status_change(
sp<CameraService> cs = const_cast<CameraService*>(
static_cast<const CameraService*>(callbacks));
- cs->onDeviceStatusChanged(static_cast<camera_device_status_t>(camera_id),
+ cs->onDeviceStatusChanged(camera_id,
static_cast<camera_device_status_t>(new_status));
}
@@ -277,7 +277,7 @@ CameraService::~CameraService() {
gCameraService = nullptr;
}
-void CameraService::onDeviceStatusChanged(camera_device_status_t cameraId,
+void CameraService::onDeviceStatusChanged(int cameraId,
camera_device_status_t newStatus) {
ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
cameraId, newStatus);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index ee4c3f9..53233bd 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -102,7 +102,7 @@ public:
/////////////////////////////////////////////////////////////////////
// HAL Callbacks
- virtual void onDeviceStatusChanged(camera_device_status_t cameraId,
+ virtual void onDeviceStatusChanged(int cameraId,
camera_device_status_t newStatus);
virtual void onTorchStatusChanged(const String8& cameraId,
ICameraServiceListener::TorchStatus
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 55555fd..af46d63 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -243,11 +243,6 @@ void CameraClient::disconnect() {
return;
}
- if (mClientPid <= 0) {
- LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
- return;
- }
-
// Make sure disconnect() is done once and once only, whether it is called
// from the user directly, or called by the destructor.
if (mHardware == 0) return;
@@ -700,6 +695,9 @@ void CameraClient::disableMsgType(int32_t msgType) {
#define CHECK_MESSAGE_INTERVAL 10 // 10ms
bool CameraClient::lockIfMessageWanted(int32_t msgType) {
+#ifdef MTK_HARDWARE
+ return true;
+#endif
int sleepCount = 0;
while (mMsgEnabled & msgType) {
if (mLock.tryLock() == NO_ERROR) {
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 66d7b00..9e6c0db 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -30,6 +30,7 @@
#include <utils/Trace.h>
#include <gui/BufferItem.h>
#include <gui/Surface.h>
+#include <camera/ICameraRecordingProxy.h>
#include <media/hardware/HardwareAPI.h>
#include "common/CameraDeviceBase.h"
@@ -826,6 +827,9 @@ status_t StreamingProcessor::processRecordingFrame() {
(uint8_t*)heap->getBase() + offset);
payload->eType = kMetadataBufferTypeANWBuffer;
payload->pBuffer = imgBuffer.mGraphicBuffer->getNativeBuffer();
+ // b/28466701
+ payload->pBuffer = (ANativeWindowBuffer*)((uint8_t*)payload->pBuffer -
+ ICameraRecordingProxy::getCommonBaseAddress());
payload->nFenceFd = -1;
ALOGVV("%s: Camera %d: Sending out ANWBuffer %p",
@@ -874,6 +878,10 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
return;
}
+ // b/28466701
+ payload->pBuffer = (ANativeWindowBuffer*)(((uint8_t*)payload->pBuffer) +
+ ICameraRecordingProxy::getCommonBaseAddress());
+
// Release the buffer back to the recording queue
size_t itemIndex;
for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 50d9d75..8b43154 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -43,6 +43,7 @@
#include <utils/Trace.h>
#include <utils/Timers.h>
+#include "CameraService.h"
#include "utils/CameraTraces.h"
#include "mediautils/SchedulingPolicyService.h"
#include "device3/Camera3Device.h"
@@ -1115,6 +1116,13 @@ status_t Camera3Device::createDefaultRequest(int templateId,
CameraMetadata *request) {
ATRACE_CALL();
ALOGV("%s: for template %d", __FUNCTION__, templateId);
+
+ if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) {
+ android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
+ IPCThreadState::self()->getCallingUid(), NULL, 0);
+ return BAD_VALUE;
+ }
+
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 9de6fe2..a1cc6ff 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -270,6 +270,37 @@ void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognitio
if (module == NULL) {
return;
}
+ if (event-> type == SOUND_MODEL_TYPE_KEYPHRASE && event->data_size != 0
+ && event->data_offset != sizeof(struct sound_trigger_phrase_recognition_event)) {
+ // set some defaults for the phrase if the recognition event won't be parsed properly
+ // TODO: read defaults from the config
+
+ struct sound_trigger_phrase_recognition_event newEvent;
+ memset(&newEvent, 0, sizeof(struct sound_trigger_phrase_recognition_event));
+
+ sp<Model> model = module->getModel(event->model);
+
+ newEvent.num_phrases = 1;
+ newEvent.phrase_extras[0].id = 100;
+ newEvent.phrase_extras[0].recognition_modes = RECOGNITION_MODE_VOICE_TRIGGER;
+ newEvent.phrase_extras[0].confidence_level = 100;
+ newEvent.phrase_extras[0].num_levels = 1;
+ newEvent.phrase_extras[0].levels[0].level = 100;
+ newEvent.phrase_extras[0].levels[0].user_id = 100;
+ newEvent.common.status = event->status;
+ newEvent.common.type = event->type;
+ newEvent.common.model = event->model;
+ newEvent.common.capture_available = event->capture_available;
+ newEvent.common.capture_session = event->capture_session;
+ newEvent.common.capture_delay_ms = event->capture_delay_ms;
+ newEvent.common.capture_preamble_ms = event->capture_preamble_ms;
+ newEvent.common.trigger_in_data = event->trigger_in_data;
+ newEvent.common.audio_config = event->audio_config;
+ newEvent.common.data_size = event->data_size;
+ newEvent.common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
+
+ event = &newEvent.common;
+ }
sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
if (eventMemory == 0) {
return;
@@ -534,6 +565,22 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM
struct sound_trigger_sound_model *sound_model =
(struct sound_trigger_sound_model *)modelMemory->pointer();
+ size_t structSize;
+ if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
+ structSize = sizeof(struct sound_trigger_phrase_sound_model);
+ } else {
+ structSize = sizeof(struct sound_trigger_sound_model);
+ }
+
+ if (sound_model->data_offset < structSize ||
+ sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
+ modelMemory->size() < sound_model->data_offset ||
+ sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
+ android_errorWriteLog(0x534e4554, "30148546");
+ ALOGE("loadSoundModel() data_size is too big");
+ return BAD_VALUE;
+ }
+
AutoMutex lock(mLock);
if (mModels.size() >= mDescriptor.properties.max_sound_models) {
@@ -603,11 +650,23 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha
return PERMISSION_DENIED;
}
- if (dataMemory != 0 && dataMemory->pointer() == NULL) {
- ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()");
+ if (dataMemory == 0 || dataMemory->pointer() == NULL) {
+ ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()");
return BAD_VALUE;
}
+
+ struct sound_trigger_recognition_config *config =
+ (struct sound_trigger_recognition_config *)dataMemory->pointer();
+
+ if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
+ config->data_size > (UINT_MAX - config->data_offset) ||
+ dataMemory->size() < config->data_offset ||
+ config->data_size > (dataMemory->size() - config->data_offset)) {
+ ALOGE("startRecognition() data_size is too big");
+ return BAD_VALUE;
+ }
+
AutoMutex lock(mLock);
if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
return INVALID_OPERATION;
@@ -616,17 +675,11 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha
if (model == 0) {
return BAD_VALUE;
}
- if ((dataMemory == 0) ||
- (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
- return BAD_VALUE;
- }
if (model->mState == Model::STATE_ACTIVE) {
return INVALID_OPERATION;
}
- struct sound_trigger_recognition_config *config =
- (struct sound_trigger_recognition_config *)dataMemory->pointer();
//TODO: get capture handle and device from audio policy service
config->capture_handle = model->mCaptureIOHandle;