Merge "DrmUtils: helpers to create hidl CryptoFactories/Plugins"
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index b3fd7e9..7032654 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -17,7 +17,6 @@
srcs: [
"DrmPluginPath.cpp",
"DrmSessionManager.cpp",
- "ICrypto.cpp",
"IDrm.cpp",
"IDrmClient.cpp",
"IMediaDrmService.cpp",
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index c8956bf..66991bd 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -144,7 +144,10 @@
}
sp<ICrypto> MakeCrypto(status_t *pstatus) {
- return MakeObject<ICrypto, CryptoHal>(pstatus);
+ if (pstatus) {
+ *pstatus = OK;
+ }
+ return new CryptoHal();
}
std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]) {
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
deleted file mode 100644
index a2594aa..0000000
--- a/drm/libmediadrm/ICrypto.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2012 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_NDEBUG 0
-#define LOG_TAG "ICrypto"
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <cutils/log.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AString.h>
-#include <mediadrm/ICrypto.h>
-#include <utils/Log.h>
-
-namespace android {
-
-enum {
- INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
- IS_CRYPTO_SUPPORTED,
- CREATE_PLUGIN,
- DESTROY_PLUGIN,
- REQUIRES_SECURE_COMPONENT,
- DECRYPT,
- NOTIFY_RESOLUTION,
- SET_MEDIADRM_SESSION,
- SET_HEAP,
- UNSET_HEAP,
-};
-
-struct BpCrypto : public BpInterface<ICrypto> {
- explicit BpCrypto(const sp<IBinder> &impl)
- : BpInterface<ICrypto>(impl) {
- }
-
- virtual status_t initCheck() const {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- remote()->transact(INIT_CHECK, data, &reply);
-
- return reply.readInt32();
- }
-
- virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.write(uuid, 16);
- remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
-
- return reply.readInt32() != 0;
- }
-
- virtual status_t createPlugin(
- const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.write(uuid, 16);
- data.writeInt32(opaqueSize);
-
- if (opaqueSize > 0) {
- data.write(opaqueData, opaqueSize);
- }
-
- remote()->transact(CREATE_PLUGIN, data, &reply);
-
- return reply.readInt32();
- }
-
- virtual status_t destroyPlugin() {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- remote()->transact(DESTROY_PLUGIN, data, &reply);
-
- return reply.readInt32();
- }
-
- virtual bool requiresSecureDecoderComponent(
- const char *mime) const {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeCString(mime);
- remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
-
- return reply.readInt32() != 0;
- }
-
- virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
- CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const SourceBuffer &source, size_t offset,
- const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- const DestinationBuffer &destination, AString *errorDetailMsg) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeInt32(mode);
- data.writeInt32(pattern.mEncryptBlocks);
- data.writeInt32(pattern.mSkipBlocks);
-
- static const uint8_t kDummy[16] = { 0 };
-
- if (key == NULL) {
- key = kDummy;
- }
-
- if (iv == NULL) {
- iv = kDummy;
- }
-
- data.write(key, 16);
- data.write(iv, 16);
-
- size_t totalSize = 0;
- for (size_t i = 0; i < numSubSamples; ++i) {
- totalSize += subSamples[i].mNumBytesOfEncryptedData;
- totalSize += subSamples[i].mNumBytesOfClearData;
- }
-
- data.writeInt32(totalSize);
- data.writeStrongBinder(IInterface::asBinder(source.mSharedMemory));
- data.writeInt32(source.mHeapSeqNum);
- data.writeInt32(offset);
-
- data.writeInt32(numSubSamples);
- data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
-
- data.writeInt32((int32_t)destination.mType);
- if (destination.mType == kDestinationTypeNativeHandle) {
- if (destination.mHandle == NULL) {
- return BAD_VALUE;
- }
- data.writeNativeHandle(destination.mHandle);
- } else {
- if (destination.mSharedMemory == NULL) {
- return BAD_VALUE;
- }
- data.writeStrongBinder(IInterface::asBinder(destination.mSharedMemory));
- }
-
- remote()->transact(DECRYPT, data, &reply);
-
- ssize_t result = reply.readInt32();
-
- if (isCryptoError(result)) {
- AString msg = reply.readCString();
- if (errorDetailMsg) {
- *errorDetailMsg = msg;
- }
- }
-
- return result;
- }
-
- virtual void notifyResolution(
- uint32_t width, uint32_t height) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeInt32(width);
- data.writeInt32(height);
- remote()->transact(NOTIFY_RESOLUTION, data, &reply);
- }
-
- virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
-
- writeVector(data, sessionId);
- remote()->transact(SET_MEDIADRM_SESSION, data, &reply);
-
- return reply.readInt32();
- }
-
- virtual int32_t setHeap(const sp<IMemoryHeap> &heap) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(heap));
- status_t err = remote()->transact(SET_HEAP, data, &reply);
- if (err != NO_ERROR) {
- return -1;
- }
- int32_t seqNum;
- if (reply.readInt32(&seqNum) != NO_ERROR) {
- return -1;
- }
- return seqNum;
- }
-
- virtual void unsetHeap(int32_t seqNum) {
- Parcel data, reply;
- data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeInt32(seqNum);
- remote()->transact(UNSET_HEAP, data, &reply);
- return;
- }
-
-
-private:
- void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
- uint32_t size = reply.readInt32();
- vector.insertAt((size_t)0, size);
- reply.read(vector.editArray(), size);
- }
-
- void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
- data.writeInt32(vector.size());
- data.write(vector.array(), vector.size());
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
-};
-
-IMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
-
-////////////////////////////////////////////////////////////////////////////////
-
-void BnCrypto::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
- uint32_t size = data.readInt32();
- if (vector.insertAt((size_t)0, size) < 0) {
- vector.clear();
- }
- if (data.read(vector.editArray(), size) != NO_ERROR) {
- vector.clear();
- android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
- }
-}
-
-void BnCrypto::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
- reply->writeInt32(vector.size());
- reply->write(vector.array(), vector.size());
-}
-
-status_t BnCrypto::onTransact(
- uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
- switch (code) {
- case INIT_CHECK:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
- reply->writeInt32(initCheck());
-
- return OK;
- }
-
- case IS_CRYPTO_SUPPORTED:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
- uint8_t uuid[16];
- data.read(uuid, sizeof(uuid));
- reply->writeInt32(isCryptoSchemeSupported(uuid));
-
- return OK;
- }
-
- case CREATE_PLUGIN:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
-
- uint8_t uuid[16];
- data.read(uuid, sizeof(uuid));
-
- size_t opaqueSize = data.readInt32();
- void *opaqueData = NULL;
-
- const size_t kMaxOpaqueSize = 100 * 1024;
- if (opaqueSize > kMaxOpaqueSize) {
- return BAD_VALUE;
- }
-
- opaqueData = malloc(opaqueSize);
- if (NULL == opaqueData) {
- return NO_MEMORY;
- }
-
- data.read(opaqueData, opaqueSize);
- reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
-
- free(opaqueData);
- opaqueData = NULL;
-
- return OK;
- }
-
- case DESTROY_PLUGIN:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
- reply->writeInt32(destroyPlugin());
-
- return OK;
- }
-
- case REQUIRES_SECURE_COMPONENT:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
-
- const char *mime = data.readCString();
- if (mime == NULL) {
- reply->writeInt32(BAD_VALUE);
- } else {
- reply->writeInt32(requiresSecureDecoderComponent(mime));
- }
-
- return OK;
- }
-
- case DECRYPT:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
-
- 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));
-
- uint8_t iv[16];
- data.read(iv, sizeof(iv));
-
- size_t totalSize = data.readInt32();
-
- SourceBuffer source;
-
- source.mSharedMemory =
- interface_cast<IMemory>(data.readStrongBinder());
- if (source.mSharedMemory == NULL) {
- reply->writeInt32(BAD_VALUE);
- return OK;
- }
- source.mHeapSeqNum = data.readInt32();
-
- int32_t offset = data.readInt32();
-
- int32_t numSubSamples = data.readInt32();
- if (numSubSamples < 0 || numSubSamples > 0xffff) {
- reply->writeInt32(BAD_VALUE);
- return OK;
- }
-
- std::unique_ptr<CryptoPlugin::SubSample[]> subSamples =
- std::make_unique<CryptoPlugin::SubSample[]>(numSubSamples);
-
- data.read(subSamples.get(),
- sizeof(CryptoPlugin::SubSample) * numSubSamples);
-
- DestinationBuffer destination;
- destination.mType = (DestinationType)data.readInt32();
- if (destination.mType == kDestinationTypeNativeHandle) {
- destination.mHandle = data.readNativeHandle();
- if (destination.mHandle == NULL) {
- reply->writeInt32(BAD_VALUE);
- return OK;
- }
- } else if (destination.mType == kDestinationTypeSharedMemory) {
- destination.mSharedMemory =
- interface_cast<IMemory>(data.readStrongBinder());
- if (destination.mSharedMemory == NULL) {
- reply->writeInt32(BAD_VALUE);
- return OK;
- }
- sp<IMemory> dest = destination.mSharedMemory;
- if (totalSize > dest->size() ||
- (size_t)dest->offset() > dest->size() - totalSize) {
- reply->writeInt32(BAD_VALUE);
- android_errorWriteLog(0x534e4554, "71389378");
- return OK;
- }
- } else {
- reply->writeInt32(BAD_VALUE);
- android_errorWriteLog(0x534e4554, "70526702");
- return OK;
- }
-
- AString errorDetailMsg;
- ssize_t result;
-
- size_t sumSubsampleSizes = 0;
- bool overflow = false;
- for (int32_t i = 0; i < numSubSamples; ++i) {
- CryptoPlugin::SubSample &ss = subSamples[i];
- if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) {
- sumSubsampleSizes += ss.mNumBytesOfEncryptedData;
- } else {
- overflow = true;
- }
- if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) {
- sumSubsampleSizes += ss.mNumBytesOfClearData;
- } else {
- overflow = true;
- }
- }
-
- if (overflow || sumSubsampleSizes != totalSize) {
- result = -EINVAL;
- } else if (totalSize > source.mSharedMemory->size()) {
- result = -EINVAL;
- } else if ((size_t)offset > source.mSharedMemory->size() - totalSize) {
- result = -EINVAL;
- } else {
- result = decrypt(key, iv, mode, pattern, source, offset,
- subSamples.get(), numSubSamples, destination, &errorDetailMsg);
- }
-
- reply->writeInt32(result);
-
- if (isCryptoError(result)) {
- reply->writeCString(errorDetailMsg.c_str());
- }
-
- if (destination.mType == kDestinationTypeNativeHandle) {
- int err;
- if ((err = native_handle_close(destination.mHandle)) < 0) {
- ALOGW("secure buffer native_handle_close failed: %d", err);
- }
- if ((err = native_handle_delete(destination.mHandle)) < 0) {
- ALOGW("secure buffer native_handle_delete failed: %d", err);
- }
- }
-
- subSamples.reset();
- return OK;
- }
-
- case NOTIFY_RESOLUTION:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
-
- int32_t width = data.readInt32();
- int32_t height = data.readInt32();
- notifyResolution(width, height);
-
- return OK;
- }
-
- case SET_MEDIADRM_SESSION:
- {
- CHECK_INTERFACE(IDrm, data, reply);
- Vector<uint8_t> sessionId;
- readVector(data, sessionId);
- reply->writeInt32(setMediaDrmSession(sessionId));
- return OK;
- }
-
- case SET_HEAP:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
- sp<IMemoryHeap> heap =
- interface_cast<IMemoryHeap>(data.readStrongBinder());
- reply->writeInt32(setHeap(heap));
- return OK;
- }
-
- case UNSET_HEAP:
- {
- CHECK_INTERFACE(ICrypto, data, reply);
- int32_t seqNum = data.readInt32();
- unsetHeap(seqNum);
- return OK;
- }
-
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-} // namespace android
diff --git a/drm/libmediadrm/IMediaDrmService.cpp b/drm/libmediadrm/IMediaDrmService.cpp
index 0b650f2..020c063 100644
--- a/drm/libmediadrm/IMediaDrmService.cpp
+++ b/drm/libmediadrm/IMediaDrmService.cpp
@@ -42,13 +42,6 @@
{
}
- virtual sp<ICrypto> makeCrypto() {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
- remote()->transact(MAKE_CRYPTO, data, &reply);
- return interface_cast<ICrypto>(reply.readStrongBinder());
- }
-
virtual sp<IDrm> makeDrm() {
Parcel data, reply;
data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
@@ -66,12 +59,6 @@
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code) {
- case MAKE_CRYPTO: {
- CHECK_INTERFACE(IMediaDrmService, data, reply);
- sp<ICrypto> crypto = makeCrypto();
- reply->writeStrongBinder(IInterface::asBinder(crypto));
- return NO_ERROR;
- } break;
case MAKE_DRM: {
CHECK_INTERFACE(IMediaDrmService, data, reply);
sp<IDrm> drm = makeDrm();
@@ -90,9 +77,4 @@
return makeDrm();
}
-template<>
-sp<ICrypto> IMediaDrmService::makeObject<ICrypto>() {
- return makeCrypto();
-}
-
} // namespace android
diff --git a/drm/libmediadrm/include/mediadrm/CryptoHal.h b/drm/libmediadrm/include/mediadrm/CryptoHal.h
index 9e61777..865ca38 100644
--- a/drm/libmediadrm/include/mediadrm/CryptoHal.h
+++ b/drm/libmediadrm/include/mediadrm/CryptoHal.h
@@ -36,7 +36,7 @@
namespace android {
-struct CryptoHal : public BnCrypto {
+struct CryptoHal : public ICrypto {
CryptoHal();
virtual ~CryptoHal();
diff --git a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
index 7dcce94..899362f 100644
--- a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
+++ b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
@@ -25,7 +25,6 @@
namespace android {
-struct ICrypto;
struct IDrm;
class IMediaDrmService: public IInterface
@@ -33,8 +32,6 @@
public:
DECLARE_META_INTERFACE(MediaDrmService);
-
- virtual sp<ICrypto> makeCrypto() = 0;
virtual sp<IDrm> makeDrm() = 0;
template<typename I> sp<I> makeObject();
diff --git a/drm/libmediadrm/interface/mediadrm/ICrypto.h b/drm/libmediadrm/interface/mediadrm/ICrypto.h
index 6d896b8..48a0c44 100644
--- a/drm/libmediadrm/interface/mediadrm/ICrypto.h
+++ b/drm/libmediadrm/interface/mediadrm/ICrypto.h
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#include <binder/IInterface.h>
#include <cutils/native_handle.h>
#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
#ifndef ANDROID_ICRYPTO_H_
@@ -29,8 +30,9 @@
class IMemory;
class IMemoryHeap;
-struct ICrypto : public IInterface {
- DECLARE_META_INTERFACE(Crypto);
+struct ICrypto : public RefBase {
+
+ virtual ~ICrypto() {}
virtual status_t initCheck() const = 0;
@@ -79,19 +81,13 @@
virtual int32_t setHeap(const sp<IMemoryHeap>& heap) = 0;
virtual void unsetHeap(int32_t seqNum) = 0;
+protected:
+ ICrypto() {}
+
private:
DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
};
-struct BnCrypto : public BnInterface<ICrypto> {
- virtual status_t onTransact(
- uint32_t code, const Parcel &data, Parcel *reply,
- uint32_t flags = 0);
-private:
- void readVector(const Parcel &data, Vector<uint8_t> &vector) const;
- void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;
-};
-
} // namespace android
#endif // ANDROID_ICRYPTO_H_
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 20ca35c..54184e0 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1392,6 +1392,12 @@
return af->getMicrophones(microphones);
}
+status_t AudioSystem::setAudioHalPids(const std::vector<pid_t>& pids) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) return PERMISSION_DENIED;
+ return af->setAudioHalPids(pids);
+}
+
status_t AudioSystem::getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 6e9a7cf..04ef3dd 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -90,10 +90,12 @@
SET_MASTER_BALANCE,
GET_MASTER_BALANCE,
SET_EFFECT_SUSPENDED,
+ SET_AUDIO_HAL_PIDS
};
#define MAX_ITEMS_PER_LIST 1024
+
class BpAudioFlinger : public BpInterface<IAudioFlinger>
{
public:
@@ -900,6 +902,20 @@
status = reply.readParcelableVector(microphones);
return status;
}
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(pids.size());
+ for (auto pid : pids) {
+ data.writeInt32(pid);
+ }
+ status_t status = remote()->transact(SET_AUDIO_HAL_PIDS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast <status_t> (reply.readInt32());
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -955,7 +971,8 @@
case SET_MODE:
case SET_MIC_MUTE:
case SET_LOW_RAM_DEVICE:
- case SYSTEM_READY: {
+ case SYSTEM_READY:
+ case SET_AUDIO_HAL_PIDS: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1544,6 +1561,31 @@
}
return NO_ERROR;
}
+ case SET_AUDIO_HAL_PIDS: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ std::vector<pid_t> pids;
+ int32_t size;
+ status_t status = data.readInt32(&size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+ if (size > MAX_ITEMS_PER_LIST) {
+ size = MAX_ITEMS_PER_LIST;
+ }
+ for (int32_t i = 0; i < size; i++) {
+ int32_t pid;
+ status = data.readInt32(&pid);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ pids.push_back(pid);
+ }
+ reply->writeInt32(setAudioHalPids(pids));
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 12da0de..d7266b4 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -399,6 +399,12 @@
static bool isCallScreenModeSupported();
+ /**
+ * Send audio HAL server process pids to native audioserver process for use
+ * when generating audio HAL servers tombstones
+ */
+ static status_t setAudioHalPids(const std::vector<pid_t>& pids);
+
// ----------------------------------------------------------------------------
class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 0a65857..308e9d3 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -523,6 +523,8 @@
/* List available microphones and their characteristics */
virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 1335a0c..c30da3c 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -20,6 +20,7 @@
#define LOG_TAG "DevicesFactoryHalHidl"
//#define LOG_NDEBUG 0
+#include "android/hidl/manager/1.0/IServiceManager.h"
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include <media/audiohal/hidl/HalDeathHandler.h>
#include <utils/Log.h>
@@ -28,6 +29,8 @@
#include "DeviceHalHidl.h"
#include "DevicesFactoryHalHidl.h"
+#include <set>
+
using ::android::hardware::audio::CPP_VERSION::IDevice;
using ::android::hardware::audio::CPP_VERSION::Result;
using ::android::hardware::Return;
@@ -108,5 +111,29 @@
return BAD_VALUE;
}
+status_t DevicesFactoryHalHidl::getHalPids(std::vector<pid_t> *pids) {
+ std::set<pid_t> pidsSet;
+
+ for (const auto& factory : mDeviceFactories) {
+ using ::android::hidl::base::V1_0::DebugInfo;
+ using android::hidl::manager::V1_0::IServiceManager;
+
+ DebugInfo debugInfo;
+ auto ret = factory->getDebugInfo([&] (const auto &info) {
+ debugInfo = info;
+ });
+ if (!ret.isOk()) {
+ return INVALID_OPERATION;
+ }
+ if (debugInfo.pid == (int)IServiceManager::PidConstant::NO_PID) {
+ continue;
+ }
+ pidsSet.insert(debugInfo.pid);
+ }
+
+ *pids = {pidsSet.begin(), pidsSet.end()};
+ return NO_ERROR;
+}
+
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 8775e7b..52185c8 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -37,6 +37,9 @@
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+ status_t getHalPids(std::vector<pid_t> *pids) override;
+
private:
std::vector<sp<IDevicesFactory>> mDeviceFactories;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index 0e1f1bb..a5aef1b 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -37,6 +37,14 @@
}
return mLocalFactory->openDevice(name, device);
}
+
+status_t DevicesFactoryHalHybrid::getHalPids(std::vector<pid_t> *pids) {
+ if (mHidlFactory != 0) {
+ return mHidlFactory->getHalPids(pids);
+ }
+ return INVALID_OPERATION;
+}
+
} // namespace CPP_VERSION
template <>
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
index 545bb70..2189b36 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -36,6 +36,8 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+ status_t getHalPids(std::vector<pid_t> *pids) override;
+
private:
sp<DevicesFactoryHalInterface> mLocalFactory;
sp<DevicesFactoryHalInterface> mHidlFactory;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalLocal.h b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
index 5d108dd..2b011f4 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalLocal.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
@@ -33,6 +33,10 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+ status_t getHalPids(std::vector<pid_t> *pids __unused) override {
+ return INVALID_OPERATION;
+ }
+
private:
friend class DevicesFactoryHalHybrid;
diff --git a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
index 14af384..e9ac1ce 100644
--- a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
@@ -20,6 +20,7 @@
#include <media/audiohal/DeviceHalInterface.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include <vector>
namespace android {
@@ -30,6 +31,8 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device) = 0;
+ virtual status_t getHalPids(std::vector<pid_t> *pids) = 0;
+
static sp<DevicesFactoryHalInterface> create();
protected:
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 5301f5c..762ed19 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -39,6 +39,7 @@
"libpowermanager",
"libstagefright",
"libstagefright_foundation",
+ "libstagefright_framecapture_utils",
"libstagefright_httplive",
"libutils",
],
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 81ffcbc..f2a38dd 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -58,6 +58,7 @@
#include <media/Metadata.h>
#include <media/AudioTrack.h>
#include <media/MemoryLeakTrackUtil.h>
+#include <media/stagefright/FrameCaptureProcessor.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaCodecList.h>
@@ -447,6 +448,8 @@
mNextConnId = 1;
MediaPlayerFactory::registerBuiltinFactories();
+ // initialize the frame capture utilities
+ (void)FrameCaptureProcessor::getInstance();
}
MediaPlayerService::~MediaPlayerService()
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index f666ad0..7531578 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -4,7 +4,7 @@
AImageReader_acquireLatestImageAsync; # introduced=26
AImageReader_acquireNextImage; # introduced=24
AImageReader_acquireNextImageAsync; # introduced=26
- AImageReader_getWindowNativeHandle; #vndk
+ AImageReader_getWindowNativeHandle; # llndk
AImageReader_delete; # introduced=24
AImageReader_getFormat; # introduced=24
AImageReader_getHeight; # introduced=24
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 8a9039c..5047b19 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -51,6 +51,10 @@
"libmedia_headers",
],
+ include_dirs: [
+ // For DEBUGGER_SIGNAL
+ "system/core/debuggerd/include",
+ ],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 971ae9f..b132782 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -167,9 +167,16 @@
}
bool modifyAudioRoutingAllowed() {
+ return modifyAudioRoutingAllowed(
+ IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
+}
+
+bool modifyAudioRoutingAllowed(pid_t pid, uid_t uid) {
+ if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
- bool ok = PermissionCache::checkCallingPermission(sModifyAudioRouting);
- if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");
+ bool ok = PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
+ if (!ok) ALOGE("%s(): android.permission.MODIFY_AUDIO_ROUTING denied for uid %d",
+ __func__, uid);
return ok;
}
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 96f7802..4a3e470 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -14,13 +14,50 @@
* limitations under the License.
*/
+#define LOG_TAG "TimeCheck"
#include <utils/Log.h>
#include <mediautils/TimeCheck.h>
#include <mediautils/EventLog.h>
+#include "debuggerd/handler.h"
namespace android {
+// Audio HAL server pids vector used to generate audio HAL processes tombstone
+// when audioserver watchdog triggers.
+// We use a lockless storage to avoid potential deadlocks in the context of watchdog
+// trigger.
+// Protection again simultaneous writes is not needed given one update takes place
+// during AudioFlinger construction and other comes necessarily later once the IAudioFlinger
+// interface is available.
+// The use of an atomic index just guaranties that current vector is fully initialized
+// when read.
+/* static */
+void TimeCheck::accessAudioHalPids(std::vector<pid_t>* pids, bool update) {
+ static constexpr int kNumAudioHalPidsVectors = 3;
+ static std::vector<pid_t> audioHalPids[kNumAudioHalPidsVectors];
+ static std::atomic<int> curAudioHalPids = 0;
+
+ if (update) {
+ audioHalPids[(curAudioHalPids + 1) % kNumAudioHalPidsVectors] = *pids;
+ curAudioHalPids++;
+ } else {
+ *pids = audioHalPids[curAudioHalPids];
+ }
+}
+
+/* static */
+void TimeCheck::setAudioHalPids(const std::vector<pid_t>& pids) {
+ accessAudioHalPids(&(const_cast<std::vector<pid_t>&>(pids)), true);
+}
+
+/* static */
+std::vector<pid_t> TimeCheck::getAudioHalPids() {
+ std::vector<pid_t> pids;
+ accessAudioHalPids(&pids, false);
+ return pids;
+}
+
/* static */
sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
{
@@ -83,6 +120,18 @@
status = mCond.waitRelative(mMutex, waitTimeNs);
}
if (status != NO_ERROR) {
+ // Generate audio HAL processes tombstones and allow time to complete
+ // before forcing restart
+ std::vector<pid_t> pids = getAudioHalPids();
+ if (pids.size() != 0) {
+ for (const auto& pid : pids) {
+ ALOGI("requesting tombstone for pid: %d", pid);
+ sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
+ }
+ sleep(1);
+ } else {
+ ALOGI("No HAL process pid available, skipping tombstones");
+ }
LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
}
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 2595761..9e852fd 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -85,6 +85,7 @@
bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool settingsAllowed();
bool modifyAudioRoutingAllowed();
+bool modifyAudioRoutingAllowed(pid_t pid, uid_t uid);
bool modifyDefaultAudioEffectsAllowed();
bool dumpAllowed();
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index 6c5f656..5ba6d7c 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -20,7 +20,7 @@
#include <utils/KeyedVector.h>
#include <utils/Thread.h>
-
+#include <vector>
namespace android {
@@ -35,6 +35,8 @@
TimeCheck(const char *tag, uint32_t timeoutMs = kDefaultTimeOutMs);
~TimeCheck();
+ static void setAudioHalPids(const std::vector<pid_t>& pids);
+ static std::vector<pid_t> getAudioHalPids();
private:
@@ -63,6 +65,7 @@
};
static sp<TimeCheckThread> getTimeCheckThread();
+ static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
const nsecs_t mEndTimeNs;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 8429b98..9756abb 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -70,6 +70,7 @@
#include <media/nbaio/PipeReader.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
#include <private/android_filesystem_config.h>
//#define BUFLOG_NDEBUG 0
@@ -193,6 +194,9 @@
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
mMediaLogNotifier->run("MediaLogNotifier");
+ std::vector<pid_t> halPids;
+ mDevicesFactoryHal->getHalPids(&halPids);
+ TimeCheck::setAudioHalPids(halPids);
}
void AudioFlinger::onFirstRef()
@@ -218,6 +222,11 @@
gAudioFlinger = this;
}
+status_t AudioFlinger::setAudioHalPids(const std::vector<pid_t>& pids) {
+ TimeCheck::setAudioHalPids(pids);
+ return NO_ERROR;
+}
+
AudioFlinger::~AudioFlinger()
{
while (!mRecordThreads.isEmpty()) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 995b724..3b6bbdb 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -281,6 +281,8 @@
virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
+
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index d54ab42..1355b1b 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -29,7 +29,9 @@
#include <system/audio_effects/effect_visualizer.h>
#include <audio_utils/channels.h>
#include <audio_utils/primitives.h>
+#include <media/AudioContainers.h>
#include <media/AudioEffect.h>
+#include <media/AudioDeviceTypeAddr.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <mediautils/ServiceUtilities.h>
@@ -1229,9 +1231,11 @@
}
}
-status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
+status_t AudioFlinger::EffectModule::sendSetAudioDevicesCommand(
+ const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode)
{
- if (device == AUDIO_DEVICE_NONE) {
+ audio_devices_t deviceType = deviceTypesToBitMask(getAudioDeviceTypes(devices));
+ if (deviceType == AUDIO_DEVICE_NONE) {
return NO_ERROR;
}
@@ -1243,17 +1247,26 @@
if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
status_t cmdStatus;
uint32_t size = sizeof(status_t);
- uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
- EFFECT_CMD_SET_INPUT_DEVICE;
- status = mEffectInterface->command(cmd,
+ // FIXME: use audio device types and addresses when the hal interface is ready.
+ status = mEffectInterface->command(cmdCode,
sizeof(uint32_t),
- &device,
+ &deviceType,
&size,
&cmdStatus);
}
return status;
}
+status_t AudioFlinger::EffectModule::setDevices(const AudioDeviceTypeAddrVector &devices)
+{
+ return sendSetAudioDevicesCommand(devices, EFFECT_CMD_SET_DEVICE);
+}
+
+status_t AudioFlinger::EffectModule::setInputDevice(const AudioDeviceTypeAddr &device)
+{
+ return sendSetAudioDevicesCommand({device}, EFFECT_CMD_SET_INPUT_DEVICE);
+}
+
status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
{
Mutex::Autolock _l(mLock);
@@ -2288,12 +2301,21 @@
return mEffects.size();
}
-// setDevice_l() must be called with ThreadBase::mLock held
-void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
+// setDevices_l() must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setDevices_l(const AudioDeviceTypeAddrVector &devices)
{
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
- mEffects[i]->setDevice(device);
+ mEffects[i]->setDevices(devices);
+ }
+}
+
+// setInputDevice_l() must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setInputDevice_l(const AudioDeviceTypeAddr &device)
+{
+ size_t size = mEffects.size();
+ for (size_t i = 0; i < size; i++) {
+ mEffects[i]->setInputDevice(device);
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 220874d..dbf63c8 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -109,7 +109,8 @@
const effect_descriptor_t& desc() const { return mDescriptor; }
wp<EffectChain>& chain() { return mChain; }
- status_t setDevice(audio_devices_t device);
+ status_t setDevices(const AudioDeviceTypeAddrVector &devices);
+ status_t setInputDevice(const AudioDeviceTypeAddr &device);
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(audio_mode_t mode);
status_t setAudioSource(audio_source_t source);
@@ -158,6 +159,7 @@
status_t start_l();
status_t stop_l();
status_t remove_effect_from_hal_l();
+ status_t sendSetAudioDevicesCommand(const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode);
mutable Mutex mLock; // mutex for process, commands and handles list protection
wp<ThreadBase> mThread; // parent thread
@@ -350,7 +352,8 @@
// FIXME use float to improve the dynamic range
bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false);
void resetVolume_l();
- void setDevice_l(audio_devices_t device);
+ void setDevices_l(const AudioDeviceTypeAddrVector &devices);
+ void setInputDevice_l(const AudioDeviceTypeAddr &device);
void setMode_l(audio_mode_t mode);
void setAudioSource_l(audio_source_t source);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index bd031ea..4be21b1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1378,8 +1378,8 @@
effectCreated = true;
// FIXME: use vector of device and address when effect interface is ready.
- effect->setDevice(deviceTypesToBitMask(outDeviceTypes()));
- effect->setDevice(inDeviceType());
+ effect->setDevices(outDeviceTypeAddrs());
+ effect->setInputDevice(inDeviceTypeAddr());
effect->setMode(mAudioFlinger->getMode());
effect->setAudioSource(mAudioSource);
}
@@ -1495,8 +1495,8 @@
return status;
}
- effect->setDevice(deviceTypesToBitMask(outDeviceTypes()));
- effect->setDevice(inDeviceType());
+ effect->setDevices(outDeviceTypeAddrs());
+ effect->setInputDevice(inDeviceTypeAddr());
effect->setMode(mAudioFlinger->getMode());
effect->setAudioSource(mAudioSource);
@@ -4070,7 +4070,7 @@
#endif
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(type);
+ mEffectChains[i]->setDevices_l(deviceTypeAddrs);
}
// mPatch.num_sinks is not set when the thread is created so that
@@ -8321,7 +8321,7 @@
mInDeviceTypeAddr.mAddress = patch->sources[0].ext.device.address;
audio_port_handle_t deviceId = patch->sources[0].id;
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(mInDeviceTypeAddr.mType);
+ mEffectChains[i]->setInputDevice_l(inDeviceTypeAddr());
}
checkBtNrec_l();
@@ -8391,7 +8391,7 @@
mOutDevices = outDevices;
mOutDeviceTypeAddrs = deviceTypeAddrsFromDescriptors(mOutDevices);
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(deviceTypesToBitMask(outDeviceTypes()));
+ mEffectChains[i]->setDevices_l(outDeviceTypeAddrs());
}
}
@@ -8922,7 +8922,11 @@
}
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(type);
+ if (isOutput()) {
+ mEffectChains[i]->setDevices_l(sinkDeviceTypeAddrs);
+ } else {
+ mEffectChains[i]->setInputDevice_l(sourceDeviceTypeAddr);
+ }
}
if (!isOutput()) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index a70b7ae..ef7eb6e 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -321,6 +321,13 @@
return isOutput() ? outDeviceTypes() : DeviceTypeSet({inDeviceType()});
}
+ const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const {
+ return mOutDeviceTypeAddrs;
+ }
+ const AudioDeviceTypeAddr& inDeviceTypeAddr() const {
+ return mInDeviceTypeAddr;
+ }
+
virtual bool isOutput() const = 0;
virtual sp<StreamHalInterface> stream() const = 0;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index bd73cde..92d8c83 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -69,6 +69,14 @@
API_INPUT_TELEPHONY_RX, // used for capture from telephony RX path
} input_type_t;
+ typedef enum {
+ API_OUTPUT_INVALID = -1,
+ API_OUTPUT_LEGACY = 0,// e.g. audio playing to speaker
+ API_OUT_MIX_PLAYBACK, // used for "remote submix" playback of audio from remote source
+ // to local capture
+ API_OUTPUT_TELEPHONY_TX, // used for playback to telephony TX path
+ } output_type_t;
+
public:
virtual ~AudioPolicyInterface() {}
//
@@ -115,7 +123,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs) = 0;
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType) = 0;
// indicates to the audio policy manager that the output starts being used by corresponding stream.
virtual status_t startOutput(audio_port_handle_t portId) = 0;
// indicates to the audio policy manager that the output stops being used by corresponding stream.
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3ea69f1..355e4f0 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -945,7 +945,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
bool *isRequestedDeviceForExclusiveUse,
- std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs)
+ std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs,
+ output_type_t *outputType)
{
DeviceVector outputDevices;
const audio_port_handle_t requestedPortId = *selectedDeviceId;
@@ -953,6 +954,7 @@
const sp<DeviceDescriptor> requestedDevice =
mAvailableOutputDevices.getDeviceFromId(requestedPortId);
+ *outputType = API_OUTPUT_INVALID;
status_t status = getAudioAttributes(resultAttr, attr, *stream);
if (status != NO_ERROR) {
return status;
@@ -991,7 +993,13 @@
mix->mDeviceAddress,
AUDIO_FORMAT_DEFAULT);
*selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
+
ALOGV("getOutputForAttr() returns output %d", *output);
+ if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
+ *outputType = API_OUT_MIX_PLAYBACK;
+ } else {
+ *outputType = API_OUTPUT_LEGACY;
+ }
return NO_ERROR;
}
// Virtual sources must always be dynamicaly or explicitly routed
@@ -1048,6 +1056,12 @@
*selectedDeviceId = getFirstDeviceId(outputDevices);
+ if (outputDevices.onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
+ *outputType = API_OUTPUT_TELEPHONY_TX;
+ } else {
+ *outputType = API_OUTPUT_LEGACY;
+ }
+
ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
return NO_ERROR;
@@ -1062,7 +1076,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs)
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType)
{
// The supplied portId must be AUDIO_PORT_HANDLE_NONE
if (*portId != AUDIO_PORT_HANDLE_NONE) {
@@ -1082,7 +1097,7 @@
status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse,
- &secondaryOutputDescs);
+ &secondaryOutputDescs, outputType);
if (status != NO_ERROR) {
return status;
}
@@ -3909,10 +3924,11 @@
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
bool isRequestedDeviceForExclusiveUse = false;
std::vector<sp<SwAudioOutputDescriptor>> secondaryOutputs;
+ output_type_t outputType;
getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
&attributes, &stream, sourceDesc->uid(), &config, &flags,
&selectedDeviceId, &isRequestedDeviceForExclusiveUse,
- &secondaryOutputs);
+ &secondaryOutputs, &outputType);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %s",
__FUNCTION__, dumpDeviceTypes(sinkDevices.types()).c_str());
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 500b636..322c188 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -121,7 +121,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
- std::vector<audio_io_handle_t> *secondaryOutputs) override;
+ std::vector<audio_io_handle_t> *secondaryOutputs,
+ output_type_t *outputType) override;
virtual status_t startOutput(audio_port_handle_t portId);
virtual status_t stopOutput(audio_port_handle_t portId);
virtual void releaseOutput(audio_port_handle_t portId);
@@ -809,7 +810,8 @@
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
bool *isRequestedDeviceForExclusiveUse,
- std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs);
+ std::vector<sp<SwAudioOutputDescriptor>> *secondaryDescs,
+ output_type_t *outputType);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevices(
const DeviceVector &devices,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 10355bf..feb930e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -181,13 +181,13 @@
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
- ALOGV("getOutputForAttr()");
+ ALOGV("%s()", __func__);
Mutex::Autolock _l(mLock);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
- "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
+ "%s uid %d tried to pass itself off as %d", __func__, callingUid, uid);
uid = callingUid;
}
if (!mPackageManager.allowPlaybackCapture(uid)) {
@@ -197,27 +197,39 @@
&& !bypassInterruptionPolicyAllowed(pid, uid)) {
attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
}
- audio_output_flags_t originalFlags = flags;
AutoCallerClear acc;
+ AudioPolicyInterface::output_type_t outputType;
status_t result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
config,
&flags, selectedDeviceId, portId,
- secondaryOutputs);
+ secondaryOutputs,
+ &outputType);
// FIXME: Introduce a way to check for the the telephony device before opening the output
- if ((result == NO_ERROR) &&
- (flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) &&
- !modifyPhoneStateAllowed(pid, uid)) {
- // If the app tries to play music through the telephony device and doesn't have permission
- // the fallback to the default output device.
- mAudioPolicyManager->releaseOutput(*portId);
- flags = originalFlags;
- *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- *portId = AUDIO_PORT_HANDLE_NONE;
- secondaryOutputs->clear();
- result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, config,
- &flags, selectedDeviceId, portId,
- secondaryOutputs);
+ if (result == NO_ERROR) {
+ // enforce permission (if any) required for each type of input
+ switch (outputType) {
+ case AudioPolicyInterface::API_OUTPUT_LEGACY:
+ break;
+ case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
+ if (!modifyPhoneStateAllowed(pid, uid)) {
+ ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
+ __func__, uid);
+ result = PERMISSION_DENIED;
+ }
+ break;
+ case AudioPolicyInterface::API_OUT_MIX_PLAYBACK:
+ if (!modifyAudioRoutingAllowed(pid, uid)) {
+ ALOGE("%s() permission denied: modify audio routing not allowed for uid %d",
+ __func__, uid);
+ result = PERMISSION_DENIED;
+ }
+ break;
+ case AudioPolicyInterface::API_OUTPUT_INVALID:
+ default:
+ LOG_ALWAYS_FATAL("%s() encountered an invalid output type %d",
+ __func__, (int)outputType);
+ }
}
if (result == NO_ERROR) {
@@ -434,7 +446,7 @@
}
break;
case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
- if (!modifyAudioRoutingAllowed()) {
+ if (!modifyAudioRoutingAllowed(pid, uid)) {
ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
status = PERMISSION_DENIED;
}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 1ee1eea..e4a19ea 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -179,9 +179,10 @@
audio_port_handle_t localPortId;
if (!portId) portId = &localPortId;
*portId = AUDIO_PORT_HANDLE_NONE;
+ AudioPolicyInterface::output_type_t outputType;
ASSERT_EQ(OK, mManager->getOutputForAttr(
&attr, output, AUDIO_SESSION_NONE, &stream, 0 /*uid*/, &config, &flags,
- selectedDeviceId, portId, {}));
+ selectedDeviceId, portId, {}, &outputType));
ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
ASSERT_NE(AUDIO_IO_HANDLE_NONE, *output);
}
diff --git a/services/mediadrm/MediaDrmService.cpp b/services/mediadrm/MediaDrmService.cpp
index 5afd079..4715bc2 100644
--- a/services/mediadrm/MediaDrmService.cpp
+++ b/services/mediadrm/MediaDrmService.cpp
@@ -34,10 +34,6 @@
String16("media.drm"), new MediaDrmService());
}
-sp<ICrypto> MediaDrmService::makeCrypto() {
- return new CryptoHal;
-}
-
sp<IDrm> MediaDrmService::makeDrm() {
return new DrmHal;
}
diff --git a/services/mediadrm/MediaDrmService.h b/services/mediadrm/MediaDrmService.h
index 3607201..87bdb53 100644
--- a/services/mediadrm/MediaDrmService.h
+++ b/services/mediadrm/MediaDrmService.h
@@ -34,7 +34,6 @@
static void instantiate();
// IMediaDrmService interface
- virtual sp<ICrypto> makeCrypto();
virtual sp<IDrm> makeDrm();
private:
MediaDrmService() {}