Merge "cas: fix crash with partially scrambled audio content"
diff --git a/apex/Android.bp b/apex/Android.bp
index 51e4c23..422880a 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -15,6 +15,7 @@
apex {
name: "com.android.media",
manifest: "manifest.json",
+ java_libs: ["updatable-media"],
native_shared_libs: [
// Extractor plugins
"libaacextractor",
@@ -28,7 +29,7 @@
"liboggextractor",
"libwavextractor",
// MediaPlayer2
- "libmediaplayer2_jni",
+ "libmedia2_jni",
],
key: "com.android.media.key",
}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index f4c0341..b72348f 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -63,6 +63,7 @@
typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
namespace {
@@ -156,26 +157,26 @@
}
}
-static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
+static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
switch(level) {
- case HdcpLevel::HDCP_NONE:
+ case HdcpLevel_V1_2::HDCP_NONE:
return DrmPlugin::kHdcpNone;
- case HdcpLevel::HDCP_V1:
+ case HdcpLevel_V1_2::HDCP_V1:
return DrmPlugin::kHdcpV1;
- case HdcpLevel::HDCP_V2:
+ case HdcpLevel_V1_2::HDCP_V2:
return DrmPlugin::kHdcpV2;
- case HdcpLevel::HDCP_V2_1:
+ case HdcpLevel_V1_2::HDCP_V2_1:
return DrmPlugin::kHdcpV2_1;
- case HdcpLevel::HDCP_V2_2:
+ case HdcpLevel_V1_2::HDCP_V2_2:
return DrmPlugin::kHdcpV2_2;
- case HdcpLevel::HDCP_NO_OUTPUT:
+ case HdcpLevel_V1_2::HDCP_V2_3:
+ return DrmPlugin::kHdcpV2_3;
+ case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
return DrmPlugin::kHdcpNoOutput;
default:
return DrmPlugin::kHdcpLevelUnknown;
}
}
-
-
static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
keyedVector) {
std::vector<KeyValue> stdKeyedVector;
@@ -1093,22 +1094,31 @@
}
status_t err = UNKNOWN_ERROR;
- if (mPluginV1_1 == NULL) {
- return ERROR_DRM_CANNOT_HANDLE;
- }
-
*connected = DrmPlugin::kHdcpLevelUnknown;
*max = DrmPlugin::kHdcpLevelUnknown;
- Return<void> hResult = mPluginV1_1->getHdcpLevels(
- [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
- if (status == Status::OK) {
- *connected = toHdcpLevel(hConnected);
- *max = toHdcpLevel(hMax);
- }
- err = toStatusT(status);
- }
- );
+ Return<void> hResult;
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->getHdcpLevels_1_2(
+ [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
+ if (status == Status_V1_2::OK) {
+ *connected = toHdcpLevel(hConnected);
+ *max = toHdcpLevel(hMax);
+ }
+ err = toStatusT_1_2(status);
+ });
+ } else if (mPluginV1_1 != NULL) {
+ hResult = mPluginV1_1->getHdcpLevels(
+ [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
+ if (status == Status::OK) {
+ *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
+ *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
+ }
+ err = toStatusT(status);
+ });
+ } else {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
return hResult.isOk() ? err : DEAD_OBJECT;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index a9b897b..ba5fa65 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -63,6 +63,7 @@
typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
struct DrmPlugin : public IDrmPlugin {
explicit DrmPlugin(SessionLibrary* sessionLibrary);
@@ -162,6 +163,13 @@
return Void();
}
+ Return<void> getHdcpLevels_1_2(getHdcpLevels_1_2_cb _hidl_cb) {
+ HdcpLevel_V1_2 connectedLevel = HdcpLevel_V1_2::HDCP_NONE;
+ HdcpLevel_V1_2 maxLevel = HdcpLevel_V1_2::HDCP_NO_OUTPUT;
+ _hidl_cb(Status_V1_2::OK, connectedLevel, maxLevel);
+ return Void();
+ }
+
Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override;
Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index f4d4da6..b86f177 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -171,6 +171,9 @@
};
inline CMediaTrack *wrap(MediaTrackHelper *track) {
+ if (track == nullptr) {
+ return nullptr;
+ }
CMediaTrack *wrapper = (CMediaTrack*) malloc(sizeof(CMediaTrack));
wrapper->data = track;
wrapper->free = [](void *data) -> void {
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
index e828a7f..493eba3 100644
--- a/include/media/MediaTrack.h
+++ b/include/media/MediaTrack.h
@@ -142,7 +142,7 @@
class MediaTrackCUnwrapper : public MediaTrack {
public:
- explicit MediaTrackCUnwrapper(CMediaTrack *wrapper);
+ static MediaTrackCUnwrapper *create(CMediaTrack *wrapper);
virtual status_t start();
virtual status_t stop();
@@ -155,6 +155,7 @@
virtual ~MediaTrackCUnwrapper();
private:
+ explicit MediaTrackCUnwrapper(CMediaTrack *wrapper);
CMediaTrack *wrapper;
MediaBufferGroup *bufferGroup;
};
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index cc1534a..2013575 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -4868,7 +4868,9 @@
off64_t offset, bool isSubsampleEncryption, uint32_t flags) {
int32_t ivlength;
- CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength));
+ if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) {
+ return ERROR_MALFORMED;
+ }
// only 0, 8 and 16 byte initialization vectors are supported
if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index fffcda0..3b03601 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -62,7 +62,7 @@
, mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
, mInService(inService)
, mServiceInterface(serviceInterface)
- , mAtomicTimestamp()
+ , mAtomicInternalTimestamp()
, mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
, mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
{
@@ -349,8 +349,7 @@
}
}
-aaudio_result_t AudioStreamInternal::requestStop()
-{
+aaudio_result_t AudioStreamInternal::requestStop() {
aaudio_result_t result = stopCallback();
if (result != AAUDIO_OK) {
return result;
@@ -364,7 +363,7 @@
mClockModel.stop(AudioClock::getNanoseconds());
setState(AAUDIO_STREAM_STATE_STOPPING);
- mAtomicTimestamp.clear();
+ mAtomicInternalTimestamp.clear();
return mServiceInterface.stopStream(mServiceStreamHandle);
}
@@ -413,8 +412,8 @@
int64_t *framePosition,
int64_t *timeNanoseconds) {
// Generated in server and passed to client. Return latest.
- if (mAtomicTimestamp.isValid()) {
- Timestamp timestamp = mAtomicTimestamp.read();
+ if (mAtomicInternalTimestamp.isValid()) {
+ Timestamp timestamp = mAtomicInternalTimestamp.read();
int64_t position = timestamp.getPosition() + mFramesOffsetFromService;
if (position >= 0) {
*framePosition = position;
@@ -461,7 +460,7 @@
aaudio_result_t AudioStreamInternal::onTimestampHardware(AAudioServiceMessage *message) {
Timestamp timestamp(message->timestamp.position, message->timestamp.timestamp);
- mAtomicTimestamp.write(timestamp);
+ mAtomicInternalTimestamp.write(timestamp);
return AAUDIO_OK;
}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 3bb9e1e..1c88f52 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -163,7 +163,7 @@
AAudioServiceInterface &mServiceInterface; // abstract interface to the service
- SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
+ SimpleDoubleBuffer<Timestamp> mAtomicInternalTimestamp;
AtomicRequestor mNeedCatchUp; // Ask read() or write() to sync on first timestamp.
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 58ef7b1..7dcb620 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -259,6 +259,7 @@
if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ result = systemStopFromCallback();
break;
}
}
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 9af47b2..6af8e7d 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -71,7 +71,7 @@
mClockModel.stop(AudioClock::getNanoseconds());
setState(AAUDIO_STREAM_STATE_PAUSING);
- mAtomicTimestamp.clear();
+ mAtomicInternalTimestamp.clear();
return mServiceInterface.pauseStream(mServiceStreamHandle);
}
@@ -294,6 +294,7 @@
}
} else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ result = systemStopFromCallback();
break;
}
}
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 2fb3986..0d71efc 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -316,7 +316,7 @@
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
ALOGD("%s(%p) called", __func__, stream);
- return audioStream->systemStop();
+ return audioStream->systemStopFromApp();
}
AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 391af29..e39a075 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -119,21 +119,29 @@
return AAUDIO_OK;
}
-aaudio_result_t AudioStream::safeStart() {
+aaudio_result_t AudioStream::systemStart() {
std::lock_guard<std::mutex> lock(mStreamLock);
+
if (collidesWithCallback()) {
ALOGE("%s cannot be called from a callback!", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
- return requestStart();
+
+ aaudio_result_t result = requestStart();
+ if (result == AAUDIO_OK) {
+ // We only call this for logging in "dumpsys audio". So ignore return code.
+ (void) mPlayerBase->start();
+ }
+ return result;
}
-aaudio_result_t AudioStream::safePause() {
+aaudio_result_t AudioStream::systemPause() {
+ std::lock_guard<std::mutex> lock(mStreamLock);
+
if (!isPauseSupported()) {
return AAUDIO_ERROR_UNIMPLEMENTED;
}
- std::lock_guard<std::mutex> lock(mStreamLock);
if (collidesWithCallback()) {
ALOGE("%s cannot be called from a callback!", __func__);
return AAUDIO_ERROR_INVALID_STATE;
@@ -169,7 +177,12 @@
return AAUDIO_ERROR_INVALID_STATE;
}
- return requestPause();
+ aaudio_result_t result = requestPause();
+ if (result == AAUDIO_OK) {
+ // We only call this for logging in "dumpsys audio". So ignore return code.
+ (void) mPlayerBase->pause();
+ }
+ return result;
}
aaudio_result_t AudioStream::safeFlush() {
@@ -192,12 +205,31 @@
return requestFlush();
}
-aaudio_result_t AudioStream::safeStop() {
+aaudio_result_t AudioStream::systemStopFromCallback() {
+ std::lock_guard<std::mutex> lock(mStreamLock);
+ aaudio_result_t result = safeStop();
+ if (result == AAUDIO_OK) {
+ // We only call this for logging in "dumpsys audio". So ignore return code.
+ (void) mPlayerBase->stop();
+ }
+ return result;
+}
+
+aaudio_result_t AudioStream::systemStopFromApp() {
std::lock_guard<std::mutex> lock(mStreamLock);
if (collidesWithCallback()) {
- ALOGE("stream cannot be stopped from a callback!");
+ ALOGE("stream cannot be stopped by calling from a callback!");
return AAUDIO_ERROR_INVALID_STATE;
}
+ aaudio_result_t result = safeStop();
+ if (result == AAUDIO_OK) {
+ // We only call this for logging in "dumpsys audio". So ignore return code.
+ (void) mPlayerBase->stop();
+ }
+ return result;
+}
+
+aaudio_result_t AudioStream::safeStop() {
switch (getState()) {
// Proceed with stopping.
@@ -224,7 +256,7 @@
case AAUDIO_STREAM_STATE_CLOSING:
case AAUDIO_STREAM_STATE_CLOSED:
default:
- ALOGW("requestStop() stream not running, state = %s",
+ ALOGW("%s() stream not running, state = %s", __func__,
AAudio_convertStreamStateToText(getState()));
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -349,21 +381,33 @@
}
}
-aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds)
+aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds __unused)
{
if (!mHasThread) {
ALOGE("joinThread() - but has no thread");
return AAUDIO_ERROR_INVALID_STATE;
}
+ aaudio_result_t result = AAUDIO_OK;
+ // If the callback is stopping the stream because the app passed back STOP
+ // then we don't need to join(). The thread is already about to exit.
+ if (pthread_self() != mThread) {
+ // Called from an app thread. Not the callback.
#if 0
- // TODO implement equivalent of pthread_timedjoin_np()
- struct timespec abstime;
- int err = pthread_timedjoin_np(mThread, returnArg, &abstime);
+ // TODO implement equivalent of pthread_timedjoin_np()
+ struct timespec abstime;
+ int err = pthread_timedjoin_np(mThread, returnArg, &abstime);
#else
- int err = pthread_join(mThread, returnArg);
+ int err = pthread_join(mThread, returnArg);
#endif
+ if (err) {
+ ALOGE("%s() pthread_join() returns err = %d", __func__, err);
+ result = AAudioConvert_androidToAAudioResult(-err);
+ }
+ }
+ // This must be set false so that the callback thread can be created
+ // when the stream is restarted.
mHasThread = false;
- return err ? AAudioConvert_androidToAAudioResult(-errno) : mThreadRegistrationResult;
+ return (result != AAUDIO_OK) ? result : mThreadRegistrationResult;
}
aaudio_data_callback_result_t AudioStream::maybeCallDataCallback(void *audioData,
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 60200b2..46951f5 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -51,21 +51,6 @@
virtual ~AudioStream();
- /**
- * Lock a mutex and make sure we are not calling from a callback function.
- * @return result of requestStart();
- */
- aaudio_result_t safeStart();
-
- aaudio_result_t safePause();
-
- aaudio_result_t safeFlush();
-
- aaudio_result_t safeStop();
-
- aaudio_result_t safeClose();
-
- // =========== Begin ABSTRACT methods ===========================
protected:
/* Asynchronous requests.
@@ -74,7 +59,7 @@
virtual aaudio_result_t requestStart() = 0;
/**
- * Check the state to see if Pause if currently legal.
+ * Check the state to see if Pause is currently legal.
*
* @param result pointer to return code
* @return true if OK to continue, if false then return result
@@ -356,33 +341,28 @@
mPlayerBase->unregisterWithAudioManager();
}
- // Pass start request through PlayerBase for tracking.
- aaudio_result_t systemStart() {
- mPlayerBase->start();
- // Pass aaudio_result_t around the PlayerBase interface, which uses status__t.
- return mPlayerBase->getResult();
- }
+ aaudio_result_t systemStart();
- // Pass pause request through PlayerBase for tracking.
- aaudio_result_t systemPause() {
- mPlayerBase->pause();
- return mPlayerBase->getResult();
- }
+ aaudio_result_t systemPause();
- // Pass stop request through PlayerBase for tracking.
- aaudio_result_t systemStop() {
- mPlayerBase->stop();
- return mPlayerBase->getResult();
- }
+ aaudio_result_t safeFlush();
+
+ /**
+ * This is called when an app calls AAudioStream_requestStop();
+ * It prevents calls from a callback.
+ */
+ aaudio_result_t systemStopFromApp();
+
+ /**
+ * This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP.
+ */
+ aaudio_result_t systemStopFromCallback();
+
+ aaudio_result_t safeClose();
protected:
- // PlayerBase allows the system to control the stream.
- // Calling through PlayerBase->start() notifies the AudioManager of the player state.
- // The AudioManager also can start/stop a stream by calling mPlayerBase->playerStart().
- // systemStart() ==> mPlayerBase->start() mPlayerBase->playerStart() ==> requestStart()
- // \ /
- // ------ AudioManager -------
+ // PlayerBase allows the system to control the stream volume.
class MyPlayerBase : public android::PlayerBase {
public:
explicit MyPlayerBase(AudioStream *parent);
@@ -406,20 +386,19 @@
void clearParentReference() { mParent = nullptr; }
+ // Just a stub. The ability to start audio through PlayerBase is being deprecated.
android::status_t playerStart() override {
- // mParent should NOT be null. So go ahead and crash if it is.
- mResult = mParent->safeStart();
- return AAudioConvert_aaudioToAndroidStatus(mResult);
+ return android::NO_ERROR;
}
+ // Just a stub. The ability to pause audio through PlayerBase is being deprecated.
android::status_t playerPause() override {
- mResult = mParent->safePause();
- return AAudioConvert_aaudioToAndroidStatus(mResult);
+ return android::NO_ERROR;
}
+ // Just a stub. The ability to stop audio through PlayerBase is being deprecated.
android::status_t playerStop() override {
- mResult = mParent->safeStop();
- return AAudioConvert_aaudioToAndroidStatus(mResult);
+ return android::NO_ERROR;
}
android::status_t playerSetVolume() override {
@@ -548,6 +527,8 @@
private:
+ aaudio_result_t safeStop();
+
std::mutex mStreamLock;
const android::sp<MyPlayerBase> mPlayerBase;
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index a6b9f5d..2edab58 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -78,8 +78,9 @@
void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
aaudio_data_callback_result_t callbackResult;
- // This illegal size can be used to tell AudioFlinger to stop calling us.
- // This takes advantage of AudioFlinger killing the stream.
+ // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
+ // This takes advantage of them killing the stream when they see a size out of range.
+ // That is an undocumented behavior.
// TODO add to API in AudioRecord and AudioTrack
const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
@@ -95,7 +96,7 @@
ALOGW("processCallbackCommon() data, stream disconnected");
audioBuffer->size = SIZE_STOP_CALLBACKS;
} else if (!mCallbackEnabled.load()) {
- ALOGW("processCallbackCommon() stopping because callback disabled");
+ ALOGW("processCallbackCommon() no data because callback disabled");
audioBuffer->size = SIZE_STOP_CALLBACKS;
} else {
if (audioBuffer->frameCount == 0) {
@@ -115,10 +116,16 @@
}
if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
audioBuffer->size = audioBuffer->frameCount * getBytesPerDeviceFrame();
- } else { // STOP or invalid result
- ALOGW("%s() callback requested stop, fake an error", __func__);
- audioBuffer->size = SIZE_STOP_CALLBACKS;
- // Disable the callback just in case AudioFlinger keeps trying to call us.
+ } else {
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+ ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ } else {
+ ALOGW("%s() callback returned invalid result = %d",
+ __func__, callbackResult);
+ }
+ audioBuffer->size = 0;
+ systemStopFromCallback();
+ // Disable the callback just in case the system keeps trying to call us.
mCallbackEnabled.store(false);
}
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 1ac2558..c995e99 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -288,7 +288,7 @@
aaudio_result_t AudioStreamTrack::requestPause() {
if (mAudioTrack.get() == nullptr) {
- ALOGE("requestPause() no AudioTrack");
+ ALOGE("%s() no AudioTrack", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -304,7 +304,7 @@
aaudio_result_t AudioStreamTrack::requestFlush() {
if (mAudioTrack.get() == nullptr) {
- ALOGE("requestFlush() no AudioTrack");
+ ALOGE("%s() no AudioTrack", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -318,7 +318,7 @@
aaudio_result_t AudioStreamTrack::requestStop() {
if (mAudioTrack.get() == nullptr) {
- ALOGE("requestStop() no AudioTrack");
+ ALOGE("%s() no AudioTrack", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 827df6a..1417aaf 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -50,6 +50,7 @@
"libmediametrics",
"libmediautils",
"libnblog",
+ "libprocessgroup",
"libutils",
],
export_shared_lib_headers: ["libbinder"],
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 65b8a38..72a23e3 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -26,6 +26,7 @@
#include <media/AudioRecord.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
+#include <processgroup/sched_policy.h>
#include <media/IAudioFlinger.h>
#include <media/MediaAnalyticsItem.h>
#include <media/TypeConverter.h>
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index baeae8b..4c762ed 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -784,7 +784,8 @@
status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
const char *address = "";
@@ -798,7 +799,7 @@
if (device_name != NULL) {
name = device_name;
}
- return aps->setDeviceConnectionState(device, state, address, name);
+ return aps->setDeviceConnectionState(device, state, address, name, encodedFormat);
}
audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
@@ -812,7 +813,8 @@
status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
const char *address = "";
@@ -826,7 +828,7 @@
if (device_name != NULL) {
name = device_name;
}
- return aps->handleDeviceConfigChange(device, address, name);
+ return aps->handleDeviceConfigChange(device, address, name, encodedFormat);
}
status_t AudioSystem::setPhoneState(audio_mode_t state)
@@ -1335,6 +1337,13 @@
return aps->isHapticPlaybackSupported();
}
+status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
// ---------------------------------------------------------------------------
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index b444d2d..e9a0e22 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -29,6 +29,7 @@
#include <media/AudioTrack.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
+#include <processgroup/sched_policy.h>
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioParameter.h>
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 272415c..8c7fac5 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -92,6 +92,7 @@
IS_HAPTIC_PLAYBACK_SUPPORTED,
SET_UID_DEVICE_AFFINITY,
REMOVE_UID_DEVICE_AFFINITY,
+ GET_OFFLOAD_FORMATS_A2DP
};
#define MAX_ITEMS_PER_LIST 1024
@@ -108,7 +109,8 @@
audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -116,6 +118,7 @@
data.writeInt32(static_cast <uint32_t>(state));
data.writeCString(device_address);
data.writeCString(device_name);
+ data.writeInt32(static_cast <uint32_t>(encodedFormat));
remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
@@ -134,13 +137,15 @@
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast <uint32_t>(device));
data.writeCString(device_address);
data.writeCString(device_name);
+ data.writeInt32(static_cast <uint32_t>(encodedFormat));
remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
@@ -884,7 +889,30 @@
return reply.readInt32();
}
- virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+ {
+ if (formats == NULL) {
+ return BAD_VALUE;
+ }
+
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_OFFLOAD_FORMATS_A2DP, data, &reply);
+ if (status != NO_ERROR || (status = (status_t)reply.readInt32()) != NO_ERROR) {
+ return status;
+ }
+
+ size_t list_size = reply.readUint32();
+
+ for (size_t i = 0; i < list_size; i++) {
+ formats->push_back(static_cast<audio_format_t>(reply.readInt32()));
+ }
+ return NO_ERROR;
+ }
+
+
+ virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
@@ -1096,7 +1124,8 @@
case SET_ASSISTANT_UID:
case SET_A11Y_SERVICES_UIDS:
case SET_UID_DEVICE_AFFINITY:
- case REMOVE_UID_DEVICE_AFFINITY: {
+ case REMOVE_UID_DEVICE_AFFINITY:
+ case GET_OFFLOAD_FORMATS_A2DP: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1121,6 +1150,7 @@
static_cast <audio_policy_dev_state_t>(data.readInt32());
const char *device_address = data.readCString();
const char *device_name = data.readCString();
+ audio_format_t codecFormat = static_cast <audio_format_t>(data.readInt32());
if (device_address == nullptr || device_name == nullptr) {
ALOGE("Bad Binder transaction: SET_DEVICE_CONNECTION_STATE for device %u", device);
reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
@@ -1128,7 +1158,8 @@
reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
state,
device_address,
- device_name)));
+ device_name,
+ codecFormat)));
}
return NO_ERROR;
} break;
@@ -1154,13 +1185,16 @@
static_cast <audio_devices_t>(data.readInt32());
const char *device_address = data.readCString();
const char *device_name = data.readCString();
+ audio_format_t codecFormat =
+ static_cast <audio_format_t>(data.readInt32());
if (device_address == nullptr || device_name == nullptr) {
ALOGE("Bad Binder transaction: HANDLE_DEVICE_CONFIG_CHANGE for device %u", device);
reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
} else {
reply->writeInt32(static_cast<uint32_t> (handleDeviceConfigChange(device,
device_address,
- device_name)));
+ device_name,
+ codecFormat)));
}
return NO_ERROR;
} break;
@@ -1745,6 +1779,21 @@
return NO_ERROR;
}
+ case GET_OFFLOAD_FORMATS_A2DP: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ std::vector<audio_format_t> encodingFormats;
+ status_t status = getHwOffloadEncodingFormatsSupportedForA2DP(&encodingFormats);
+ reply->writeInt32(status);
+ if (status != NO_ERROR) {
+ return NO_ERROR;
+ }
+ reply->writeUint32(static_cast<uint32_t>(encodingFormats.size()));
+ for (size_t i = 0; i < encodingFormats.size(); i++)
+ reply->writeInt32(static_cast<int32_t>(encodingFormats[i]));
+ return NO_ERROR;
+ }
+
+
case ADD_STREAM_DEFAULT_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_uuid_t type;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 781e9df..a208602 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -209,12 +209,14 @@
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
- const char *device_address, const char *device_name);
+ const char *device_address, const char *device_name,
+ audio_format_t encodedFormat);
static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
static status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
static status_t setPhoneState(audio_mode_t state);
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
@@ -342,6 +344,9 @@
static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ static status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
+
// numSurroundFormats holds the maximum number of formats and bool value allowed in the array.
// When numSurroundFormats is 0, surroundFormats and surroundFormatsEnabled will not be
// populated. The actual number of surround formats should be returned at numSurroundFormats.
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index fb4fe93..177adc2 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -44,12 +44,14 @@
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name) = 0;
+ const char *device_name,
+ audio_format_t encodedFormat) = 0;
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name) = 0;
+ const char *device_name,
+ audio_format_t encodedFormat) = 0;
virtual status_t setPhoneState(audio_mode_t state) = 0;
virtual status_t setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) = 0;
@@ -186,6 +188,8 @@
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported) = 0;
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats) = 0;
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
virtual status_t setAssistantUid(uid_t uid) = 0;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 3efb5de..68dae56 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -213,6 +213,7 @@
"android.hidl.token@1.0-utils",
"liblog",
"libcutils",
+ "libprocessgroup",
"libutils",
"libbinder",
"libsonivox",
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 590ba1a..f9fa86e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -23,6 +23,7 @@
#include <media/IDataSource.h>
#include <media/IMediaHTTPService.h>
#include <media/IMediaMetadataRetriever.h>
+#include <processgroup/sched_policy.h>
#include <utils/String8.h>
#include <utils/KeyedVector.h>
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 9511931..4ed3382 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -57,7 +57,7 @@
}
MediaTrack *MediaExtractorCUnwrapper::getTrack(size_t index) {
- return new MediaTrackCUnwrapper(plugin->getTrack(plugin->data, index));
+ return MediaTrackCUnwrapper::create(plugin->getTrack(plugin->data, index));
}
status_t MediaExtractorCUnwrapper::getTrackMetaData(
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index 036e79d..89c9b25 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -65,6 +65,13 @@
bufferGroup = nullptr;
}
+MediaTrackCUnwrapper *MediaTrackCUnwrapper::create(CMediaTrack *cmediatrack) {
+ if (cmediatrack == nullptr) {
+ return nullptr;
+ }
+ return new MediaTrackCUnwrapper(cmediatrack);
+}
+
MediaTrackCUnwrapper::~MediaTrackCUnwrapper() {
wrapper->free(wrapper->data);
free(wrapper);
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 1c2b9d7..cf2ce99 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -75,14 +75,16 @@
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name) = 0;
+ const char *device_name,
+ audio_format_t encodedFormat) = 0;
// retrieve a device connection status
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
// indicate a change in device configuration
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name) = 0;
+ const char *device_name,
+ audio_format_t encodedFormat) = 0;
// indicate a change in phone state. Valid phones states are defined by audio_mode_t
virtual void setPhoneState(audio_mode_t state) = 0;
// force using a specific device category for the specified usage
@@ -234,6 +236,9 @@
virtual bool isHapticPlaybackSupported() = 0;
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats) = 0;
+
virtual void setAppState(uid_t uid, app_state_t state);
};
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 46a2a40..837ca47 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -76,6 +76,21 @@
}
/**
+ * Check whether audio device has encoding capability.
+ *
+ * @param[in] device to consider
+ *
+ * @return true if device has encoding capability, false otherwise..
+ */
+static inline bool device_has_encoding_capability(audio_devices_t device)
+{
+ if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ return true;
+ }
+ return false;
+}
+
+/**
* Returns the priority of a given audio source for capture. The priority is used when more than one
* capture session is active on a given input stream to determine which session drives routing and
* effect configuration.
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 14b995b..e1ecc61 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -154,6 +154,7 @@
void setDevices(const DeviceVector &devices) { mDevices = devices; }
bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const;
+ virtual bool deviceSupportsEncodedFormats(audio_devices_t device);
virtual uint32_t latency();
virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
virtual bool isFixedVolume(audio_devices_t device);
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index b581665..cc43fe6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -44,8 +44,18 @@
const FormatVector& encodedFormats() const { return mEncodedFormats; }
+ audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
+
+ void setEncodedFormat(audio_format_t format) {
+ mCurrentEncodedFormat = format;
+ }
+
bool equals(const sp<DeviceDescriptor>& other) const;
+ bool hasCurrentEncodedFormat() const;
+
+ bool supportsFormat(audio_format_t format);
+
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -69,6 +79,7 @@
audio_devices_t mDeviceType;
FormatVector mEncodedFormats;
audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
+ audio_format_t mCurrentEncodedFormat;
};
class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
@@ -88,9 +99,10 @@
audio_devices_t types() const { return mDeviceTypes; }
- // If 'address' is empty, a device with a non-empty address may be returned
- // if there is no device with the specified 'type' and empty address.
- sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address = {}) const;
+ // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
+ // address may be returned if there is no device with the specified 'type' and empty address.
+ sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
+ audio_format_t codec) const;
DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
/**
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index d7dc4b0..eb34da4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -130,9 +130,11 @@
public:
sp<HwModule> getModuleFromName(const char *name) const;
- sp<HwModule> getModuleForDeviceTypes(audio_devices_t device) const;
+ sp<HwModule> getModuleForDeviceTypes(audio_devices_t device,
+ audio_format_t encodedFormat) const;
- sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device) const;
+ sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device,
+ audio_format_t encodedFormat) const;
DeviceVector getAvailableDevicesFromModuleName(const char *name,
const DeviceVector &availableDevices) const;
@@ -149,6 +151,7 @@
* @param type of the device requested
* @param address of the device requested
* @param name of the device that requested
+ * @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format
* @param matchAddress true if a strong match is required
* @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...)
* @return device descriptor associated to the type (and address if matchAddress is true)
@@ -156,6 +159,7 @@
sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t type,
const char *address,
const char *name,
+ audio_format_t encodedFormat,
bool allowToCreate = false,
bool matchAddress = true) const;
@@ -171,7 +175,8 @@
*/
sp<DeviceDescriptor> createDevice(const audio_devices_t type,
const char *address,
- const char *name) const;
+ const char *name,
+ const audio_format_t encodedFormat) const;
/**
* @brief cleanUpForDevice: loop on all profiles of all modules to remove device from
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index d0c05a5..dc409a7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -94,7 +94,10 @@
bool supportsDeviceTypes(audio_devices_t device) const
{
if (audio_is_output_devices(device)) {
- return mSupportedDevices.types() & device;
+ if (deviceSupportsEncodedFormats(device)) {
+ return mSupportedDevices.types() & device;
+ }
+ return false;
}
return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN);
}
@@ -116,6 +119,16 @@
return mSupportedDevices.contains(device);
}
+ bool deviceSupportsEncodedFormats(audio_devices_t device) const
+ {
+ DeviceVector deviceList =
+ mSupportedDevices.getDevicesFromTypeMask(device);
+ if (!deviceList.empty()) {
+ return deviceList.itemAt(0)->hasCurrentEncodedFormat();
+ }
+ return false;
+ }
+
void clearSupportedDevices() { mSupportedDevices.clear(); }
void addSupportedDevice(const sp<DeviceDescriptor> &device)
{
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 643cbd1..57328f0 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -364,6 +364,16 @@
return filteredDevices.filter(devices);
}
+bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device)
+{
+ if (isDuplicated()) {
+ return (mOutput1->deviceSupportsEncodedFormats(device)
+ || mOutput2->deviceSupportsEncodedFormats(device));
+ } else {
+ return mProfile->deviceSupportsEncodedFormats(device);
+ }
+}
+
uint32_t SwAudioOutputDescriptor::latency()
{
if (isDuplicated()) {
@@ -687,7 +697,9 @@
for (size_t i = 0; i < size(); i++) {
sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (!outputDesc->isDuplicated() &&
- outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP &&
+ outputDesc->deviceSupportsEncodedFormats(
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) {
return this->keyAt(i);
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index d18091c..799950c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -296,7 +296,8 @@
// assuming PolicyMix only for remote submix for input
// so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX
audio_devices_t device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
- auto mixDevice = availDevices.getDevice(device, mix->mDeviceAddress);
+ auto mixDevice =
+ availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
if (mixDevice != nullptr) {
if (policyMix != NULL) {
*policyMix = mix;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 01111c5..2ed8455 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <audio_utils/string.h>
+#include <set>
#include "DeviceDescriptor.h"
#include "TypeConverter.h"
#include "AudioGain.h"
@@ -37,6 +38,7 @@
AUDIO_PORT_ROLE_SOURCE),
mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
{
+ mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
mAddress = String8("0");
}
@@ -45,6 +47,12 @@
mEncodedFormats.add(AUDIO_FORMAT_AC3);
mEncodedFormats.add(AUDIO_FORMAT_IEC61937);
}
+ // For backward compatibility always indicate support for SBC and AAC if no
+ // supported format is listed in the configuration file
+ if ((type & AUDIO_DEVICE_OUT_ALL_A2DP) != 0 && mEncodedFormats.isEmpty()) {
+ mEncodedFormats.add(AUDIO_FORMAT_SBC);
+ mEncodedFormats.add(AUDIO_FORMAT_AAC);
+ }
}
audio_port_handle_t DeviceDescriptor::getId() const
@@ -58,21 +66,49 @@
mId = getNextUniqueId();
}
-void DeviceDescriptor::detach()
-{
+void DeviceDescriptor::detach() {
mId = AUDIO_PORT_HANDLE_NONE;
AudioPort::detach();
}
+template<typename T>
+bool checkEqual(const T& f1, const T& f2)
+{
+ std::set<typename T::value_type> s1(f1.begin(), f1.end());
+ std::set<typename T::value_type> s2(f2.begin(), f2.end());
+ return s1 == s2;
+}
+
bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
{
// Devices are considered equal if they:
// - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
// - have the same address
+ // - have the same encodingFormats (if device supports encoding)
if (other == 0) {
return false;
}
- return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
+
+ return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress) &&
+ checkEqual(mEncodedFormats, other->mEncodedFormats);
+}
+
+bool DeviceDescriptor::hasCurrentEncodedFormat() const
+{
+ if (!device_has_encoding_capability(type())) {
+ return true;
+ }
+ return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
+}
+
+bool DeviceDescriptor::supportsFormat(audio_format_t format)
+{
+ for (const auto& devFormat : mEncodedFormats) {
+ if (devFormat == format) {
+ return true;
+ }
+ }
+ return false;
}
void DeviceVector::refreshTypes()
@@ -167,12 +203,17 @@
return deviceTypes;
}
-sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address) const
+sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
+ audio_format_t format) const
{
sp<DeviceDescriptor> device;
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->type() == type) {
- if (address == "" || itemAt(i)->address() == address) {
+ // Assign device if address is empty or matches and
+ // format is default or matches
+ if (((address == "" || itemAt(i)->address() == address) &&
+ format == AUDIO_FORMAT_DEFAULT) ||
+ itemAt(i)->supportsFormat(format)) {
device = itemAt(i);
if (itemAt(i)->address() == address) {
break;
@@ -180,8 +221,8 @@
}
}
}
- ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p",
- __func__, type, address.string(), device.get());
+ ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
+ __func__, type, address.string(), device.get(), format);
return device;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 7d2d094..85d9bce 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -273,32 +273,34 @@
return nullptr;
}
-sp <HwModule> HwModuleCollection::getModuleForDeviceTypes(audio_devices_t device) const
+sp <HwModule> HwModuleCollection::getModuleForDeviceTypes(audio_devices_t type,
+ audio_format_t encodedFormat) const
{
for (const auto& module : *this) {
- const auto& profiles = audio_is_output_device(device) ?
+ const auto& profiles = audio_is_output_device(type) ?
module->getOutputProfiles() : module->getInputProfiles();
for (const auto& profile : profiles) {
- if (profile->supportsDeviceTypes(device)) {
- return module;
+ if (profile->supportsDeviceTypes(type)) {
+ if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
+ DeviceVector declaredDevices = module->getDeclaredDevices();
+ sp <DeviceDescriptor> deviceDesc =
+ declaredDevices.getDevice(type, String8(), encodedFormat);
+ if (deviceDesc) {
+ return module;
+ }
+ } else {
+ return module;
+ }
}
}
}
return nullptr;
}
-sp <HwModule> HwModuleCollection::getModuleForDevice(const sp<DeviceDescriptor> &device) const
+sp<HwModule> HwModuleCollection::getModuleForDevice(const sp<DeviceDescriptor> &device,
+ audio_format_t encodedFormat) const
{
- for (const auto& module : *this) {
- const auto& profiles = audio_is_output_device(device->type()) ?
- module->getOutputProfiles() : module->getInputProfiles();
- for (const auto& profile : profiles) {
- if (profile->supportsDevice(device)) {
- return module;
- }
- }
- }
- return nullptr;
+ return getModuleForDeviceTypes(device->type(), encodedFormat);
}
DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
@@ -314,6 +316,7 @@
sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType,
const char *address,
const char *name,
+ const audio_format_t encodedFormat,
bool allowToCreate,
bool matchAddress) const
{
@@ -325,8 +328,14 @@
for (const auto& hwModule : *this) {
DeviceVector moduleDevices = hwModule->getAllDevices();
- auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress);
+ auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
if (moduleDevice) {
+ if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
+ moduleDevice->setEncodedFormat(encodedFormat);
+ if (moduleDevice->address() != devAddress) {
+ moduleDevice->setAddress(devAddress);
+ }
+ }
if (allowToCreate) {
moduleDevice->attach(hwModule);
}
@@ -338,14 +347,15 @@
name, deviceType, address);
return nullptr;
}
- return createDevice(deviceType, address, name);
+ return createDevice(deviceType, address, name, encodedFormat);
}
sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type,
const char *address,
- const char *name) const
+ const char *name,
+ const audio_format_t encodedFormat) const
{
- sp<HwModule> hwModule = getModuleForDeviceTypes(type);
+ sp<HwModule> hwModule = getModuleForDeviceTypes(type, encodedFormat);
if (hwModule == 0) {
ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
address);
@@ -354,8 +364,9 @@
sp<DeviceDescriptor> device = new DeviceDescriptor(type, String8(name));
device->setName(String8(name));
device->setAddress(String8(address));
+ device->setEncodedFormat(encodedFormat);
- // Add the device to the list of dynamic devices
+ // Add the device to the list of dynamic devices
hwModule->addDynamicDevice(device);
// Reciprocally attach the device to the module
device->attach(hwModule);
@@ -370,7 +381,8 @@
if (profile->supportsDevice(device, false /*matchAdress*/)) {
// @todo quid of audio profile? import the profile from device of the same type?
- const auto &isoTypeDeviceForProfile = profile->getSupportedDevices().getDevice(type);
+ const auto &isoTypeDeviceForProfile =
+ profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT);
device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
ALOGV("%s: adding device %s to profile %s", __FUNCTION__,
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 1154654..98d375c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -140,6 +140,8 @@
static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
/** optional: device address, char string less than 64. */
static constexpr const char *address = "address";
+ /** optional: the list of encoded audio formats that are known to be supported. */
+ static constexpr const char *encodedFormats = "encodedFormats";
};
static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
@@ -511,7 +513,13 @@
ALOGW("%s: bad type %08x", __func__, type);
return Status::fromStatusT(BAD_VALUE);
}
- Element deviceDesc = new DeviceDescriptor(type, String8(name.c_str()));
+ std::string encodedFormatsLiteral = getXmlAttribute(cur, Attributes::encodedFormats);
+ ALOGV("%s: %s %s=%s", __func__, tag, Attributes::encodedFormats, encodedFormatsLiteral.c_str());
+ FormatVector encodedFormats;
+ if (!encodedFormatsLiteral.empty()) {
+ encodedFormats = formatsFromString(encodedFormatsLiteral, " ");
+ }
+ Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str()));
std::string address = getXmlAttribute(cur, Attributes::address);
if (!address.empty()) {
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 3d68cd8..cc5a025 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -506,7 +506,7 @@
if (strategy != STRATEGY_SONIFICATION) {
// no sonification on remote submix (e.g. WFD)
if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- String8("0")) != 0) {
+ String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5c8a799..cc151e7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -81,9 +81,11 @@
status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
- status_t status = setDeviceConnectionStateInt(device, state, device_address, device_name);
+ status_t status = setDeviceConnectionStateInt(device, state, device_address,
+ device_name, encodedFormat);
nextAudioPortGeneration();
return status;
}
@@ -101,16 +103,17 @@
status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
- ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
- deviceType, state, device_address, device_name);
+ ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X",
+ deviceType, state, device_address, device_name, encodedFormat);
// connect/disconnect only 1 device at a time
if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
sp<DeviceDescriptor> device =
- mHwModules.getDeviceDescriptor(deviceType, device_address, device_name,
+ mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
if (device == 0) {
return INVALID_OPERATION;
@@ -133,10 +136,22 @@
ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
return INVALID_OPERATION;
}
- ALOGV("%s() connecting device %s", __func__, device->toString().c_str());
+ ALOGV("%s() connecting device %s format %x",
+ __func__, device->toString().c_str(), encodedFormat);
// register new device as available
- if (mAvailableOutputDevices.add(device) < 0) {
+ index = mAvailableOutputDevices.add(device);
+ if (index >= 0) {
+ sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat);
+ if (module == 0) {
+ ALOGD("setDeviceConnectionState() could not find HW module for device %s",
+ device->toString().c_str());
+ mAvailableOutputDevices.remove(device);
+ return INVALID_OPERATION;
+ }
+ ALOGV("setDeviceConnectionState() module name=%s", module->getName());
+ mAvailableOutputDevices[index]->attach(module);
+ } else {
return NO_MEMORY;
}
@@ -178,6 +193,9 @@
checkOutputsForDevice(device, state, outputs);
+ // Reset active device codec
+ device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
+
// Propagate device availability to Engine
mEngine->setDeviceConnectionState(device, state);
} break;
@@ -248,6 +266,13 @@
ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
return INVALID_OPERATION;
}
+ sp<HwModule> module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT);
+ if (module == NULL) {
+ ALOGW("setDeviceConnectionState(): could not find HW module for device %s",
+ device->toString().c_str());
+ return INVALID_OPERATION;
+ }
+
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
broadcastDeviceConnectionState(device, state);
@@ -318,7 +343,8 @@
const char *device_address)
{
sp<DeviceDescriptor> devDesc =
- mHwModules.getDeviceDescriptor(device, device_address, "", false /* allowToCreate */,
+ mHwModules.getDeviceDescriptor(device, device_address, "", AUDIO_FORMAT_DEFAULT,
+ false /* allowToCreate */,
(strlen(device_address) != 0)/*matchAddress*/);
if (devDesc == 0) {
@@ -338,50 +364,61 @@
return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
- return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
+ return (deviceVector->getDevice(
+ device, String8(device_address), AUDIO_FORMAT_DEFAULT) != 0) ?
AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
status_t status;
String8 reply;
AudioParameter param;
int isReconfigA2dpSupported = 0;
- ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
- device, device_address, device_name);
+ ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s encodedFormat: 0x%X",
+ device, device_address, device_name, encodedFormat);
// connect/disconnect only 1 device at a time
if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
// Check if the device is currently connected
- sp<DeviceDescriptor> devDesc =
- mHwModules.getDeviceDescriptor(device, device_address, device_name);
- if (devDesc == 0 || mAvailableOutputDevices.indexOf(devDesc) < 0) {
+ DeviceVector availableDevices = getAvailableOutputDevices();
+ DeviceVector deviceList = availableDevices.getDevicesFromTypeMask(device);
+ if (deviceList.empty()) {
// Nothing to do: device is not connected
return NO_ERROR;
}
+ sp<DeviceDescriptor> devDesc = deviceList.itemAt(0);
// For offloaded A2DP, Hw modules may have the capability to
- // configure codecs. Check if any of the loaded hw modules
- // supports this.
- // If supported, send a set parameter to configure A2DP codecs
- // and return. No need to toggle device state.
+ // configure codecs.
+ // Handle two specific cases by sending a set parameter to
+ // configure A2DP codecs. No need to toggle device state.
+ // Case 1: A2DP active device switches from primary to primary
+ // module
+ // Case 2: A2DP device config changes on primary module.
if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
- reply = mpClientInterface->getParameters(
- AUDIO_IO_HANDLE_NONE,
- String8(AudioParameter::keyReconfigA2dpSupported));
- AudioParameter repliedParameters(reply);
- repliedParameters.getInt(
- String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
- if (isReconfigA2dpSupported) {
- const String8 key(AudioParameter::keyReconfigA2dp);
- param.add(key, String8("true"));
- mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
- return NO_ERROR;
+ sp<HwModule> module = mHwModules.getModuleForDeviceTypes(device, encodedFormat);
+ audio_module_handle_t primaryHandle = mPrimaryOutput->getModuleHandle();
+ if (availablePrimaryOutputDevices().contains(devDesc) &&
+ (module != 0 && module->getHandle() == primaryHandle)) {
+ reply = mpClientInterface->getParameters(
+ AUDIO_IO_HANDLE_NONE,
+ String8(AudioParameter::keyReconfigA2dpSupported));
+ AudioParameter repliedParameters(reply);
+ repliedParameters.getInt(
+ String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
+ if (isReconfigA2dpSupported) {
+ const String8 key(AudioParameter::keyReconfigA2dp);
+ param.add(key, String8("true"));
+ mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
+ devDesc->setEncodedFormat(encodedFormat);
+ return NO_ERROR;
+ }
}
}
@@ -389,7 +426,8 @@
// This will force reading again the device configuration
status = setDeviceConnectionState(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- device_address, device_name);
+ device_address, device_name,
+ devDesc->getEncodedFormat());
if (status != NO_ERROR) {
ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
status);
@@ -398,7 +436,7 @@
status = setDeviceConnectionState(device,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- device_address, device_name);
+ device_address, device_name, encodedFormat);
if (status != NO_ERROR) {
ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
status);
@@ -408,6 +446,43 @@
return NO_ERROR;
}
+status_t AudioPolicyManager::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ ALOGV("getHwOffloadEncodingFormatsSupportedForA2DP()");
+ char *tok = NULL, *saveptr;
+ status_t status = NO_ERROR;
+ char encoding_formats_list[PROPERTY_VALUE_MAX];
+ audio_format_t format = AUDIO_FORMAT_DEFAULT;
+ // FIXME This list should not come from a property but the supported encoded
+ // formats of declared A2DP devices in primary module
+ property_get("persist.bluetooth.a2dp_offload.cap", encoding_formats_list, "");
+ tok = strtok_r(encoding_formats_list, "-", &saveptr);
+ for (;tok != NULL; tok = strtok_r(NULL, "-", &saveptr)) {
+ if (strcmp(tok, "sbc") == 0) {
+ ALOGV("%s: SBC offload supported\n",__func__);
+ format = AUDIO_FORMAT_SBC;
+ } else if (strcmp(tok, "aptx") == 0) {
+ ALOGV("%s: APTX offload supported\n",__func__);
+ format = AUDIO_FORMAT_APTX;
+ } else if (strcmp(tok, "aptxhd") == 0) {
+ ALOGV("%s: APTX HD offload supported\n",__func__);
+ format = AUDIO_FORMAT_APTX_HD;
+ } else if (strcmp(tok, "ldac") == 0) {
+ ALOGV("%s: LDAC offload supported\n",__func__);
+ format = AUDIO_FORMAT_LDAC;
+ } else if (strcmp(tok, "aac") == 0) {
+ ALOGV("%s: AAC offload supported\n",__func__);
+ format = AUDIO_FORMAT_AAC;
+ } else {
+ ALOGE("%s: undefined token - %s\n",__func__, tok);
+ continue;
+ }
+ formats->push_back(format);
+ }
+ return status;
+}
+
uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs)
{
bool createTxPatch = false;
@@ -464,15 +539,18 @@
}
if (isRx) {
patchBuilder.addSink(device).
- addSource(mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX));
+ addSource(mAvailableInputDevices.getDevice(
+ AUDIO_DEVICE_IN_TELEPHONY_RX, String8(), AUDIO_FORMAT_DEFAULT));
} else {
patchBuilder.addSource(device).
- addSink(mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX));
+ addSink(mAvailableOutputDevices.getDevice(
+ AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT));
}
// @TODO: still ignoring the address, or not dealing platform with mutliple telephonydevices
const sp<DeviceDescriptor> outputDevice = isRx ?
- device : mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX);
+ device : mAvailableOutputDevices.getDevice(
+ AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs =
getOutputsForDevices(DeviceVector(outputDevice), mOutputs);
audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
@@ -736,6 +814,10 @@
if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
continue;
}
+ // reject profiles if connected device does not support codec
+ if (!curProfile->deviceSupportsEncodedFormats(devices.types())) {
+ continue;
+ }
if (!directOnly) return curProfile;
// when searching for direct outputs, if several profiles are compatible, give priority
// to one with offload capability
@@ -840,7 +922,8 @@
*output = desc->mIoHandle;
AudioMix *mix = desc->mPolicyMix;
sp<DeviceDescriptor> deviceDesc =
- mAvailableOutputDevices.getDevice(mix->mDeviceType, mix->mDeviceAddress);
+ mAvailableOutputDevices.getDevice(
+ mix->mDeviceType, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
*selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
ALOGV("%s returns output %d", __func__, *output);
return NO_ERROR;
@@ -883,7 +966,8 @@
*output = AUDIO_IO_HANDLE_NONE;
if (!msdDevices.isEmpty()) {
*output = getOutputForDevices(msdDevices, session, *stream, config, flags);
- sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(deviceType);
+ sp<DeviceDescriptor> deviceDesc =
+ mAvailableOutputDevices.getDevice(deviceType, String8(), AUDIO_FORMAT_DEFAULT);
if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(deviceDesc) == NO_ERROR) {
ALOGV("%s() Using MSD devices %s instead of device %s",
__func__, msdDevices.toString().c_str(), deviceDesc->toString().c_str());
@@ -1158,7 +1242,7 @@
ALOGE("%s() unable to get MSD module", __func__);
return NO_INIT;
}
- sp<HwModule> deviceModule = mHwModules.getModuleForDevice(outputDevice);
+ sp<HwModule> deviceModule = mHwModules.getModuleForDevice(outputDevice, AUDIO_FORMAT_DEFAULT);
if (deviceModule == nullptr) {
ALOGE("%s() unable to get module for %s", __func__, outputDevice->toString().c_str());
return NO_INIT;
@@ -1456,7 +1540,8 @@
} else {
newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
- devices.add(mAvailableOutputDevices.getDevice(newDeviceType, String8(address)));
+ devices.add(mAvailableOutputDevices.getDevice(newDeviceType,
+ String8(address), AUDIO_FORMAT_DEFAULT));
}
// requiresMuteCheck is false when we can bypass mute strategy.
@@ -1574,7 +1659,8 @@
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address,
- "remote-submix");
+ "remote-submix",
+ AUDIO_FORMAT_DEFAULT);
}
return NO_ERROR;
@@ -1620,7 +1706,7 @@
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputDesc->mPolicyMix->mDeviceAddress,
- "remote-submix");
+ "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
bool forceDeviceUpdate = false;
@@ -1812,7 +1898,8 @@
}
*inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- String8(attr->tags + strlen("addr=")));
+ String8(attr->tags + strlen("addr=")),
+ AUDIO_FORMAT_DEFAULT);
} else {
if (explicitRoutingDevice != nullptr) {
device = explicitRoutingDevice;
@@ -1831,7 +1918,8 @@
// know about it and is therefore considered "legacy"
*inputType = API_INPUT_LEGACY;
} else if (audio_is_remote_submix_device(device->type())) {
- device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"));
+ device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"),
+ AUDIO_FORMAT_DEFAULT);
*inputType = API_INPUT_MIX_CAPTURE;
} else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
*inputType = API_INPUT_TELEPHONY_RX;
@@ -2065,7 +2153,7 @@
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address, "remote-submix");
+ address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
}
@@ -2116,7 +2204,7 @@
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address, "remote-submix");
+ address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
resetInputDevice(input);
@@ -2536,11 +2624,11 @@
if (mix.mMixType == MIX_TYPE_PLAYERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address.string(), "remote-submix");
+ address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
} else {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address.string(), "remote-submix");
+ address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
} else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
String8 address = mix.mDeviceAddress;
@@ -2614,13 +2702,13 @@
AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address.string(), "remote-submix");
+ address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address.string(), "remote-submix");
+ address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
rSubmixModule->removeOutputProfile(address);
rSubmixModule->removeInputProfile(address);
@@ -2664,7 +2752,8 @@
// reevaluate outputs for all given devices
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
- devices[i].mType, devices[i].mAddress, String8());
+ devices[i].mType, devices[i].mAddress, String8(),
+ AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs;
if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
outputs) != NO_ERROR) {
@@ -2685,7 +2774,8 @@
// reevaluate outputs for all found devices
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
- devices[i].mType, devices[i].mAddress, String8());
+ devices[i].mType, devices[i].mAddress, String8(),
+ AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs;
if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputs) != NO_ERROR) {
@@ -3442,7 +3532,8 @@
sp<DeviceDescriptor> srcDevice =
mAvailableInputDevices.getDevice(source->ext.device.type,
- String8(source->ext.device.address));
+ String8(source->ext.device.address),
+ AUDIO_FORMAT_DEFAULT);
if (srcDevice == 0) {
ALOGW("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
return BAD_VALUE;
@@ -3726,14 +3817,16 @@
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.c_str(),
- name.c_str());
+ name.c_str(),
+ AUDIO_FORMAT_DEFAULT);
if (status != NO_ERROR) {
continue;
}
status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(),
- name.c_str());
+ name.c_str(),
+ AUDIO_FORMAT_DEFAULT);
profileUpdated |= (status == NO_ERROR);
}
// FIXME: Why doing this for input HDMI devices if we don't augment their reported formats?
@@ -3746,14 +3839,16 @@
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.c_str(),
- name.c_str());
+ name.c_str(),
+ AUDIO_FORMAT_DEFAULT);
if (status != NO_ERROR) {
continue;
}
status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(),
- name.c_str());
+ name.c_str(),
+ AUDIO_FORMAT_DEFAULT);
profileUpdated |= (status == NO_ERROR);
}
@@ -4178,7 +4273,8 @@
// first list already open outputs that can be routed to this device
for (size_t i = 0; i < mOutputs.size(); i++) {
desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && desc->supportsDevice(device)) {
+ if (!desc->isDuplicated() && desc->supportsDevice(device)
+ && desc->deviceSupportsEncodedFormats(deviceType)) {
ALOGV("checkOutputsForDevice(): adding opened output %d on device %s",
mOutputs.keyAt(i), device->toString().c_str());
outputs.add(mOutputs.keyAt(i));
@@ -4341,7 +4437,8 @@
desc = mOutputs.valueAt(i);
if (!desc->isDuplicated()) {
// exact match on device
- if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)) {
+ if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
+ && desc->deviceSupportsEncodedFormats(deviceType)) {
outputs.add(mOutputs.keyAt(i));
} else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
@@ -4628,7 +4725,8 @@
ALOGVV("output %zu isDuplicated=%d device=%s",
i, openOutputs.valueAt(i)->isDuplicated(),
openOutputs.valueAt(i)->supportedDevices().toString().c_str());
- if (openOutputs.valueAt(i)->supportsAllDevices(devices)) {
+ if (openOutputs.valueAt(i)->supportsAllDevices(devices)
+ && openOutputs.valueAt(i)->deviceSupportsEncodedFormats(devices.types())) {
ALOGVV("%s() found output %d", __func__, openOutputs.keyAt(i));
outputs.add(openOutputs.keyAt(i));
}
@@ -4684,9 +4782,10 @@
maxLatency = desc->latency();
}
}
- ALOGV("%s: strategy %d, moving from output %s to output %s", __func__, strategy,
- (srcOutputs.isEmpty()? "none" : std::to_string(srcOutputs[0]).c_str()),
- (dstOutputs.isEmpty()? "none" : std::to_string(dstOutputs[0]).c_str()));
+ ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
+ "%s: strategy %d, moving from output %s to output %s", __func__, strategy,
+ std::to_string(srcOutputs[0]).c_str(),
+ std::to_string(dstOutputs[0]).c_str());
// mute strategy while moving tracks from one output to another
for (audio_io_handle_t srcOut : srcOutputs) {
sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
@@ -5404,9 +5503,10 @@
if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
return mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
- String8(attributes.tags + strlen("addr=")));
+ String8(attributes.tags + strlen("addr=")),
+ AUDIO_FORMAT_DEFAULT);
}
- return mAvailableInputDevices.getDevice(device);
+ return mAvailableInputDevices.getDevice(device, String8(), AUDIO_FORMAT_DEFAULT);
}
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index e99de16..fb1f7cb 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -97,12 +97,14 @@
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
virtual void setPhoneState(audio_mode_t state);
virtual void setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
@@ -239,6 +241,9 @@
bool reported);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
+
// return the strategy corresponding to a given stream type
routing_strategy getStrategy(audio_stream_type_t stream) const;
@@ -731,7 +736,8 @@
status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
void updateMono(audio_io_handle_t output) {
AudioParameter param;
param.addInt(String8(AudioParameter::keyMonoOutput), (int)mMasterMono);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 2c904d9..49c541c 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -32,7 +32,8 @@
status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -49,7 +50,7 @@
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->setDeviceConnectionState(device, state,
- device_address, device_name);
+ device_address, device_name, encodedFormat);
}
audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
@@ -66,7 +67,8 @@
status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -79,7 +81,7 @@
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->handleDeviceConfigChange(device, device_address,
- device_name);
+ device_name, encodedFormat);
}
status_t AudioPolicyService::setPhoneState(audio_mode_t state)
@@ -1138,6 +1140,17 @@
surroundFormatsEnabled, reported);
}
+status_t AudioPolicyService::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ AutoCallerClear acc;
+ return mAudioPolicyManager->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
status_t AudioPolicyService::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 959e757..c073b7c 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -61,13 +61,15 @@
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(
audio_devices_t device,
const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
virtual status_t setPhoneState(audio_mode_t state);
virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
@@ -218,6 +220,8 @@
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported);
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
virtual status_t setAssistantUid(uid_t uid);
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 3b6dc80..a104ee5 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -69,8 +69,8 @@
include $(CLEAR_VARS)
# seccomp is not required for coverage build.
ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES_arm := crash_dump.policy mediacodec.policy
-LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediacodec.policy
+LOCAL_REQUIRED_MODULES_arm := crash_dump.policy mediaswcodec.policy
+LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediaswcodec.policy
endif
LOCAL_SRC_FILES := \
main_swcodecservice.cpp \
@@ -137,4 +137,26 @@
include $(BUILD_PREBUILT)
endif
+####################################################################
+
+# sw service seccomp policy
+ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
+include $(CLEAR_VARS)
+LOCAL_MODULE := mediaswcodec.policy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
+# mediaswcodec runs in 32-bit combatibility mode. For 64 bit architectures,
+# use the 32 bit policy
+ifdef TARGET_2ND_ARCH
+ ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
+ LOCAL_SRC_FILES := seccomp_policy/mediaswcodec-$(TARGET_2ND_ARCH).policy
+ else
+ LOCAL_SRC_FILES := seccomp_policy/mediaswcodec-$(TARGET_ARCH).policy
+ endif
+else
+ LOCAL_SRC_FILES := seccomp_policy/mediaswcodec-$(TARGET_ARCH).policy
+endif
+include $(BUILD_PREBUILT)
+endif
+
include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
index 1168825..12397fb 100644
--- a/services/mediacodec/main_swcodecservice.cpp
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -26,12 +26,10 @@
using namespace android;
-// TODO: replace policy with software codec-only policies
-// Must match location in Android.mk.
static const char kSystemSeccompPolicyPath[] =
- "/system/etc/seccomp_policy/mediacodec.policy";
+ "/system/etc/seccomp_policy/mediaswcodec.policy";
static const char kVendorSeccompPolicyPath[] =
- "/vendor/etc/seccomp_policy/mediacodec.policy";
+ "/vendor/etc/seccomp_policy/mediaswcodec.policy";
// Disable Scudo's mismatch allocation check, as it is being triggered
// by some third party code.
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
new file mode 100644
index 0000000..588141a
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -0,0 +1,60 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+futex: 1
+# ioctl calls are filtered via the selinux policy.
+ioctl: 1
+sched_yield: 1
+close: 1
+dup: 1
+ppoll: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap2: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3
+munmap: 1
+prctl: 1
+getuid32: 1
+writev: 1
+sigaltstack: 1
+clone: 1
+exit: 1
+lseek: 1
+rt_sigprocmask: 1
+openat: 1
+fstat64: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
+getdents64: 1
+readlinkat: 1
+read: 1
+pread64: 1
+fstatfs64: 1
+gettimeofday: 1
+faccessat: 1
+_llseek: 1
+fstatat64: 1
+ugetrlimit: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
+getrandom: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
new file mode 120000
index 0000000..ab2592a
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
@@ -0,0 +1 @@
+mediacodec-x86.policy
\ No newline at end of file
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 43b0a37..3616fa2 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -121,7 +121,7 @@
mutable std::mutex mLockStreams;
std::vector<android::sp<AAudioServiceStreamBase>> mRegisteredStreams;
- SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
+ SimpleDoubleBuffer<Timestamp> mAtomicEndpointTimestamp;
android::AudioClient mMmapClient; // set in open, used in open and startStream
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 2f1ec7e..0a415fd 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -181,8 +181,8 @@
// Get timestamp that was written by the real-time service thread, eg. mixer.
aaudio_result_t AAudioServiceEndpointShared::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
- if (mAtomicTimestamp.isValid()) {
- Timestamp timestamp = mAtomicTimestamp.read();
+ if (mAtomicEndpointTimestamp.isValid()) {
+ Timestamp timestamp = mAtomicEndpointTimestamp.read();
*positionFrames = timestamp.getPosition();
*timeNanos = timestamp.getNanoseconds();
return AAUDIO_OK;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index defbb7b..b16b5dc 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -43,7 +43,7 @@
AAudioServiceStreamBase::AAudioServiceStreamBase(AAudioService &audioService)
: mUpMessageQueue(nullptr)
, mTimestampThread("AATime")
- , mAtomicTimestamp()
+ , mAtomicStreamTimestamp()
, mAudioService(audioService) {
mMmapClient.clientUid = -1;
mMmapClient.clientPid = -1;
@@ -182,7 +182,7 @@
setSuspended(false);
// Start with fresh presentation timestamps.
- mAtomicTimestamp.clear();
+ mAtomicStreamTimestamp.clear();
mClientHandle = AUDIO_PORT_HANDLE_NONE;
result = startDevice();
@@ -291,16 +291,20 @@
}
// implement Runnable, periodically send timestamps to client
+__attribute__((no_sanitize("integer")))
void AAudioServiceStreamBase::run() {
ALOGD("%s() %s entering >>>>>>>>>>>>>> TIMESTAMPS", __func__, getTypeText());
TimestampScheduler timestampScheduler;
timestampScheduler.setBurstPeriod(mFramesPerBurst, getSampleRate());
timestampScheduler.start(AudioClock::getNanoseconds());
int64_t nextTime = timestampScheduler.nextAbsoluteTime();
+ int32_t loopCount = 0;
while(mThreadEnabled.load()) {
+ loopCount++;
if (AudioClock::getNanoseconds() >= nextTime) {
aaudio_result_t result = sendCurrentTimestamp();
if (result != AAUDIO_OK) {
+ ALOGE("%s() timestamp thread got result = %d", __func__, result);
break;
}
nextTime = timestampScheduler.nextAbsoluteTime();
@@ -310,7 +314,8 @@
AudioClock::sleepUntilNanoTime(nextTime);
}
}
- ALOGD("%s() %s exiting <<<<<<<<<<<<<< TIMESTAMPS", __func__, getTypeText());
+ ALOGD("%s() %s exiting after %d loops <<<<<<<<<<<<<< TIMESTAMPS",
+ __func__, getTypeText(), loopCount);
}
void AAudioServiceStreamBase::disconnect() {
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 7904b25..ffc768b 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -301,7 +301,7 @@
// TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger.
audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE;
- SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
+ SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp;
android::AAudioService &mAudioService;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 9377945..837b080 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -162,7 +162,7 @@
aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
if (result == AAUDIO_OK) {
Timestamp timestamp(*positionFrames, *timeNanos);
- mAtomicTimestamp.write(timestamp);
+ mAtomicStreamTimestamp.write(timestamp);
*positionFrames = timestamp.getPosition();
*timeNanos = timestamp.getNanoseconds();
} else if (result != AAUDIO_ERROR_UNAVAILABLE) {
@@ -184,8 +184,8 @@
static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
// TODO Get presentation timestamp from the HAL
- if (mAtomicTimestamp.isValid()) {
- Timestamp timestamp = mAtomicTimestamp.read();
+ if (mAtomicStreamTimestamp.isValid()) {
+ Timestamp timestamp = mAtomicStreamTimestamp.read();
*positionFrames = timestamp.getPosition();
*timeNanos = timestamp.getNanoseconds() + serviceEndpointMMAP->getHardwareTimeOffsetNanos();
return AAUDIO_OK;
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index d5450fe..14742dd 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -238,15 +238,15 @@
}
void AAudioServiceStreamShared::markTransferTime(Timestamp ×tamp) {
- mAtomicTimestamp.write(timestamp);
+ mAtomicStreamTimestamp.write(timestamp);
}
// Get timestamp that was written by mixer or distributor.
aaudio_result_t AAudioServiceStreamShared::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
// TODO Get presentation timestamp from the HAL
- if (mAtomicTimestamp.isValid()) {
- Timestamp timestamp = mAtomicTimestamp.read();
+ if (mAtomicStreamTimestamp.isValid()) {
+ Timestamp timestamp = mAtomicStreamTimestamp.read();
*positionFrames = timestamp.getPosition();
*timeNanos = timestamp.getNanoseconds();
return AAUDIO_OK;