Merge "Turn off overflow protection for various math functions"
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 3420617..814a643 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -41,6 +41,14 @@
struct DescribeColorFormat2Params;
struct DataConverter;
+// Treble shared memory
+namespace hidl { namespace memory { namespace V1_0 {
+struct IAllocator;
+struct IMemory;
+}}};
+typedef hidl::memory::V1_0::IAllocator TAllocator;
+typedef hidl::memory::V1_0::IMemory TMemory;
+
struct ACodec : public AHierarchicalStateMachine, public CodecBase {
ACodec();
@@ -86,6 +94,12 @@
static status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]);
+ // Read the flag from "media.use_treble_omx", save it locally, and return
+ // it.
+ bool updateTrebleFlag();
+ // Return the saved flag.
+ bool getTrebleFlag() const;
+
protected:
virtual ~ACodec();
@@ -218,6 +232,8 @@
sp<IOMX> mOMX;
sp<IOMXNode> mOMXNode;
int32_t mNodeGeneration;
+ bool mTrebleFlag;
+ sp<TAllocator> mAllocator[2];
sp<MemoryDealer> mDealer[2];
bool mUsingNativeWindow;
diff --git a/include/media/stagefright/OMXClient.h b/include/media/stagefright/OMXClient.h
index 6973405..6b86cbf 100644
--- a/include/media/stagefright/OMXClient.h
+++ b/include/media/stagefright/OMXClient.h
@@ -27,6 +27,7 @@
OMXClient();
status_t connect();
+ status_t connectTreble();
void disconnect();
sp<IOMX> interface() {
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
index c8995c9..71d2908 100644
--- a/media/libmedia/OMXBuffer.cpp
+++ b/media/libmedia/OMXBuffer.cpp
@@ -166,7 +166,7 @@
mMem = std::move(source.mMem);
mGraphicBuffer = std::move(source.mGraphicBuffer);
mNativeHandle = std::move(source.mNativeHandle);
- mHidlMemory = source.mHidlMemory; // TODO(b/34093434): Use move when available
+ mHidlMemory = std::move(source.mHidlMemory);
return *this;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 3199495..2d4c475 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1318,16 +1318,33 @@
}
sp<IMediaPlayerClient> c;
+ sp<Client> nextClient;
+ status_t errStartNext = NO_ERROR;
{
Mutex::Autolock l(client->mLock);
c = client->mClient;
if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
+ nextClient = client->mNextClient;
+
if (client->mAudioOutput != NULL)
client->mAudioOutput->switchToNextOutput();
- client->mNextClient->start();
- if (client->mNextClient->mClient != NULL) {
- client->mNextClient->mClient->notify(
- MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+
+ errStartNext = nextClient->start();
+ }
+ }
+
+ if (nextClient != NULL) {
+ sp<IMediaPlayerClient> nc;
+ {
+ Mutex::Autolock l(nextClient->mLock);
+ nc = nextClient->mClient;
+ }
+ if (nc != NULL) {
+ if (errStartNext == NO_ERROR) {
+ nc->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+ } else {
+ nc->notify(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN , 0, obj);
+ ALOGE("gapless:start playback for next track failed, err(%d)", errStartNext);
}
}
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c63ab47..3235e81 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -46,6 +46,8 @@
#include <media/hardware/HardwareAPI.h>
#include <media/OMXBuffer.h>
+#include <hidlmemory/mapping.h>
+
#include <OMX_AudioExt.h>
#include <OMX_VideoExt.h>
#include <OMX_Component.h>
@@ -59,6 +61,10 @@
#include "include/SharedMemoryBuffer.h"
#include "omx/OMXUtils.h"
+#include <android/hidl/memory/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include "omx/hal/1.0/utils/WOmxNode.h"
+
namespace android {
using binder::Status;
@@ -282,7 +288,9 @@
////////////////////////////////////////////////////////////////////////////////
-struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
+struct ACodec::DeathNotifier :
+ public IBinder::DeathRecipient,
+ public ::android::hardware::hidl_death_recipient {
explicit DeathNotifier(const sp<AMessage> ¬ify)
: mNotify(notify) {
}
@@ -291,6 +299,12 @@
mNotify->post();
}
+ virtual void serviceDied(
+ uint64_t /* cookie */,
+ const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+ mNotify->post();
+ }
+
protected:
virtual ~DeathNotifier() {}
@@ -560,6 +574,8 @@
memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
changeState(mUninitializedState);
+
+ updateTrebleFlag();
}
ACodec::~ACodec() {
@@ -811,7 +827,11 @@
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
- CHECK(mDealer[portIndex] == NULL);
+ if (getTrebleFlag()) {
+ CHECK(mAllocator[portIndex] == NULL);
+ } else {
+ CHECK(mDealer[portIndex] == NULL);
+ }
CHECK(mBuffers[portIndex].isEmpty());
status_t err;
@@ -874,14 +894,26 @@
return NO_MEMORY;
}
- size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
if (mode != IOMX::kPortModePresetSecureBuffer) {
- mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+ if (getTrebleFlag()) {
+ mAllocator[portIndex] = TAllocator::getService("ashmem");
+ if (mAllocator[portIndex] == nullptr) {
+ ALOGE("hidl allocator on port %d is null",
+ (int)portIndex);
+ return NO_MEMORY;
+ }
+ } else {
+ size_t totalSize = def.nBufferCountActual *
+ (alignedSize + alignedConvSize);
+ mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+ }
}
const sp<AMessage> &format =
portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
+ hidl_memory hidlMemToken;
+ sp<TMemory> hidlMem;
sp<IMemory> mem;
BufferInfo info;
@@ -903,30 +935,86 @@
: new SecureBuffer(format, native_handle, bufSize);
info.mCodecData = info.mData;
} else {
- mem = mDealer[portIndex]->allocate(bufSize);
- if (mem == NULL || mem->pointer() == NULL) {
- return NO_MEMORY;
- }
+ if (getTrebleFlag()) {
+ bool success;
+ auto transStatus = mAllocator[portIndex]->allocate(
+ bufSize,
+ [&success, &hidlMemToken](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ hidlMemToken = m;
+ });
- err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID);
+ if (!transStatus.isOk()) {
+ ALOGE("hidl's AshmemAllocator failed at the "
+ "transport: %s",
+ transStatus.description().c_str());
+ return NO_MEMORY;
+ }
+ if (!success) {
+ return NO_MEMORY;
+ }
+ hidlMem = mapMemory(hidlMemToken);
+
+ err = mOMXNode->useBuffer(
+ portIndex, hidlMemToken, &info.mBufferID);
+ } else {
+ mem = mDealer[portIndex]->allocate(bufSize);
+ if (mem == NULL || mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
+
+ err = mOMXNode->useBuffer(
+ portIndex, mem, &info.mBufferID);
+ }
if (mode == IOMX::kPortModeDynamicANWBuffer) {
- ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
+ VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
+ getTrebleFlag() ?
+ (void*)hidlMem->getPointer() : mem->pointer());
+ metaData->nFenceFd = -1;
}
- info.mCodecData = new SharedMemoryBuffer(format, mem);
- info.mCodecRef = mem;
+ if (getTrebleFlag()) {
+ info.mCodecData = new SharedMemoryBuffer(
+ format, hidlMem);
+ info.mCodecRef = hidlMem;
+ } else {
+ info.mCodecData = new SharedMemoryBuffer(
+ format, mem);
+ info.mCodecRef = mem;
+ }
// if we require conversion, allocate conversion buffer for client use;
// otherwise, reuse codec buffer
if (mConverter[portIndex] != NULL) {
CHECK_GT(conversionBufferSize, (size_t)0);
- mem = mDealer[portIndex]->allocate(conversionBufferSize);
- if (mem == NULL|| mem->pointer() == NULL) {
- return NO_MEMORY;
+ if (getTrebleFlag()) {
+ bool success;
+ mAllocator[portIndex]->allocate(
+ conversionBufferSize,
+ [&success, &hidlMemToken](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ hidlMemToken = m;
+ });
+ if (!success) {
+ return NO_MEMORY;
+ }
+ hidlMem = mapMemory(hidlMemToken);
+ info.mData = new SharedMemoryBuffer(format, hidlMem);
+ info.mMemRef = hidlMem;
+ } else {
+ mem = mDealer[portIndex]->allocate(
+ conversionBufferSize);
+ if (mem == NULL|| mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
+ info.mData = new SharedMemoryBuffer(format, mem);
+ info.mMemRef = mem;
}
- info.mData = new SharedMemoryBuffer(format, mem);
- info.mMemRef = mem;
} else {
info.mData = info.mCodecData;
info.mMemRef = info.mCodecRef;
@@ -1458,8 +1546,11 @@
}
}
- // clear mDealer even on an error
- mDealer[portIndex].clear();
+ if (getTrebleFlag()) {
+ mAllocator[portIndex].clear();
+ } else {
+ mDealer[portIndex].clear();
+ }
return err;
}
@@ -6041,8 +6132,16 @@
if (mDeathNotifier != NULL) {
if (mCodec->mOMXNode != NULL) {
- sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
- binder->unlinkToDeath(mDeathNotifier);
+ if (mCodec->getTrebleFlag()) {
+ auto tOmxNode =
+ (static_cast<
+ ::android::hardware::media::omx::V1_0::utils::
+ LWOmxNode*>(mCodec->mOMXNode.get()))->mBase;
+ tOmxNode->unlinkToDeath(mDeathNotifier);
+ } else {
+ sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
+ binder->unlinkToDeath(mDeathNotifier);
+ }
}
mDeathNotifier.clear();
}
@@ -6130,7 +6229,8 @@
CHECK(mCodec->mOMXNode == NULL);
OMXClient client;
- if (client.connect() != OK) {
+ if ((mCodec->updateTrebleFlag() ?
+ client.connectTreble() : client.connect()) != OK) {
mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
return false;
}
@@ -6202,10 +6302,18 @@
}
mDeathNotifier = new DeathNotifier(notify);
- if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
- // This was a local binder, if it dies so do we, we won't care
- // about any notifications in the afterlife.
- mDeathNotifier.clear();
+ if (mCodec->getTrebleFlag()) {
+ auto tOmxNode = (static_cast<::android::hardware::media::omx::V1_0::
+ utils::LWOmxNode*>(omxNode.get()))->mBase;
+ if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+ mDeathNotifier.clear();
+ }
+ } else {
+ if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
+ // This was a local binder, if it dies so do we, we won't care
+ // about any notifications in the afterlife.
+ mDeathNotifier.clear();
+ }
}
notify = new AMessage(kWhatOMXMessageList, mCodec);
@@ -7181,7 +7289,11 @@
mCodec->mBuffers[kPortIndexOutput].size());
err = FAILED_TRANSACTION;
} else {
- mCodec->mDealer[kPortIndexOutput].clear();
+ if (mCodec->getTrebleFlag()) {
+ mCodec->mAllocator[kPortIndexOutput].clear();
+ } else {
+ mCodec->mDealer[kPortIndexOutput].clear();
+ }
}
if (err == OK) {
@@ -7564,7 +7676,8 @@
}
OMXClient client;
- status_t err = client.connect();
+ status_t err = getTrebleFlag() ?
+ client.connectTreble() : client.connect();
if (err != OK) {
return err;
}
@@ -7780,4 +7893,15 @@
return OK;
}
+bool ACodec::updateTrebleFlag() {
+ mTrebleFlag = bool(property_get_bool("debug.treble_omx", 0));
+ ALOGV("updateTrebleFlag() returns %s",
+ mTrebleFlag ? "true" : "false");
+ return mTrebleFlag;
+}
+
+bool ACodec::getTrebleFlag() const {
+ return mTrebleFlag;
+}
+
} // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index c2407f7..410dbc9 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -113,7 +113,11 @@
libstagefright_foundation \
libdl \
libRScpp \
- libhidlbase \
+ libhidlbase \
+ libhidlmemory \
+ android.hidl.memory@1.0 \
+ android.hardware.media.omx@1.0 \
+ android.hardware.media.omx@1.0-utils \
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libmedia
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index 40eb942..fee3739 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -34,6 +34,11 @@
mMemory(mem) {
}
+SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem)
+ : MediaCodecBuffer(format, new ABuffer(mem->getPointer(), mem->getSize())),
+ mTMemory(mem) {
+}
+
SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size)
: MediaCodecBuffer(format, new ABuffer(nullptr, size)),
mPointer(ptr) {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index a29aff0..b4e694c 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -29,6 +29,8 @@
#include "include/OMX.h"
+#include "omx/hal/1.0/utils/WOmx.h"
+
namespace android {
OMXClient::OMXClient() {
@@ -53,6 +55,21 @@
return OK;
}
+status_t OMXClient::connectTreble() {
+ using namespace ::android::hardware::media::omx::V1_0;
+ sp<IOmx> tOmx = IOmx::getService("default");
+ if (tOmx.get() == nullptr) {
+ ALOGE("Cannot obtain Treble IOmx.");
+ return NO_INIT;
+ }
+ if (!tOmx->isRemote()) {
+ ALOGE("Treble IOmx is in passthrough mode.");
+ return NO_INIT;
+ }
+ mOMX = new utils::LWOmx(tOmx);
+ return OK;
+}
+
void OMXClient::disconnect() {
mOMX.clear();
}
diff --git a/media/libstagefright/filters/Android.mk b/media/libstagefright/filters/Android.mk
index f8e8352..830d2aa 100644
--- a/media/libstagefright/filters/Android.mk
+++ b/media/libstagefright/filters/Android.mk
@@ -22,7 +22,9 @@
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-LOCAL_SHARED_LIBRARIES := libmedia
+LOCAL_SHARED_LIBRARIES := \
+ libmedia \
+ libhidlmemory \
LOCAL_MODULE:= libstagefright_mediafilter
diff --git a/media/libstagefright/include/SharedMemoryBuffer.h b/media/libstagefright/include/SharedMemoryBuffer.h
index 1d7f7a6..92df68a 100644
--- a/media/libstagefright/include/SharedMemoryBuffer.h
+++ b/media/libstagefright/include/SharedMemoryBuffer.h
@@ -19,6 +19,7 @@
#define SHARED_MEMORY_BUFFER_H_
#include <media/MediaCodecBuffer.h>
+#include <android/hidl/memory/1.0/IMemory.h>
namespace android {
@@ -30,7 +31,9 @@
*/
class SharedMemoryBuffer : public MediaCodecBuffer {
public:
+ typedef ::android::hidl::memory::V1_0::IMemory TMemory;
SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMemory> &mem);
+ SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem);
virtual ~SharedMemoryBuffer() = default;
@@ -38,6 +41,7 @@
SharedMemoryBuffer() = delete;
const sp<IMemory> mMemory;
+ const sp<TMemory> mTMemory;
};
} // namespace android
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 03aaa71..39ed759 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -1133,7 +1133,7 @@
buffer_meta = new BufferMeta(
params, hParams, portIndex, false /* copy */, data);
} else {
- data = static_cast<OMX_U8 *>(params->pointer());
+ data = static_cast<OMX_U8 *>(paramsPointer);
buffer_meta = new BufferMeta(
params, hParams, portIndex, false /* copy */, NULL);
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 9cfb4f2..d27a496 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -298,6 +298,7 @@
switch (l.type) {
case omx_message::EVENT:
t->type = Message::Type::EVENT;
+ t->data.eventData.event = uint32_t(l.u.event_data.event);
t->data.eventData.data1 = l.u.event_data.data1;
t->data.eventData.data2 = l.u.event_data.data2;
t->data.eventData.data3 = l.u.event_data.data3;
@@ -343,6 +344,7 @@
switch (t.type) {
case Message::Type::EVENT:
l->type = omx_message::EVENT;
+ l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
l->u.event_data.data1 = t.data.eventData.data1;
l->u.event_data.data2 = t.data.eventData.data2;
l->u.event_data.data3 = t.data.eventData.data3;
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
index df3ef78..6b21138 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
@@ -196,6 +196,7 @@
}
status_t status = toStatusT(mBase->fillBuffer(
buffer, codecBuffer, fenceNh));
+ native_handle_close(fenceNh);
native_handle_delete(fenceNh);
return status;
}
@@ -217,6 +218,7 @@
flags,
toRawTicks(timestamp),
fenceNh));
+ native_handle_close(fenceNh);
native_handle_delete(fenceNh);
return status;
}
@@ -240,6 +242,7 @@
return NO_MEMORY;
}
status_t status = toStatusT(mBase->dispatchMessage(tMsg));
+ native_handle_close(nh);
native_handle_delete(nh);
return status;
}
@@ -392,7 +395,7 @@
return toStatus(mBase->fillBuffer(
buffer,
omxBuffer,
- native_handle_read_fd(fence)));
+ dup(native_handle_read_fd(fence))));
}
Return<Status> TWOmxNode::emptyBuffer(
@@ -407,7 +410,7 @@
omxBuffer,
flags,
toOMXTicks(timestampUs),
- native_handle_read_fd(fence)));
+ dup(native_handle_read_fd(fence))));
}
Return<void> TWOmxNode::getExtensionIndex(
@@ -422,7 +425,7 @@
Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
omx_message lMsg;
- if (!wrapAs(&lMsg, tMsg)) {
+ if (!convertTo(&lMsg, tMsg)) {
return Status::BAD_VALUE;
}
return toStatus(mBase->dispatchMessage(lMsg));
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
index 87e7961..d5549fb 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
@@ -45,6 +45,7 @@
}
mBase->onMessages(tMessages);
for (auto& handle : handles) {
+ native_handle_close(handle);
native_handle_delete(handle);
}
}
@@ -61,7 +62,7 @@
std::list<omx_message> lMessages;
for (size_t i = 0; i < tMessages.size(); ++i) {
lMessages.push_back(omx_message{});
- wrapAs(&lMessages.back(), tMessages[i]);
+ convertTo(&lMessages.back(), tMessages[i]);
}
mBase->onMessages(lMessages);
return Return<void>();
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
index 6a99d8c..6f4d864 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -298,6 +298,7 @@
switch (l.type) {
case omx_message::EVENT:
t->type = Message::Type::EVENT;
+ t->data.eventData.event = uint32_t(l.u.event_data.event);
t->data.eventData.data1 = l.u.event_data.data1;
t->data.eventData.data2 = l.u.event_data.data2;
t->data.eventData.data3 = l.u.event_data.data3;
@@ -343,6 +344,7 @@
switch (t.type) {
case Message::Type::EVENT:
l->type = omx_message::EVENT;
+ l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
l->u.event_data.data1 = t.data.eventData.data1;
l->u.event_data.data2 = t.data.eventData.data2;
l->u.event_data.data3 = t.data.eventData.data3;
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
index dc04b67..6764ba8 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
@@ -196,6 +196,7 @@
}
status_t status = toStatusT(mBase->fillBuffer(
buffer, codecBuffer, fenceNh));
+ native_handle_close(fenceNh);
native_handle_delete(fenceNh);
return status;
}
@@ -217,6 +218,7 @@
flags,
toRawTicks(timestamp),
fenceNh));
+ native_handle_close(fenceNh);
native_handle_delete(fenceNh);
return status;
}
@@ -240,6 +242,7 @@
return NO_MEMORY;
}
status_t status = toStatusT(mBase->dispatchMessage(tMsg));
+ native_handle_close(nh);
native_handle_delete(nh);
return status;
}
@@ -392,7 +395,7 @@
return toStatus(mBase->fillBuffer(
buffer,
omxBuffer,
- native_handle_read_fd(fence)));
+ dup(native_handle_read_fd(fence))));
}
Return<Status> TWOmxNode::emptyBuffer(
@@ -407,7 +410,7 @@
omxBuffer,
flags,
toOMXTicks(timestampUs),
- native_handle_read_fd(fence)));
+ dup(native_handle_read_fd(fence))));
}
Return<void> TWOmxNode::getExtensionIndex(
@@ -422,7 +425,7 @@
Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
omx_message lMsg;
- if (!wrapAs(&lMsg, tMsg)) {
+ if (!convertTo(&lMsg, tMsg)) {
return Status::BAD_VALUE;
}
return toStatus(mBase->dispatchMessage(lMsg));
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
index 4773572..fea5a9a 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
@@ -45,6 +45,7 @@
}
mBase->onMessages(tMessages);
for (auto& handle : handles) {
+ native_handle_close(handle);
native_handle_delete(handle);
}
}
@@ -61,7 +62,7 @@
std::list<omx_message> lMessages;
for (size_t i = 0; i < tMessages.size(); ++i) {
lMessages.push_back(omx_message{});
- wrapAs(&lMessages.back(), tMessages[i]);
+ convertTo(&lMessages.back(), tMessages[i]);
}
mBase->onMessages(lMessages);
return Return<void>();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a248912..1b39e22 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1878,7 +1878,7 @@
config->channel_mask,
flags);
- if (*devices == AUDIO_DEVICE_NONE) {
+ if (devices == NULL || *devices == AUDIO_DEVICE_NONE) {
return BAD_VALUE;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index eb61ec4..54c406c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1932,7 +1932,7 @@
ALOG_ASSERT(inputDesc != 0);
sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
- if (index < 0) {
+ if (audioSession == 0) {
ALOGW("releaseInput() unknown session %d on input %d", session, input);
return;
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index f708654..f429df8 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -684,7 +684,6 @@
int CameraService::getDeviceVersion(const String8& cameraId, int* facing) {
ATRACE_CALL();
- struct camera_info info;
int deviceVersion = 0;
@@ -692,6 +691,7 @@
int id = cameraIdToInt(cameraId);
if (id < 0) return -1;
+ struct camera_info info;
if (mModule->getCameraInfo(id, &info) != OK) {
return -1;
}
@@ -710,8 +710,15 @@
hardware::hidl_version maxVersion{0,0};
res = mCameraProviderManager->getHighestSupportedVersion(String8::std_string(cameraId),
&maxVersion);
- if (res == NAME_NOT_FOUND) return -1;
+ if (res != OK) return -1;
deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
+
+ hardware::CameraInfo info;
+ if (facing) {
+ res = mCameraProviderManager->getCameraInfo(String8::std_string(cameraId), &info);
+ if (res != OK) return -1;
+ *facing = info.facing;
+ }
}
return deviceVersion;
}
@@ -1532,17 +1539,14 @@
// give flashlight a chance to close devices if necessary.
mFlashlight->prepareDeviceOpen(cameraId);
- // TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDs
- int id = cameraIdToInt(cameraId);
- if (id == -1) {
- ALOGE("%s: Invalid camera ID %s, cannot get device version from HAL.", __FUNCTION__,
- cameraId.string());
- return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Bad camera ID \"%s\" passed to camera open", cameraId.string());
- }
-
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
+ if (facing == -1) {
+ ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.string());
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
+ "Unable to get camera device \"%s\" facing", cameraId.string());
+ }
+
sp<BasicClient> tmp = nullptr;
if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
@@ -1880,9 +1884,13 @@
}
int facing = -1;
-
- int deviceVersion = getDeviceVersion(id, &facing);
-
+ int deviceVersion = getDeviceVersion(id, /*out*/ &facing);
+ if (facing == -1) {
+ String8 msg = String8::format("Unable to get facing for camera device %s",
+ id.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
+ }
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
case CAMERA_DEVICE_API_VERSION_3_0:
@@ -2188,8 +2196,11 @@
const std::set<userid_t>& newUserIds) {
String8 newUsers = toString(newUserIds);
String8 oldUsers = toString(oldUserIds);
+ if (oldUsers.size() == 0) {
+ oldUsers = "<None>";
+ }
// Log the new and old users
- logEvent(String8::format("USER_SWITCH previous allowed users: %s , current allowed users: %s",
+ logEvent(String8::format("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
oldUsers.string(), newUsers.string()));
}
@@ -2735,181 +2746,162 @@
status_t CameraService::dump(int fd, const Vector<String16>& args) {
ATRACE_CALL();
- String8 result("Dump of the Camera Service:\n");
if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
- result = result.format("Permission Denial: "
- "can't dump CameraService from pid=%d, uid=%d\n",
+ dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
getCallingPid(),
getCallingUid());
- write(fd, result.string(), result.size());
- } else {
- bool locked = tryLock(mServiceLock);
- // failed to lock - CameraService is probably deadlocked
- if (!locked) {
- result.append("CameraService may be deadlocked\n");
- write(fd, result.string(), result.size());
- }
+ return NO_ERROR;
+ }
+ bool locked = tryLock(mServiceLock);
+ // failed to lock - CameraService is probably deadlocked
+ if (!locked) {
+ dprintf(fd, "!! CameraService may be deadlocked !!\n");
+ }
- bool hasClient = false;
- if (!mInitialized) {
- result = String8::format("No camera HAL available!\n");
- write(fd, result.string(), result.size());
+ if (!mInitialized) {
+ dprintf(fd, "!! No camera HAL available !!\n");
- // Dump event log for error information
- dumpEventLog(fd);
-
- if (locked) mServiceLock.unlock();
- return NO_ERROR;
- }
- if (mModule == nullptr) {
- mCameraProviderManager->dump(fd, args);
- // TODO - need way more dumping here
-
- if (locked) mServiceLock.unlock();
- return NO_ERROR;
- }
-
- result = String8::format("Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
- result.appendFormat("Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
- result.appendFormat("Camera module name: %s\n", mModule->getModuleName());
- result.appendFormat("Camera module author: %s\n", mModule->getModuleAuthor());
- result.appendFormat("Number of camera devices: %d\n", mNumberOfCameras);
- result.appendFormat("Number of normal camera devices: %d\n", mNumberOfNormalCameras);
- String8 activeClientString = mActiveClientManager.toString();
- result.appendFormat("Active Camera Clients:\n%s", activeClientString.string());
- result.appendFormat("Allowed users:\n%s\n", toString(mAllowedUsers).string());
-
- sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
- if (desc == NULL) {
- result.appendFormat("Vendor tags left unimplemented.\n");
- } else {
- result.appendFormat("Vendor tag definitions:\n");
- }
-
- write(fd, result.string(), result.size());
-
- if (desc != NULL) {
- desc->dump(fd, /*verbosity*/2, /*indentation*/4);
- }
-
+ // Dump event log for error information
dumpEventLog(fd);
- bool stateLocked = tryLock(mCameraStatesLock);
- if (!stateLocked) {
- result = String8::format("CameraStates in use, may be deadlocked\n");
- write(fd, result.string(), result.size());
+ if (locked) mServiceLock.unlock();
+ return NO_ERROR;
+ }
+ dprintf(fd, "\n== Service global info: ==\n\n");
+ dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
+ dprintf(fd, "Number of normal camera devices: %d\n", mNumberOfNormalCameras);
+ String8 activeClientString = mActiveClientManager.toString();
+ dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
+ dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
+
+ dumpEventLog(fd);
+
+ bool stateLocked = tryLock(mCameraStatesLock);
+ if (!stateLocked) {
+ dprintf(fd, "CameraStates in use, may be deadlocked\n");
+ }
+
+ for (auto& state : mCameraStates) {
+ String8 cameraId = state.first;
+
+ dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.string());
+
+ CameraParameters p = state.second->getShimParams();
+ if (!p.isEmpty()) {
+ dprintf(fd, " Camera1 API shim is using parameters:\n ");
+ p.dump(fd, args);
}
- for (auto& state : mCameraStates) {
- String8 cameraId = state.first;
- result = String8::format("Camera %s information:\n", cameraId.string());
- camera_info info;
+ auto clientDescriptor = mActiveClientManager.get(cameraId);
+ if (clientDescriptor == nullptr) {
+ dprintf(fd, " Device %s is closed, no client instance\n",
+ cameraId.string());
+ continue;
+ }
+ dprintf(fd, " Device %s is open. Client instance dump:\n",
+ cameraId.string());
+ dprintf(fd, " Client priority level: %d\n", clientDescriptor->getPriority());
+ dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId());
+ auto client = clientDescriptor->getValue();
+ dprintf(fd, " Client package: %s\n",
+ String8(client->getPackageName()).string());
+
+ client->dumpClient(fd, args);
+
+ if (mModule != nullptr) {
+ dprintf(fd, "== Camera HAL device %s static information: ==\n", cameraId.string());
+
+ camera_info info;
status_t rc = mModule->getCameraInfo(cameraIdToInt(cameraId), &info);
+ int deviceVersion = -1;
if (rc != OK) {
- result.appendFormat(" Error reading static information!\n");
- write(fd, result.string(), result.size());
+ dprintf(fd, " Error reading static information!\n");
} else {
- result.appendFormat(" Facing: %s\n",
+ dprintf(fd, " Facing: %s\n",
info.facing == CAMERA_FACING_BACK ? "BACK" :
- info.facing == CAMERA_FACING_FRONT ? "FRONT" : "EXTERNAL");
- result.appendFormat(" Orientation: %d\n", info.orientation);
- int deviceVersion;
+ info.facing == CAMERA_FACING_FRONT ? "FRONT" : "EXTERNAL");
+ dprintf(fd, " Orientation: %d\n", info.orientation);
+
if (mModule->getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_0) {
deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
} else {
deviceVersion = info.device_version;
}
-
- auto conflicting = state.second->getConflicting();
- result.appendFormat(" Resource Cost: %d\n", state.second->getCost());
- result.appendFormat(" Conflicting Devices:");
- for (auto& id : conflicting) {
- result.appendFormat(" %s", id.string());
- }
- if (conflicting.size() == 0) {
- result.appendFormat(" NONE");
- }
- result.appendFormat("\n");
-
- result.appendFormat(" Device version: %#x\n", deviceVersion);
- if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_0) {
- result.appendFormat(" Device static metadata:\n");
- write(fd, result.string(), result.size());
- dump_indented_camera_metadata(info.static_camera_characteristics,
- fd, /*verbosity*/2, /*indentation*/4);
- } else {
- write(fd, result.string(), result.size());
- }
-
- CameraParameters p = state.second->getShimParams();
- if (!p.isEmpty()) {
- result = String8::format(" Camera1 API shim is using parameters:\n ");
- write(fd, result.string(), result.size());
- p.dump(fd, args);
- }
}
- auto clientDescriptor = mActiveClientManager.get(cameraId);
- if (clientDescriptor == nullptr) {
- result = String8::format(" Device %s is closed, no client instance\n",
- cameraId.string());
- write(fd, result.string(), result.size());
- continue;
+ auto conflicting = state.second->getConflicting();
+ dprintf(fd, " Resource Cost: %d\n", state.second->getCost());
+ dprintf(fd, " Conflicting Devices:");
+ for (auto& id : conflicting) {
+ dprintf(fd, " %s", id.string());
}
- hasClient = true;
- result = String8::format(" Device %s is open. Client instance dump:\n\n",
- cameraId.string());
- result.appendFormat("Client priority level: %d\n", clientDescriptor->getPriority());
- result.appendFormat("Client PID: %d\n", clientDescriptor->getOwnerId());
+ if (conflicting.size() == 0) {
+ dprintf(fd, " NONE");
+ }
+ dprintf(fd, "\n");
- auto client = clientDescriptor->getValue();
- result.appendFormat("Client package: %s\n",
- String8(client->getPackageName()).string());
- write(fd, result.string(), result.size());
-
- client->dumpClient(fd, args);
+ dprintf(fd, " Device version: %#x\n", deviceVersion);
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_0) {
+ dprintf(fd, " Device static metadata:\n");
+ dump_indented_camera_metadata(info.static_camera_characteristics,
+ fd, /*verbosity*/2, /*indentation*/4);
+ }
}
- if (stateLocked) mCameraStatesLock.unlock();
+ }
- if (!hasClient) {
- result = String8::format("\nNo active camera clients yet.\n");
- write(fd, result.string(), result.size());
- }
+ if (stateLocked) mCameraStatesLock.unlock();
- if (locked) mServiceLock.unlock();
+ if (locked) mServiceLock.unlock();
- // Dump camera traces if there were any
- write(fd, "\n", 1);
- camera3::CameraTraces::dump(fd, args);
+ if (mModule == nullptr) {
+ mCameraProviderManager->dump(fd, args);
+ } else {
+ dprintf(fd, "\n== Camera Module HAL static info: ==\n");
+ dprintf(fd, "Camera module HAL API version: 0x%x\n", mModule->getHalApiVersion());
+ dprintf(fd, "Camera module API version: 0x%x\n", mModule->getModuleApiVersion());
+ dprintf(fd, "Camera module name: %s\n", mModule->getModuleName());
+ dprintf(fd, "Camera module author: %s\n", mModule->getModuleAuthor());
+ }
- // Process dump arguments, if any
- int n = args.size();
- String16 verboseOption("-v");
- String16 unreachableOption("--unreachable");
- for (int i = 0; i < n; i++) {
- if (args[i] == verboseOption) {
- // change logging level
- if (i + 1 >= n) continue;
- String8 levelStr(args[i+1]);
- int level = atoi(levelStr.string());
- result = String8::format("\nSetting log level to %d.\n", level);
- setLogLevel(level);
- write(fd, result.string(), result.size());
- } else if (args[i] == unreachableOption) {
- // Dump memory analysis
- // TODO - should limit be an argument parameter?
- UnreachableMemoryInfo info;
- bool success = GetUnreachableMemory(info, /*limit*/ 10000);
- if (!success) {
- dprintf(fd, "\nUnable to dump unreachable memory. "
- "Try disabling SELinux enforcement.\n");
- } else {
- dprintf(fd, "\nDumping unreachable memory:\n");
- std::string s = info.ToString(/*log_contents*/ true);
- write(fd, s.c_str(), s.size());
- }
+ dprintf(fd, "\n== Vendor tags: ==\n\n");
+
+ sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
+ if (desc == NULL) {
+ dprintf(fd, "No vendor tags.\n");
+ } else {
+ desc->dump(fd, /*verbosity*/2, /*indentation*/2);
+ }
+
+ // Dump camera traces if there were any
+ dprintf(fd, "\n");
+ camera3::CameraTraces::dump(fd, args);
+
+ // Process dump arguments, if any
+ int n = args.size();
+ String16 verboseOption("-v");
+ String16 unreachableOption("--unreachable");
+ for (int i = 0; i < n; i++) {
+ if (args[i] == verboseOption) {
+ // change logging level
+ if (i + 1 >= n) continue;
+ String8 levelStr(args[i+1]);
+ int level = atoi(levelStr.string());
+ dprintf(fd, "\nSetting log level to %d.\n", level);
+ setLogLevel(level);
+ } else if (args[i] == unreachableOption) {
+ // Dump memory analysis
+ // TODO - should limit be an argument parameter?
+ UnreachableMemoryInfo info;
+ bool success = GetUnreachableMemory(info, /*limit*/ 10000);
+ if (!success) {
+ dprintf(fd, "\n== Unable to dump unreachable memory. "
+ "Try disabling SELinux enforcement. ==\n");
+ } else {
+ dprintf(fd, "\n== Dumping unreachable memory: ==\n");
+ std::string s = info.ToString(/*log_contents*/ true);
+ write(fd, s.c_str(), s.size());
}
}
}
@@ -2917,21 +2909,19 @@
}
void CameraService::dumpEventLog(int fd) {
- String8 result = String8("\nPrior client events (most recent at top):\n");
+ dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
Mutex::Autolock l(mLogLock);
for (const auto& msg : mEventLog) {
- result.appendFormat(" %s\n", msg.string());
+ dprintf(fd, " %s\n", msg.string());
}
if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
- result.append(" ...\n");
+ dprintf(fd, " ...\n");
} else if (mEventLog.size() == 0) {
- result.append(" [no events yet]\n");
+ dprintf(fd, " [no events yet]\n");
}
- result.append("\n");
-
- write(fd, result.string(), result.size());
+ dprintf(fd, "\n");
}
void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index f6ca903..2618838 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1285,37 +1285,34 @@
}
status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
- String8 result;
- result.appendFormat("CameraDeviceClient[%s] (%p) dump:\n",
+ dprintf(fd, " CameraDeviceClient[%s] (%p) dump:\n",
mCameraIdStr.string(),
(getRemoteCallback() != NULL ?
IInterface::asBinder(getRemoteCallback()).get() : NULL) );
- result.appendFormat(" Current client UID %u\n", mClientUid);
+ dprintf(fd, " Current client UID %u\n", mClientUid);
- result.append(" State:\n");
- result.appendFormat(" Request ID counter: %d\n", mRequestIdCounter);
+ dprintf(fd, " State:\n");
+ dprintf(fd, " Request ID counter: %d\n", mRequestIdCounter);
if (mInputStream.configured) {
- result.appendFormat(" Current input stream ID: %d\n",
- mInputStream.id);
+ dprintf(fd, " Current input stream ID: %d\n", mInputStream.id);
} else {
- result.append(" No input stream configured.\n");
+ dprintf(fd, " No input stream configured.\n");
}
if (!mStreamMap.isEmpty()) {
- result.append(" Current output stream/surface IDs:\n");
+ dprintf(fd, " Current output stream/surface IDs:\n");
for (size_t i = 0; i < mStreamMap.size(); i++) {
- result.appendFormat(" Stream %d Surface %d\n",
+ dprintf(fd, " Stream %d Surface %d\n",
mStreamMap.valueAt(i).streamId(),
mStreamMap.valueAt(i).surfaceId());
}
} else if (!mDeferredStreams.isEmpty()) {
- result.append(" Current deferred surface output stream IDs:\n");
+ dprintf(fd, " Current deferred surface output stream IDs:\n");
for (auto& streamId : mDeferredStreams) {
- result.appendFormat(" Stream %d\n", streamId);
+ dprintf(fd, " Stream %d\n", streamId);
}
} else {
- result.append(" No output streams configured.\n");
+ dprintf(fd, " No output streams configured.\n");
}
- write(fd, result.string(), result.size());
// TODO: print dynamic/request section from most recent requests
mFrameProcessor->dump(fd, args);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index f691dc1..f44fd08 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -47,43 +47,25 @@
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
ServiceInteractionProxy* proxy) {
- int numProviders = 0;
- {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- if (proxy == nullptr) {
- ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
- return BAD_VALUE;
- }
- mListener = listener;
- mServiceProxy = proxy;
-
- // Registering will trigger notifications for all already-known providers
- bool success = mServiceProxy->registerForNotifications(
- /* instance name, empty means no filter */ "",
- this);
- if (!success) {
- ALOGE("%s: Unable to register with hardware service manager for notifications "
- "about camera providers", __FUNCTION__);
- return INVALID_OPERATION;
- }
- numProviders = mProviders.size();
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ if (proxy == nullptr) {
+ ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
+ return BAD_VALUE;
}
+ mListener = listener;
+ mServiceProxy = proxy;
- if (numProviders == 0) {
- // Remote provider might have not been initialized
- // Wait for a bit and see if we get one registered
- std::mutex mtx;
- std::unique_lock<std::mutex> lock(mtx);
- mProviderRegistered.wait_for(lock, std::chrono::seconds(15));
- if (mProviders.size() == 0) {
- ALOGI("%s: Unable to get one registered provider within timeout!",
- __FUNCTION__);
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- // See if there's a passthrough HAL, but let's not complain if there's not
- addProvider(kLegacyProviderName, /*expected*/ false);
- }
+ // Registering will trigger notifications for all already-known providers
+ bool success = mServiceProxy->registerForNotifications(
+ /* instance name, empty means no filter */ "",
+ this);
+ if (!success) {
+ ALOGE("%s: Unable to register with hardware service manager for notifications "
+ "about camera providers", __FUNCTION__);
+ return INVALID_OPERATION;
}
-
+ // See if there's a passthrough HAL, but let's not complain if there's not
+ addProvider(kLegacyProviderName, /*expected*/ false);
return OK;
}
@@ -294,14 +276,12 @@
std::lock_guard<std::mutex> lock(mInterfaceMutex);
addProvider(name);
- mProviderRegistered.notify_one();
return hardware::Return<void>();
}
status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- dprintf(fd, "Available camera providers and devices:\n");
for (auto& provider : mProviders) {
provider->dump(fd, args);
}
@@ -335,12 +315,11 @@
mServiceProxy->getService(newProvider);
if (interface == nullptr) {
+ ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ newProvider.c_str());
if (expected) {
- ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
- newProvider.c_str());
return BAD_VALUE;
} else {
- // Not guaranteed to be found, so not an error if it wasn't
return OK;
}
}
@@ -482,18 +461,46 @@
}
status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
- dprintf(fd, " %s: %zu devices:\n", mProviderName.c_str(), mDevices.size());
+ dprintf(fd, "== Camera Provider HAL %s (v2.4) static info: %zu devices: ==\n",
+ mProviderName.c_str(), mDevices.size());
for (auto& device : mDevices) {
- dprintf(fd, " %s: Resource cost: %d\n", device->mName.c_str(),
- device->mResourceCost.resourceCost);
- if (device->mResourceCost.conflictingDevices.size() > 0) {
- dprintf(fd, " Conflicting devices:\n");
+ dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
+ device->mVersion.get_major(), device->mVersion.get_minor());
+ dprintf(fd, " Resource cost: %d\n", device->mResourceCost.resourceCost);
+ if (device->mResourceCost.conflictingDevices.size() == 0) {
+ dprintf(fd, " Conflicting devices: None\n");
+ } else {
+ dprintf(fd, " Conflicting devices:\n");
for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
- dprintf(fd, " %s\n",
+ dprintf(fd, " %s\n",
device->mResourceCost.conflictingDevices[i].c_str());
}
}
+ dprintf(fd, " API1 info:\n");
+ dprintf(fd, " Has a flash unit: %s\n",
+ device->hasFlashUnit() ? "true" : "false");
+ hardware::CameraInfo info;
+ status_t res = device->getCameraInfo(&info);
+ if (res != OK) {
+ dprintf(fd, " <Error reading camera info: %s (%d)>\n",
+ strerror(-res), res);
+ } else {
+ dprintf(fd, " Facing: %s\n",
+ info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
+ dprintf(fd, " Orientation: %d\n", info.orientation);
+ }
+ CameraMetadata info2;
+ res = device->getCameraCharacteristics(&info2);
+ if (res == INVALID_OPERATION) {
+ dprintf(fd, " API2 not directly supported\n");
+ } else if (res != OK) {
+ dprintf(fd, " <Error reading camera characteristics: %s (%d)>\n",
+ strerror(-res), res);
+ } else {
+ dprintf(fd, " API2 camera characteristics:\n");
+ info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
+ }
}
return OK;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index f21e07d..5ae16cd 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -20,7 +20,6 @@
#include <vector>
#include <string>
#include <mutex>
-#include <condition_variable>
#include <camera/CameraParameters2.h>
#include <camera/CameraMetadata.h>
@@ -220,8 +219,6 @@
// All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
mutable std::mutex mInterfaceMutex;
- std::condition_variable mProviderRegistered;
-
// the status listener update callbacks will lock mStatusMutex
mutable std::mutex mStatusListenerMutex;
wp<StatusListener> mListener;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 977e7a8..208dcb6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -750,7 +750,7 @@
mTagMonitor.dumpMonitoredMetadata(fd);
if (mInterface->valid()) {
- lines = String8(" HAL device dump:\n");
+ lines = String8(" HAL device dump:\n");
write(fd, lines.string(), lines.size());
mInterface->dump(fd);
}
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index f781ded..1469b74 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -85,6 +85,9 @@
/*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false);
mBuffersInFlight.push_back(bufferItem);
+ mFrameCount++;
+ mLastTimestamp = bufferItem.mTimestamp;
+
return OK;
}
@@ -220,6 +223,7 @@
mHandoutTotalBufferCount = 0;
mFrameCount = 0;
+ mLastTimestamp = 0;
if (mConsumer.get() == 0) {
sp<IGraphicBufferProducer> producer;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index b5883e3..f971116 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -239,6 +239,7 @@
}
mLastTimestamp = timestamp;
+ mFrameCount++;
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 07f9491..c9f43aa 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -322,6 +322,13 @@
"queueing buffer to output failed (%d)", status);
}
+ // If the queued buffer replaces a pending buffer in the async
+ // queue, no onBufferReleased is called by the buffer queue.
+ // Proactively trigger the callback to avoid buffer loss.
+ if (queueOutput.bufferReplaced) {
+ onBufferReleasedByOutputLocked(mOutputs[id]);
+ }
+
ALOGV("queued buffer %#" PRIx64 " to output %p",
bufferItem.mGraphicBuffer->getId(), mOutputs[id].get());
}
@@ -335,6 +342,12 @@
ATRACE_CALL();
Mutex::Autolock lock(mMutex);
+ onBufferReleasedByOutputLocked(from);
+}
+
+void Camera3StreamSplitter::onBufferReleasedByOutputLocked(
+ const sp<IGraphicBufferProducer>& from) {
+
sp<GraphicBuffer> buffer;
sp<Fence> fence;
status_t status = from->detachNextBuffer(&buffer, &fence);
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 32ae073..92371ff 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -103,6 +103,11 @@
// onFrameAvailable call to proceed.
void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from);
+ // This is the implementation of onBufferReleasedByOutput without the mutex locked.
+ // It could either be called from onBufferReleasedByOutput or from
+ // onFrameAvailable when a buffer in the async buffer queue is overwritten.
+ void onBufferReleasedByOutputLocked(const sp<IGraphicBufferProducer>& from);
+
// When this is called, the splitter disconnects from (i.e., abandons) its
// input queue and signals any waiting onFrameAvailable calls to wake up.
// It still processes callbacks from other outputs, but only detaches their
diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp
index 374dc5e..0198690 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.cpp
+++ b/services/camera/libcameraservice/utils/CameraTraces.cpp
@@ -74,7 +74,7 @@
return BAD_VALUE;
}
- dprintf(fd, "Camera traces (%zu):\n", pcsList.size());
+ dprintf(fd, "== Camera error traces (%zu): ==\n", pcsList.size());
if (pcsList.empty()) {
dprintf(fd, " No camera traces collected.\n");
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index a5f0751..4cbf737 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -17,7 +17,8 @@
LOCAL_REQUIRED_MODULES_arm := mediacodec-seccomp.policy
LOCAL_SRC_FILES := main_codecservice.cpp minijail/minijail.cpp
LOCAL_SHARED_LIBRARIES := libmedia libmediacodecservice libbinder libutils \
- liblog libminijail
+ liblog libminijail libcutils \
+ android.hardware.media.omx@1.0
LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index a2868c1..f6cde85 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -25,11 +25,14 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
+#include <cutils/properties.h>
// from LOCAL_C_INCLUDES
#include "MediaCodecService.h"
#include "minijail/minijail.h"
+#include <android/hardware/media/omx/1.0/IOmx.h>
+
using namespace android;
int main(int argc __unused, char** argv)
@@ -42,6 +45,21 @@
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
MediaCodecService::instantiate();
+
+ // Treble
+ bool useTrebleOmx = bool(property_get_bool("debug.treble_omx", 0));
+ if (useTrebleOmx) {
+ using namespace ::android::hardware::media::omx::V1_0;
+ sp<IOmx> omx = IOmx::getService(true);
+ if (omx == nullptr) {
+ ALOGE("Cannot create a Treble IOmx service.");
+ } else if (omx->registerAsService("default") != OK) {
+ ALOGE("Cannot register a Treble IOmx service.");
+ } else {
+ ALOGV("Treble IOmx service created.");
+ }
+ }
+
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 12b9d76..2bf2201 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -24,8 +24,7 @@
libbinder \
liblog \
libmediadrm \
- libutils \
- libandroidfw
+ libutils
ifeq ($(ENABLE_TREBLE), true)
LOCAL_SHARED_LIBRARIES += \
libhidlbase \