Merge "AudioPolicy: callback for recording configuration change"
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
index 53cbf80..6666343 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
@@ -33,7 +33,7 @@
// decrypted data. In theory, the output size can be larger than the input
// size, but in practice this will never happen for AES-CTR.
ssize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv,
- Mode mode, const void* srcPtr,
+ Mode mode, const Pattern &pattern, const void* srcPtr,
const SubSample* subSamples, size_t numSubSamples,
void* dstPtr, AString* errorDetailMsg) {
if (secure) {
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
index fd38f28..de84c36 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
@@ -44,7 +44,7 @@
virtual ssize_t decrypt(
bool secure, const KeyId keyId, const Iv iv,
- Mode mode, const void* srcPtr,
+ Mode mode, const Pattern &pattern, const void* srcPtr,
const SubSample* subSamples, size_t numSubSamples,
void* dstPtr, android::AString* errorDetailMsg);
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
index c856d7d..1e80f8e 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
@@ -792,15 +792,17 @@
ssize_t
MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16],
- Mode mode, const void *srcPtr, const SubSample *subSamples,
- size_t numSubSamples, void *dstPtr, AString * /* errorDetailMsg */)
+ Mode mode, const Pattern &pattern, const void *srcPtr,
+ const SubSample *subSamples, size_t numSubSamples,
+ void *dstPtr, AString * /* errorDetailMsg */)
{
- ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, "
+ ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, "
+ "pattern:{encryptBlocks=%d, skipBlocks=%d} src=%p, "
"subSamples=%s, dst=%p)",
(int)secure,
arrayToString(key, sizeof(key)).string(),
arrayToString(iv, sizeof(iv)).string(),
- (int)mode, srcPtr,
+ (int)mode, pattern.mEncryptBlocks, pattern.mSkipBlocks, srcPtr,
subSamplesToString(subSamples, numSubSamples).string(),
dstPtr);
return OK;
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
index db266f9..40d4e84 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
@@ -159,7 +159,7 @@
ssize_t decrypt(bool secure,
const uint8_t key[16], const uint8_t iv[16],
- Mode mode, const void *srcPtr,
+ Mode mode, const Pattern &pattern, const void *srcPtr,
const SubSample *subSamples, size_t numSubSamples,
void *dstPtr, AString *errorDetailMsg);
private:
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 114e194..2f95b90 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -321,6 +321,8 @@
audio_io_handle_t *handle);
static status_t stopAudioSource(audio_io_handle_t handle);
+ static status_t setMasterMono(bool mono);
+ static status_t getMasterMono(bool *mono);
// ----------------------------------------------------------------------------
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 6b93f6f..ceca71a 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -165,6 +165,9 @@
const audio_attributes_t *attributes,
audio_io_handle_t *handle) = 0;
virtual status_t stopAudioSource(audio_io_handle_t handle) = 0;
+
+ virtual status_t setMasterMono(bool mono) = 0;
+ virtual status_t getMasterMono(bool *mono) = 0;
};
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index ea316de..5e324ad 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -51,6 +51,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index cdfa159..93ffa93 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -119,6 +119,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg = NULL);
diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h
index 4f6a1ef..034cb35 100644
--- a/include/ndk/NdkMediaCodec.h
+++ b/include/ndk/NdkMediaCodec.h
@@ -170,6 +170,11 @@
AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1
} cryptoinfo_mode_t;
+typedef struct {
+ int32_t encryptBlocks;
+ int32_t skipBlocks;
+} cryptoinfo_pattern_t;
+
/**
* Create an AMediaCodecCryptoInfo from scratch. Use this if you need to use custom
* crypto info, rather than one obtained from AMediaExtractor.
@@ -199,6 +204,13 @@
media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*);
/**
+ * Set the crypto pattern on an AMediaCryptoInfo object
+ */
+void AMediaCodecCryptoInfo_setPattern(
+ AMediaCodecCryptoInfo *info,
+ cryptoinfo_pattern_t *pattern);
+
+/**
* The number of subsamples that make up the buffer's contents.
*/
size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*);
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 1f3880f..e458f3c 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -305,8 +305,6 @@
return mEpoch;
}
- size_t getFramesFilled();
-
private:
Modulo<uint32_t> mEpoch;
};
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 999e7eb..a1892e4 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -3097,7 +3097,10 @@
//ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
effect_param_t *p = (effect_param_t *)pCmdData;
-
+ if (SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
+ android_errorWriteLog(0x534e4554, "26347509");
+ return -EINVAL;
+ }
if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
cmdSize < (sizeof(effect_param_t) + p->psize) ||
pReplyData == NULL || replySize == NULL ||
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index a48a4e3..4dc8b45 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -1956,7 +1956,10 @@
//ALOGV("\tReverb_command cmdCode Case: "
// "EFFECT_CMD_GET_PARAM start");
effect_param_t *p = (effect_param_t *)pCmdData;
-
+ if (SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
+ android_errorWriteLog(0x534e4554, "26347509");
+ return -EINVAL;
+ }
if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
cmdSize < (sizeof(effect_param_t) + p->psize) ||
pReplyData == NULL || replySize == NULL ||
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 46622ea..1ea2003 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -1166,6 +1166,20 @@
return aps->stopAudioSource(handle);
}
+status_t AudioSystem::setMasterMono(bool mono)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->setMasterMono(mono);
+}
+
+status_t AudioSystem::getMasterMono(bool *mono)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->getMasterMono(mono);
+}
+
// ---------------------------------------------------------------------------
int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 9d5d996..9fad500 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -347,27 +347,6 @@
(mFrameCountP2 - 1);
}
-size_t ClientProxy::getFramesFilled() {
- audio_track_cblk_t* cblk = mCblk;
- int32_t front;
- int32_t rear;
-
- if (mIsOut) {
- front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
- rear = cblk->u.mStreaming.mRear;
- } else {
- rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
- front = cblk->u.mStreaming.mFront;
- }
- ssize_t filled = rear - front;
- // pipe should not be overfull
- if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
- ALOGE("Shared memory control block is corrupt (filled=%zd); shutting down", filled);
- return 0;
- }
- return (size_t)filled;
-}
-
// ---------------------------------------------------------------------------
void AudioTrackClientProxy::flush()
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 76b5924..c95d4c4 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -74,6 +74,8 @@
START_AUDIO_SOURCE,
STOP_AUDIO_SOURCE,
SET_AUDIO_PORT_CALLBACK_ENABLED,
+ SET_MASTER_MONO,
+ GET_MASTER_MONO,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -767,6 +769,37 @@
status = (status_t)reply.readInt32();
return status;
}
+
+ virtual status_t setMasterMono(bool mono)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(mono));
+ status_t status = remote()->transact(SET_MASTER_MONO, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t getMasterMono(bool *mono)
+ {
+ if (mono == nullptr) {
+ return BAD_VALUE;
+ }
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+ status_t status = remote()->transact(GET_MASTER_MONO, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = static_cast<status_t>(reply.readInt32());
+ if (status == NO_ERROR) {
+ *mono = static_cast<bool>(reply.readInt32());
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1311,6 +1344,25 @@
return NO_ERROR;
} break;
+ case SET_MASTER_MONO: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ bool mono = static_cast<bool>(data.readInt32());
+ status_t status = setMasterMono(mono);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ } break;
+
+ case GET_MASTER_MONO: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ bool mono;
+ status_t status = getMasterMono(&mono);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32(static_cast<int32_t>(mono));
+ }
+ return NO_ERROR;
+ } break;
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 7fb1acc..79059c6 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -98,7 +98,7 @@
bool secure,
const uint8_t key[16],
const uint8_t iv[16],
- CryptoPlugin::Mode mode,
+ CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
@@ -107,6 +107,8 @@
data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
data.writeInt32(secure);
data.writeInt32(mode);
+ data.writeInt32(pattern.mEncryptBlocks);
+ data.writeInt32(pattern.mSkipBlocks);
static const uint8_t kDummy[16] = { 0 };
@@ -261,7 +263,11 @@
CHECK_INTERFACE(ICrypto, data, reply);
const char *mime = data.readCString();
- reply->writeInt32(requiresSecureDecoderComponent(mime));
+ if (mime == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ } else {
+ reply->writeInt32(requiresSecureDecoderComponent(mime));
+ }
return OK;
}
@@ -272,6 +278,9 @@
bool secure = data.readInt32() != 0;
CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
+ CryptoPlugin::Pattern pattern;
+ pattern.mEncryptBlocks = data.readInt32();
+ pattern.mSkipBlocks = data.readInt32();
uint8_t key[16];
data.read(key, sizeof(key));
@@ -282,6 +291,10 @@
size_t totalSize = data.readInt32();
sp<IMemory> sharedBuffer =
interface_cast<IMemory>(data.readStrongBinder());
+ if (sharedBuffer == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
int32_t offset = data.readInt32();
int32_t numSubSamples = data.readInt32();
@@ -330,7 +343,7 @@
secure,
key,
iv,
- mode,
+ mode, pattern,
sharedBuffer, offset,
subSamples, numSubSamples,
secure ? secureBufferId : dstPtr,
diff --git a/media/libmedia/IMediaCodecList.cpp b/media/libmedia/IMediaCodecList.cpp
index e2df104..737f50c 100644
--- a/media/libmedia/IMediaCodecList.cpp
+++ b/media/libmedia/IMediaCodecList.cpp
@@ -157,6 +157,10 @@
{
CHECK_INTERFACE(IMediaCodecList, data, reply);
const char *type = data.readCString();
+ if (type == NULL) {
+ reply->writeInt32(NAME_NOT_FOUND);
+ return NO_ERROR;
+ }
bool isEncoder = static_cast<bool>(data.readInt32());
size_t startIndex = static_cast<size_t>(data.readInt32());
ssize_t index = findCodecByType(type, isEncoder, startIndex);
@@ -172,6 +176,10 @@
{
CHECK_INTERFACE(IMediaCodecList, data, reply);
const char *name = data.readCString();
+ if (name == NULL) {
+ reply->writeInt32(NAME_NOT_FOUND);
+ return NO_ERROR;
+ }
ssize_t index = findCodecByName(name);
if (index > INT32_MAX || index < 0) {
index = NAME_NOT_FOUND;
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index dbf524e..0bee8d3 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -224,6 +224,11 @@
const char* srcUrl = data.readCString();
+ if (httpService == NULL || srcUrl == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ return NO_ERROR;
+ }
+
KeyedVector<String8, String8> headers;
size_t numHeaders = (size_t) data.readInt64();
for (size_t i = 0; i < numHeaders; ++i) {
@@ -250,7 +255,11 @@
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
sp<IDataSource> source =
interface_cast<IDataSource>(data.readStrongBinder());
- reply->writeInt32(setDataSource(source));
+ if (source == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ } else {
+ reply->writeInt32(setDataSource(source));
+ }
return NO_ERROR;
} break;
case GET_FRAME_AT_TIME: {
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 942aec3..c523629 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -444,6 +444,10 @@
}
const char* url = data.readCString();
+ if (httpService == NULL || url == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ return NO_ERROR;
+ }
KeyedVector<String8, String8> headers;
int32_t numHeaders = data.readInt32();
for (int i = 0; i < numHeaders; ++i) {
@@ -467,14 +471,22 @@
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<IStreamSource> source =
interface_cast<IStreamSource>(data.readStrongBinder());
- reply->writeInt32(setDataSource(source));
+ if (source == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ } else {
+ reply->writeInt32(setDataSource(source));
+ }
return NO_ERROR;
}
case SET_DATA_SOURCE_CALLBACK: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<IDataSource> source =
interface_cast<IDataSource>(data.readStrongBinder());
- reply->writeInt32(setDataSource(source));
+ if (source == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ } else {
+ reply->writeInt32(setDataSource(source));
+ }
return NO_ERROR;
}
case SET_VIDEO_SURFACETEXTURE: {
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 05f8670..afc94ab 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -220,6 +220,10 @@
const String16 opPackageName = data.readString16();
sp<IRemoteDisplayClient> client(
interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
+ if (client == NULL) {
+ reply->writeStrongBinder(NULL);
+ return NO_ERROR;
+ }
String8 iface(data.readString8());
sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));
reply->writeStrongBinder(IInterface::asBinder(display));
diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp
index 4598686..6cb4440 100644
--- a/media/libmedia/IResourceManagerService.cpp
+++ b/media/libmedia/IResourceManagerService.cpp
@@ -132,6 +132,9 @@
int64_t clientId = data.readInt64();
sp<IResourceManagerClient> client(
interface_cast<IResourceManagerClient>(data.readStrongBinder()));
+ if (client == NULL) {
+ return NO_ERROR;
+ }
Vector<MediaResource> resources;
readFromParcel(data, &resources);
addResource(pid, clientId, client, resources);
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
index 840e453..8c0905c 100644
--- a/media/libmedia/IStreamSource.cpp
+++ b/media/libmedia/IStreamSource.cpp
@@ -111,7 +111,11 @@
sp<IMemory> mem =
interface_cast<IMemory>(data.readStrongBinder());
- buffers.push(mem);
+ if (mem != NULL) {
+ buffers.push(mem);
+ } else if (data.dataAvail() == 0) {
+ break;
+ }
}
setBuffers(buffers);
break;
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index 147d35f..b57f6ef 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -239,6 +239,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
@@ -256,7 +257,7 @@
const void *srcPtr = static_cast<uint8_t *>(sharedBuffer->pointer()) + offset;
return mPlugin->decrypt(
- secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr,
+ secure, key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
errorDetailMsg);
}
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 99ea95d..7705f30 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -54,6 +54,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a416381..dda0a57 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1246,7 +1246,10 @@
if (client->mAudioOutput != NULL)
client->mAudioOutput->switchToNextOutput();
client->mNextClient->start();
- client->mNextClient->mClient->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+ if (client->mNextClient->mClient != NULL) {
+ client->mNextClient->mClient->notify(
+ MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+ }
}
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index ec06711..9a4a350 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -1,7 +1,6 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
LOCAL_SRC_FILES:= \
ACodec.cpp \
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8c61108..77722be 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -688,6 +688,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg) {
@@ -703,6 +704,8 @@
msg->setPointer("key", (void *)key);
msg->setPointer("iv", (void *)iv);
msg->setInt32("mode", mode);
+ msg->setInt32("encryptBlocks", pattern.mEncryptBlocks);
+ msg->setInt32("skipBlocks", pattern.mSkipBlocks);
msg->setInt64("timeUs", presentationTimeUs);
msg->setInt32("flags", flags);
msg->setPointer("errorDetailMsg", errorDetailMsg);
@@ -2452,11 +2455,16 @@
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
+ CryptoPlugin::Pattern pattern;
+ CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
+ CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
+
ssize_t result = mCrypto->decrypt(
(mFlags & kFlagIsSecure) != 0,
key,
iv,
mode,
+ pattern,
info->mSharedEncryptedBuffer,
offset,
subSamples,
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index 88690cf..266f01b 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -1,6 +1,5 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
AAC_LIBRARY = fraunhofer
@@ -35,24 +34,28 @@
src/transform.c \
src/memalign.c
-ifeq ($(VOTT), v5)
-LOCAL_SRC_FILES += \
- src/asm/ARMV5E/AutoCorrelation_v5.s \
- src/asm/ARMV5E/band_nrg_v5.s \
- src/asm/ARMV5E/CalcWindowEnergy_v5.s \
- src/asm/ARMV5E/PrePostMDCT_v5.s \
- src/asm/ARMV5E/R4R8First_v5.s \
- src/asm/ARMV5E/Radix4FFT_v5.s
-endif
+ifneq ($(ARCH_ARM_HAVE_NEON),true)
+ LOCAL_SRC_FILES_arm := \
+ src/asm/ARMV5E/AutoCorrelation_v5.s \
+ src/asm/ARMV5E/band_nrg_v5.s \
+ src/asm/ARMV5E/CalcWindowEnergy_v5.s \
+ src/asm/ARMV5E/PrePostMDCT_v5.s \
+ src/asm/ARMV5E/R4R8First_v5.s \
+ src/asm/ARMV5E/Radix4FFT_v5.s
-ifeq ($(VOTT), v7)
-LOCAL_SRC_FILES += \
- src/asm/ARMV5E/AutoCorrelation_v5.s \
- src/asm/ARMV5E/band_nrg_v5.s \
- src/asm/ARMV5E/CalcWindowEnergy_v5.s \
- src/asm/ARMV7/PrePostMDCT_v7.s \
- src/asm/ARMV7/R4R8First_v7.s \
- src/asm/ARMV7/Radix4FFT_v7.s
+ LOCAL_CFLAGS_arm := -DARMV5E -DARM_INASM -DARMV5_INASM
+ LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+else
+ LOCAL_SRC_FILES_arm := \
+ src/asm/ARMV5E/AutoCorrelation_v5.s \
+ src/asm/ARMV5E/band_nrg_v5.s \
+ src/asm/ARMV5E/CalcWindowEnergy_v5.s \
+ src/asm/ARMV7/PrePostMDCT_v7.s \
+ src/asm/ARMV7/R4R8First_v7.s \
+ src/asm/ARMV7/Radix4FFT_v7.s
+ LOCAL_CFLAGS_arm := -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM -DARMV6_INASM
+ LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+ LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/src/asm/ARMV7
endif
LOCAL_MODULE := libstagefright_aacenc
@@ -71,17 +74,6 @@
$(LOCAL_PATH)/inc \
$(LOCAL_PATH)/basic_op
-ifeq ($(VOTT), v5)
-LOCAL_CFLAGS += -DARMV5E -DARM_INASM -DARMV5_INASM
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_CFLAGS += -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM -DARMV6_INASM
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
-endif
-
LOCAL_CFLAGS += -Werror
LOCAL_CLANG := true
LOCAL_SANITIZE := signed-integer-overflow unsigned-integer-overflow
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index 5b90b33..4d12f82 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -1,8 +1,5 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
-
-
LOCAL_SRC_FILES := \
src/autocorr.c \
@@ -53,37 +50,39 @@
src/weight_a.c \
src/mem_align.c
+ifneq ($(ARCH_ARM_HAVE_NEON),true)
+ LOCAL_SRC_FILES_arm := \
+ src/asm/ARMV5E/convolve_opt.s \
+ src/asm/ARMV5E/cor_h_vec_opt.s \
+ src/asm/ARMV5E/Deemph_32_opt.s \
+ src/asm/ARMV5E/Dot_p_opt.s \
+ src/asm/ARMV5E/Filt_6k_7k_opt.s \
+ src/asm/ARMV5E/Norm_Corr_opt.s \
+ src/asm/ARMV5E/pred_lt4_1_opt.s \
+ src/asm/ARMV5E/residu_asm_opt.s \
+ src/asm/ARMV5E/scale_sig_opt.s \
+ src/asm/ARMV5E/Syn_filt_32_opt.s \
+ src/asm/ARMV5E/syn_filt_opt.s
-ifeq ($(VOTT), v5)
-LOCAL_SRC_FILES += \
- src/asm/ARMV5E/convolve_opt.s \
- src/asm/ARMV5E/cor_h_vec_opt.s \
- src/asm/ARMV5E/Deemph_32_opt.s \
- src/asm/ARMV5E/Dot_p_opt.s \
- src/asm/ARMV5E/Filt_6k_7k_opt.s \
- src/asm/ARMV5E/Norm_Corr_opt.s \
- src/asm/ARMV5E/pred_lt4_1_opt.s \
- src/asm/ARMV5E/residu_asm_opt.s \
- src/asm/ARMV5E/scale_sig_opt.s \
- src/asm/ARMV5E/Syn_filt_32_opt.s \
- src/asm/ARMV5E/syn_filt_opt.s
+ LOCAL_CFLAGS_arm := -DARM -DASM_OPT
+ LOCAL_C_INCLUDES_arm = $(LOCAL_PATH)/src/asm/ARMV5E
+else
+ LOCAL_SRC_FILES_arm := \
+ src/asm/ARMV7/convolve_neon.s \
+ src/asm/ARMV7/cor_h_vec_neon.s \
+ src/asm/ARMV7/Deemph_32_neon.s \
+ src/asm/ARMV7/Dot_p_neon.s \
+ src/asm/ARMV7/Filt_6k_7k_neon.s \
+ src/asm/ARMV7/Norm_Corr_neon.s \
+ src/asm/ARMV7/pred_lt4_1_neon.s \
+ src/asm/ARMV7/residu_asm_neon.s \
+ src/asm/ARMV7/scale_sig_neon.s \
+ src/asm/ARMV7/Syn_filt_32_neon.s \
+ src/asm/ARMV7/syn_filt_neon.s
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_SRC_FILES += \
- src/asm/ARMV7/convolve_neon.s \
- src/asm/ARMV7/cor_h_vec_neon.s \
- src/asm/ARMV7/Deemph_32_neon.s \
- src/asm/ARMV7/Dot_p_neon.s \
- src/asm/ARMV7/Filt_6k_7k_neon.s \
- src/asm/ARMV7/Norm_Corr_neon.s \
- src/asm/ARMV7/pred_lt4_1_neon.s \
- src/asm/ARMV7/residu_asm_neon.s \
- src/asm/ARMV7/scale_sig_neon.s \
- src/asm/ARMV7/Syn_filt_32_neon.s \
- src/asm/ARMV7/syn_filt_neon.s
-
+ LOCAL_CFLAGS_arm := -DARM -DARMV7 -DASM_OPT
+ LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+ LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/src/asm/ARMV7
endif
LOCAL_MODULE := libstagefright_amrwbenc
@@ -101,17 +100,6 @@
$(LOCAL_PATH)/src \
$(LOCAL_PATH)/inc
-ifeq ($(VOTT), v5)
-LOCAL_CFLAGS += -DARM -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_CFLAGS += -DARM -DARMV7 -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
-endif
-
LOCAL_CFLAGS += -Werror
LOCAL_CLANG := true
#LOCAL_SANITIZE := signed-integer-overflow
diff --git a/media/libstagefright/codecs/common/Config.mk b/media/libstagefright/codecs/common/Config.mk
deleted file mode 100644
index a843cef..0000000
--- a/media/libstagefright/codecs/common/Config.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# This configure file is just for Linux projects against Android
-#
-
-VOPRJ :=
-VONJ :=
-
-# WARNING:
-# Using v7 breaks generic build
-ifeq ($(TARGET_ARCH),arm)
-VOTT := v5
-else
-VOTT := pc
-endif
-
-# Do we also need to check on ARCH_ARM_HAVE_ARMV7A? - probably not
-ifeq ($(TARGET_ARCH),arm)
- ifeq ($(ARCH_ARM_HAVE_NEON),true)
- VOTT := v7
- endif
-endif
-
-VOTEST := 0
-
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 38618da..11581c1 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -28,19 +28,22 @@
src/pvmp3_stereo_proc.cpp \
src/pvmp3_reorder.cpp \
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += \
+LOCAL_SRC_FILES_arm += \
src/asm/pvmp3_polyphase_filter_window_gcc.s \
src/asm/pvmp3_mdct_18_gcc.s \
src/asm/pvmp3_dct_9_gcc.s \
src/asm/pvmp3_dct_16_gcc.s
-else
-LOCAL_SRC_FILES += \
+LOCAL_SRC_FILES_other_archs := \
src/pvmp3_polyphase_filter_window.cpp \
src/pvmp3_mdct_18.cpp \
src/pvmp3_dct_9.cpp \
src/pvmp3_dct_16.cpp
-endif
+
+LOCAL_SRC_FILES_arm64 := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_mips := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_mips64 := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_x86 := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_x86_64 := $(LOCAL_SRC_FILES_other_archs)
LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/include \
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.mk b/media/libstagefright/codecs/on2/h264dec/Android.mk
index e7492b1..7159674 100644
--- a/media/libstagefright/codecs/on2/h264dec/Android.mk
+++ b/media/libstagefright/codecs/on2/h264dec/Android.mk
@@ -84,17 +84,15 @@
./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S \
./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S \
-ifeq ($(TARGET_ARCH),arm)
- ifeq ($(ARCH_ARM_HAVE_NEON),true)
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_ARM_NEON := true
-# LOCAL_CFLAGS := -std=c99 -D._NEON -D._OMXDL
- LOCAL_CFLAGS := -DH264DEC_NEON -DH264DEC_OMXDL
- LOCAL_SRC_FILES += $(MY_ASM) $(MY_OMXDL_C_SRC) $(MY_OMXDL_ASM_SRC)
- LOCAL_C_INCLUDES += $(LOCAL_PATH)/./source/arm_neon_asm_gcc
- LOCAL_C_INCLUDES += $(LOCAL_PATH)/./omxdl/arm_neon/api \
+ LOCAL_CFLAGS_arm := -DH264DEC_NEON -DH264DEC_OMXDL
+ LOCAL_SRC_FILES_arm := $(MY_ASM) $(MY_OMXDL_C_SRC) $(MY_OMXDL_ASM_SRC)
+ LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/./source/arm_neon_asm_gcc
+ LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/./omxdl/arm_neon/api \
$(LOCAL_PATH)/./omxdl/arm_neon/vc/api \
$(LOCAL_PATH)/./omxdl/arm_neon/vc/m4p10/api
- endif
endif
LOCAL_CLANG := true
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index a770f49..72823e2 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -23,7 +23,6 @@
#include "include/SoftVideoEncoderOMXComponent.h"
-#include <hardware/gralloc.h>
#include <media/hardware/HardwareAPI.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -71,7 +70,6 @@
mBitrate(192000),
mFramerate(30 << 16), // Q16 format
mColorFormat(OMX_COLOR_FormatYUV420Planar),
- mGrallocModule(NULL),
mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock
mMinCompressionRatio(1), // max output size is normally the input size
mComponentRole(componentRole),
@@ -500,13 +498,6 @@
return NULL;
}
- if (mGrallocModule == NULL) {
- CHECK_EQ(0, hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mGrallocModule));
- }
-
- const gralloc_module_t *grmodule =
- (const gralloc_module_t *)mGrallocModule;
-
buffer_handle_t handle;
int format;
size_t srcStride;
@@ -564,19 +555,21 @@
return NULL;
}
+ auto& mapper = GraphicBufferMapper::get();
+
void *bits = NULL;
struct android_ycbcr ycbcr;
status_t res;
if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- res = grmodule->lock_ycbcr(
- grmodule, handle,
+ res = mapper.lockYCbCr(
+ handle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
- 0, 0, width, height, &ycbcr);
+ Rect(width, height), &ycbcr);
} else {
- res = grmodule->lock(
- grmodule, handle,
+ res = mapper.lock(
+ handle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER,
- 0, 0, width, height, &bits);
+ Rect(width, height), &bits);
}
if (res != OK) {
ALOGE("Unable to lock image buffer %p for access", handle);
@@ -620,7 +613,7 @@
break;
}
- if (grmodule->unlock(grmodule, handle) != OK) {
+ if (mapper.unlock(handle) != OK) {
ALOGE("Unable to unlock image buffer %p for access", handle);
}
diff --git a/media/mtp/MtpDebug.cpp b/media/mtp/MtpDebug.cpp
index 9f3037d..1c04bcf 100644
--- a/media/mtp/MtpDebug.cpp
+++ b/media/mtp/MtpDebug.cpp
@@ -101,6 +101,7 @@
{ "MTP_FORMAT_TIFF_IT", 0x380E },
{ "MTP_FORMAT_JP2", 0x380F },
{ "MTP_FORMAT_JPX", 0x3810 },
+ { "MTP_FORMAT_DNG", 0x3811 },
{ "MTP_FORMAT_UNDEFINED_FIRMWARE", 0xB802 },
{ "MTP_FORMAT_WINDOWS_IMAGE_FORMAT", 0xB881 },
{ "MTP_FORMAT_UNDEFINED_AUDIO", 0xB900 },
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 30843a7..6f72a3e 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -866,15 +866,19 @@
return currentHandle;
}
-int MtpDevice::reapEventRequest(int handle) {
+int MtpDevice::reapEventRequest(int handle, uint32_t (*parameters)[3]) {
Mutex::Autolock autoLock(mEventMutex);
- if (!mProcessingEvent || mCurrentEventHandle != handle) {
+ if (!mProcessingEvent || mCurrentEventHandle != handle || !parameters) {
return -1;
}
mProcessingEvent = false;
const int readSize = mEventPacket.readResponse(mRequestIntr->dev);
const int result = mEventPacket.getEventCode();
- return readSize == 0 ? 0 : result;
+ // MTP event has three parameters.
+ (*parameters)[0] = mEventPacket.getParameter(1);
+ (*parameters)[1] = mEventPacket.getParameter(2);
+ (*parameters)[2] = mEventPacket.getParameter(3);
+ return readSize != 0 ? result : 0;
}
void MtpDevice::discardEventRequest(int handle) {
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 60f08ba..edc608f 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -124,8 +124,9 @@
int submitEventRequest();
// Waits for MTP event from the device and returns MTP event code. It blocks the current thread
// until it receives an event from the device. |handle| should be a request handle returned
- // by |submitEventRequest|. Returns 0 for cancellations. Returns -1 for errors.
- int reapEventRequest(int handle);
+ // by |submitEventRequest|. The function writes event parameters to |parameters|. Returns 0 for
+ // cancellations. Returns -1 for errors.
+ int reapEventRequest(int handle, uint32_t (*parameters)[3]);
// Cancels an event request. |handle| should be request handle returned by
// |submitEventRequest|. If there is a thread blocked by |reapEventRequest| with the same
// |handle|, the thread will resume.
diff --git a/media/mtp/mtp.h b/media/mtp/mtp.h
index 7b80d2e..adfb102 100644
--- a/media/mtp/mtp.h
+++ b/media/mtp/mtp.h
@@ -93,6 +93,7 @@
#define MTP_FORMAT_TIFF_IT 0x380E // Tag Image File Format for Information Technology (graphic arts)
#define MTP_FORMAT_JP2 0x380F // JPEG2000 Baseline File Format
#define MTP_FORMAT_JPX 0x3810 // JPEG2000 Extended File Format
+#define MTP_FORMAT_DNG 0x3811 // Digital Negative
#define MTP_FORMAT_UNDEFINED_FIRMWARE 0xB802
#define MTP_FORMAT_WINDOWS_IMAGE_FORMAT 0xB881
#define MTP_FORMAT_UNDEFINED_AUDIO 0xB900
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index cd0c462..8e36065 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -372,6 +372,7 @@
uint8_t key[16];
uint8_t iv[16];
cryptoinfo_mode_t mode;
+ cryptoinfo_pattern_t pattern;
size_t *clearbytes;
size_t *encryptedbytes;
} AMediaCodecCryptoInfo;
@@ -391,6 +392,10 @@
subSamples[i].mNumBytesOfEncryptedData = crypto->encryptedbytes[i];
}
+ CryptoPlugin::Pattern pattern;
+ pattern.mEncryptBlocks = crypto->pattern.encryptBlocks;
+ pattern.mSkipBlocks = crypto->pattern.skipBlocks;
+
AString errormsg;
status_t err = codec->mCodec->queueSecureInputBuffer(idx,
offset,
@@ -398,7 +403,8 @@
crypto->numsubsamples,
crypto->key,
crypto->iv,
- (CryptoPlugin::Mode) crypto->mode,
+ (CryptoPlugin::Mode)crypto->mode,
+ pattern,
time,
flags,
&errormsg);
@@ -410,6 +416,12 @@
}
+EXPORT
+void AMediaCodecCryptoInfo_setPattern(AMediaCodecCryptoInfo *info,
+ cryptoinfo_pattern_t *pattern) {
+ info->pattern.encryptBlocks = pattern->encryptBlocks;
+ info->pattern.skipBlocks = pattern->skipBlocks;
+}
EXPORT
AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
@@ -431,6 +443,8 @@
memcpy(ret->key, key, 16);
memcpy(ret->iv, iv, 16);
ret->mode = mode;
+ ret->pattern.encryptBlocks = 0;
+ ret->pattern.skipBlocks = 0;
// clearbytes and encryptedbytes point at the actual data, which follows
ret->clearbytes = (size_t*) (ret + 1); // point immediately after the struct
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index d6624f7..3f99b43 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -37,6 +37,7 @@
#include <cpustats/ThreadCpuUsage.h>
#endif
#endif
+#include <audio_utils/conversion.h>
#include <audio_utils/format.h>
#include "AudioMixer.h"
#include "FastMixer.h"
@@ -64,7 +65,8 @@
mFastTracksGen(0),
mTotalNativeFramesWritten(0),
// timestamp
- mNativeFramesWrittenButNotPresented(0) // the = 0 is to silence the compiler
+ mNativeFramesWrittenButNotPresented(0), // the = 0 is to silence the compiler
+ mMasterMono(false)
{
// FIXME pass sInitial as parameter to base class constructor, and make it static local
mPrevious = &sInitial;
@@ -417,6 +419,10 @@
memset(mMixerBuffer, 0, mMixerBufferSize);
mMixerBufferState = ZEROED;
}
+
+ if (mMasterMono.load()) { // memory_order_seq_cst
+ mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount);
+ }
// prepare the buffer used to write to sink
void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 06a68fb..e38878e 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIO_FAST_MIXER_H
#define ANDROID_AUDIO_FAST_MIXER_H
+#include <atomic>
#include "FastThread.h"
#include "StateQueue.h"
#include "FastMixerState.h"
@@ -36,6 +37,8 @@
FastMixerStateQueue* sq();
+ virtual void setMasterMono(bool mono) { mMasterMono.store(mono); /* memory_order_seq_cst */ }
+
private:
FastMixerStateQueue mSQ;
@@ -82,6 +85,8 @@
AudioTimestamp mTimestamp;
uint32_t mNativeFramesWrittenButNotPresented;
+ // accessed without lock between multiple threads.
+ std::atomic_bool mMasterMono;
}; // class FastMixer
} // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7c9b81e..65166b0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -36,6 +36,7 @@
#include <hardware/audio.h>
#include <audio_effects/effect_ns.h>
#include <audio_effects/effect_aec.h>
+#include <audio_utils/conversion.h>
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
#include <audio_utils/minifloat.h>
@@ -527,6 +528,7 @@
case AUDIO_SOURCE_VOICE_RECOGNITION: return "voice recognition";
case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication";
case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix";
+ case AUDIO_SOURCE_UNPROCESSED: return "unprocessed";
case AUDIO_SOURCE_FM_TUNER: return "FM tuner";
case AUDIO_SOURCE_HOTWORD: return "hotword";
default: return "unknown";
@@ -669,7 +671,19 @@
// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held
status_t AudioFlinger::ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair)
{
- sp<ConfigEvent> configEvent = (ConfigEvent *)new SetParameterConfigEvent(keyValuePair);
+ sp<ConfigEvent> configEvent;
+ AudioParameter param(keyValuePair);
+ int value;
+ if (param.getInt(String8(AUDIO_PARAMETER_MONO_OUTPUT), value) == NO_ERROR) {
+ setMasterMono_l(value != 0);
+ if (param.size() == 1) {
+ return NO_ERROR; // should be a solo parameter - we don't pass down
+ }
+ param.remove(String8(AUDIO_PARAMETER_MONO_OUTPUT));
+ configEvent = new SetParameterConfigEvent(param.toString());
+ } else {
+ configEvent = new SetParameterConfigEvent(keyValuePair);
+ }
return sendConfigEvent_l(configEvent);
}
@@ -1610,6 +1624,7 @@
dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer);
dprintf(fd, " Effect buffer: %p\n", mEffectBuffer);
dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask);
+ dprintf(fd, " Standby delay ns=%lld\n", (long long)mStandbyDelayNs);
AudioStreamOut *output = mOutput;
audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE;
String8 flagsAsString = outputFlagsToString(flags);
@@ -2534,7 +2549,8 @@
- mSinkBufferSize from frame count * frame size
- mActiveSleepTimeUs from activeSleepTimeUs()
- mIdleSleepTimeUs from idleSleepTimeUs()
- - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only)
+ - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) or forced to at least
+ kDefaultStandbyTimeInNsecs when connected to an A2DP device.
- maxPeriod from frame count and sample rate (MIXER only)
The parameters that affect these derived values are:
@@ -2553,6 +2569,15 @@
mSinkBufferSize = mNormalFrameCount * mFrameSize;
mActiveSleepTimeUs = activeSleepTimeUs();
mIdleSleepTimeUs = idleSleepTimeUs();
+
+ // make sure standby delay is not too short when connected to an A2DP sink to avoid
+ // truncating audio when going to standby.
+ mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs;
+ if ((mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) {
+ if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) {
+ mStandbyDelayNs = kDefaultStandbyTimeInNsecs;
+ }
+ }
}
void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
@@ -2903,6 +2928,13 @@
void *buffer = mEffectBufferValid ? mEffectBuffer : mSinkBuffer;
audio_format_t format = mEffectBufferValid ? mEffectBufferFormat : mFormat;
+ // mono blend occurs for mixer threads only (not direct or offloaded)
+ // and is handled here if we're going directly to the sink.
+ if (requireMonoBlend() && !mEffectBufferValid) {
+ mono_blend(
+ mMixerBuffer, mMixerBufferFormat, mChannelCount, mNormalFrameCount);
+ }
+
memcpy_by_audio_format(buffer, format, mMixerBuffer, mMixerBufferFormat,
mNormalFrameCount * mChannelCount);
}
@@ -2938,6 +2970,11 @@
// TODO use mSleepTimeUs == 0 as an additional condition.
if (mEffectBufferValid) {
//ALOGV("writing effect buffer to sink buffer format %#x", mFormat);
+
+ if (requireMonoBlend()) {
+ mono_blend(mEffectBuffer, mEffectBufferFormat, mChannelCount, mNormalFrameCount);
+ }
+
memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat,
mNormalFrameCount * mChannelCount);
}
@@ -3280,7 +3317,8 @@
: PlaybackThread(audioFlinger, output, id, device, type, systemReady),
// mAudioMixer below
// mFastMixer below
- mFastMixerFutex(0)
+ mFastMixerFutex(0),
+ mMasterMono(false)
// mOutputSink below
// mPipeSink below
// mNormalSink below
@@ -4272,6 +4310,7 @@
status_t& status)
{
bool reconfig = false;
+ bool a2dpDeviceChanged = false;
status = NO_ERROR;
@@ -4348,6 +4387,8 @@
// forward device change to effects that have requested to be
// aware of attached audio device.
if (value != AUDIO_DEVICE_NONE) {
+ a2dpDeviceChanged =
+ (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP);
mOutDevice = value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mOutDevice);
@@ -4391,7 +4432,7 @@
sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
}
- return reconfig;
+ return reconfig || a2dpDeviceChanged;
}
@@ -4404,6 +4445,7 @@
PlaybackThread::dumpInternals(fd, args);
dprintf(fd, " Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs);
dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
+ dprintf(fd, " Master mono: %s\n", mMasterMono ? "on" : "off");
// Make a non-atomic copy of fast mixer dump state so it won't change underneath us
// while we are dumping it. It may be inconsistent, but it won't mutate!
@@ -4831,6 +4873,7 @@
status_t& status)
{
bool reconfig = false;
+ bool a2dpDeviceChanged = false;
status = NO_ERROR;
@@ -4840,6 +4883,8 @@
// forward device change to effects that have requested to be
// aware of attached audio device.
if (value != AUDIO_DEVICE_NONE) {
+ a2dpDeviceChanged =
+ (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP);
mOutDevice = value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mOutDevice);
@@ -4872,7 +4917,7 @@
}
}
- return reconfig;
+ return reconfig || a2dpDeviceChanged;
}
uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 114d43c..8eed50d 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -400,6 +400,8 @@
String16 getWakeLockTag();
virtual void preExit() { }
+ virtual void setMasterMono_l(bool mono __unused) { }
+ virtual bool requireMonoBlend() { return false; }
friend class AudioFlinger; // for mEffectChains
@@ -909,6 +911,7 @@
// mFastMixer->sq() // for mutating and pushing state
int32_t mFastMixerFutex; // for cold idle
+ std::atomic_bool mMasterMono;
public:
virtual bool hasFastMixer() const { return mFastMixer != 0; }
virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const {
@@ -916,6 +919,15 @@
return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
}
+protected:
+ virtual void setMasterMono_l(bool mono) {
+ mMasterMono.store(mono);
+ if (mFastMixer != nullptr) { /* hasFastMixer() */
+ mFastMixer->setMasterMono(mMasterMono);
+ }
+ }
+ // the FastMixer performs mono blend if it exists.
+ virtual bool requireMonoBlend() { return mMasterMono.load() && !hasFastMixer(); }
};
class DirectOutputThread : public PlaybackThread {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 42fb9e5..dd3f144 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -228,6 +228,9 @@
audio_io_handle_t *handle,
uid_t uid) = 0;
virtual status_t stopAudioSource(audio_io_handle_t handle) = 0;
+
+ virtual status_t setMasterMono(bool mono) = 0;
+ virtual status_t getMasterMono(bool *mono) = 0;
};
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index dffeb7e..0c28fc9 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -10,10 +10,12 @@
src/IOProfile.cpp \
src/AudioPort.cpp \
src/AudioProfile.cpp \
+ src/AudioRoute.cpp \
src/AudioPolicyMix.cpp \
src/AudioPatch.cpp \
src/AudioInputDescriptor.cpp \
src/AudioOutputDescriptor.cpp \
+ src/AudioCollections.cpp \
src/EffectDescriptor.cpp \
src/ConfigParsingUtils.cpp \
src/SoundTriggerSession.cpp \
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
new file mode 100644
index 0000000..814c5c2
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <system/audio.h>
+#include <cutils/config_utils.h>
+
+namespace android {
+
+class AudioPort;
+class AudioRoute;
+
+class AudioPortVector : public Vector<sp<AudioPort> >
+{
+public:
+ sp<AudioPort> findByTagName(const String8 &tagName) const;
+};
+
+
+class AudioRouteVector : public Vector<sp<AudioRoute> >
+{
+public:
+ status_t dump(int fd) const;
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 9aaaddf..12e42ea 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -16,6 +16,7 @@
#pragma once
+#include "AudioCollections.h"
#include "AudioProfile.h"
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -28,6 +29,7 @@
class HwModule;
class AudioGain;
+class AudioRoute;
typedef Vector<sp<AudioGain> > AudioGainCollection;
class AudioPort : public virtual RefBase
@@ -44,6 +46,8 @@
audio_port_type_t getType() const { return mType; }
audio_port_role_t getRole() const { return mRole; }
+ virtual const String8 getTagName() const = 0;
+
void setGains(const AudioGainCollection &gains) { mGains = gains; }
const AudioGainCollection &getGains() const { return mGains; }
@@ -114,6 +118,9 @@
(mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
}
+ void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
+ const AudioRouteVector &getRoutes() const { return mRoutes; }
+
void dump(int fd, int spaces, bool verbose = true) const;
void log(const char* indent) const;
@@ -124,11 +131,12 @@
void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
- String8 mName;
+ String8 mName;
audio_port_type_t mType;
audio_port_role_t mRole;
uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
+ AudioRouteVector mRoutes; // Routes involving this port
static volatile int32_t mNextUniqueId;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
new file mode 100644
index 0000000..67e197f
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "AudioCollections.h"
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+
+namespace android
+{
+
+class AudioPort;
+class DeviceDescriptor;
+
+typedef enum {
+ AUDIO_ROUTE_MUX = 0,
+ AUDIO_ROUTE_MIX = 1
+} audio_route_type_t;
+
+class AudioRoute : public virtual RefBase
+{
+public:
+ AudioRoute(audio_route_type_t type) : mType(type) {}
+
+ void setSources(const AudioPortVector &sources) { mSources = sources; }
+ const AudioPortVector &getSources() const { return mSources; }
+
+ void setSink(const sp<AudioPort> &sink) { mSink = sink; }
+ const sp<AudioPort> &getSink() const { return mSink; }
+
+ audio_route_type_t getType() const { return mType; }
+
+ void dump(int fd, int spaces) const;
+
+private:
+ AudioPortVector mSources;
+ sp<AudioPort> mSink;
+ audio_route_type_t mType;
+
+};
+
+}; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 8ece51b..54fcd0b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -34,8 +34,9 @@
virtual ~DeviceDescriptor() {}
+ virtual const String8 getTagName() const { return mTagName; }
+
audio_devices_t type() const { return mDeviceType; }
- const String8 getTagName() const { return mTagName; }
bool equals(const sp<DeviceDescriptor>& other) const;
@@ -56,7 +57,7 @@
String8 mAddress;
private:
- String8 mTagName;
+ String8 mTagName; // Unique human readable identifier for a device port found in conf file.
audio_devices_t mDeviceType;
audio_port_handle_t mId;
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index f71a1a4..93d03e6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -17,6 +17,7 @@
#pragma once
#include "DeviceDescriptor.h"
+#include "AudioRoute.h"
#include <hardware/audio.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
@@ -46,7 +47,7 @@
const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; }
- void setDeclaredDevices(const DeviceVector &devices) { mDeclaredDevices = devices; }
+ void setDeclaredDevices(const DeviceVector &devices);
const InputProfileCollection &getInputProfiles() const { return mInputProfiles; }
@@ -57,6 +58,10 @@
void setHalVersion(uint32_t halVersion) { mHalVersion = halVersion; }
uint32_t getHalVersion() const { return mHalVersion; }
+ sp<DeviceDescriptor> getRouteSinkDevice(const sp<AudioRoute> &route) const;
+ DeviceVector getRouteSourceDevices(const sp<AudioRoute> &route) const;
+ void setRoutes(const AudioRouteVector &routes);
+
status_t addOutputProfile(const sp<IOProfile> &profile);
status_t addInputProfile(const sp<IOProfile> &profile);
status_t addProfile(const sp<IOProfile> &profile);
@@ -70,6 +75,11 @@
audio_module_handle_t getHandle() const { return mHandle; }
+ sp<AudioPort> findPortByTagName(const String8 &tagName) const
+ {
+ return mPorts.findByTagName(tagName);
+ }
+
// TODO remove from here (split serialization)
void dump(int fd);
@@ -79,8 +89,12 @@
InputProfileCollection mInputProfiles; // input profiles exposed by this module
private:
+ void refreshSupportedDevices();
+
uint32_t mHalVersion; // audio HAL API version
DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
+ AudioRouteVector mRoutes;
+ AudioPortVector mPorts;
};
class HwModuleCollection : public Vector<sp<HwModule> >
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 310acff..eae9586 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -33,8 +33,11 @@
class IOProfile : public AudioPort
{
public:
- IOProfile(const String8 &name, audio_port_role_t role);
- virtual ~IOProfile();
+ IOProfile(const String8 &name, audio_port_role_t role)
+ : AudioPort(name, AUDIO_PORT_TYPE_MIX, role) {}
+
+ // For a Profile aka MixPort, tag name and name are equivalent.
+ virtual const String8 getTagName() const { return getName(); }
// This method is used for both output and input.
// If parameter updatedSamplingRate is non-NULL, it is assigned the actual sample rate.
@@ -101,8 +104,7 @@
const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }
private:
- DeviceVector mSupportedDevices; // supported devices
- // (devices this output can be routed to)
+ DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
};
class InputProfile : public IOProfile
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
new file mode 100644
index 0000000..f66af6b
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioCollections"
+//#define LOG_NDEBUG 0
+
+#include "AudioCollections.h"
+#include "AudioPort.h"
+#include "AudioRoute.h"
+#include "HwModule.h"
+#include "AudioGain.h"
+
+namespace android {
+
+sp<AudioPort> AudioPortVector::findByTagName(const String8 &tagName) const
+{
+ sp<AudioPort> port = 0;
+ for (size_t i = 0; i < size(); i++) {
+ if (itemAt(i)->getTagName() == tagName) {
+ port = itemAt(i);
+ break;
+ }
+ }
+ return port;
+}
+
+status_t AudioRouteVector::dump(int fd) const
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+
+ snprintf(buffer, SIZE, "\nAudio Route dump (%zu):\n", size());
+ write(fd, buffer, strlen(buffer));
+ for (size_t i = 0; i < size(); i++) {
+ snprintf(buffer, SIZE, "- Route %zu:\n", i + 1);
+ write(fd, buffer, strlen(buffer));
+ itemAt(i)->dump(fd, 4);
+ }
+ return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
new file mode 100644
index 0000000..79ad1f7
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "APM::AudioRoute"
+//#define LOG_NDEBUG 0
+
+#include "AudioRoute.h"
+#include "HwModule.h"
+#include "AudioGain.h"
+
+namespace android
+{
+
+void AudioRoute::dump(int fd, int spaces) const
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix");
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "%*s- Sink: %s\n", spaces, "", mSink->getTagName().string());
+ result.append(buffer);
+
+ if (mSources.size() != 0) {
+ snprintf(buffer, SIZE, "%*s- Sources: \n", spaces, "");
+ result.append(buffer);
+ for (size_t i = 0; i < mSources.size(); i++) {
+ snprintf(buffer, SIZE, "%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string());
+ result.append(buffer);
+ }
+ }
+ result.append("\n");
+
+ write(fd, result.string(), result.size());
+}
+
+}
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index d752485..538876c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -281,6 +281,10 @@
snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
result.append(buffer);
}
+ if (!mTagName.isEmpty()) {
+ snprintf(buffer, SIZE, "%*s- tag name: %s\n", spaces, "", mTagName.string());
+ result.append(buffer);
+ }
std::string deviceLiteral;
if (DeviceConverter::toString(mDeviceType, deviceLiteral)) {
snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index dce0890..93ab9c7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -61,6 +61,7 @@
{
profile->attach(this);
mOutputProfiles.add(profile);
+ mPorts.add(profile);
return NO_ERROR;
}
@@ -68,6 +69,7 @@
{
profile->attach(this);
mInputProfiles.add(profile);
+ mPorts.add(profile);
return NO_ERROR;
}
@@ -132,6 +134,88 @@
return NO_ERROR;
}
+void HwModule::setDeclaredDevices(const DeviceVector &devices)
+{
+ mDeclaredDevices = devices;
+ for (size_t i = 0; i < devices.size(); i++) {
+ mPorts.add(devices[i]);
+ }
+}
+
+sp<DeviceDescriptor> HwModule::getRouteSinkDevice(const sp<AudioRoute> &route) const
+{
+ sp<DeviceDescriptor> sinkDevice = 0;
+ if (route->getSink()->getType() == AUDIO_PORT_TYPE_DEVICE) {
+ sinkDevice = mDeclaredDevices.getDeviceFromTagName(route->getSink()->getTagName());
+ }
+ return sinkDevice;
+}
+
+DeviceVector HwModule::getRouteSourceDevices(const sp<AudioRoute> &route) const
+{
+ DeviceVector sourceDevices;
+ Vector <sp<AudioPort> > sources = route->getSources();
+ for (size_t i = 0; i < sources.size(); i++) {
+ if (sources[i]->getType() == AUDIO_PORT_TYPE_DEVICE) {
+ sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(sources[i]->getTagName()));
+ }
+ }
+ return sourceDevices;
+}
+
+void HwModule::setRoutes(const AudioRouteVector &routes)
+{
+ mRoutes = routes;
+ // Now updating the streams (aka IOProfile until now) supported devices
+ refreshSupportedDevices();
+}
+
+void HwModule::refreshSupportedDevices()
+{
+ // Now updating the streams (aka IOProfile until now) supported devices
+ for (size_t i = 0; i < mInputProfiles.size(); i++) {
+ sp<IOProfile> stream = mInputProfiles[i];
+ DeviceVector sourceDevices;
+ const AudioRouteVector &routes = stream->getRoutes();
+ for (size_t j = 0; j < routes.size(); j++) {
+ sp<AudioPort> sink = routes[j]->getSink();
+ if (sink == 0 || stream != sink) {
+ ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);
+ continue;
+ }
+ DeviceVector sourceDevicesForRoute = getRouteSourceDevices(routes[j]);
+ if (sourceDevicesForRoute.isEmpty()) {
+ ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string());
+ continue;
+ }
+ sourceDevices.add(sourceDevicesForRoute);
+ }
+ if (sourceDevices.isEmpty()) {
+ ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string());
+ continue;
+ }
+ stream->setSupportedDevices(sourceDevices);
+ }
+ for (size_t i = 0; i < mOutputProfiles.size(); i++) {
+ sp<IOProfile> stream = mOutputProfiles[i];
+ DeviceVector sinkDevices;
+ const AudioRouteVector &routes = stream->getRoutes();
+ for (size_t j = 0; j < routes.size(); j++) {
+ sp<AudioPort> source = routes[j]->getSources().findByTagName(stream->getTagName());
+ if (source == 0 || stream != source) {
+ ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);
+ continue;
+ }
+ sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(routes[j]);
+ if (sinkDevice == 0) {
+ ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string());
+ continue;
+ }
+ sinkDevices.add(sinkDevice);
+ }
+ stream->setSupportedDevices(sinkDevices);
+ }
+}
void HwModule::dump(int fd)
{
@@ -163,6 +247,10 @@
}
}
mDeclaredDevices.dump(fd, String8("Declared"), 2, true);
+ if (!mRoutes.empty()) {
+ write(fd, " - Audio Route:\n", strlen(" - Audio Route:\n"));
+ mRoutes.dump(fd);
+ }
}
sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fe38f54..6e0a071 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -24,15 +24,6 @@
namespace android {
-IOProfile::IOProfile(const String8 &name, audio_port_role_t role)
- : AudioPort(name, AUDIO_PORT_TYPE_MIX, role)
-{
-}
-
-IOProfile::~IOProfile()
-{
-}
-
// checks if the IO profile is compatible with specified parameters.
// Sampling rate, format and channel mask must be specified in order to
// get a valid a match
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
index 497d555..ccb10ae 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
@@ -30,24 +30,16 @@
context),
mPolicySubsystem(static_cast<const PolicySubsystem *>(
instanceConfigurableElement->getBelongingSubsystem())),
- mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface()),
- mApplicableInputDevice(mDefaultApplicableInputDevice)
+ mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
mId = static_cast<audio_source_t>(context.getItemAsInteger(MappingKeyIdentifier));
// Declares the strategy to audio policy engine
mPolicyPluginInterface->addInputSource(getFormattedMappingValue(), mId);
}
-bool InputSource::receiveFromHW(string & /*error*/)
-{
- blackboardWrite(&mApplicableInputDevice, sizeof(mApplicableInputDevice));
- return true;
-}
-
bool InputSource::sendToHW(string & /*error*/)
{
uint32_t applicableInputDevice;
blackboardRead(&applicableInputDevice, sizeof(applicableInputDevice));
- mApplicableInputDevice = applicableInputDevice;
- return mPolicyPluginInterface->setDeviceForInputSource(mId, mApplicableInputDevice);
+ return mPolicyPluginInterface->setDeviceForInputSource(mId, applicableInputDevice);
}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
index 67c5b50..0db4f70 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
@@ -32,7 +32,6 @@
const CMappingContext &context);
protected:
- virtual bool receiveFromHW(std::string &error);
virtual bool sendToHW(std::string &error);
private:
@@ -44,6 +43,4 @@
android::AudioPolicyPluginInterface *mPolicyPluginInterface;
audio_source_t mId; /**< input source identifier to link with audio.h. */
- uint32_t mApplicableInputDevice; /**< applicable input device for this strategy. */
- static const uint32_t mDefaultApplicableInputDevice = 0; /**< default input device. */
};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
index 1848813..5c536d5 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
@@ -31,8 +31,7 @@
context),
mPolicySubsystem(static_cast<const PolicySubsystem *>(
instanceConfigurableElement->getBelongingSubsystem())),
- mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface()),
- mApplicableOutputDevice(mDefaultApplicableOutputDevice)
+ mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
mId = static_cast<routing_strategy>(context.getItemAsInteger(MappingKeyIdentifier));
@@ -40,12 +39,6 @@
mPolicyPluginInterface->addStrategy(getFormattedMappingValue(), mId);
}
-bool Strategy::receiveFromHW(string & /*error*/)
-{
- blackboardWrite(&mApplicableOutputDevice, sizeof(mApplicableOutputDevice));
- return true;
-}
-
bool Strategy::sendToHW(string & /*error*/)
{
uint32_t applicableOutputDevice;
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
index 9a9b3e4..cbb72e2 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
@@ -32,7 +32,6 @@
const CMappingContext &context);
protected:
- virtual bool receiveFromHW(std::string &error);
virtual bool sendToHW(std::string &error);
private:
@@ -44,6 +43,4 @@
android::AudioPolicyPluginInterface *mPolicyPluginInterface;
android::routing_strategy mId; /**< strategy identifier to link with audio.h.*/
- uint32_t mApplicableOutputDevice; /**< applicable output device for this strategy. */
- static const uint32_t mDefaultApplicableOutputDevice = 0; /**< default output device. */
};
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
index 1916b9b..eb7d78f 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
@@ -31,8 +31,7 @@
context),
mPolicySubsystem(static_cast<const PolicySubsystem *>(
instanceConfigurableElement->getBelongingSubsystem())),
- mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface()),
- mApplicableStrategy(mDefaultApplicableStrategy)
+ mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
mId = static_cast<audio_usage_t>(context.getItemAsInteger(MappingKeyIdentifier));
@@ -40,17 +39,10 @@
mPolicyPluginInterface->addUsage(getFormattedMappingValue(), mId);
}
-bool Usage::receiveFromHW(string & /*error*/)
-{
- blackboardWrite(&mApplicableStrategy, sizeof(mApplicableStrategy));
- return true;
-}
-
bool Usage::sendToHW(string & /*error*/)
{
uint32_t applicableStrategy;
blackboardRead(&applicableStrategy, sizeof(applicableStrategy));
- mApplicableStrategy = applicableStrategy;
return mPolicyPluginInterface->setStrategyForUsage(mId,
- static_cast<routing_strategy>(mApplicableStrategy));
+ static_cast<routing_strategy>(applicableStrategy));
}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
index 8e9b638..3b82f8c 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
@@ -32,7 +32,6 @@
const CMappingContext &context);
protected:
- virtual bool receiveFromHW(std::string &error);
virtual bool sendToHW(std::string &error);
private:
@@ -44,6 +43,4 @@
android::AudioPolicyPluginInterface *mPolicyPluginInterface;
audio_usage_t mId; /**< usage identifier to link with audio.h. */
- uint32_t mApplicableStrategy; /**< applicable strategy for this usage. */
- static const uint32_t mDefaultApplicableStrategy = 0; /**< default strategy. */
};
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 32341ec..074af50 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -246,10 +246,17 @@
return mPolicyParameterMgr->getForceUse(usage);
}
-status_t Engine::setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
- const char *deviceAddress)
+status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t /*state*/)
{
- return mPolicyParameterMgr->setDeviceConnectionState(devices, state, deviceAddress);
+ if (audio_is_output_device(devDesc->type())) {
+ return mPolicyParameterMgr->setAvailableOutputDevices(
+ mApmObserver->getAvailableOutputDevices().types());
+ } else if (audio_is_input_device(devDesc->type())) {
+ return mPolicyParameterMgr->setAvailableInputDevices(
+ mApmObserver->getAvailableInputDevices().types());
+ }
+ return BAD_TYPE;
}
template <>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 79bc8ff..8a15e5e 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -86,8 +86,7 @@
virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
audio_policy_dev_state_t state)
{
- return mPolicyEngine->setDeviceConnectionState(devDesc->type(), state,
- devDesc->mAddress);
+ return mPolicyEngine->setDeviceConnectionState(devDesc, state);
}
virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin, int indexMax)
@@ -180,9 +179,8 @@
audio_mode_t getPhoneState() const;
status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
- status_t setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
- const char *deviceAddress);
-
+ status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state);
float volIndexToDb(device_category category, audio_stream_type_t stream, int indexInUi);
status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index cfe49d4..3e40a2b 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -387,41 +387,26 @@
return interface->getLiteralValue(valueToCheck, literalValue);
}
-status_t ParameterManagerWrapper::setDeviceConnectionState(audio_devices_t devices,
- audio_policy_dev_state_t state,
- const char */*deviceAddres*/)
+status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
{
- ISelectionCriterionInterface *criterion = NULL;
-
- if (audio_is_output_devices(devices)) {
- criterion = mPolicyCriteria[gOutputDeviceCriterionTag];
- } else if (devices & AUDIO_DEVICE_BIT_IN) {
- criterion = mPolicyCriteria[gInputDeviceCriterionTag];
- } else {
- return BAD_TYPE;
- }
+ ISelectionCriterionInterface *criterion = mPolicyCriteria[gInputDeviceCriterionTag];
if (criterion == NULL) {
- ALOGE("%s: no criterion found for devices", __FUNCTION__);
+ ALOGE("%s: no criterion found for input devices", __FUNCTION__);
return DEAD_OBJECT;
}
+ criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
+ applyPlatformConfiguration();
+ return NO_ERROR;
+}
- int32_t previousDevices = criterion->getCriterionState();
- switch (state)
- {
- case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
- criterion->setCriterionState(previousDevices |= devices);
- break;
-
- case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE:
- if (devices & AUDIO_DEVICE_BIT_IN) {
- devices &= ~AUDIO_DEVICE_BIT_IN;
- }
- criterion->setCriterionState(previousDevices &= ~devices);
- break;
-
- default:
- return BAD_VALUE;
+status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
+{
+ ISelectionCriterionInterface *criterion = mPolicyCriteria[gOutputDeviceCriterionTag];
+ if (criterion == NULL) {
+ ALOGE("%s: no criterion found for output devices", __FUNCTION__);
+ return DEAD_OBJECT;
}
+ criterion->setCriterionState(outputDevices);
applyPlatformConfiguration();
return NO_ERROR;
}
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 3c5f2c0..4c1acfe 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -103,18 +103,22 @@
audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
/**
- * Set the connection state of device(s).
- * It will set the associated policy parameter framework criterion.
+ * Set the available input devices i.e. set the associated policy parameter framework criterion
*
- * @param[in] devices mask of devices for which the state has changed.
- * @param[in] state of availability of this(these) device(s).
- * @param[in] deviceAddress: the mask might not be enough, as it may represents a type of
- * device, so address of the device will help precise identification.
+ * @param[in] inputDevices mask of available input devices.
*
* @return NO_ERROR if devices criterion updated correctly, error code otherwise.
*/
- status_t setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
- const char *deviceAddress);
+ status_t setAvailableInputDevices(audio_devices_t inputDevices);
+
+ /**
+ * Set the available output devices i.e. set the associated policy parameter framework criterion
+ *
+ * @param[in] outputDevices mask of available output devices.
+ *
+ * @return NO_ERROR if devices criterion updated correctly, error code otherwise.
+ */
+ status_t setAvailableOutputDevices(audio_devices_t outputDevices);
private:
/**
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index a66be09..b0df018 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -662,6 +662,7 @@
break;
case AUDIO_SOURCE_VOICE_RECOGNITION:
+ case AUDIO_SOURCE_UNPROCESSED:
case AUDIO_SOURCE_HOTWORD:
if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index af8a2b9..04af88d 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -842,15 +842,15 @@
goto non_direct_output;
}
- // Do not allow offloading if one non offloadable effect is enabled. This prevents from
- // creating an offloaded track and tearing it down immediately after start when audioflinger
- // detects there is an active non offloadable effect.
+ // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
+ // This prevents creating an offloaded track and tearing it down immediately after start
+ // when audioflinger detects there is an active non offloadable effect.
// FIXME: We should check the audio session here but we do not have it in this context.
// This may prevent offloading in rare situations where effects are left active by apps
// in the background.
if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
- !mEffects.isNonOffloadableEffectEnabled()) {
+ !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
profile = getProfileForDirectOutput(device,
samplingRate,
format,
@@ -2090,6 +2090,8 @@
result.append(buffer);
snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
result.append(buffer);
+ snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
+ result.append(buffer);
write(fd, result.string(), result.size());
@@ -2117,6 +2119,10 @@
offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
offloadInfo.has_video);
+ if (mMasterMono) {
+ return false; // no offloading if mono is set.
+ }
+
// Check if offload has been disabled
char propValue[PROPERTY_VALUE_MAX];
if (property_get("audio.offload.disable", propValue, "0")) {
@@ -2880,6 +2886,44 @@
return status;
}
+status_t AudioPolicyManager::setMasterMono(bool mono)
+{
+ if (mMasterMono == mono) {
+ return NO_ERROR;
+ }
+ mMasterMono = mono;
+ // if enabling mono we close all offloaded devices, which will invalidate the
+ // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
+ // for recreating the new AudioTrack as non-offloaded PCM.
+ //
+ // If disabling mono, we leave all tracks as is: we don't know which clients
+ // and tracks are able to be recreated as offloaded. The next "song" should
+ // play back offloaded.
+ if (mMasterMono) {
+ Vector<audio_io_handle_t> offloaded;
+ for (size_t i = 0; i < mOutputs.size(); ++i) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ offloaded.push(desc->mIoHandle);
+ }
+ }
+ for (size_t i = 0; i < offloaded.size(); ++i) {
+ closeOutput(offloaded[i]);
+ }
+ }
+ // update master mono for all remaining outputs
+ for (size_t i = 0; i < mOutputs.size(); ++i) {
+ updateMono(mOutputs.keyAt(i));
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getMasterMono(bool *mono)
+{
+ *mono = mMasterMono;
+ return NO_ERROR;
+}
+
status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
@@ -2946,7 +2990,8 @@
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
- mTtsOutputAvailable(false)
+ mTtsOutputAvailable(false),
+ mMasterMono(false)
{
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
@@ -3371,6 +3416,7 @@
{
outputDesc->setIoHandle(output);
mOutputs.add(output, outputDesc);
+ updateMono(output); // update mono status when adding to output list
nextAudioPortGeneration();
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 59163ca..37faac2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -24,6 +24,7 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
+#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>
#include "AudioPolicyInterface.h"
@@ -231,6 +232,9 @@
uid_t uid);
virtual status_t stopAudioSource(audio_io_handle_t handle);
+ virtual status_t setMasterMono(bool mono);
+ virtual status_t getMasterMono(bool *mono);
+
// Audio policy configuration file parsing (audio_policy.conf)
// TODO candidates to be moved to ConfigParsingUtils
void defaultAudioPolicyConfig(void);
@@ -565,6 +569,7 @@
bool mBeaconMuted; // has STREAM_TTS been muted
bool mTtsOutputAvailable; // true if a dedicated output for TTS stream is available
+ bool mMasterMono; // true if we wish to force all outputs to mono
AudioPolicyMixCollection mPolicyMixes; // list of registered mixes
#ifdef AUDIO_POLICY_TEST
@@ -644,6 +649,11 @@
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
+ void updateMono(audio_io_handle_t output) {
+ AudioParameter param;
+ param.addInt(String8(AUDIO_PARAMETER_MONO_OUTPUT), (int)mMasterMono);
+ mpClientInterface->setParameters(output, param.toString());
+ }
};
};
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 282ddeb..f6f8276 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -323,7 +323,8 @@
VOICE_CALL_SRC_TAG,
CAMCORDER_SRC_TAG,
VOICE_REC_SRC_TAG,
- VOICE_COMM_SRC_TAG
+ VOICE_COMM_SRC_TAG,
+ UNPROCESSED_SRC_TAG
};
// returns the audio_source_t enum corresponding to the input source name or
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 8c976aa..c7486a5 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -560,7 +560,7 @@
ALOGV("mAudioPolicyManager == NULL");
return false;
}
-
+ Mutex::Autolock _l(mLock);
return mAudioPolicyManager->isOffloadSupported(info);
}
@@ -700,4 +700,25 @@
return mAudioPolicyManager->stopAudioSource(handle);
}
+status_t AudioPolicyService::setMasterMono(bool mono)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ if (!settingsAllowed()) {
+ return PERMISSION_DENIED;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->setMasterMono(mono);
+}
+
+status_t AudioPolicyService::getMasterMono(bool *mono)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->getMasterMono(mono);
+}
+
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index 13af3ef..08b2a3b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -619,4 +619,14 @@
return INVALID_OPERATION;
}
+status_t AudioPolicyService::setMasterMono(bool mono)
+{
+ return INVALID_OPERATION;
+}
+
+status_t AudioPolicyService::getMasterMono(bool *mono)
+{
+ return INVALID_OPERATION;
+}
+
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 4c11d93..160f4f0 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -202,6 +202,9 @@
audio_io_handle_t *handle);
virtual status_t stopAudioSource(audio_io_handle_t handle);
+ virtual status_t setMasterMono(bool mono);
+ virtual status_t getMasterMono(bool *mono);
+
status_t doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index a9a984a..21a75cd 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -11,9 +11,7 @@
# service executable
include $(CLEAR_VARS)
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64))
-LOCAL_ADDITIONAL_DEPENDENCIES += mediaextractor-seccomp.policy
-endif
+LOCAL_REQUIRED_MODULES_arm := mediaextractor-seccomp.policy
LOCAL_SRC_FILES := main_extractorservice.cpp minijail/minijail.cpp
LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils liblog libicuuc libminijail
LOCAL_STATIC_LIBRARIES := libicuandroid_utils
diff --git a/services/mediaextractor/minijail/Android.mk b/services/mediaextractor/minijail/Android.mk
index 79182bd..17ff2c1 100644
--- a/services/mediaextractor/minijail/Android.mk
+++ b/services/mediaextractor/minijail/Android.mk
@@ -4,7 +4,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := mediaextractor-seccomp.policy
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy/
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
# mediaextractor runs in 32-bit combatibility mode. For 64 bit architectures,
# use the 32 bit policy
diff --git a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
index f30b3ad..f23e38f 100644
--- a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
+++ b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
@@ -36,3 +36,4 @@
setpriority: 1
sigaltstack: 1
brk: 1
+sched_setscheduler: 1