Merge "Camera: Check for invalid camera during API version calls"
diff --git a/include/media/IMediaExtractor.h b/include/media/IMediaExtractor.h
index e0a81f1..06db359 100644
--- a/include/media/IMediaExtractor.h
+++ b/include/media/IMediaExtractor.h
@@ -42,6 +42,8 @@
// returns an empty metadata object.
virtual sp<MetaData> getMetaData() = 0;
+ virtual status_t getMetrics(Parcel *reply) = 0;
+
enum Flags {
CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index 211f794..9ce6cc5 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -48,6 +48,8 @@
// returns an empty metadata object.
virtual sp<MetaData> getMetaData();
+ status_t getMetrics(Parcel *reply);
+
enum Flags {
CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
@@ -74,6 +76,8 @@
MediaAnalyticsItem *mAnalyticsItem;
+ virtual void populateMetrics();
+
private:
typedef bool (*SnifferFunc)(
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
index e414757..ad0d37b 100644
--- a/include/media/stagefright/NuMediaExtractor.h
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -78,6 +78,7 @@
status_t getSampleTrackIndex(size_t *trackIndex);
status_t getSampleTime(int64_t *sampleTimeUs);
status_t getSampleMeta(sp<MetaData> *sampleMeta);
+ status_t getMetrics(Parcel *reply);
bool getCachedDuration(int64_t *durationUs, bool *eos) const;
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 9ee8fa8..36ea1be 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include <time.h>
-
#define LOG_TAG "StreamHalHidl"
//#define LOG_NDEBUG 0
@@ -40,6 +38,7 @@
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ReadCommand = ::android::hardware::audio::V2_0::IStreamIn::ReadCommand;
namespace android {
@@ -241,8 +240,7 @@
} // namespace
StreamOutHalHidl::StreamOutHalHidl(const sp<IStreamOut>& stream)
- : StreamHalHidl(stream.get()), mStream(stream), mEfGroup(nullptr),
- mGetPresentationPositionNotSupported(false), mPPosFromWrite{ 0, OK, 0, { 0, 0 } } {
+ : StreamHalHidl(stream.get()), mStream(stream), mWriterClient(0), mEfGroup(nullptr) {
}
StreamOutHalHidl::~StreamOutHalHidl() {
@@ -265,7 +263,15 @@
status_t StreamOutHalHidl::getLatency(uint32_t *latency) {
if (mStream == 0) return NO_INIT;
- return processReturn("getLatency", mStream->getLatency(), latency);
+ if (mWriterClient == gettid() && mCommandMQ) {
+ return callWriterThread(
+ WriteCommand::GET_LATENCY, "getLatency", nullptr, 0,
+ [&](const WriteStatus& writeStatus) {
+ *latency = writeStatus.reply.latencyMs;
+ });
+ } else {
+ return processReturn("getLatency", mStream->getLatency(), latency);
+ }
}
status_t StreamOutHalHidl::setVolume(float left, float right) {
@@ -288,10 +294,30 @@
return status;
}
- const size_t availBytes = mDataMQ->availableToWrite();
- if (bytes > availBytes) { bytes = availBytes; }
- if (!mDataMQ->write(static_cast<const uint8_t*>(buffer), bytes)) {
- ALOGW("data message queue write failed");
+ return callWriterThread(
+ WriteCommand::WRITE, "write", static_cast<const uint8_t*>(buffer), bytes,
+ [&] (const WriteStatus& writeStatus) {
+ *written = writeStatus.reply.written;
+ });
+}
+
+status_t StreamOutHalHidl::callWriterThread(
+ WriteCommand cmd, const char* cmdName,
+ const uint8_t* data, size_t dataSize, StreamOutHalHidl::WriterCallback callback) {
+ if (!mCommandMQ->write(&cmd)) {
+ ALOGE("command message queue write failed for \"%s\"", cmdName);
+ return -EAGAIN;
+ }
+ if (data != nullptr) {
+ size_t availableToWrite = mDataMQ->availableToWrite();
+ if (dataSize > availableToWrite) {
+ ALOGW("truncating write data from %d to %d due to insufficient data queue space",
+ (int32_t)dataSize, (int32_t)availableToWrite);
+ dataSize = availableToWrite;
+ }
+ if (!mDataMQ->write(data, dataSize)) {
+ ALOGE("data message queue write failed for \"%s\"", cmdName);
+ }
}
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
@@ -301,24 +327,18 @@
status_t ret = mEfGroup->wait(
static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState, NS_PER_SEC);
if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
- WriteStatus writeStatus =
- { Result::NOT_INITIALIZED, 0, Result::NOT_INITIALIZED, 0, { 0, 0 } };
- mStatusMQ->read(&writeStatus);
- if (writeStatus.writeRetval == Result::OK) {
- status = OK;
- *written = writeStatus.written;
- mPPosFromWrite.status = processReturn(
- "get_presentation_position", writeStatus.presentationPositionRetval);
- if (mPPosFromWrite.status == OK) {
- mPPosFromWrite.frames = writeStatus.frames;
- mPPosFromWrite.ts.tv_sec = writeStatus.timeStamp.tvSec;
- mPPosFromWrite.ts.tv_nsec = writeStatus.timeStamp.tvNSec;
- }
- mPPosFromWrite.obtained = getCurrentTimeMs();
- } else {
- status = processReturn("write", writeStatus.writeRetval);
+ WriteStatus writeStatus;
+ writeStatus.retval = Result::NOT_INITIALIZED;
+ if (!mStatusMQ->read(&writeStatus)) {
+ ALOGE("status message read failed for \"%s\"", cmdName);
}
- return status;
+ if (writeStatus.retval == Result::OK) {
+ ret = OK;
+ callback(writeStatus);
+ } else {
+ ret = processReturn(cmdName, writeStatus.retval);
+ }
+ return ret;
}
if (ret == -EAGAIN) {
// This normally retries no more than once.
@@ -327,23 +347,20 @@
return ret;
}
-uint64_t StreamOutHalHidl::getCurrentTimeMs() {
- struct timespec timeNow;
- clock_gettime(CLOCK_MONOTONIC, &timeNow);
- return timeNow.tv_sec * 1000000 + timeNow.tv_nsec / 1000;
-}
-
status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
+ std::unique_ptr<CommandMQ> tempCommandMQ;
std::unique_ptr<DataMQ> tempDataMQ;
std::unique_ptr<StatusMQ> tempStatusMQ;
Result retval;
Return<void> ret = mStream->prepareForWriting(
1, bufferSize, ThreadPriority(mHalThreadPriority),
[&](Result r,
+ const CommandMQ::Descriptor& commandMQ,
const DataMQ::Descriptor& dataMQ,
const StatusMQ::Descriptor& statusMQ) {
retval = r;
if (retval == Result::OK) {
+ tempCommandMQ.reset(new CommandMQ(commandMQ));
tempDataMQ.reset(new DataMQ(dataMQ));
tempStatusMQ.reset(new StatusMQ(statusMQ));
if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
@@ -354,8 +371,13 @@
if (!ret.isOk() || retval != Result::OK) {
return processReturn("prepareForWriting", ret, retval);
}
- if (!tempDataMQ || !tempDataMQ->isValid() || !tempStatusMQ || !tempStatusMQ->isValid()
- || !mEfGroup) {
+ if (!tempCommandMQ || !tempCommandMQ->isValid() ||
+ !tempDataMQ || !tempDataMQ->isValid() ||
+ !tempStatusMQ || !tempStatusMQ->isValid() ||
+ !mEfGroup) {
+ ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
+ ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
+ "Command message queue for writing is invalid");
ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for writing");
ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for writing is invalid");
ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for writing");
@@ -364,8 +386,10 @@
ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
return NO_INIT;
}
+ mCommandMQ = std::move(tempCommandMQ);
mDataMQ = std::move(tempDataMQ);
mStatusMQ = std::move(tempStatusMQ);
+ mWriterClient = gettid();
return OK;
}
@@ -443,31 +467,27 @@
status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
if (mStream == 0) return NO_INIT;
- if (mGetPresentationPositionNotSupported) return INVALID_OPERATION;
- if (getCurrentTimeMs() - mPPosFromWrite.obtained <= 1000) {
- // No more than 1 ms passed since the last write, use cached result to avoid binder calls.
- if (mPPosFromWrite.status == OK) {
- *frames = mPPosFromWrite.frames;
- timestamp->tv_sec = mPPosFromWrite.ts.tv_sec;
- timestamp->tv_nsec = mPPosFromWrite.ts.tv_nsec;
- }
- return mPPosFromWrite.status;
+ if (mWriterClient == gettid() && mCommandMQ) {
+ return callWriterThread(
+ WriteCommand::GET_PRESENTATION_POSITION, "getPresentationPosition", nullptr, 0,
+ [&](const WriteStatus& writeStatus) {
+ *frames = writeStatus.reply.presentationPosition.frames;
+ timestamp->tv_sec = writeStatus.reply.presentationPosition.timeStamp.tvSec;
+ timestamp->tv_nsec = writeStatus.reply.presentationPosition.timeStamp.tvNSec;
+ });
+ } else {
+ Result retval;
+ Return<void> ret = mStream->getPresentationPosition(
+ [&](Result r, uint64_t hidlFrames, const TimeSpec& hidlTimeStamp) {
+ retval = r;
+ if (retval == Result::OK) {
+ *frames = hidlFrames;
+ timestamp->tv_sec = hidlTimeStamp.tvSec;
+ timestamp->tv_nsec = hidlTimeStamp.tvNSec;
+ }
+ });
+ return processReturn("getPresentationPosition", ret, retval);
}
-
- Result retval;
- Return<void> ret = mStream->getPresentationPosition(
- [&](Result r, uint64_t hidlFrames, const TimeSpec& hidlTimeStamp) {
- retval = r;
- if (retval == Result::OK) {
- *frames = hidlFrames;
- timestamp->tv_sec = hidlTimeStamp.tvSec;
- timestamp->tv_nsec = hidlTimeStamp.tvNSec;
- }
- });
- if (ret.isOk() && retval == Result::NOT_SUPPORTED) {
- mGetPresentationPositionNotSupported = true;
- }
- return processReturn("getPresentationPosition", ret, retval);
}
void StreamOutHalHidl::onWriteReady() {
@@ -493,7 +513,7 @@
StreamInHalHidl::StreamInHalHidl(const sp<IStreamIn>& stream)
- : StreamHalHidl(stream.get()), mStream(stream), mEfGroup(nullptr) {
+ : StreamHalHidl(stream.get()), mStream(stream), mReaderClient(0), mEfGroup(nullptr) {
}
StreamInHalHidl::~StreamInHalHidl() {
@@ -525,33 +545,53 @@
}
status_t status;
- if (!mDataMQ) {
- if ((status = prepareForReading(bytes)) != OK) return status;
- // Trigger the first read.
- mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
+ if (!mDataMQ && (status = prepareForReading(bytes)) != OK) {
+ return status;
}
+ ReadParameters params;
+ params.command = ReadCommand::READ;
+ params.params.read = bytes;
+ return callReaderThread(params, "read",
+ [&](const ReadStatus& readStatus) {
+ const size_t availToRead = mDataMQ->availableToRead();
+ if (!mDataMQ->read(static_cast<uint8_t*>(buffer), std::min(bytes, availToRead))) {
+ ALOGE("data message queue read failed for \"read\"");
+ }
+ ALOGW_IF(availToRead != readStatus.reply.read,
+ "HAL read report inconsistent: mq = %d, status = %d",
+ (int32_t)availToRead, (int32_t)readStatus.reply.read);
+ *read = readStatus.reply.read;
+ });
+}
+
+status_t StreamInHalHidl::callReaderThread(
+ const ReadParameters& params, const char* cmdName,
+ StreamInHalHidl::ReaderCallback callback) {
+ if (!mCommandMQ->write(¶ms)) {
+ ALOGW("command message queue write failed");
+ return -EAGAIN;
+ }
+ mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
+
// TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
uint32_t efState = 0;
retry:
status_t ret = mEfGroup->wait(
static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState, NS_PER_SEC);
if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
- ReadStatus readStatus = { Result::NOT_INITIALIZED, 0 };
- const size_t availToRead = mDataMQ->availableToRead();
- if (bytes > availToRead) { bytes = availToRead; }
- mDataMQ->read(static_cast<uint8_t*>(buffer), bytes);
- mStatusMQ->read(&readStatus);
- mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
- if (readStatus.retval == Result::OK) {
- ALOGW_IF(availToRead != readStatus.read,
- "HAL read report inconsistent: mq = %d, status = %d",
- (int32_t)availToRead, (int32_t)readStatus.read);
- *read = readStatus.read;
- } else {
- status = processReturn("read", readStatus.retval);
+ ReadStatus readStatus;
+ readStatus.retval = Result::NOT_INITIALIZED;
+ if (!mStatusMQ->read(&readStatus)) {
+ ALOGE("status message read failed for \"%s\"", cmdName);
}
- return status;
+ if (readStatus.retval == Result::OK) {
+ ret = OK;
+ callback(readStatus);
+ } else {
+ ret = processReturn(cmdName, readStatus.retval);
+ }
+ return ret;
}
if (ret == -EAGAIN) {
// This normally retries no more than once.
@@ -561,16 +601,19 @@
}
status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
+ std::unique_ptr<CommandMQ> tempCommandMQ;
std::unique_ptr<DataMQ> tempDataMQ;
std::unique_ptr<StatusMQ> tempStatusMQ;
Result retval;
Return<void> ret = mStream->prepareForReading(
1, bufferSize, ThreadPriority(mHalThreadPriority),
[&](Result r,
+ const CommandMQ::Descriptor& commandMQ,
const DataMQ::Descriptor& dataMQ,
const StatusMQ::Descriptor& statusMQ) {
retval = r;
if (retval == Result::OK) {
+ tempCommandMQ.reset(new CommandMQ(commandMQ));
tempDataMQ.reset(new DataMQ(dataMQ));
tempStatusMQ.reset(new StatusMQ(statusMQ));
if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
@@ -581,8 +624,13 @@
if (!ret.isOk() || retval != Result::OK) {
return processReturn("prepareForReading", ret, retval);
}
- if (!tempDataMQ || !tempDataMQ->isValid() || !tempStatusMQ || !tempStatusMQ->isValid()
- || !mEfGroup) {
+ if (!tempCommandMQ || !tempCommandMQ->isValid() ||
+ !tempDataMQ || !tempDataMQ->isValid() ||
+ !tempStatusMQ || !tempStatusMQ->isValid() ||
+ !mEfGroup) {
+ ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
+ ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
+ "Command message queue for writing is invalid");
ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for reading");
ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "Data message queue for reading is invalid");
ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for reading");
@@ -591,8 +639,10 @@
ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
return NO_INIT;
}
+ mCommandMQ = std::move(tempCommandMQ);
mDataMQ = std::move(tempDataMQ);
mStatusMQ = std::move(tempStatusMQ);
+ mReaderClient = gettid();
return OK;
}
@@ -603,16 +653,26 @@
status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
if (mStream == 0) return NO_INIT;
- Result retval;
- Return<void> ret = mStream->getCapturePosition(
- [&](Result r, uint64_t hidlFrames, uint64_t hidlTime) {
- retval = r;
- if (retval == Result::OK) {
- *frames = hidlFrames;
- *time = hidlTime;
- }
- });
- return processReturn("getCapturePosition", ret, retval);
+ if (mReaderClient == gettid() && mCommandMQ) {
+ ReadParameters params;
+ params.command = ReadCommand::GET_CAPTURE_POSITION;
+ return callReaderThread(params, "getCapturePosition",
+ [&](const ReadStatus& readStatus) {
+ *frames = readStatus.reply.capturePosition.frames;
+ *time = readStatus.reply.capturePosition.time;
+ });
+ } else {
+ Result retval;
+ Return<void> ret = mStream->getCapturePosition(
+ [&](Result r, uint64_t hidlFrames, uint64_t hidlTime) {
+ retval = r;
+ if (retval == Result::OK) {
+ *frames = hidlFrames;
+ *time = hidlTime;
+ }
+ });
+ return processReturn("getCapturePosition", ret, retval);
+ }
}
} // namespace android
diff --git a/media/libaudiohal/StreamHalHidl.h b/media/libaudiohal/StreamHalHidl.h
index 8b5867e..db217a8 100644
--- a/media/libaudiohal/StreamHalHidl.h
+++ b/media/libaudiohal/StreamHalHidl.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HARDWARE_STREAM_HAL_HIDL_H
#define ANDROID_HARDWARE_STREAM_HAL_HIDL_H
+#include <atomic>
+
#include <android/hardware/audio/2.0/IStream.h>
#include <android/hardware/audio/2.0/IStreamIn.h>
#include <android/hardware/audio/2.0/IStreamOut.h>
@@ -32,7 +34,9 @@
using ::android::hardware::EventFlag;
using ::android::hardware::MessageQueue;
using ::android::hardware::Return;
+using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
+using WriteCommand = ::android::hardware::audio::V2_0::IStreamOut::WriteCommand;
using WriteStatus = ::android::hardware::audio::V2_0::IStreamOut::WriteStatus;
namespace android {
@@ -155,28 +159,27 @@
private:
friend class DeviceHalHidl;
+ typedef MessageQueue<WriteCommand, hardware::kSynchronizedReadWrite> CommandMQ;
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
wp<StreamOutHalInterfaceCallback> mCallback;
sp<IStreamOut> mStream;
+ std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
+ std::atomic<pid_t> mWriterClient;
EventFlag* mEfGroup;
- bool mGetPresentationPositionNotSupported;
- struct {
- uint64_t obtained;
- status_t status;
- uint64_t frames;
- struct timespec ts;
- } mPPosFromWrite;
// Can not be constructed directly by clients.
StreamOutHalHidl(const sp<IStreamOut>& stream);
virtual ~StreamOutHalHidl();
- uint64_t getCurrentTimeMs();
+ using WriterCallback = std::function<void(const WriteStatus& writeStatus)>;
+ status_t callWriterThread(
+ WriteCommand cmd, const char* cmdName,
+ const uint8_t* data, size_t dataSize, WriterCallback callback);
status_t prepareForWriting(size_t bufferSize);
};
@@ -200,12 +203,15 @@
private:
friend class DeviceHalHidl;
+ typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
sp<IStreamIn> mStream;
+ std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
+ std::atomic<pid_t> mReaderClient;
EventFlag* mEfGroup;
// Can not be constructed directly by clients.
@@ -213,6 +219,9 @@
virtual ~StreamInHalHidl();
+ using ReaderCallback = std::function<void(const ReadStatus& readStatus)>;
+ status_t callReaderThread(
+ const ReadParameters& params, const char* cmdName, ReaderCallback callback);
status_t prepareForReading(size_t bufferSize);
};
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 0f4f092..bfc43a6 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -36,7 +36,8 @@
FLAGS,
GETDRMTRACKINFO,
SETUID,
- NAME
+ NAME,
+ GETMETRICS
};
class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -94,6 +95,16 @@
return NULL;
}
+ virtual status_t getMetrics(Parcel * reply) {
+ Parcel data;
+ data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+ status_t ret = remote()->transact(GETMETRICS, data, reply);
+ if (ret == NO_ERROR) {
+ return OK;
+ }
+ return UNKNOWN_ERROR;
+ }
+
virtual uint32_t flags() const {
ALOGV("flags NOT IMPLEMENTED");
return 0;
@@ -169,6 +180,11 @@
}
return UNKNOWN_ERROR;
}
+ case GETMETRICS: {
+ CHECK_INTERFACE(IMediaExtractor, data, reply);
+ status_t ret = getMetrics(reply);
+ return ret;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
index 71d2908..6d54a13 100644
--- a/media/libmedia/OMXBuffer.cpp
+++ b/media/libmedia/OMXBuffer.cpp
@@ -90,6 +90,13 @@
case kBufferTypeANWBuffer:
{
+ if (mGraphicBuffer == NULL) {
+ return parcel->writeBool(false);
+ }
+ status_t err = parcel->writeBool(true);
+ if (err != OK) {
+ return err;
+ }
return parcel->write(*mGraphicBuffer);
}
@@ -130,15 +137,21 @@
case kBufferTypeANWBuffer:
{
- sp<GraphicBuffer> buffer = new GraphicBuffer();
-
- status_t err = parcel->read(*buffer);
-
+ bool notNull;
+ status_t err = parcel->readBool(¬Null);
if (err != OK) {
return err;
}
-
- mGraphicBuffer = buffer;
+ if (notNull) {
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ status_t err = parcel->read(*buffer);
+ if (err != OK) {
+ return err;
+ }
+ mGraphicBuffer = buffer;
+ } else {
+ mGraphicBuffer = nullptr;
+ }
break;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 9ce65c4..d00e377 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -275,6 +275,7 @@
}
status_t StagefrightRecorder::setNextOutputFile(int fd) {
+ Mutex::Autolock autolock(mLock);
// Only support MPEG4
if (mOutputFormat != OUTPUT_FORMAT_MPEG_4) {
ALOGE("Only MP4 file format supports setting next output file");
@@ -290,6 +291,10 @@
// start with a clean, empty file
ftruncate(fd, 0);
int nextFd = dup(fd);
+ if (mWriter == NULL) {
+ ALOGE("setNextOutputFile failed. Writer has been freed");
+ return INVALID_OPERATION;
+ }
return mWriter->setNextFd(nextFd);
}
@@ -851,6 +856,8 @@
}
status_t StagefrightRecorder::prepare() {
+ ALOGV("prepare");
+ Mutex::Autolock autolock(mLock);
if (mVideoSource == VIDEO_SOURCE_SURFACE) {
return prepareInternal();
}
@@ -859,6 +866,7 @@
status_t StagefrightRecorder::start() {
ALOGV("start");
+ Mutex::Autolock autolock(mLock);
if (mOutputFd < 0) {
ALOGE("Output file descriptor is invalid");
return INVALID_OPERATION;
@@ -1867,6 +1875,7 @@
status_t StagefrightRecorder::stop() {
ALOGV("stop");
+ Mutex::Autolock autolock(mLock);
status_t err = OK;
if (mCaptureFpsEnable && mCameraSourceTimeLapse != NULL) {
@@ -1984,6 +1993,7 @@
status_t StagefrightRecorder::dump(
int fd, const Vector<String16>& args) const {
ALOGV("dump");
+ Mutex::Autolock autolock(mLock);
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 870c5d0..b7d0b0e 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -43,7 +43,6 @@
struct StagefrightRecorder : public MediaRecorderBase {
explicit StagefrightRecorder(const String16 &opPackageName);
virtual ~StagefrightRecorder();
-
virtual status_t init();
virtual status_t setAudioSource(audio_source_t as);
virtual status_t setVideoSource(video_source vs);
@@ -73,6 +72,7 @@
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const;
private:
+ mutable Mutex mLock;
sp<hardware::ICamera> mCamera;
sp<ICameraRecordingProxy> mCameraProxy;
sp<IGraphicBufferProducer> mPreviewSurface;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 1d62498..0a0a8aa 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -634,6 +634,11 @@
sp<MediaCodecBuffer> buffer;
mCodec->getOutputBuffer(index, &buffer);
+ if (buffer == NULL) {
+ handleError(UNKNOWN_ERROR);
+ return false;
+ }
+
if (index >= mOutputBuffers.size()) {
for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
mOutputBuffers.add();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 42e95da..9350440 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -405,10 +405,10 @@
msg->setInt32("flags", flags);
sp<AMessage> response;
- msg->postAndAwaitResponse(&response);
+ status_t postStatus = msg->postAndAwaitResponse(&response);
int32_t err;
- if (!response->findInt32("err", &err)) {
+ if (postStatus != OK || response.get() == nullptr || !response->findInt32("err", &err)) {
err = INVALID_OPERATION;
} else if (err == OK && isOffloaded != NULL) {
int32_t offload;
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 4a965ba..ded79f3 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -130,7 +130,7 @@
}
String8 cacheConfig;
- bool disconnectAtHighwatermark;
+ bool disconnectAtHighwatermark = false;
KeyedVector<String8, String8> nonCacheSpecificHeaders;
if (headers != NULL) {
nonCacheSpecificHeaders = *headers;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 87d7d3c..0dd3e88 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -4515,8 +4515,8 @@
// fall through
}
- off64_t offset;
- size_t size;
+ off64_t offset = 0;
+ size_t size = 0;
uint32_t cts, stts;
bool isSyncSample;
bool newBuffer = false;
@@ -5066,6 +5066,10 @@
return NULL;
}
+void MPEG4Extractor::populateMetrics() {
+ ALOGV("MPEG4Extractor::populateMetrics");
+}
+
static bool LegacySniffMPEG4(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
uint8_t header[8];
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 677d43e..62c0d8a 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -55,7 +55,7 @@
namespace android {
// key for media statistics
-static const char *KeyName_Extractor = "extractor";
+static const char *kKeyExtractor = "extractor";
// attrs for media statistics
MediaExtractor::MediaExtractor() {
@@ -67,7 +67,7 @@
mAnalyticsItem = NULL;
if (MEDIA_LOG) {
- mAnalyticsItem = new MediaAnalyticsItem(KeyName_Extractor);
+ mAnalyticsItem = new MediaAnalyticsItem(kKeyExtractor);
(void) mAnalyticsItem->generateSessionID();
}
}
@@ -93,6 +93,23 @@
return new MetaData;
}
+status_t MediaExtractor::getMetrics(Parcel *reply) {
+
+ if (mAnalyticsItem == NULL || reply == NULL) {
+ return UNKNOWN_ERROR;
+ }
+
+ populateMetrics();
+ mAnalyticsItem->writeToParcel(reply);
+
+ return OK;
+}
+
+void MediaExtractor::populateMetrics() {
+ ALOGV("MediaExtractor::populateMetrics");
+ // normally overridden in subclasses
+}
+
uint32_t MediaExtractor::flags() const {
return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
}
@@ -247,24 +264,23 @@
// track the container format (mpeg, aac, wvm, etc)
if (MEDIA_LOG) {
if (ret->mAnalyticsItem != NULL) {
+ size_t ntracks = ret->countTracks();
ret->mAnalyticsItem->setCString("fmt", ret->name());
// tracks (size_t)
- ret->mAnalyticsItem->setInt32("ntrk", ret->countTracks());
+ ret->mAnalyticsItem->setInt32("ntrk", ntracks);
// metadata
sp<MetaData> pMetaData = ret->getMetaData();
if (pMetaData != NULL) {
String8 xx = pMetaData->toString();
- ALOGD("metadata says: %s", xx.string());
- // can grab various fields like:
// 'titl' -- but this verges into PII
// 'mime'
const char *mime = NULL;
if (pMetaData->findCString(kKeyMIMEType, &mime)) {
ret->mAnalyticsItem->setCString("mime", mime);
}
- // what else is interesting here?
+ // what else is interesting and not already available?
}
- }
+ }
}
}
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index d25ce6c..1c1acb0 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -569,6 +569,11 @@
return OK;
}
+status_t NuMediaExtractor::getMetrics(Parcel *reply) {
+ status_t status = mImpl->getMetrics(reply);
+ return status;
+}
+
bool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const {
if (mTotalBitrate >= 0) {
*bitrate = mTotalBitrate;
diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
index 54c9fa3..4134698 100644
--- a/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/SampleIterator.cpp
@@ -305,8 +305,16 @@
return ERROR_OUT_OF_RANGE;
}
- while (sampleIndex >= mTTSSampleIndex + mTTSCount) {
- if (mTimeToSampleIndex == mTable->mTimeToSampleCount) {
+ while (true) {
+ if (mTTSSampleIndex > UINT32_MAX - mTTSCount) {
+ return ERROR_OUT_OF_RANGE;
+ }
+ if(sampleIndex < mTTSSampleIndex + mTTSCount) {
+ break;
+ }
+ if (mTimeToSampleIndex == mTable->mTimeToSampleCount ||
+ (mTTSDuration != 0 && mTTSCount > UINT32_MAX / mTTSDuration) ||
+ mTTSSampleTime > UINT32_MAX - (mTTSCount * mTTSDuration)) {
return ERROR_OUT_OF_RANGE;
}
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index fa05886..f847119 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -66,6 +66,8 @@
protected:
virtual ~MPEG4Extractor();
+ virtual void populateMetrics();
+
private:
struct PsshInfo {
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 4909100..a0ddc28 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -43,6 +43,35 @@
static const OMX_U32 kPortIndexInput = 0;
+class GraphicBufferSource::OmxBufferSource : public BnOMXBufferSource {
+public:
+ GraphicBufferSource* mSource;
+
+ OmxBufferSource(GraphicBufferSource* source): mSource(source) {
+ }
+
+ Status onOmxExecuting() override {
+ return mSource->onOmxExecuting();
+ }
+
+ Status onOmxIdle() override {
+ return mSource->onOmxIdle();
+ }
+
+ Status onOmxLoaded() override {
+ return mSource->onOmxLoaded();
+ }
+
+ Status onInputBufferAdded(int bufferId) override {
+ return mSource->onInputBufferAdded(bufferId);
+ }
+
+ Status onInputBufferEmptied(
+ int bufferId, const OMXFenceParcelable& fenceParcel) override {
+ return mSource->onInputBufferEmptied(bufferId, fenceParcel);
+ }
+};
+
GraphicBufferSource::GraphicBufferSource() :
mInitCheck(UNKNOWN_ERROR),
mExecuting(false),
@@ -66,7 +95,8 @@
mTimePerFrameUs(-1ll),
mPrevCaptureUs(-1ll),
mPrevFrameUs(-1ll),
- mInputBufferTimeOffsetUs(0ll) {
+ mInputBufferTimeOffsetUs(0ll),
+ mOmxBufferSource(new OmxBufferSource(this)) {
ALOGV("GraphicBufferSource");
String8 name("GraphicBufferSource");
@@ -766,7 +796,7 @@
// Do setInputSurface() first, the node will try to enable metadata
// mode on input, and does necessary error checking. If this fails,
// we can't use this input surface on the node.
- status_t err = omxNode->setInputSurface(this);
+ status_t err = omxNode->setInputSurface(mOmxBufferSource);
if (err != NO_ERROR) {
ALOGE("Unable to set input surface: %d", err);
return Status::fromServiceSpecificError(err);
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 80fe078..153a035 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -55,7 +55,6 @@
* things up until we're ready to go.
*/
class GraphicBufferSource : public BnGraphicBufferSource,
- public BnOMXBufferSource,
public BufferQueue::ConsumerListener {
public:
GraphicBufferSource();
@@ -77,26 +76,26 @@
// This is called when OMX transitions to OMX_StateExecuting, which means
// we can start handing it buffers. If we already have buffers of data
// sitting in the BufferQueue, this will send them to the codec.
- Status onOmxExecuting() override;
+ Status onOmxExecuting();
// This is called when OMX transitions to OMX_StateIdle, indicating that
// the codec is meant to return all buffers back to the client for them
// to be freed. Do NOT submit any more buffers to the component.
- Status onOmxIdle() override;
+ Status onOmxIdle();
// This is called when OMX transitions to OMX_StateLoaded, indicating that
// we are shutting down.
- Status onOmxLoaded() override;
+ Status onOmxLoaded();
// A "codec buffer", i.e. a buffer that can be used to pass data into
// the encoder, has been allocated. (This call does not call back into
// OMXNodeInstance.)
- Status onInputBufferAdded(int32_t bufferID) override;
+ Status onInputBufferAdded(int32_t bufferID);
// Called from OnEmptyBufferDone. If we have a BQ buffer available,
// fill it with a new frame of data; otherwise, just mark it as available.
Status onInputBufferEmptied(
- int32_t bufferID, const OMXFenceParcelable& fenceParcel) override;
+ int32_t bufferID, const OMXFenceParcelable& fenceParcel);
// Configure the buffer source to be used with an OMX node with the default
// data space.
@@ -301,6 +300,9 @@
ColorAspects mColorAspects;
+ class OmxBufferSource;
+ sp<OmxBufferSource> mOmxBufferSource;
+
void onMessageReceived(const sp<AMessage> &msg);
DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource);
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index d27a496..68a3ed2 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -294,7 +294,7 @@
if (!*nh) {
return false;
}
- t->fence = inHidlHandle(*nh);
+ t->fence = *nh;
switch (l.type) {
case omx_message::EVENT:
t->type = Message::Type::EVENT;
@@ -592,6 +592,16 @@
}
case OMXBuffer::kBufferTypeANWBuffer: {
t->type = CodecBuffer::Type::ANW_BUFFER;
+ if (l.mGraphicBuffer == nullptr) {
+ t->attr.anwBuffer.width = 0;
+ t->attr.anwBuffer.height = 0;
+ t->attr.anwBuffer.stride = 0;
+ t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
+ t->attr.anwBuffer.layerCount = 0;
+ t->attr.anwBuffer.usage = 0;
+ t->nativeHandle = hidl_handle();
+ return true;
+ }
t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
@@ -636,6 +646,10 @@
return true;
}
case CodecBuffer::Type::ANW_BUFFER: {
+ if (t.nativeHandle.getNativeHandle() == nullptr) {
+ *l = OMXBuffer(sp<GraphicBuffer>(nullptr));
+ return true;
+ }
*l = OMXBuffer(sp<GraphicBuffer>(new GraphicBuffer(
t.attr.anwBuffer.width,
t.attr.anwBuffer.height,
@@ -2082,6 +2096,7 @@
t->transformHint = l.transformHint;
t->numPendingBuffers = l.numPendingBuffers;
t->nextFrameNumber = l.nextFrameNumber;
+ t->bufferReplaced = l.bufferReplaced;
return true;
}
@@ -2107,6 +2122,7 @@
l->transformHint = t.transformHint;
l->numPendingBuffers = t.numPendingBuffers;
l->nextFrameNumber = t.nextFrameNumber;
+ l->bufferReplaced = t.bufferReplaced;
return true;
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
index 9de8e3e..8ba2924 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
@@ -78,10 +78,6 @@
return toBinderStatus(mBase->signalEndOfInputStream());
}
-::android::IBinder* LWGraphicBufferSource::onAsBinder() {
- return nullptr;
-}
-
// TWGraphicBufferSource
TWGraphicBufferSource::TWGraphicBufferSource(
sp<LGraphicBufferSource> const& base) : mBase(base) {
@@ -89,47 +85,51 @@
Return<void> TWGraphicBufferSource::configure(
const sp<IOmxNode>& omxNode, Dataspace dataspace) {
- return toHardwareStatus(mBase->configure(
- new LWOmxNode(omxNode),
- toRawDataspace(dataspace)));
+ mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
+ return Void();
}
Return<void> TWGraphicBufferSource::setSuspend(bool suspend) {
- return toHardwareStatus(mBase->setSuspend(suspend));
+ mBase->setSuspend(suspend);
+ return Void();
}
Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
int64_t repeatAfterUs) {
- return toHardwareStatus(mBase->setRepeatPreviousFrameDelayUs(
- repeatAfterUs));
+ mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
- return toHardwareStatus(mBase->setMaxFps(maxFps));
+ mBase->setMaxFps(maxFps);
+ return Void();
}
Return<void> TWGraphicBufferSource::setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) {
- return toHardwareStatus(mBase->setTimeLapseConfig(
- timePerFrameUs, timePerCaptureUs));
+ mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
- return toHardwareStatus(mBase->setStartTimeUs(startTimeUs));
+ mBase->setStartTimeUs(startTimeUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setColorAspects(
const ColorAspects& aspects) {
- return toHardwareStatus(mBase->setColorAspects(toCompactColorAspects(
- aspects)));
+ mBase->setColorAspects(toCompactColorAspects(aspects));
+ return Void();
}
Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
- return toHardwareStatus(mBase->setTimeOffsetUs(timeOffsetUs));
+ mBase->setTimeOffsetUs(timeOffsetUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
- return toHardwareStatus(mBase->signalEndOfInputStream());
+ mBase->signalEndOfInputStream();
+ return Void();
}
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
index 0b9f2ed..69efdde 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
@@ -23,7 +23,7 @@
#include <frameworks/native/include/binder/Binder.h>
#include <IOMX.h>
-#include <android/IGraphicBufferSource.h>
+#include <android/BnGraphicBufferSource.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/graphics/common/1.0/types.h>
@@ -60,10 +60,11 @@
*/
typedef ::android::IGraphicBufferSource LGraphicBufferSource;
+typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
TGraphicBufferSource;
-struct LWGraphicBufferSource : public LGraphicBufferSource {
+struct LWGraphicBufferSource : public BnGraphicBufferSource {
sp<TGraphicBufferSource> mBase;
LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
::android::binder::Status configure(
@@ -78,8 +79,6 @@
::android::binder::Status setColorAspects(int32_t aspects) override;
::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
::android::binder::Status signalEndOfInputStream() override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWGraphicBufferSource : public TGraphicBufferSource {
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
index 0fa8c4c..da1c23d 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
@@ -79,10 +79,6 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
-::android::IBinder* LWOmx::onAsBinder() {
- return nullptr;
-}
-
// TWOmx
TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.h b/media/libstagefright/omx/hal/1.0/impl/WOmx.h
index 5618d27..ab11c6a 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmx.h
@@ -45,6 +45,7 @@
using ::android::List;
using ::android::IOMX;
+using ::android::BnOMX;
/**
* Wrapper classes for conversion
@@ -55,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmx : public IOMX {
+struct LWOmx : public BnOMX {
sp<IOmx> mBase;
LWOmx(sp<IOmx> const& base);
status_t listNodes(List<IOMX::ComponentInfo>* list) override;
@@ -66,8 +67,6 @@
status_t createInputSurface(
sp<::android::IGraphicBufferProducer>* bufferProducer,
sp<::android::IGraphicBufferSource>* bufferSource) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmx : public IOmx {
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp
index a459c9f..3bd6c6e 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.cpp
@@ -203,7 +203,8 @@
Return<void> TWOmxBufferProducer::connect(
const sp<IOmxProducerListener>& listener,
int32_t api, bool producerControlledByApp, connect_cb _hidl_cb) {
- sp<IProducerListener> lListener = new LWOmxProducerListener(listener);
+ sp<IProducerListener> lListener = listener == nullptr ?
+ nullptr : new LWOmxProducerListener(listener);
IGraphicBufferProducer::QueueBufferOutput lOutput;
status_t status = mBase->connect(lListener,
static_cast<int>(api),
@@ -479,7 +480,8 @@
status_t LWOmxBufferProducer::connect(
const sp<IProducerListener>& listener, int api,
bool producerControlledByApp, QueueBufferOutput* output) {
- sp<IOmxProducerListener> tListener = new TWOmxProducerListener(listener);
+ sp<IOmxProducerListener> tListener = listener == nullptr ?
+ nullptr : new TWOmxProducerListener(listener);
status_t fnStatus;
status_t transStatus = toStatusT(mBase->connect(
tListener, static_cast<int32_t>(api), producerControlledByApp,
@@ -582,10 +584,6 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
-::android::IBinder* LWOmxBufferProducer::onAsBinder() {
- return nullptr;
-}
-
} // namespace implementation
} // namespace V1_0
} // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h
index a991f49..65b093c 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferProducer.h
@@ -47,6 +47,7 @@
using ::android::sp;
using ::android::IGraphicBufferProducer;
+using ::android::BnGraphicBufferProducer;
using ::android::IProducerListener;
struct TWOmxBufferProducer : public IOmxBufferProducer {
@@ -91,7 +92,7 @@
Return<void> getUniqueId(getUniqueId_cb _hidl_cb) override;
};
-struct LWOmxBufferProducer : public IGraphicBufferProducer {
+struct LWOmxBufferProducer : public BnGraphicBufferProducer {
sp<IOmxBufferProducer> mBase;
LWOmxBufferProducer(sp<IOmxBufferProducer> const& base);
@@ -128,8 +129,6 @@
sp<Fence>* outFence, float outTransformMatrix[16]) override;
void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
status_t getUniqueId(uint64_t* outId) const override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp
index 2e00894..97bcee0 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.cpp
@@ -61,38 +61,34 @@
::android::binder::Status status = toBinderStatus(
mBase->onInputBufferEmptied(
static_cast<uint32_t>(bufferId), fence));
- if (native_handle_delete(fenceNh) != 0) {
- return ::android::binder::Status::fromExceptionCode(
- ::android::binder::Status::EX_NULL_POINTER,
- "Cannot delete native handle");
- }
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
return status;
}
-::android::IBinder* LWOmxBufferSource::onAsBinder() {
- return nullptr;
-}
-
// TWOmxBufferSource
TWOmxBufferSource::TWOmxBufferSource(sp<IOMXBufferSource> const& base) :
mBase(base) {
}
Return<void> TWOmxBufferSource::onOmxExecuting() {
- return toHardwareStatus(mBase->onOmxExecuting());
+ mBase->onOmxExecuting();
+ return Void();
}
Return<void> TWOmxBufferSource::onOmxIdle() {
- return toHardwareStatus(mBase->onOmxIdle());
+ mBase->onOmxIdle();
+ return Void();
}
Return<void> TWOmxBufferSource::onOmxLoaded() {
- return toHardwareStatus(mBase->onOmxLoaded());
+ mBase->onOmxLoaded();
+ return Void();
}
Return<void> TWOmxBufferSource::onInputBufferAdded(uint32_t buffer) {
- return toHardwareStatus(mBase->onInputBufferAdded(
- static_cast<int32_t>(buffer)));
+ mBase->onInputBufferAdded(int32_t(buffer));
+ return Void();
}
Return<void> TWOmxBufferSource::onInputBufferEmptied(
@@ -102,8 +98,8 @@
return ::android::hardware::Status::fromExceptionCode(
::android::hardware::Status::EX_BAD_PARCELABLE);
}
- return toHardwareStatus(mBase->onInputBufferEmptied(
- static_cast<int32_t>(buffer), fenceParcelable));
+ mBase->onInputBufferEmptied(int32_t(buffer), fenceParcelable);
+ return Void();
}
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h
index a2e940f..83bf46f 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxBufferSource.h
@@ -22,7 +22,7 @@
#include <hidl/Status.h>
#include <frameworks/native/include/binder/Binder.h>
-#include <android/IOMXBufferSource.h>
+#include <android/BnOMXBufferSource.h>
#include <OMXFenceParcelable.h>
namespace android {
@@ -45,6 +45,7 @@
using ::android::OMXFenceParcelable;
using ::android::IOMXBufferSource;
+using ::android::BnOMXBufferSource;
/**
* Wrapper classes for conversion
@@ -55,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxBufferSource : public IOMXBufferSource {
+struct LWOmxBufferSource : public BnOMXBufferSource {
sp<IOmxBufferSource> mBase;
LWOmxBufferSource(sp<IOmxBufferSource> const& base);
::android::binder::Status onOmxExecuting() override;
@@ -64,8 +65,6 @@
::android::binder::Status onInputBufferAdded(int32_t bufferID) override;
::android::binder::Status onInputBufferEmptied(
int32_t bufferID, OMXFenceParcelable const& fenceParcel) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxBufferSource : public IOmxBufferSource {
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
index 6b21138..26617aa 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
@@ -252,10 +252,6 @@
return toStatusT(mBase->setQuirks(static_cast<uint32_t>(quirks)));;
}
-::android::IBinder* LWOmxNode::onAsBinder() {
- return nullptr;
-}
-
// TWOmxNode
TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) {
}
@@ -281,7 +277,8 @@
}
Return<Status> TWOmxNode::setParameter(
- uint32_t index, hidl_vec<uint8_t> const& params) {
+ uint32_t index, hidl_vec<uint8_t> const& inParams) {
+ hidl_vec<uint8_t> params(inParams);
return toStatus(mBase->setParameter(
toEnumIndexType(index),
static_cast<void const*>(params.data()),
@@ -301,7 +298,8 @@
}
Return<Status> TWOmxNode::setConfig(
- uint32_t index, const hidl_vec<uint8_t>& config) {
+ uint32_t index, const hidl_vec<uint8_t>& inConfig) {
+ hidl_vec<uint8_t> config(inConfig);
return toStatus(mBase->setConfig(
toEnumIndexType(index),
static_cast<void const*>(config.data()),
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.h b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.h
index d606f3a..12c2f04 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.h
@@ -56,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxNode : public IOMXNode {
+struct LWOmxNode : public BnOMXNode {
sp<IOmxNode> mBase;
LWOmxNode(sp<IOmxNode> const& base);
status_t freeNode() override;
@@ -103,8 +103,6 @@
// TODO: this is temporary, will be removed when quirks move to OMX side.
status_t setQuirks(OMX_U32 quirks) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxNode : public IOmxNode {
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
index d5549fb..ecd1db5 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
@@ -50,10 +50,6 @@
}
}
-::android::IBinder* LWOmxObserver::onAsBinder() {
- return nullptr;
-}
-
// TWOmxObserver
TWOmxObserver::TWOmxObserver(sp<IOMXObserver> const& base) : mBase(base) {
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h
index 85593c3..cfe4281 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.h
@@ -43,6 +43,7 @@
using ::android::sp;
using ::android::IOMXObserver;
+using ::android::BnOMXObserver;
using ::android::omx_message;
/**
@@ -54,12 +55,10 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxObserver : public IOMXObserver {
+struct LWOmxObserver : public BnOMXObserver {
sp<IOmxObserver> mBase;
LWOmxObserver(sp<IOmxObserver> const& base);
void onMessages(std::list<omx_message> const& lMessages) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxObserver : public IOmxObserver {
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp
index fa6e9aa..a5eed35 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.cpp
@@ -52,11 +52,6 @@
return static_cast<bool>(mBase->needsReleaseNotify());
}
-::android::IBinder* LWOmxProducerListener::onAsBinder() {
- return nullptr;
-}
-
-
} // namespace implementation
} // namespace V1_0
} // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h
index b93a555..86656ca 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxProducerListener.h
@@ -42,6 +42,7 @@
using ::android::sp;
using ::android::IProducerListener;
+using ::android::BnProducerListener;
struct TWOmxProducerListener : public IOmxProducerListener {
sp<IProducerListener> mBase;
@@ -50,14 +51,12 @@
Return<bool> needsReleaseNotify() override;
};
-class LWOmxProducerListener : public IProducerListener {
+class LWOmxProducerListener : public BnProducerListener {
public:
sp<IOmxProducerListener> mBase;
LWOmxProducerListener(sp<IOmxProducerListener> const& base);
void onBufferReleased() override;
bool needsReleaseNotify() override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
index 6f4d864..05f0c78 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -294,7 +294,7 @@
if (!*nh) {
return false;
}
- t->fence = inHidlHandle(*nh);
+ t->fence = *nh;
switch (l.type) {
case omx_message::EVENT:
t->type = Message::Type::EVENT;
@@ -592,6 +592,16 @@
}
case OMXBuffer::kBufferTypeANWBuffer: {
t->type = CodecBuffer::Type::ANW_BUFFER;
+ if (l.mGraphicBuffer == nullptr) {
+ t->attr.anwBuffer.width = 0;
+ t->attr.anwBuffer.height = 0;
+ t->attr.anwBuffer.stride = 0;
+ t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
+ t->attr.anwBuffer.layerCount = 0;
+ t->attr.anwBuffer.usage = 0;
+ t->nativeHandle = hidl_handle();
+ return true;
+ }
t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
@@ -636,6 +646,10 @@
return true;
}
case CodecBuffer::Type::ANW_BUFFER: {
+ if (t.nativeHandle.getNativeHandle() == nullptr) {
+ *l = OMXBuffer(sp<GraphicBuffer>(nullptr));
+ return true;
+ }
*l = OMXBuffer(sp<GraphicBuffer>(new GraphicBuffer(
t.attr.anwBuffer.width,
t.attr.anwBuffer.height,
@@ -2082,6 +2096,7 @@
t->transformHint = l.transformHint;
t->numPendingBuffers = l.numPendingBuffers;
t->nextFrameNumber = l.nextFrameNumber;
+ t->bufferReplaced = l.bufferReplaced;
return true;
}
@@ -2107,6 +2122,7 @@
l->transformHint = t.transformHint;
l->numPendingBuffers = t.numPendingBuffers;
l->nextFrameNumber = t.nextFrameNumber;
+ l->bufferReplaced = t.bufferReplaced;
return true;
}
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
index 037e9b2..a23b48a 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
@@ -78,10 +78,6 @@
return toBinderStatus(mBase->signalEndOfInputStream());
}
-::android::IBinder* LWGraphicBufferSource::onAsBinder() {
- return nullptr;
-}
-
// TWGraphicBufferSource
TWGraphicBufferSource::TWGraphicBufferSource(
sp<LGraphicBufferSource> const& base) : mBase(base) {
@@ -89,47 +85,51 @@
Return<void> TWGraphicBufferSource::configure(
const sp<IOmxNode>& omxNode, Dataspace dataspace) {
- return toHardwareStatus(mBase->configure(
- new LWOmxNode(omxNode),
- toRawDataspace(dataspace)));
+ mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
+ return Void();
}
Return<void> TWGraphicBufferSource::setSuspend(bool suspend) {
- return toHardwareStatus(mBase->setSuspend(suspend));
+ mBase->setSuspend(suspend);
+ return Void();
}
Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
int64_t repeatAfterUs) {
- return toHardwareStatus(mBase->setRepeatPreviousFrameDelayUs(
- repeatAfterUs));
+ mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
- return toHardwareStatus(mBase->setMaxFps(maxFps));
+ mBase->setMaxFps(maxFps);
+ return Void();
}
Return<void> TWGraphicBufferSource::setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) {
- return toHardwareStatus(mBase->setTimeLapseConfig(
- timePerFrameUs, timePerCaptureUs));
+ mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
- return toHardwareStatus(mBase->setStartTimeUs(startTimeUs));
+ mBase->setStartTimeUs(startTimeUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::setColorAspects(
const ColorAspects& aspects) {
- return toHardwareStatus(mBase->setColorAspects(toCompactColorAspects(
- aspects)));
+ mBase->setColorAspects(toCompactColorAspects(aspects));
+ return Void();
}
Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
- return toHardwareStatus(mBase->setTimeOffsetUs(timeOffsetUs));
+ mBase->setTimeOffsetUs(timeOffsetUs);
+ return Void();
}
Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
- return toHardwareStatus(mBase->signalEndOfInputStream());
+ mBase->signalEndOfInputStream();
+ return Void();
}
} // namespace utils
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
index 17a4486..d21de42 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
@@ -23,7 +23,7 @@
#include <frameworks/native/include/binder/Binder.h>
#include <IOMX.h>
-#include <android/IGraphicBufferSource.h>
+#include <android/BnGraphicBufferSource.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/graphics/common/1.0/types.h>
@@ -60,10 +60,11 @@
*/
typedef ::android::IGraphicBufferSource LGraphicBufferSource;
+typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
TGraphicBufferSource;
-struct LWGraphicBufferSource : public LGraphicBufferSource {
+struct LWGraphicBufferSource : public BnGraphicBufferSource {
sp<TGraphicBufferSource> mBase;
LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
::android::binder::Status configure(
@@ -78,8 +79,6 @@
::android::binder::Status setColorAspects(int32_t aspects) override;
::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
::android::binder::Status signalEndOfInputStream() override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWGraphicBufferSource : public TGraphicBufferSource {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
index 07c9255..00f40cd 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
@@ -79,10 +79,6 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
-::android::IBinder* LWOmx::onAsBinder() {
- return nullptr;
-}
-
// TWOmx
TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
}
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.h b/media/libstagefright/omx/hal/1.0/utils/WOmx.h
index 26affad..73adc55 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmx.h
@@ -45,6 +45,7 @@
using ::android::List;
using ::android::IOMX;
+using ::android::BnOMX;
/**
* Wrapper classes for conversion
@@ -55,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmx : public IOMX {
+struct LWOmx : public BnOMX {
sp<IOmx> mBase;
LWOmx(sp<IOmx> const& base);
status_t listNodes(List<IOMX::ComponentInfo>* list) override;
@@ -66,8 +67,6 @@
status_t createInputSurface(
sp<::android::IGraphicBufferProducer>* bufferProducer,
sp<::android::IGraphicBufferSource>* bufferSource) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmx : public IOmx {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
index 49f2706..cfb0cce 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
@@ -203,7 +203,8 @@
Return<void> TWOmxBufferProducer::connect(
const sp<IOmxProducerListener>& listener,
int32_t api, bool producerControlledByApp, connect_cb _hidl_cb) {
- sp<IProducerListener> lListener = new LWOmxProducerListener(listener);
+ sp<IProducerListener> lListener = listener == nullptr ?
+ nullptr : new LWOmxProducerListener(listener);
IGraphicBufferProducer::QueueBufferOutput lOutput;
status_t status = mBase->connect(lListener,
static_cast<int>(api),
@@ -479,7 +480,8 @@
status_t LWOmxBufferProducer::connect(
const sp<IProducerListener>& listener, int api,
bool producerControlledByApp, QueueBufferOutput* output) {
- sp<IOmxProducerListener> tListener = new TWOmxProducerListener(listener);
+ sp<IOmxProducerListener> tListener = listener == nullptr ?
+ nullptr : new TWOmxProducerListener(listener);
status_t fnStatus;
status_t transStatus = toStatusT(mBase->connect(
tListener, static_cast<int32_t>(api), producerControlledByApp,
@@ -582,10 +584,6 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
-::android::IBinder* LWOmxBufferProducer::onAsBinder() {
- return nullptr;
-}
-
} // namespace utils
} // namespace V1_0
} // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
index 46abd27..a5d2961 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
@@ -47,6 +47,7 @@
using ::android::sp;
using ::android::IGraphicBufferProducer;
+using ::android::BnGraphicBufferProducer;
using ::android::IProducerListener;
struct TWOmxBufferProducer : public IOmxBufferProducer {
@@ -91,7 +92,7 @@
Return<void> getUniqueId(getUniqueId_cb _hidl_cb) override;
};
-struct LWOmxBufferProducer : public IGraphicBufferProducer {
+struct LWOmxBufferProducer : public BnGraphicBufferProducer {
sp<IOmxBufferProducer> mBase;
LWOmxBufferProducer(sp<IOmxBufferProducer> const& base);
@@ -128,8 +129,6 @@
sp<Fence>* outFence, float outTransformMatrix[16]) override;
void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
status_t getUniqueId(uint64_t* outId) const override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
} // namespace utils
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
index 1ebd9a7..f3f5b9d 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
@@ -61,38 +61,34 @@
::android::binder::Status status = toBinderStatus(
mBase->onInputBufferEmptied(
static_cast<uint32_t>(bufferId), fence));
- if (native_handle_delete(fenceNh) != 0) {
- return ::android::binder::Status::fromExceptionCode(
- ::android::binder::Status::EX_NULL_POINTER,
- "Cannot delete native handle");
- }
+ native_handle_close(fenceNh);
+ native_handle_delete(fenceNh);
return status;
}
-::android::IBinder* LWOmxBufferSource::onAsBinder() {
- return nullptr;
-}
-
// TWOmxBufferSource
TWOmxBufferSource::TWOmxBufferSource(sp<IOMXBufferSource> const& base) :
mBase(base) {
}
Return<void> TWOmxBufferSource::onOmxExecuting() {
- return toHardwareStatus(mBase->onOmxExecuting());
+ mBase->onOmxExecuting();
+ return Void();
}
Return<void> TWOmxBufferSource::onOmxIdle() {
- return toHardwareStatus(mBase->onOmxIdle());
+ mBase->onOmxIdle();
+ return Void();
}
Return<void> TWOmxBufferSource::onOmxLoaded() {
- return toHardwareStatus(mBase->onOmxLoaded());
+ mBase->onOmxLoaded();
+ return Void();
}
Return<void> TWOmxBufferSource::onInputBufferAdded(uint32_t buffer) {
- return toHardwareStatus(mBase->onInputBufferAdded(
- static_cast<int32_t>(buffer)));
+ mBase->onInputBufferAdded(int32_t(buffer));
+ return Void();
}
Return<void> TWOmxBufferSource::onInputBufferEmptied(
@@ -102,8 +98,8 @@
return ::android::hardware::Status::fromExceptionCode(
::android::hardware::Status::EX_BAD_PARCELABLE);
}
- return toHardwareStatus(mBase->onInputBufferEmptied(
- static_cast<int32_t>(buffer), fenceParcelable));
+ mBase->onInputBufferEmptied(int32_t(buffer), fenceParcelable);
+ return Void();
}
} // namespace utils
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
index 3bf35c5..1214300 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
@@ -22,7 +22,7 @@
#include <hidl/Status.h>
#include <frameworks/native/include/binder/Binder.h>
-#include <android/IOMXBufferSource.h>
+#include <android/BnOMXBufferSource.h>
#include <OMXFenceParcelable.h>
namespace android {
@@ -45,6 +45,7 @@
using ::android::OMXFenceParcelable;
using ::android::IOMXBufferSource;
+using ::android::BnOMXBufferSource;
/**
* Wrapper classes for conversion
@@ -55,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxBufferSource : public IOMXBufferSource {
+struct LWOmxBufferSource : public BnOMXBufferSource {
sp<IOmxBufferSource> mBase;
LWOmxBufferSource(sp<IOmxBufferSource> const& base);
::android::binder::Status onOmxExecuting() override;
@@ -64,8 +65,6 @@
::android::binder::Status onInputBufferAdded(int32_t bufferID) override;
::android::binder::Status onInputBufferEmptied(
int32_t bufferID, OMXFenceParcelable const& fenceParcel) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxBufferSource : public IOmxBufferSource {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
index 6764ba8..3bb7a99 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
@@ -252,10 +252,6 @@
return toStatusT(mBase->setQuirks(static_cast<uint32_t>(quirks)));;
}
-::android::IBinder* LWOmxNode::onAsBinder() {
- return nullptr;
-}
-
// TWOmxNode
TWOmxNode::TWOmxNode(sp<IOMXNode> const& base) : mBase(base) {
}
@@ -281,7 +277,8 @@
}
Return<Status> TWOmxNode::setParameter(
- uint32_t index, hidl_vec<uint8_t> const& params) {
+ uint32_t index, hidl_vec<uint8_t> const& inParams) {
+ hidl_vec<uint8_t> params(inParams);
return toStatus(mBase->setParameter(
toEnumIndexType(index),
static_cast<void const*>(params.data()),
@@ -301,7 +298,8 @@
}
Return<Status> TWOmxNode::setConfig(
- uint32_t index, const hidl_vec<uint8_t>& config) {
+ uint32_t index, const hidl_vec<uint8_t>& inConfig) {
+ hidl_vec<uint8_t> config(inConfig);
return toStatus(mBase->setConfig(
toEnumIndexType(index),
static_cast<void const*>(config.data()),
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
index cb0b1a7..9c4bb4a 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
@@ -56,7 +56,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxNode : public IOMXNode {
+struct LWOmxNode : public BnOMXNode {
sp<IOmxNode> mBase;
LWOmxNode(sp<IOmxNode> const& base);
status_t freeNode() override;
@@ -103,8 +103,6 @@
// TODO: this is temporary, will be removed when quirks move to OMX side.
status_t setQuirks(OMX_U32 quirks) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxNode : public IOmxNode {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
index fea5a9a..db971f8 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
@@ -50,10 +50,6 @@
}
}
-::android::IBinder* LWOmxObserver::onAsBinder() {
- return nullptr;
-}
-
// TWOmxObserver
TWOmxObserver::TWOmxObserver(sp<IOMXObserver> const& base) : mBase(base) {
}
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
index b1e2eb1..b9eb412 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
@@ -43,6 +43,7 @@
using ::android::sp;
using ::android::IOMXObserver;
+using ::android::BnOMXObserver;
using ::android::omx_message;
/**
@@ -54,12 +55,10 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxObserver : public IOMXObserver {
+struct LWOmxObserver : public BnOMXObserver {
sp<IOmxObserver> mBase;
LWOmxObserver(sp<IOmxObserver> const& base);
void onMessages(std::list<omx_message> const& lMessages) override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
struct TWOmxObserver : public IOmxObserver {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
index d43215d..80b0f71 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
@@ -52,11 +52,6 @@
return static_cast<bool>(mBase->needsReleaseNotify());
}
-::android::IBinder* LWOmxProducerListener::onAsBinder() {
- return nullptr;
-}
-
-
} // namespace utils
} // namespace V1_0
} // namespace omx
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
index 5b5e830..2be077b 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
@@ -42,6 +42,7 @@
using ::android::sp;
using ::android::IProducerListener;
+using ::android::BnProducerListener;
struct TWOmxProducerListener : public IOmxProducerListener {
sp<IProducerListener> mBase;
@@ -50,14 +51,12 @@
Return<bool> needsReleaseNotify() override;
};
-class LWOmxProducerListener : public IProducerListener {
+class LWOmxProducerListener : public BnProducerListener {
public:
sp<IOmxProducerListener> mBase;
LWOmxProducerListener(sp<IOmxProducerListener> const& base);
void onBufferReleased() override;
bool needsReleaseNotify() override;
-protected:
- ::android::IBinder* onAsBinder() override;
};
} // namespace utils
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 6df2065..1583218 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -62,8 +62,13 @@
constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE;
constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE;
+static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
+static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");
+
constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
+constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
+
struct func_desc {
struct usb_interface_descriptor intf;
struct usb_endpoint_descriptor_no_audio sink;
@@ -459,19 +464,28 @@
mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", USB_FFS_MAX_WRITE);
mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", USB_FFS_MAX_READ);
- while (mMaxWrite > USB_FFS_MAX_WRITE && mMaxRead > USB_FFS_MAX_READ) {
+ size_t attempts = 0;
+ while (mMaxWrite >= USB_FFS_MAX_WRITE && mMaxRead >= USB_FFS_MAX_READ &&
+ attempts < ENDPOINT_ALLOC_RETRIES) {
// If larger contiguous chunks of memory aren't available, attempt to try
// smaller allocations.
if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxWrite)) ||
ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxRead))) {
+ if (errno == ENODEV) {
+ // Driver hasn't enabled endpoints yet.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ attempts += 1;
+ continue;
+ }
mMaxWrite /= 2;
mMaxRead /=2;
} else {
return 0;
}
}
+ // Try to start MtpServer anyway, with the smallest max r/w values
PLOG(ERROR) << "Functionfs could not allocate any memory!";
- return -1;
+ return 0;
}
int MtpFfsHandle::configure(bool usePtp) {
@@ -583,7 +597,7 @@
uint64_t file_length = mfr.length;
uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE),
file_length + sizeof(mtp_data_header));
- uint64_t offset = 0;
+ uint64_t offset = mfr.offset;
struct usb_endpoint_descriptor mBulkIn_desc;
int packet_size;
@@ -594,7 +608,10 @@
packet_size = mBulkIn_desc.wMaxPacketSize;
}
- int init_read_len = packet_size - sizeof(mtp_data_header);
+ // If file_length is larger than a size_t, truncating would produce the wrong comparison.
+ // Instead, promote the left side to 64 bits, then truncate the small result.
+ int init_read_len = std::min(
+ static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length);
char *data = mBuffer1.data();
char *data2 = mBuffer2.data();
@@ -620,10 +637,10 @@
if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) +
sizeof(mtp_data_header), init_read_len, offset))
!= init_read_len) return -1;
+ if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
+ if (file_length == static_cast<unsigned>(init_read_len)) return 0;
file_length -= init_read_len;
offset += init_read_len;
- if (writeHandle(mBulkIn, data, packet_size) == -1) return -1;
- if (file_length == 0) return 0;
// Break down the file into pieces that fit in buffers
while(file_length > 0) {
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index 44ff0f3..b4d5a97 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -59,6 +59,10 @@
int sendFile(mtp_file_range mfr);
int sendEvent(mtp_event me);
+ /**
+ * Open ffs endpoints and allocate necessary kernel and user memory.
+ * Will sleep until endpoints are enabled, for up to 1 second.
+ */
int start();
void close();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 17f6b5a..0547a69 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -651,22 +651,6 @@
return String8(formattedTime);
}
-int CameraService::getCameraPriorityFromProcState(int procState) {
- // Find the priority for the camera usage based on the process state. Higher priority clients
- // win for evictions.
- if (procState < 0) {
- ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__,
- procState);
- return -1;
- }
- // Treat sleeping TOP processes the same as regular TOP processes, for
- // access priority. This is important for lock-screen camera launch scenarios
- if (procState == PROCESS_STATE_TOP_SLEEPING) {
- procState = PROCESS_STATE_TOP;
- }
- return INT_MAX - procState;
-}
-
Status CameraService::getCameraVendorTagDescriptor(
/*out*/
hardware::camera2::params::VendorTagDescriptor* desc) {
@@ -1212,20 +1196,24 @@
std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
ownerPids.push_back(clientPid);
- // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking
- // address of PROCESS_STATE_NONEXISTENT as a reference argument
- // for the vector constructor. PROCESS_STATE_NONEXISTENT does
- // not have an out-of-class definition.
- std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT);
+ std::vector<int> priorityScores(ownerPids.size());
+ std::vector<int> states(ownerPids.size());
- // Get priorites of all active PIDs
- ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0],
- /*out*/&priorities[0]);
+ // Get priority scores of all active PIDs
+ status_t err = ProcessInfoService::getProcessStatesScoresFromPids(
+ ownerPids.size(), &ownerPids[0], /*out*/&states[0],
+ /*out*/&priorityScores[0]);
+ if (err != OK) {
+ ALOGE("%s: Priority score query failed: %d",
+ __FUNCTION__, err);
+ return err;
+ }
// Update all active clients' priorities
- std::map<int,int> pidToPriorityMap;
+ std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
for (size_t i = 0; i < ownerPids.size() - 1; i++) {
- pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i]));
+ pidToPriorityMap.emplace(ownerPids[i],
+ resource_policy::ClientPriority(priorityScores[i], states[i]));
}
mActiveClientManager.updatePriorities(pidToPriorityMap);
@@ -1242,7 +1230,9 @@
clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
state->getConflicting(),
- getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid);
+ priorityScores[priorityScores.size() - 1],
+ clientPid,
+ states[states.size() - 1]);
// Find clients that would be evicted
auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
@@ -1259,19 +1249,22 @@
mActiveClientManager.getIncompatibleClients(clientDescriptor);
String8 msg = String8::format("%s : DENIED connect device %s client for package %s "
- "(PID %d, priority %d) due to eviction policy", curTime.string(),
+ "(PID %d, score %d state %d) due to eviction policy", curTime.string(),
cameraId.string(), packageName.string(), clientPid,
- getCameraPriorityFromProcState(priorities[priorities.size() - 1]));
+ priorityScores[priorityScores.size() - 1],
+ states[states.size() - 1]);
for (auto& i : incompatibleClients) {
msg.appendFormat("\n - Blocked by existing device %s client for package %s"
- "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
- String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
- i->getPriority());
+ "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
+ i->getKey().string(),
+ String8{i->getValue()->getPackageName()}.string(),
+ i->getOwnerId(), i->getPriority().getScore(),
+ i->getPriority().getState());
ALOGE(" Conflicts with: Device %s, client package %s (PID %"
- PRId32 ", priority %" PRId32 ")", i->getKey().string(),
+ PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(),
String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
- i->getPriority());
+ i->getPriority().getScore(), i->getPriority().getState());
}
// Log the client's attempt
@@ -1299,12 +1292,14 @@
// Log the clients evicted
logEvent(String8::format("EVICT device %s client held by package %s (PID"
- " %" PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for"
- " package %s (PID %d, priority %" PRId32 ")",
+ " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
+ " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
i->getKey().string(), String8{clientSp->getPackageName()}.string(),
- i->getOwnerId(), i->getPriority(), cameraId.string(),
+ i->getOwnerId(), i->getPriority().getScore(),
+ i->getPriority().getState(), cameraId.string(),
packageName.string(), clientPid,
- getCameraPriorityFromProcState(priorities[priorities.size() - 1])));
+ priorityScores[priorityScores.size() - 1],
+ states[states.size() - 1]));
// Notify the client of disconnection
clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
@@ -2135,9 +2130,11 @@
// Log the clients evicted
logEvent(String8::format("EVICT device %s client held by package %s (PID %"
- PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.",
- i->getKey().string(), String8{clientSp->getPackageName()}.string(),
- i->getOwnerId(), i->getPriority()));
+ PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due"
+ " to user switch.", i->getKey().string(),
+ String8{clientSp->getPackageName()}.string(),
+ i->getOwnerId(), i->getPriority().getScore(),
+ i->getPriority().getState()));
}
@@ -2673,7 +2670,8 @@
String8 key = i->getKey();
int32_t cost = i->getCost();
int32_t pid = i->getOwnerId();
- int32_t priority = i->getPriority();
+ int32_t score = i->getPriority().getScore();
+ int32_t state = i->getPriority().getState();
auto conflicting = i->getConflicting();
auto clientSp = i->getValue();
String8 packageName;
@@ -2683,8 +2681,8 @@
uid_t clientUid = clientSp->getClientUid();
clientUserId = multiuser_get_user_id(clientUid);
}
- ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %"
- PRId32 ", ", key.string(), cost, pid, priority);
+ ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
+ PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state);
if (clientSp.get() != nullptr) {
ret.appendFormat("User Id: %d, ", clientUserId);
@@ -2706,16 +2704,18 @@
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
const String8& key, const sp<BasicClient>& value, int32_t cost,
- const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) {
+ const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
+ int32_t state) {
return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
- key, value, cost, conflictingKeys, priority, ownerId);
+ key, value, cost, conflictingKeys, score, ownerId, state);
}
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
- partial->getConflicting(), partial->getPriority(), partial->getOwnerId());
+ partial->getConflicting(), partial->getPriority().getScore(),
+ partial->getOwnerId(), partial->getPriority().getState());
}
// ----------------------------------------------------------------------------
@@ -2786,21 +2786,23 @@
}
auto clientDescriptor = mActiveClientManager.get(cameraId);
- if (clientDescriptor == nullptr) {
+ if (clientDescriptor != nullptr) {
+ dprintf(fd, " Device %s is open. Client instance dump:\n",
+ cameraId.string());
+ dprintf(fd, " Client priority score: %d state: %d\n",
+ clientDescriptor->getPriority().getScore(),
+ clientDescriptor->getPriority().getState());
+ 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);
+ } else {
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());
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index d463b59..c7acdc9 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -75,11 +75,6 @@
API_2 = 2
};
- // Process state (mirrors frameworks/base/core/java/android/app/ActivityManager.java)
- static const int PROCESS_STATE_NONEXISTENT = -1;
- static const int PROCESS_STATE_TOP = 2;
- static const int PROCESS_STATE_TOP_SLEEPING = 5;
-
// 3 second busy timeout when other clients are connecting
static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000;
@@ -402,8 +397,8 @@
* Make a ClientDescriptor object wrapping the given BasicClient strong pointer.
*/
static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
- int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority,
- int32_t ownerId);
+ int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
+ int32_t ownerId, int32_t state);
/**
* Make a ClientDescriptor object wrapping the given BasicClient strong pointer with
@@ -775,11 +770,6 @@
*/
static String8 getFormattedCurrentTime();
- /**
- * Get the camera eviction priority from the current process state given by ActivityManager.
- */
- static int getCameraPriorityFromProcState(int procState);
-
static binder::Status makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 5a5d7b7..d45891f 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -19,6 +19,7 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferAlloc.h>
#include <private/gui/ComposerService.h>
#include <utils/Log.h>
#include <utils/Trace.h>
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index b5b86a3..f44c4a3 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -26,6 +26,8 @@
namespace android {
+class IGraphicBufferAlloc;
+
namespace camera3 {
struct StreamInfo;
diff --git a/services/camera/libcameraservice/utils/ClientManager.h b/services/camera/libcameraservice/utils/ClientManager.h
index 830c50b..d7135f1 100644
--- a/services/camera/libcameraservice/utils/ClientManager.h
+++ b/services/camera/libcameraservice/utils/ClientManager.h
@@ -31,6 +31,43 @@
namespace android {
namespace resource_policy {
+class ClientPriority {
+public:
+ ClientPriority(int32_t score, int32_t state) :
+ mScore(score), mState(state) {}
+
+ int32_t getScore() const { return mScore; }
+ int32_t getState() const { return mState; }
+
+ bool operator==(const ClientPriority& rhs) const {
+ return (this->mScore == rhs.mScore) && (this->mState == rhs.mState);
+ }
+
+ bool operator< (const ClientPriority& rhs) const {
+ if (this->mScore == rhs.mScore) {
+ return this->mState < rhs.mState;
+ } else {
+ return this->mScore < rhs.mScore;
+ }
+ }
+
+ bool operator> (const ClientPriority& rhs) const {
+ return rhs < *this;
+ }
+
+ bool operator<=(const ClientPriority& rhs) const {
+ return !(*this > rhs);
+ }
+
+ bool operator>=(const ClientPriority& rhs) const {
+ return !(*this < rhs);
+ }
+
+private:
+ int32_t mScore;
+ int32_t mState;
+};
+
// --------------------------------------------------------------------------------
/**
@@ -45,9 +82,9 @@
class ClientDescriptor final {
public:
ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
- const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId);
+ const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state);
ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys,
- int32_t priority, int32_t ownerId);
+ int32_t score, int32_t ownerId, int32_t state);
~ClientDescriptor();
@@ -69,7 +106,7 @@
/**
* Return the priority for this descriptor.
*/
- int32_t getPriority() const;
+ const ClientPriority &getPriority() const;
/**
* Return the owner ID for this descriptor.
@@ -89,7 +126,7 @@
/**
* Set the proirity for this descriptor.
*/
- void setPriority(int32_t priority);
+ void setPriority(const ClientPriority& priority);
// This class is ordered by key
template<class K, class V>
@@ -100,7 +137,7 @@
VALUE mValue;
int32_t mCost;
std::set<KEY> mConflicting;
- int32_t mPriority;
+ ClientPriority mPriority;
int32_t mOwnerId;
}; // class ClientDescriptor
@@ -111,16 +148,17 @@
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost,
- const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId) : mKey{key},
- mValue{value}, mCost{cost}, mConflicting{conflictingKeys}, mPriority{priority},
+ const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) :
+ mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys},
+ mPriority(score, state),
mOwnerId{ownerId} {}
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost,
- std::set<KEY>&& conflictingKeys, int32_t priority, int32_t ownerId) :
+ std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) :
mKey{std::forward<KEY>(key)}, mValue{std::forward<VALUE>(value)}, mCost{cost},
- mConflicting{std::forward<std::set<KEY>>(conflictingKeys)}, mPriority{priority},
- mOwnerId{ownerId} {}
+ mConflicting{std::forward<std::set<KEY>>(conflictingKeys)},
+ mPriority(score, state), mOwnerId{ownerId} {}
template<class KEY, class VALUE>
ClientDescriptor<KEY, VALUE>::~ClientDescriptor() {}
@@ -141,7 +179,7 @@
}
template<class KEY, class VALUE>
-int32_t ClientDescriptor<KEY, VALUE>::getPriority() const {
+const ClientPriority& ClientDescriptor<KEY, VALUE>::getPriority() const {
return mPriority;
}
@@ -165,7 +203,7 @@
}
template<class KEY, class VALUE>
-void ClientDescriptor<KEY, VALUE>::setPriority(int32_t priority) {
+void ClientDescriptor<KEY, VALUE>::setPriority(const ClientPriority& priority) {
mPriority = priority;
}
@@ -231,7 +269,7 @@
* Given a map containing owner (pid) -> priority mappings, update the priority of each
* ClientDescriptor with an owner in this mapping.
*/
- void updatePriorities(const std::map<int32_t,int32_t>& ownerPriorityList);
+ void updatePriorities(const std::map<int32_t,ClientPriority>& ownerPriorityList);
/**
* Remove all ClientDescriptors.
@@ -383,17 +421,17 @@
const KEY& key = client->getKey();
int32_t cost = client->getCost();
- int32_t priority = client->getPriority();
+ ClientPriority priority = client->getPriority();
int32_t owner = client->getOwnerId();
int64_t totalCost = getCurrentCostLocked() + cost;
// Determine the MRU of the owners tied for having the highest priority
int32_t highestPriorityOwner = owner;
- int32_t highestPriority = priority;
+ ClientPriority highestPriority = priority;
for (const auto& i : mClients) {
- int32_t curPriority = i->getPriority();
- if (curPriority >= highestPriority) {
+ ClientPriority curPriority = i->getPriority();
+ if (curPriority <= highestPriority) {
highestPriority = curPriority;
highestPriorityOwner = i->getOwnerId();
}
@@ -408,7 +446,7 @@
for (const auto& i : mClients) {
const KEY& curKey = i->getKey();
int32_t curCost = i->getCost();
- int32_t curPriority = i->getPriority();
+ ClientPriority curPriority = i->getPriority();
int32_t curOwner = i->getOwnerId();
bool conflicting = (curKey == key || i->isConflicting(key) ||
@@ -417,13 +455,13 @@
if (!returnIncompatibleClients) {
// Find evicted clients
- if (conflicting && curPriority > priority) {
+ if (conflicting && curPriority < priority) {
// Pre-existing conflicting client with higher priority exists
evictList.clear();
evictList.push_back(client);
return evictList;
} else if (conflicting || ((totalCost > mMaxCost && curCost > 0) &&
- (curPriority <= priority) &&
+ (curPriority >= priority) &&
!(highestPriorityOwner == owner && owner == curOwner))) {
// Add a pre-existing client to the eviction list if:
// - We are adding a client with higher priority that conflicts with this one.
@@ -437,7 +475,7 @@
} else {
// Find clients preventing the incoming client from being added
- if (curPriority > priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) {
+ if (curPriority < priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) {
// Pre-existing conflicting client with higher priority exists
evictList.push_back(i);
}
@@ -524,7 +562,7 @@
template<class KEY, class VALUE, class LISTENER>
void ClientManager<KEY, VALUE, LISTENER>::updatePriorities(
- const std::map<int32_t,int32_t>& ownerPriorityList) {
+ const std::map<int32_t,ClientPriority>& ownerPriorityList) {
Mutex::Autolock lock(mLock);
for (auto& i : mClients) {
auto j = ownerPriorityList.find(i->getOwnerId());
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 2bf2201..a49d715 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -24,6 +24,7 @@
libbinder \
liblog \
libmediadrm \
+ libhidltransport \
libutils
ifeq ($(ENABLE_TREBLE), true)
LOCAL_SHARED_LIBRARIES += \
diff --git a/services/radio/RadioService.cpp b/services/radio/RadioService.cpp
index a73ed8f..f7a73c3 100644
--- a/services/radio/RadioService.cpp
+++ b/services/radio/RadioService.cpp
@@ -68,10 +68,11 @@
radio_properties_t properties;
properties.handle =
(radio_handle_t)android_atomic_inc(&mNextUniqueId);
-
- ALOGI("loaded default module %s, handle %d", properties.product, properties.handle);
-
convertProperties(&properties, &halProperties);
+
+ ALOGI("loaded default module %s, ver %s, handle %d", properties.product,
+ properties.version, properties.handle);
+
sp<Module> module = new Module(dev, properties);
mModules.add(properties.handle, module);
}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 54f9b95..78845b7 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -923,7 +923,10 @@
void SoundTriggerHwService::ModuleClient::onFirstRef()
{
- IInterface::asBinder(mClient)->linkToDeath(this);
+ sp<IBinder> binder = IInterface::asBinder(mClient);
+ if (binder != 0) {
+ binder->linkToDeath(this);
+ }
}
SoundTriggerHwService::ModuleClient::~ModuleClient()