Merge "MediaController2: Match APIs with MediaPlayerBase" into pi-dev
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 6b25302..2a3e668 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -67,8 +67,6 @@
, mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
, mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
{
- ALOGD("%s - mWakeupDelayNanos = %d, mMinimumSleepNanos = %d",
- __func__, mWakeupDelayNanos, mMinimumSleepNanos);
}
AudioStreamInternal::~AudioStreamInternal() {
@@ -231,8 +229,7 @@
aaudio_result_t AudioStreamInternal::close() {
aaudio_result_t result = AAUDIO_OK;
- ALOGD("close(): mServiceStreamHandle = 0x%08X",
- mServiceStreamHandle);
+ ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) {
// Don't close a stream while it is running.
aaudio_stream_state_t currentState = getState();
@@ -243,8 +240,8 @@
result = waitForStateChange(currentState, &nextState,
timeoutNanoseconds);
if (result != AAUDIO_OK) {
- ALOGE("close() waitForStateChange() returned %d %s",
- result, AAudio_convertResultToText(result));
+ ALOGE("%s() waitForStateChange() returned %d %s",
+ __func__, result, AAudio_convertResultToText(result));
}
}
setState(AAUDIO_STREAM_STATE_CLOSING);
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 11b43c3..0c3b1fa 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -57,8 +57,7 @@
return result;
}
if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
- ALOGE("requestPauseInternal() mServiceStreamHandle invalid = 0x%08X",
- mServiceStreamHandle);
+ ALOGE("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -70,8 +69,7 @@
aaudio_result_t AudioStreamInternalPlay::requestFlush() {
if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
- ALOGE("AudioStreamInternal::requestFlush() mServiceStreamHandle invalid = 0x%08X",
- mServiceStreamHandle);
+ ALOGE("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -86,7 +84,7 @@
// Bump offset so caller does not see the retrograde motion in getFramesRead().
int64_t offset = writeCounter - readCounter;
mFramesOffsetFromService += offset;
- ALOGD("advanceClientToMatchServerPosition() readN = %lld, writeN = %lld, offset = %lld",
+ ALOGV("%s() readN = %lld, writeN = %lld, offset = %lld", __func__,
(long long)readCounter, (long long)writeCounter, (long long)mFramesOffsetFromService);
// Force writeCounter to match readCounter.
@@ -100,9 +98,7 @@
// Write the data, block if needed and timeoutMillis > 0
aaudio_result_t AudioStreamInternalPlay::write(const void *buffer, int32_t numFrames,
- int64_t timeoutNanoseconds)
-
-{
+ int64_t timeoutNanoseconds) {
return processData((void *)buffer, numFrames, timeoutNanoseconds);
}
@@ -121,7 +117,7 @@
// Still haven't got any timestamps from server.
// Keep waiting until we get some valid timestamps then start writing to the
// current buffer position.
- ALOGD("processDataNow() wait for valid timestamps");
+ ALOGD("%s() wait for valid timestamps", __func__);
// Sleep very briefly and hope we get a timestamp soon.
*wakeTimePtr = currentNanoTime + (2000 * AAUDIO_NANOS_PER_MICROSECOND);
ATRACE_END();
@@ -203,8 +199,6 @@
aaudio_result_t AudioStreamInternalPlay::writeNowWithConversion(const void *buffer,
int32_t numFrames) {
- // ALOGD("AudioStreamInternal::writeNowWithConversion(%p, %d)",
- // buffer, numFrames);
WrappingBuffer wrappingBuffer;
uint8_t *byteBuffer = (uint8_t *) buffer;
int32_t framesLeft = numFrames;
@@ -249,7 +243,6 @@
int32_t framesWritten = numFrames - framesLeft;
mAudioEndpoint.advanceWriteIndex(framesWritten);
- // ALOGD("AudioStreamInternal::writeNowWithConversion() returns %d", framesWritten);
return framesWritten;
}
@@ -268,7 +261,6 @@
} else {
mLastFramesRead = framesRead;
}
- //ALOGD("AudioStreamInternalPlay::getFramesRead() returns %lld", (long long)framesRead);
return framesRead;
}
@@ -276,13 +268,13 @@
{
int64_t framesWritten = mAudioEndpoint.getDataWriteCounter()
+ mFramesOffsetFromService;
- //ALOGD("AudioStreamInternalPlay::getFramesWritten() returns %lld", (long long)framesWritten);
return framesWritten;
}
// Render audio in the application callback and then write the data to the stream.
void *AudioStreamInternalPlay::callbackLoop() {
+ ALOGD("%s() entering >>>>>>>>>>>>>>>", __func__);
aaudio_result_t result = AAUDIO_OK;
aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
if (!isDataCallbackSet()) return NULL;
@@ -297,7 +289,6 @@
// Write audio data to stream. This is a BLOCKING WRITE!
result = write(mCallbackBuffer, mCallbackFrames, timeoutNanos);
if ((result != mCallbackFrames)) {
- ALOGE("AudioStreamInternalPlay(): callbackLoop: write() returned %d", result);
if (result >= 0) {
// Only wrote some of the frames requested. Must have timed out.
result = AAUDIO_ERROR_TIMEOUT;
@@ -306,13 +297,13 @@
break;
}
} else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
- ALOGD("AudioStreamInternalPlay(): callback returned AAUDIO_CALLBACK_RESULT_STOP");
+ ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break;
}
}
- ALOGD("AudioStreamInternalPlay(): callbackLoop() exiting, result = %d, isActive() = %d",
- result, (int) isActive());
+ ALOGD("%s() exiting, result = %d, isActive() = %d <<<<<<<<<<<<<<",
+ __func__, result, (int) isActive());
return NULL;
}
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index c4465fd..61e03db 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -104,17 +104,17 @@
mErrorCallbackUserData = builder.getErrorCallbackUserData();
// This is very helpful for debugging in the future. Please leave it in.
- ALOGI("open() rate = %d, channels = %d, format = %d, sharing = %s, dir = %s",
+ ALOGI("open() rate = %d, channels = %d, format = %d, sharing = %s, dir = %s",
mSampleRate, mSamplesPerFrame, mFormat,
AudioStream_convertSharingModeToShortText(mSharingMode),
(getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
- ALOGI("open() device = %d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
+ ALOGI("open() device = %d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
mDeviceId,
mSessionId,
mPerformanceMode,
(isDataCallbackSet() ? "ON" : "OFF"),
mFramesPerDataCallback);
- ALOGI("open() usage = %d, contentType = %d, inputPreset = %d",
+ ALOGI("open() usage = %d, contentType = %d, inputPreset = %d",
mUsage, mContentType, mInputPreset);
return AAUDIO_OK;
@@ -242,6 +242,22 @@
return close();
}
+void AudioStream::setState(aaudio_stream_state_t state) {
+ ALOGV("%s(%p) from %d to %d", __func__, this, mState, state);
+ // CLOSED is a final state
+ if (mState == AAUDIO_STREAM_STATE_CLOSED) {
+ ALOGE("%s(%p) tried to set to %d but already CLOSED", __func__, this, state);
+
+ // Once DISCONNECTED, we can only move to CLOSED state.
+ } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
+ && state != AAUDIO_STREAM_STATE_CLOSED) {
+ ALOGE("%s(%p) tried to set to %d but already DISCONNECTED", __func__, this, state);
+
+ } else {
+ mState = state;
+ }
+}
+
aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
aaudio_stream_state_t *nextState,
int64_t timeoutNanoseconds)
@@ -313,7 +329,9 @@
setPeriodNanoseconds(periodNanoseconds);
int err = pthread_create(&mThread, nullptr, AudioStream_internalThreadProc, this);
if (err != 0) {
- return AAudioConvert_androidToAAudioResult(-errno);
+ android::status_t status = -errno;
+ ALOGE("createThread() - pthread_create() failed, %d", status);
+ return AAudioConvert_androidToAAudioResult(status);
} else {
// TODO Use AAudioThread or maybe AndroidThread
// Name the thread with an increasing index, "AAudio_#", for debugging.
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index c0db0f9..5273e36 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -471,16 +471,7 @@
mFormat = format;
}
- void setState(aaudio_stream_state_t state) {
- if (mState == AAUDIO_STREAM_STATE_CLOSED) {
- ; // CLOSED is a final state
- } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
- && state != AAUDIO_STREAM_STATE_CLOSED) {
- ; // Once DISCONNECTED, we can only move to CLOSED state.
- } else {
- mState = state;
- }
- }
+ void setState(aaudio_stream_state_t state);
void setDeviceId(int32_t deviceId) {
mDeviceId = deviceId;
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 9e96a2b..e5567dc 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -903,7 +903,6 @@
if (mPlayer == 0) {
return INVALID_OPERATION;
}
- return mPlayer->getPlaybackSettings(rate);
status_t ret = mPlayer->getPlaybackSettings(rate);
if (ret == NO_ERROR) {
ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
@@ -925,7 +924,9 @@
status_t MediaPlayer2::getSyncSettings(
AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
Mutex::Autolock _l(mLock);
- if (mPlayer == 0) return INVALID_OPERATION;
+ if (mPlayer == 0) {
+ return INVALID_OPERATION;
+ }
status_t ret = mPlayer->getSyncSettings(sync, videoFps);
if (ret == NO_ERROR) {
ALOGV("getSyncSettings(%u, %u, %f, %f)",
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 9febe12..4f46be7 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -6,6 +6,7 @@
},
srcs: [
+ "Conversion.cpp",
"FrameDropper.cpp",
"GraphicBufferSource.cpp",
"WProducerListener.cpp",
diff --git a/media/libstagefright/bqhelper/Conversion.cpp b/media/libstagefright/bqhelper/Conversion.cpp
new file mode 100644
index 0000000..ffed005
--- /dev/null
+++ b/media/libstagefright/bqhelper/Conversion.cpp
@@ -0,0 +1,1542 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/stagefright/bqhelper/Conversion.h>
+
+namespace android {
+namespace conversion {
+
+// native_handle_t helper functions.
+
+/**
+ * \brief Take an fd and create a native handle containing only the given fd.
+ * The created handle will need to be deleted manually with
+ * `native_handle_delete()`.
+ *
+ * \param[in] fd The source file descriptor (of type `int`).
+ * \return The create `native_handle_t*` that contains the given \p fd. If the
+ * supplied \p fd is negative, the created native handle will contain no file
+ * descriptors.
+ *
+ * If the native handle cannot be created, the return value will be
+ * `nullptr`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+native_handle_t* native_handle_create_from_fd(int fd) {
+ if (fd < 2) {
+ return native_handle_create(0, 0);
+ }
+ native_handle_t* nh = native_handle_create(1, 0);
+ if (nh == nullptr) {
+ return nullptr;
+ }
+ nh->data[0] = fd;
+ return nh;
+}
+
+/**
+ * \brief Extract a file descriptor from a native handle.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \param[in] index The index of the file descriptor in \p nh to read from. This
+ * input has the default value of `0`.
+ * \return The `index`-th file descriptor in \p nh. If \p nh does not have
+ * enough file descriptors, the returned value will be `-1`.
+ *
+ * This function does not duplicate the file descriptor.
+ */
+int native_handle_read_fd(native_handle_t const* nh, int index) {
+ return ((nh == nullptr) || (nh->numFds == 0) ||
+ (nh->numFds <= index) || (index < 0)) ?
+ -1 : nh->data[index];
+}
+
+/**
+ * Conversion functions
+ * ====================
+ *
+ * There are two main directions of conversion:
+ * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
+ * input. The wrapper has type `TargetType`.
+ * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
+ * corresponds to the input. The lifetime of the output does not depend on the
+ * lifetime of the input.
+ * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
+ * that cannot be copied and/or moved efficiently, or when there are multiple
+ * output arguments.
+ * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
+ * `TargetType` that cannot be copied and/or moved efficiently, or when there
+ * are multiple output arguments.
+ *
+ * `wrapIn()` and `convertTo()` functions will take output arguments before
+ * input arguments. Some of these functions might return a value to indicate
+ * success or error.
+ *
+ * In converting or wrapping something as a Treble type that contains a
+ * `hidl_handle`, `native_handle_t*` will need to be created and returned as
+ * an additional output argument, hence only `wrapIn()` or `convertTo()` would
+ * be available. The caller must call `native_handle_delete()` to deallocate the
+ * returned native handle when it is no longer needed.
+ *
+ * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
+ * not perform duplication of file descriptors, while `toTargetType()` and
+ * `convertTo()` do.
+ */
+
+/**
+ * \brief Convert `Return<void>` to `binder::Status`.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `binder::Status`.
+ */
+// convert: Return<void> -> ::android::binder::Status
+::android::binder::Status toBinderStatus(
+ Return<void> const& t) {
+ return ::android::binder::Status::fromExceptionCode(
+ t.isOk() ? OK : UNKNOWN_ERROR,
+ t.description().c_str());
+}
+
+/**
+ * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `status_t`.
+ */
+// convert: Return<void> -> status_t
+status_t toStatusT(Return<void> const& t) {
+ return t.isOk() ? OK : UNKNOWN_ERROR;
+}
+
+/**
+ * \brief Wrap `native_handle_t*` in `hidl_handle`.
+ *
+ * \param[in] nh The source `native_handle_t*`.
+ * \return The `hidl_handle` that points to \p nh.
+ */
+// wrap: native_handle_t* -> hidl_handle
+hidl_handle inHidlHandle(native_handle_t const* nh) {
+ return hidl_handle(nh);
+}
+
+/**
+ * \brief Convert `int32_t` to `Dataspace`.
+ *
+ * \param[in] l The source `int32_t`.
+ * \result The corresponding `Dataspace`.
+ */
+// convert: int32_t -> Dataspace
+Dataspace toHardwareDataspace(int32_t l) {
+ return static_cast<Dataspace>(l);
+}
+
+/**
+ * \brief Convert `Dataspace` to `int32_t`.
+ *
+ * \param[in] t The source `Dataspace`.
+ * \result The corresponding `int32_t`.
+ */
+// convert: Dataspace -> int32_t
+int32_t toRawDataspace(Dataspace const& t) {
+ return static_cast<int32_t>(t);
+}
+
+/**
+ * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that points to the buffer.
+ */
+// wrap: void*, size_t -> hidl_vec<uint8_t>
+hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
+ hidl_vec<uint8_t> t;
+ t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
+ return t;
+}
+
+/**
+ * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
+ *
+ * \param[in] l The pointer to the beginning of the opaque buffer.
+ * \param[in] size The size of the buffer.
+ * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
+ */
+// convert: void*, size_t -> hidl_vec<uint8_t>
+hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
+ hidl_vec<uint8_t> t;
+ t.resize(size);
+ uint8_t const* src = static_cast<uint8_t const*>(l);
+ std::copy(src, src + size, t.data());
+ return t;
+}
+
+/**
+ * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
+ *
+ * \param[out] t The wrapper of type `AnwBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: GraphicBuffer -> AnwBuffer
+void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
+ t->attr.width = l.getWidth();
+ t->attr.height = l.getHeight();
+ t->attr.stride = l.getStride();
+ t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
+ t->attr.layerCount = l.getLayerCount();
+ t->attr.usage = l.getUsage();
+ t->attr.id = l.getId();
+ t->attr.generationNumber = l.getGenerationNumber();
+ t->nativeHandle = hidl_handle(l.handle);
+}
+
+/**
+ * \brief Convert `AnwBuffer` to `GraphicBuffer`.
+ *
+ * \param[out] l The destination `GraphicBuffer`.
+ * \param[in] t The source `AnwBuffer`.
+ *
+ * This function will duplicate all file descriptors in \p t.
+ */
+// convert: AnwBuffer -> GraphicBuffer
+// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
+bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
+ native_handle_t* handle = t.nativeHandle == nullptr ?
+ nullptr : native_handle_clone(t.nativeHandle);
+
+ size_t const numInts = 12 + (handle ? handle->numInts : 0);
+ int32_t* ints = new int32_t[numInts];
+
+ size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
+ int* fds = new int[numFds];
+
+ ints[0] = 'GBFR';
+ ints[1] = static_cast<int32_t>(t.attr.width);
+ ints[2] = static_cast<int32_t>(t.attr.height);
+ ints[3] = static_cast<int32_t>(t.attr.stride);
+ ints[4] = static_cast<int32_t>(t.attr.format);
+ ints[5] = static_cast<int32_t>(t.attr.layerCount);
+ ints[6] = static_cast<int32_t>(t.attr.usage);
+ ints[7] = static_cast<int32_t>(t.attr.id >> 32);
+ ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
+ ints[9] = static_cast<int32_t>(t.attr.generationNumber);
+ ints[10] = 0;
+ ints[11] = 0;
+ if (handle) {
+ ints[10] = static_cast<int32_t>(handle->numFds);
+ ints[11] = static_cast<int32_t>(handle->numInts);
+ int* intsStart = handle->data + handle->numFds;
+ std::copy(handle->data, intsStart, fds);
+ std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
+ }
+
+ void const* constBuffer = static_cast<void const*>(ints);
+ size_t size = numInts * sizeof(int32_t);
+ int const* constFds = static_cast<int const*>(fds);
+ status_t status = l->unflatten(constBuffer, size, constFds, numFds);
+
+ delete [] fds;
+ delete [] ints;
+ native_handle_delete(handle);
+ return status == NO_ERROR;
+}
+
+/**
+ * Conversion functions for types outside media
+ * ============================================
+ *
+ * Some objects in libui and libgui that were made to go through binder calls do
+ * not expose ways to read or write their fields to the public. To pass an
+ * object of this kind through the HIDL boundary, translation functions need to
+ * work around the access restriction by using the publicly available
+ * `flatten()` and `unflatten()` functions.
+ *
+ * All `flatten()` and `unflatten()` overloads follow the same convention as
+ * follows:
+ *
+ * status_t flatten(ObjectType const& object,
+ * [OtherType const& other, ...]
+ * void*& buffer, size_t& size,
+ * int*& fds, size_t& numFds)
+ *
+ * status_t unflatten(ObjectType* object,
+ * [OtherType* other, ...,]
+ * void*& buffer, size_t& size,
+ * int*& fds, size_t& numFds)
+ *
+ * The number of `other` parameters varies depending on the `ObjectType`. For
+ * example, in the process of unflattening an object that contains
+ * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
+ * be created.
+ *
+ * The last four parameters always work the same way in all overloads of
+ * `flatten()` and `unflatten()`:
+ * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
+ * `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
+ * `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
+ * size (in ints) of the fd buffer pointed to by `fds`.
+ * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
+ * from, `size` is the size (in bytes) of the non-fd buffer pointed to by
+ * `buffer`, `fds` is the pointer to the fd buffer to be read from, and
+ * `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
+ * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
+ * will be advanced, while `size` and `numFds` will be decreased to reflect
+ * how much storage/data of the two buffers (fd and non-fd) have been used.
+ * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
+ * `numFds` are invalid.
+ *
+ * The return value of a successful `flatten()` or `unflatten()` call will be
+ * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
+ *
+ * For each object type that supports flattening, there will be two accompanying
+ * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
+ * return the size of the non-fd buffer that the object will need for
+ * flattening. `getFdCount()` will return the size of the fd buffer that the
+ * object will need for flattening.
+ *
+ * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
+ * `flatten()` and `unflatten()`, are similar to functions of the same name in
+ * the abstract class `Flattenable`. The only difference is that functions in
+ * this file are not member functions of the object type. For example, we write
+ *
+ * flatten(x, buffer, size, fds, numFds)
+ *
+ * instead of
+ *
+ * x.flatten(buffer, size, fds, numFds)
+ *
+ * because we cannot modify the type of `x`.
+ *
+ * There is one exception to the naming convention: `hidl_handle` that
+ * represents a fence. The four functions for this "Fence" type have the word
+ * "Fence" attched to their names because the object type, which is
+ * `hidl_handle`, does not carry the special meaning that the object itself can
+ * only contain zero or one file descriptor.
+ */
+
+// Ref: frameworks/native/libs/ui/Fence.cpp
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return The required size of the flat buffer.
+ *
+ * The current version of this function always returns 4, which is the number of
+ * bytes required to store the number of file descriptors contained in the fd
+ * part of the flat buffer.
+ */
+size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
+ return 4;
+};
+
+/**
+ * \brief Return the number of file descriptors contained in a fence.
+ *
+ * \param[in] fence The input fence of type `hidl_handle`.
+ * \return `0` if \p fence does not contain a valid file descriptor, or `1`
+ * otherwise.
+ */
+size_t getFenceFdCount(hidl_handle const& fence) {
+ return native_handle_read_fd(fence) == -1 ? 0 : 1;
+}
+
+/**
+ * \brief Unflatten `Fence` to `hidl_handle`.
+ *
+ * \param[out] fence The destination `hidl_handle`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will point to a newly created
+ * native handle, which needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < 4) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numFdsInHandle;
+ FlattenableUtils::read(buffer, size, numFdsInHandle);
+
+ if (numFdsInHandle > 1) {
+ return BAD_VALUE;
+ }
+
+ if (numFds < numFdsInHandle) {
+ return NO_MEMORY;
+ }
+
+ if (numFdsInHandle) {
+ *nh = native_handle_create_from_fd(*fds);
+ if (*nh == nullptr) {
+ return NO_MEMORY;
+ }
+ *fence = *nh;
+ ++fds;
+ --numFds;
+ } else {
+ *nh = nullptr;
+ *fence = hidl_handle();
+ }
+
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `hidl_handle` as `Fence`.
+ *
+ * \param[in] t The source `hidl_handle`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t flattenFence(hidl_handle const& fence,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFenceFlattenedSize(fence) ||
+ numFds < getFenceFdCount(fence)) {
+ return NO_MEMORY;
+ }
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size,
+ static_cast<uint32_t>(getFenceFdCount(fence)));
+ int fd = native_handle_read_fd(fence);
+ if (fd != -1) {
+ *fds = fd;
+ ++fds;
+ --numFds;
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `Fence` in `hidl_handle`.
+ *
+ * \param[out] t The wrapper of type `hidl_handle`.
+ * \param[out] nh The native handle pointed to by \p t.
+ * \param[in] l The source `Fence`.
+ *
+ * On success, \p nh will hold a newly created native handle, which must be
+ * deleted manually with `native_handle_delete()` afterwards.
+ */
+// wrap: Fence -> hidl_handle
+bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
+ != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `hidl_handle` to `Fence`.
+ *
+ * \param[out] l The destination `Fence`. `l` must not have been used
+ * (`l->isValid()` must return `false`) before this function is called.
+ * \param[in] t The source `hidl_handle`.
+ *
+ * If \p t contains a valid file descriptor, it will be duplicated.
+ */
+// convert: hidl_handle -> Fence
+bool convertTo(Fence* l, hidl_handle const& t) {
+ int fd = native_handle_read_fd(t);
+ if (fd != -1) {
+ fd = dup(fd);
+ if (fd == -1) {
+ return false;
+ }
+ }
+ native_handle_t* nh = native_handle_create_from_fd(fd);
+ if (nh == nullptr) {
+ if (fd != -1) {
+ close(fd);
+ }
+ return false;
+ }
+
+ size_t const baseSize = getFenceFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ native_handle_delete(nh);
+ return false;
+ }
+
+ size_t const baseNumFds = getFenceFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ native_handle_delete(nh);
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
+ native_handle_delete(nh);
+ return false;
+ }
+ native_handle_delete(nh);
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+ HGraphicBufferProducer::FenceTimeSnapshot const& t) {
+ constexpr size_t min = sizeof(t.state);
+ switch (t.state) {
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
+ return min;
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
+ return min + getFenceFlattenedSize(t.fence);
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+ return min + sizeof(
+ ::android::FenceTime::Snapshot::signalTime);
+ }
+ return 0;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FenceTimeSnapshot`.
+ *
+ * \param[in] t The input `FenceTimeSnapshot`.
+ * \return The number of file descriptors contained in \p snapshot.
+ */
+size_t getFdCount(
+ HGraphicBufferProducer::FenceTimeSnapshot const& t) {
+ return t.state ==
+ HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
+ getFenceFdCount(t.fence) : 0;
+}
+
+/**
+ * \brief Flatten `FenceTimeSnapshot`.
+ *
+ * \param[in] t The source `FenceTimeSnapshot`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence` if `t.state ==
+ * FENCE`.
+ */
+status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ switch (t.state) {
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::EMPTY);
+ return NO_ERROR;
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::FENCE);
+ return flattenFence(t.fence, buffer, size, fds, numFds);
+ case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
+ FlattenableUtils::write(buffer, size,
+ ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
+ FlattenableUtils::write(buffer, size, t.signalTimeNs);
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Unflatten `FenceTimeSnapshot`.
+ *
+ * \param[out] t The destination `FenceTimeSnapshot`.
+ * \param[out] nh The underlying native handle.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and the constructed snapshot contains a
+ * file descriptor, \p nh will be created to hold that file descriptor. In this
+ * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
+ */
+status_t unflatten(
+ HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < sizeof(t->state)) {
+ return NO_MEMORY;
+ }
+
+ *nh = nullptr;
+ ::android::FenceTime::Snapshot::State state;
+ FlattenableUtils::read(buffer, size, state);
+ switch (state) {
+ case ::android::FenceTime::Snapshot::State::EMPTY:
+ t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
+ return NO_ERROR;
+ case ::android::FenceTime::Snapshot::State::FENCE:
+ t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
+ return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
+ case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
+ t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
+ if (size < sizeof(t->signalTimeNs)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, t->signalTimeNs);
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
+
+/**
+ * \brief Return a lower bound on the size of the non-fd buffer required to
+ * flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+ HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
+ return sizeof(uint64_t) + // mFrameNumber
+ sizeof(uint8_t) + // mIndex
+ sizeof(uint8_t) + // mAddPostCompositeCalled
+ sizeof(uint8_t) + // mAddRetireCalled
+ sizeof(uint8_t) + // mAddReleaseCalled
+ sizeof(nsecs_t) + // mPostedTime
+ sizeof(nsecs_t) + // mRequestedPresentTime
+ sizeof(nsecs_t) + // mLatchTime
+ sizeof(nsecs_t) + // mFirstRefreshStartTime
+ sizeof(nsecs_t); // mLastRefreshStartTime
+}
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+ HGraphicBufferProducer::FrameEventsDelta const& t) {
+ return minFlattenedSize(t) +
+ getFlattenedSize(t.gpuCompositionDoneFence) +
+ getFlattenedSize(t.displayPresentFence) +
+ getFlattenedSize(t.displayRetireFence) +
+ getFlattenedSize(t.releaseFence);
+};
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `FrameEventsDelta`.
+ *
+ * \param[in] t The input `FrameEventsDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+ HGraphicBufferProducer::FrameEventsDelta const& t) {
+ return getFdCount(t.gpuCompositionDoneFence) +
+ getFdCount(t.displayPresentFence) +
+ getFdCount(t.displayRetireFence) +
+ getFdCount(t.releaseFence);
+};
+
+/**
+ * \brief Unflatten `FrameEventsDelta`.
+ *
+ * \param[out] t The destination `FrameEventsDelta`.
+ * \param[out] nh The underlying array of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
+ * populated with `nullptr` or newly created handles. Each non-null slot in \p
+ * nh will need to be deleted manually with `native_handle_delete()`.
+ */
+status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
+ std::vector<native_handle_t*>* nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < minFlattenedSize(*t)) {
+ return NO_MEMORY;
+ }
+ FlattenableUtils::read(buffer, size, t->frameNumber);
+
+ // These were written as uint8_t for alignment.
+ uint8_t temp = 0;
+ FlattenableUtils::read(buffer, size, temp);
+ size_t index = static_cast<size_t>(temp);
+ if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ t->index = static_cast<uint32_t>(index);
+
+ FlattenableUtils::read(buffer, size, temp);
+ t->addPostCompositeCalled = static_cast<bool>(temp);
+ FlattenableUtils::read(buffer, size, temp);
+ t->addRetireCalled = static_cast<bool>(temp);
+ FlattenableUtils::read(buffer, size, temp);
+ t->addReleaseCalled = static_cast<bool>(temp);
+
+ FlattenableUtils::read(buffer, size, t->postedTimeNs);
+ FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
+ FlattenableUtils::read(buffer, size, t->latchTimeNs);
+ FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
+ FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
+ FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
+
+ // Fences
+ HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
+ tSnapshot[0] = &t->gpuCompositionDoneFence;
+ tSnapshot[1] = &t->displayPresentFence;
+ tSnapshot[2] = &t->displayRetireFence;
+ tSnapshot[3] = &t->releaseFence;
+ nh->resize(4);
+ for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+ status_t status = unflatten(
+ tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ while (snapshotIndex > 0) {
+ --snapshotIndex;
+ if ((*nh)[snapshotIndex] != nullptr) {
+ native_handle_delete((*nh)[snapshotIndex]);
+ }
+ }
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventsDelta`.
+ *
+ * \param[in] t The source `FrameEventsDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
+// FrameEventsDelta::flatten
+status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
+ void*& buffer, size_t& size, int*& fds, size_t numFds) {
+ // Check that t.index is within a valid range.
+ if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
+ || t.index > std::numeric_limits<uint8_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ FlattenableUtils::write(buffer, size, t.frameNumber);
+
+ // These are static_cast to uint8_t for alignment.
+ FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addRetireCalled));
+ FlattenableUtils::write(
+ buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
+
+ FlattenableUtils::write(buffer, size, t.postedTimeNs);
+ FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
+ FlattenableUtils::write(buffer, size, t.latchTimeNs);
+ FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
+ FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
+ FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
+
+ // Fences
+ HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
+ tSnapshot[0] = &t.gpuCompositionDoneFence;
+ tSnapshot[1] = &t.displayPresentFence;
+ tSnapshot[2] = &t.displayRetireFence;
+ tSnapshot[3] = &t.releaseFence;
+ for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
+ status_t status = flatten(
+ *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
+
+/**
+ * \brief Return the size of the non-fd buffer required to flatten
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+ size_t size = 4 + // mDeltas.size()
+ sizeof(t.compositorTiming);
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ size += getFlattenedSize(t.deltas[i]);
+ }
+ return size;
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+ size_t numFds = 0;
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ numFds += getFdCount(t.deltas[i]);
+ }
+ return numFds;
+}
+
+/**
+ * \brief Unflatten `FrameEventHistoryDelta`.
+ *
+ * \param[out] t The destination `FrameEventHistoryDelta`.
+ * \param[out] nh The underlying array of arrays of native handles.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
+ * newly created handles. The second dimension of \p nh will be 4. Each non-null
+ * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
+ */
+status_t unflatten(
+ HGraphicBufferProducer::FrameEventHistoryDelta* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < 4) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::read(buffer, size, t->compositorTiming);
+
+ uint32_t deltaCount = 0;
+ FlattenableUtils::read(buffer, size, deltaCount);
+ if (static_cast<size_t>(deltaCount) >
+ ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ t->deltas.resize(deltaCount);
+ nh->resize(deltaCount);
+ for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
+ status_t status = unflatten(
+ &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `FrameEventHistoryDelta`.
+ *
+ * \param[in] t The source `FrameEventHistoryDelta`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate file descriptors contained in \p t.
+ */
+status_t flatten(
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ return BAD_VALUE;
+ }
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, t.compositorTiming);
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
+ for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
+ status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Wrap `::android::FrameEventHistoryData` in
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `::android::FrameEventHistoryDelta`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ ::android::FrameEventHistoryDelta const& l) {
+
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
+ * `::android::FrameEventHistoryDelta`.
+ *
+ * \param[out] l The destination `::android::FrameEventHistoryDelta`.
+ * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+bool convertTo(
+ ::android::FrameEventHistoryDelta* l,
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
+
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = getFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = static_cast<int*>(baseFds.get());
+ size_t numFds = baseNumFds;
+ if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/ui/Region.cpp
+
+/**
+ * \brief Return the size of the buffer required to flatten `Region`.
+ *
+ * \param[in] t The input `Region`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(Region const& t) {
+ return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
+}
+
+/**
+ * \brief Unflatten `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t unflatten(Region* t, void const*& buffer, size_t& size) {
+ if (size < sizeof(uint32_t)) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numRects = 0;
+ FlattenableUtils::read(buffer, size, numRects);
+ if (size < numRects * sizeof(Rect)) {
+ return NO_MEMORY;
+ }
+ if (numRects > (UINT32_MAX / sizeof(Rect))) {
+ return NO_MEMORY;
+ }
+
+ t->resize(numRects);
+ for (size_t r = 0; r < numRects; ++r) {
+ ::android::Rect rect(::android::Rect::EMPTY_RECT);
+ status_t status = rect.unflatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ (*t)[r] = Rect{
+ static_cast<int32_t>(rect.left),
+ static_cast<int32_t>(rect.top),
+ static_cast<int32_t>(rect.right),
+ static_cast<int32_t>(rect.bottom)};
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Flatten `Region`.
+ *
+ * \param[in] t The source `Region`.
+ * \param[in,out] buffer The pointer to the flat buffer.
+ * \param[in,out] size The size of the flat buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ */
+status_t flatten(Region const& t, void*& buffer, size_t& size) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
+ for (size_t r = 0; r < t.size(); ++r) {
+ ::android::Rect rect(
+ static_cast<int32_t>(t[r].left),
+ static_cast<int32_t>(t[r].top),
+ static_cast<int32_t>(t[r].right),
+ static_cast<int32_t>(t[r].bottom));
+ status_t status = rect.flatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ }
+ return NO_ERROR;
+}
+
+/**
+ * \brief Convert `::android::Region` to `Region`.
+ *
+ * \param[out] t The destination `Region`.
+ * \param[in] l The source `::android::Region`.
+ */
+// convert: ::android::Region -> Region
+bool convertTo(Region* t, ::android::Region const& l) {
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ if (l.flatten(buffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ if (unflatten(t, constBuffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `Region` to `::android::Region`.
+ *
+ * \param[out] l The destination `::android::Region`.
+ * \param[in] t The source `Region`.
+ */
+// convert: Region -> ::android::Region
+bool convertTo(::android::Region* l, Region const& t) {
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ if (flatten(t, buffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ if (l->unflatten(constBuffer, size) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
+// BGraphicBufferProducer::QueueBufferInput
+
+/**
+ * \brief Return a lower bound on the size of the buffer required to flatten
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return A lower bound on the size of the flat buffer.
+ */
+constexpr size_t minFlattenedSize(
+ HGraphicBufferProducer::QueueBufferInput const& /* t */) {
+ return sizeof(int64_t) + // timestamp
+ sizeof(int) + // isAutoTimestamp
+ sizeof(android_dataspace) + // dataSpace
+ sizeof(::android::Rect) + // crop
+ sizeof(int) + // scalingMode
+ sizeof(uint32_t) + // transform
+ sizeof(uint32_t) + // stickyTransform
+ sizeof(bool); // getFrameTimestamps
+}
+
+/**
+ * \brief Return the size of the buffer required to flatten
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return The required size of the flat buffer.
+ */
+size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
+ return minFlattenedSize(t) +
+ getFenceFlattenedSize(t.fence) +
+ getFlattenedSize(t.surfaceDamage) +
+ sizeof(HdrMetadata::validTypes);
+}
+
+/**
+ * \brief Return the number of file descriptors contained in
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
+ * \return The number of file descriptors contained in \p t.
+ */
+size_t getFdCount(
+ HGraphicBufferProducer::QueueBufferInput const& t) {
+ return getFenceFdCount(t.fence);
+}
+
+/**
+ * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The native handle cloned from `t.fence`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * This function will duplicate the file descriptor in `t.fence`. */
+status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
+ native_handle_t** nh,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds) {
+ if (size < getFlattenedSize(t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::write(buffer, size, t.timestamp);
+ FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
+ FlattenableUtils::write(buffer, size,
+ static_cast<android_dataspace_t>(t.dataSpace));
+ FlattenableUtils::write(buffer, size, ::android::Rect(
+ static_cast<int32_t>(t.crop.left),
+ static_cast<int32_t>(t.crop.top),
+ static_cast<int32_t>(t.crop.right),
+ static_cast<int32_t>(t.crop.bottom)));
+ FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
+ FlattenableUtils::write(buffer, size, t.transform);
+ FlattenableUtils::write(buffer, size, t.stickyTransform);
+ FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
+
+ *nh = t.fence.getNativeHandle() == nullptr ?
+ nullptr : native_handle_clone(t.fence);
+ status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = flatten(t.surfaceDamage, buffer, size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
+ return NO_ERROR;
+}
+
+/**
+ * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in,out] buffer The pointer to the flat non-fd buffer.
+ * \param[in,out] size The size of the flat non-fd buffer.
+ * \param[in,out] fds The pointer to the flat fd buffer.
+ * \param[in,out] numFds The size of the flat fd buffer.
+ * \return `NO_ERROR` on success; other value on failure.
+ *
+ * If the return value is `NO_ERROR` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+status_t unflatten(
+ HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
+ if (size < minFlattenedSize(*t)) {
+ return NO_MEMORY;
+ }
+
+ FlattenableUtils::read(buffer, size, t->timestamp);
+ int lIsAutoTimestamp;
+ FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
+ t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
+ android_dataspace_t lDataSpace;
+ FlattenableUtils::read(buffer, size, lDataSpace);
+ t->dataSpace = static_cast<Dataspace>(lDataSpace);
+ Rect lCrop;
+ FlattenableUtils::read(buffer, size, lCrop);
+ t->crop = Rect{
+ static_cast<int32_t>(lCrop.left),
+ static_cast<int32_t>(lCrop.top),
+ static_cast<int32_t>(lCrop.right),
+ static_cast<int32_t>(lCrop.bottom)};
+ int lScalingMode;
+ FlattenableUtils::read(buffer, size, lScalingMode);
+ t->scalingMode = static_cast<int32_t>(lScalingMode);
+ FlattenableUtils::read(buffer, size, t->transform);
+ FlattenableUtils::read(buffer, size, t->stickyTransform);
+ FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
+
+ status_t status = unflattenFence(&(t->fence), nh,
+ buffer, size, fds, numFds);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ // HdrMetadata ignored
+ return unflatten(&(t->surfaceDamage), buffer, size);
+}
+
+/**
+ * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::QueueBufferInput`.
+ * \param[out] nh The underlying native handle for `t->fence`.
+ * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
+ *
+ * If the return value is `true` and `t->fence` contains a valid file
+ * descriptor, \p nh will be a newly created native handle holding that file
+ * descriptor. \p nh needs to be deleted with `native_handle_delete()`
+ * afterwards.
+ */
+bool wrapAs(
+ HGraphicBufferProducer::QueueBufferInput* t,
+ native_handle_t** nh,
+ BGraphicBufferProducer::QueueBufferInput const& l) {
+
+ size_t const baseSize = l.getFlattenedSize();
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = l.getFdCount();
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
+ * `BGraphicBufferProducer::QueueBufferInput`.
+ *
+ * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
+ *
+ * If `t.fence` has a valid file descriptor, it will be duplicated.
+ */
+bool convertTo(
+ BGraphicBufferProducer::QueueBufferInput* l,
+ HGraphicBufferProducer::QueueBufferInput const& t) {
+
+ size_t const baseSize = getFlattenedSize(t);
+ std::unique_ptr<uint8_t[]> baseBuffer(
+ new (std::nothrow) uint8_t[baseSize]);
+ if (!baseBuffer) {
+ return false;
+ }
+
+ size_t const baseNumFds = getFdCount(t);
+ std::unique_ptr<int[]> baseFds(
+ new (std::nothrow) int[baseNumFds]);
+ if (!baseFds) {
+ return false;
+ }
+
+ void* buffer = static_cast<void*>(baseBuffer.get());
+ size_t size = baseSize;
+ int* fds = baseFds.get();
+ size_t numFds = baseNumFds;
+ native_handle_t* nh;
+ if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
+ return false;
+ }
+
+ void const* constBuffer = static_cast<void const*>(baseBuffer.get());
+ size = baseSize;
+ int const* constFds = static_cast<int const*>(baseFds.get());
+ numFds = baseNumFds;
+ if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
+ if (nh != nullptr) {
+ native_handle_close(nh);
+ native_handle_delete(nh);
+ }
+ return false;
+ }
+
+ native_handle_delete(nh);
+ return true;
+}
+
+// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
+// BGraphicBufferProducer::QueueBufferOutput
+
+/**
+ * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
+ * `HGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] t The wrapper of type
+ * `HGraphicBufferProducer::QueueBufferOutput`.
+ * \param[out] nh The array of array of native handles that are referred to by
+ * members of \p t.
+ * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * On success, each member of \p nh will be either `nullptr` or a newly created
+ * native handle. All the non-`nullptr` elements must be deleted individually
+ * with `native_handle_delete()`.
+ */
+// wrap: BGraphicBufferProducer::QueueBufferOutput ->
+// HGraphicBufferProducer::QueueBufferOutput
+bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
+ std::vector<std::vector<native_handle_t*> >* nh,
+ BGraphicBufferProducer::QueueBufferOutput const& l) {
+ if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
+ return false;
+ }
+ t->width = l.width;
+ t->height = l.height;
+ t->transformHint = l.transformHint;
+ t->numPendingBuffers = l.numPendingBuffers;
+ t->nextFrameNumber = l.nextFrameNumber;
+ t->bufferReplaced = l.bufferReplaced;
+ return true;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
+ * `BGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
+ * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
+ *
+ * This function will duplicate all file descriptors contained in \p t.
+ */
+// convert: HGraphicBufferProducer::QueueBufferOutput ->
+// BGraphicBufferProducer::QueueBufferOutput
+bool convertTo(
+ BGraphicBufferProducer::QueueBufferOutput* l,
+ HGraphicBufferProducer::QueueBufferOutput const& t) {
+ if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
+ return false;
+ }
+ l->width = t.width;
+ l->height = t.height;
+ l->transformHint = t.transformHint;
+ l->numPendingBuffers = t.numPendingBuffers;
+ l->nextFrameNumber = t.nextFrameNumber;
+ l->bufferReplaced = t.bufferReplaced;
+ return true;
+}
+
+/**
+ * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
+ * `HGraphicBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
+ * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
+ */
+HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
+ BGraphicBufferProducer::DisconnectMode l) {
+ switch (l) {
+ case BGraphicBufferProducer::DisconnectMode::Api:
+ return HGraphicBufferProducer::DisconnectMode::API;
+ case BGraphicBufferProducer::DisconnectMode::AllLocal:
+ return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
+ }
+ return HGraphicBufferProducer::DisconnectMode::API;
+}
+
+/**
+ * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
+ * `BGraphicBufferProducer::DisconnectMode`.
+ *
+ * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
+ * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
+ */
+BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
+ HGraphicBufferProducer::DisconnectMode t) {
+ switch (t) {
+ case HGraphicBufferProducer::DisconnectMode::API:
+ return BGraphicBufferProducer::DisconnectMode::Api;
+ case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
+ return BGraphicBufferProducer::DisconnectMode::AllLocal;
+ }
+ return BGraphicBufferProducer::DisconnectMode::Api;
+}
+
+} // namespace conversion
+} // namespace android
+
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
index c15fafa..60d8c1e 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef MEDIA_STAGEFRIGHT_CONVERSION_H_
-#define MEDIA_STAGEFRIGHT_CONVERSION_H_
+#ifndef MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
+#define MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
#include <vector>
#include <list>
@@ -83,17 +83,7 @@
*
* This function does not duplicate the file descriptor.
*/
-inline native_handle_t* native_handle_create_from_fd(int fd) {
- if (fd < 2) {
- return native_handle_create(0, 0);
- }
- native_handle_t* nh = native_handle_create(1, 0);
- if (nh == nullptr) {
- return nullptr;
- }
- nh->data[0] = fd;
- return nh;
-}
+native_handle_t* native_handle_create_from_fd(int fd);
/**
* \brief Extract a file descriptor from a native handle.
@@ -106,11 +96,7 @@
*
* This function does not duplicate the file descriptor.
*/
-inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
- return ((nh == nullptr) || (nh->numFds == 0) ||
- (nh->numFds <= index) || (index < 0)) ?
- -1 : nh->data[index];
-}
+int native_handle_read_fd(native_handle_t const* nh, int index = 0);
/**
* Conversion functions
@@ -151,12 +137,7 @@
* \return The corresponding `binder::Status`.
*/
// convert: Return<void> -> ::android::binder::Status
-inline ::android::binder::Status toBinderStatus(
- Return<void> const& t) {
- return ::android::binder::Status::fromExceptionCode(
- t.isOk() ? OK : UNKNOWN_ERROR,
- t.description().c_str());
-}
+::android::binder::Status toBinderStatus(Return<void> const& t);
/**
* \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
@@ -165,9 +146,7 @@
* \return The corresponding `status_t`.
*/
// convert: Return<void> -> status_t
-inline status_t toStatusT(Return<void> const& t) {
- return t.isOk() ? OK : UNKNOWN_ERROR;
-}
+status_t toStatusT(Return<void> const& t);
/**
* \brief Wrap `native_handle_t*` in `hidl_handle`.
@@ -176,9 +155,7 @@
* \return The `hidl_handle` that points to \p nh.
*/
// wrap: native_handle_t* -> hidl_handle
-inline hidl_handle inHidlHandle(native_handle_t const* nh) {
- return hidl_handle(nh);
-}
+hidl_handle inHidlHandle(native_handle_t const* nh);
/**
* \brief Convert `int32_t` to `Dataspace`.
@@ -187,9 +164,7 @@
* \result The corresponding `Dataspace`.
*/
// convert: int32_t -> Dataspace
-inline Dataspace toHardwareDataspace(int32_t l) {
- return static_cast<Dataspace>(l);
-}
+Dataspace toHardwareDataspace(int32_t l);
/**
* \brief Convert `Dataspace` to `int32_t`.
@@ -198,9 +173,7 @@
* \result The corresponding `int32_t`.
*/
// convert: Dataspace -> int32_t
-inline int32_t toRawDataspace(Dataspace const& t) {
- return static_cast<int32_t>(t);
-}
+int32_t toRawDataspace(Dataspace const& t);
/**
* \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
@@ -210,11 +183,7 @@
* \return A `hidl_vec<uint8_t>` that points to the buffer.
*/
// wrap: void*, size_t -> hidl_vec<uint8_t>
-inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
- hidl_vec<uint8_t> t;
- t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
- return t;
-}
+hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size);
/**
* \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
@@ -224,13 +193,7 @@
* \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
*/
// convert: void*, size_t -> hidl_vec<uint8_t>
-inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
- hidl_vec<uint8_t> t;
- t.resize(size);
- uint8_t const* src = static_cast<uint8_t const*>(l);
- std::copy(src, src + size, t.data());
- return t;
-}
+hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size);
/**
* \brief Wrap `GraphicBuffer` in `AnwBuffer`.
@@ -239,17 +202,7 @@
* \param[in] l The source `GraphicBuffer`.
*/
// wrap: GraphicBuffer -> AnwBuffer
-inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
- t->attr.width = l.getWidth();
- t->attr.height = l.getHeight();
- t->attr.stride = l.getStride();
- t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
- t->attr.layerCount = l.getLayerCount();
- t->attr.usage = l.getUsage();
- t->attr.id = l.getId();
- t->attr.generationNumber = l.getGenerationNumber();
- t->nativeHandle = hidl_handle(l.handle);
-}
+void wrapAs(AnwBuffer* t, GraphicBuffer const& l);
/**
* \brief Convert `AnwBuffer` to `GraphicBuffer`.
@@ -261,46 +214,7 @@
*/
// convert: AnwBuffer -> GraphicBuffer
// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
- native_handle_t* handle = t.nativeHandle == nullptr ?
- nullptr : native_handle_clone(t.nativeHandle);
-
- size_t const numInts = 12 + (handle ? handle->numInts : 0);
- int32_t* ints = new int32_t[numInts];
-
- size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
- int* fds = new int[numFds];
-
- ints[0] = 'GBFR';
- ints[1] = static_cast<int32_t>(t.attr.width);
- ints[2] = static_cast<int32_t>(t.attr.height);
- ints[3] = static_cast<int32_t>(t.attr.stride);
- ints[4] = static_cast<int32_t>(t.attr.format);
- ints[5] = static_cast<int32_t>(t.attr.layerCount);
- ints[6] = static_cast<int32_t>(t.attr.usage);
- ints[7] = static_cast<int32_t>(t.attr.id >> 32);
- ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
- ints[9] = static_cast<int32_t>(t.attr.generationNumber);
- ints[10] = 0;
- ints[11] = 0;
- if (handle) {
- ints[10] = static_cast<int32_t>(handle->numFds);
- ints[11] = static_cast<int32_t>(handle->numInts);
- int* intsStart = handle->data + handle->numFds;
- std::copy(handle->data, intsStart, fds);
- std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
- }
-
- void const* constBuffer = static_cast<void const*>(ints);
- size_t size = numInts * sizeof(int32_t);
- int const* constFds = static_cast<int const*>(fds);
- status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
- delete [] fds;
- delete [] ints;
- native_handle_delete(handle);
- return status == NO_ERROR;
-}
+bool convertTo(GraphicBuffer* l, AnwBuffer const& t);
/**
* Conversion functions for types outside media
@@ -387,9 +301,7 @@
* bytes required to store the number of file descriptors contained in the fd
* part of the flat buffer.
*/
-inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
- return 4;
-};
+size_t getFenceFlattenedSize(hidl_handle const& fence);
/**
* \brief Return the number of file descriptors contained in a fence.
@@ -398,9 +310,7 @@
* \return `0` if \p fence does not contain a valid file descriptor, or `1`
* otherwise.
*/
-inline size_t getFenceFdCount(hidl_handle const& fence) {
- return native_handle_read_fd(fence) == -1 ? 0 : 1;
-}
+size_t getFenceFdCount(hidl_handle const& fence);
/**
* \brief Unflatten `Fence` to `hidl_handle`.
@@ -417,38 +327,8 @@
* native handle, which needs to be deleted with `native_handle_delete()`
* afterwards.
*/
-inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
- void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
- if (size < 4) {
- return NO_MEMORY;
- }
-
- uint32_t numFdsInHandle;
- FlattenableUtils::read(buffer, size, numFdsInHandle);
-
- if (numFdsInHandle > 1) {
- return BAD_VALUE;
- }
-
- if (numFds < numFdsInHandle) {
- return NO_MEMORY;
- }
-
- if (numFdsInHandle) {
- *nh = native_handle_create_from_fd(*fds);
- if (*nh == nullptr) {
- return NO_MEMORY;
- }
- *fence = *nh;
- ++fds;
- --numFds;
- } else {
- *nh = nullptr;
- *fence = hidl_handle();
- }
-
- return NO_ERROR;
-}
+status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
/**
* \brief Flatten `hidl_handle` as `Fence`.
@@ -460,24 +340,8 @@
* \param[in,out] numFds The size of the flat fd buffer.
* \return `NO_ERROR` on success; other value on failure.
*/
-inline status_t flattenFence(hidl_handle const& fence,
- void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (size < getFenceFlattenedSize(fence) ||
- numFds < getFenceFdCount(fence)) {
- return NO_MEMORY;
- }
- // Cast to uint32_t since the size of a size_t can vary between 32- and
- // 64-bit processes
- FlattenableUtils::write(buffer, size,
- static_cast<uint32_t>(getFenceFdCount(fence)));
- int fd = native_handle_read_fd(fence);
- if (fd != -1) {
- *fds = fd;
- ++fds;
- --numFds;
- }
- return NO_ERROR;
-}
+status_t flattenFence(hidl_handle const& fence,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds);
/**
* \brief Wrap `Fence` in `hidl_handle`.
@@ -490,40 +354,7 @@
* deleted manually with `native_handle_delete()` afterwards.
*/
// wrap: Fence -> hidl_handle
-inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
- size_t const baseSize = l.getFlattenedSize();
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- size_t const baseNumFds = l.getFdCount();
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = static_cast<int*>(baseFds.get());
- size_t numFds = baseNumFds;
- if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
- != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l);
/**
* \brief Convert `hidl_handle` to `Fence`.
@@ -535,58 +366,7 @@
* If \p t contains a valid file descriptor, it will be duplicated.
*/
// convert: hidl_handle -> Fence
-inline bool convertTo(Fence* l, hidl_handle const& t) {
- int fd = native_handle_read_fd(t);
- if (fd != -1) {
- fd = dup(fd);
- if (fd == -1) {
- return false;
- }
- }
- native_handle_t* nh = native_handle_create_from_fd(fd);
- if (nh == nullptr) {
- if (fd != -1) {
- close(fd);
- }
- return false;
- }
-
- size_t const baseSize = getFenceFlattenedSize(t);
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- native_handle_delete(nh);
- return false;
- }
-
- size_t const baseNumFds = getFenceFdCount(t);
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- native_handle_delete(nh);
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = static_cast<int*>(baseFds.get());
- size_t numFds = baseNumFds;
- if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
- native_handle_delete(nh);
- return false;
- }
- native_handle_delete(nh);
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+bool convertTo(Fence* l, hidl_handle const& t);
// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
@@ -597,20 +377,7 @@
* \param[in] t The input `FenceTimeSnapshot`.
* \return The required size of the flat buffer.
*/
-inline size_t getFlattenedSize(
- HGraphicBufferProducer::FenceTimeSnapshot const& t) {
- constexpr size_t min = sizeof(t.state);
- switch (t.state) {
- case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
- return min;
- case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
- return min + getFenceFlattenedSize(t.fence);
- case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
- return min + sizeof(
- ::android::FenceTime::Snapshot::signalTime);
- }
- return 0;
-}
+size_t getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const& t);
/**
* \brief Return the number of file descriptors contained in
@@ -619,12 +386,7 @@
* \param[in] t The input `FenceTimeSnapshot`.
* \return The number of file descriptors contained in \p snapshot.
*/
-inline size_t getFdCount(
- HGraphicBufferProducer::FenceTimeSnapshot const& t) {
- return t.state ==
- HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
- getFenceFdCount(t.fence) : 0;
-}
+size_t getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const& t);
/**
* \brief Flatten `FenceTimeSnapshot`.
@@ -639,29 +401,8 @@
* This function will duplicate the file descriptor in `t.fence` if `t.state ==
* FENCE`.
*/
-inline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
- void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (size < getFlattenedSize(t)) {
- return NO_MEMORY;
- }
-
- switch (t.state) {
- case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
- FlattenableUtils::write(buffer, size,
- ::android::FenceTime::Snapshot::State::EMPTY);
- return NO_ERROR;
- case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
- FlattenableUtils::write(buffer, size,
- ::android::FenceTime::Snapshot::State::FENCE);
- return flattenFence(t.fence, buffer, size, fds, numFds);
- case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
- FlattenableUtils::write(buffer, size,
- ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
- FlattenableUtils::write(buffer, size, t.signalTimeNs);
- return NO_ERROR;
- }
- return NO_ERROR;
-}
+status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
+ void*& buffer, size_t& size, int*& fds, size_t& numFds);
/**
* \brief Unflatten `FenceTimeSnapshot`.
@@ -678,72 +419,20 @@
* file descriptor, \p nh will be created to hold that file descriptor. In this
* case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
*/
-inline status_t unflatten(
+status_t unflatten(
HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
- void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
- if (size < sizeof(t->state)) {
- return NO_MEMORY;
- }
-
- *nh = nullptr;
- ::android::FenceTime::Snapshot::State state;
- FlattenableUtils::read(buffer, size, state);
- switch (state) {
- case ::android::FenceTime::Snapshot::State::EMPTY:
- t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
- return NO_ERROR;
- case ::android::FenceTime::Snapshot::State::FENCE:
- t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
- return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
- case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
- t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
- if (size < sizeof(t->signalTimeNs)) {
- return NO_MEMORY;
- }
- FlattenableUtils::read(buffer, size, t->signalTimeNs);
- return NO_ERROR;
- }
- return NO_ERROR;
-}
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
/**
- * \brief Return a lower bound on the size of the non-fd buffer required to
- * flatten `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
- HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
- return sizeof(uint64_t) + // mFrameNumber
- sizeof(uint8_t) + // mIndex
- sizeof(uint8_t) + // mAddPostCompositeCalled
- sizeof(uint8_t) + // mAddRetireCalled
- sizeof(uint8_t) + // mAddReleaseCalled
- sizeof(nsecs_t) + // mPostedTime
- sizeof(nsecs_t) + // mRequestedPresentTime
- sizeof(nsecs_t) + // mLatchTime
- sizeof(nsecs_t) + // mFirstRefreshStartTime
- sizeof(nsecs_t); // mLastRefreshStartTime
-}
-
-/**
* \brief Return the size of the non-fd buffer required to flatten
* `FrameEventsDelta`.
*
* \param[in] t The input `FrameEventsDelta`.
* \return The required size of the flat buffer.
*/
-inline size_t getFlattenedSize(
- HGraphicBufferProducer::FrameEventsDelta const& t) {
- return minFlattenedSize(t) +
- getFlattenedSize(t.gpuCompositionDoneFence) +
- getFlattenedSize(t.displayPresentFence) +
- getFlattenedSize(t.displayRetireFence) +
- getFlattenedSize(t.releaseFence);
-};
+size_t getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const& t);
/**
* \brief Return the number of file descriptors contained in
@@ -752,13 +441,7 @@
* \param[in] t The input `FrameEventsDelta`.
* \return The number of file descriptors contained in \p t.
*/
-inline size_t getFdCount(
- HGraphicBufferProducer::FrameEventsDelta const& t) {
- return getFdCount(t.gpuCompositionDoneFence) +
- getFdCount(t.displayPresentFence) +
- getFdCount(t.displayRetireFence) +
- getFdCount(t.releaseFence);
-};
+size_t getFdCount(HGraphicBufferProducer::FrameEventsDelta const& t);
/**
* \brief Unflatten `FrameEventsDelta`.
@@ -775,60 +458,9 @@
* populated with `nullptr` or newly created handles. Each non-null slot in \p
* nh will need to be deleted manually with `native_handle_delete()`.
*/
-inline status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
+status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
std::vector<native_handle_t*>* nh,
- void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
- if (size < minFlattenedSize(*t)) {
- return NO_MEMORY;
- }
- FlattenableUtils::read(buffer, size, t->frameNumber);
-
- // These were written as uint8_t for alignment.
- uint8_t temp = 0;
- FlattenableUtils::read(buffer, size, temp);
- size_t index = static_cast<size_t>(temp);
- if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
- return BAD_VALUE;
- }
- t->index = static_cast<uint32_t>(index);
-
- FlattenableUtils::read(buffer, size, temp);
- t->addPostCompositeCalled = static_cast<bool>(temp);
- FlattenableUtils::read(buffer, size, temp);
- t->addRetireCalled = static_cast<bool>(temp);
- FlattenableUtils::read(buffer, size, temp);
- t->addReleaseCalled = static_cast<bool>(temp);
-
- FlattenableUtils::read(buffer, size, t->postedTimeNs);
- FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
- FlattenableUtils::read(buffer, size, t->latchTimeNs);
- FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
- FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
- FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
-
- // Fences
- HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
- tSnapshot[0] = &t->gpuCompositionDoneFence;
- tSnapshot[1] = &t->displayPresentFence;
- tSnapshot[2] = &t->displayRetireFence;
- tSnapshot[3] = &t->releaseFence;
- nh->resize(4);
- for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
- status_t status = unflatten(
- tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
- buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- while (snapshotIndex > 0) {
- --snapshotIndex;
- if ((*nh)[snapshotIndex] != nullptr) {
- native_handle_delete((*nh)[snapshotIndex]);
- }
- }
- return status;
- }
- }
- return NO_ERROR;
-}
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
/**
* \brief Flatten `FrameEventsDelta`.
@@ -844,47 +476,8 @@
*/
// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
// FrameEventsDelta::flatten
-inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
- void*& buffer, size_t& size, int*& fds, size_t numFds) {
- // Check that t.index is within a valid range.
- if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
- || t.index > std::numeric_limits<uint8_t>::max()) {
- return BAD_VALUE;
- }
-
- FlattenableUtils::write(buffer, size, t.frameNumber);
-
- // These are static_cast to uint8_t for alignment.
- FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
- FlattenableUtils::write(
- buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
- FlattenableUtils::write(
- buffer, size, static_cast<uint8_t>(t.addRetireCalled));
- FlattenableUtils::write(
- buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
-
- FlattenableUtils::write(buffer, size, t.postedTimeNs);
- FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
- FlattenableUtils::write(buffer, size, t.latchTimeNs);
- FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
- FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
- FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
-
- // Fences
- HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
- tSnapshot[0] = &t.gpuCompositionDoneFence;
- tSnapshot[1] = &t.displayPresentFence;
- tSnapshot[2] = &t.displayRetireFence;
- tSnapshot[3] = &t.releaseFence;
- for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
- status_t status = flatten(
- *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- return status;
- }
- }
- return NO_ERROR;
-}
+status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
+ void*& buffer, size_t& size, int*& fds, size_t numFds);
// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
@@ -895,15 +488,8 @@
* \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
* \return The required size of the flat buffer.
*/
-inline size_t getFlattenedSize(
- HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
- size_t size = 4 + // mDeltas.size()
- sizeof(t.compositorTiming);
- for (size_t i = 0; i < t.deltas.size(); ++i) {
- size += getFlattenedSize(t.deltas[i]);
- }
- return size;
-}
+size_t getFlattenedSize(
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t);
/**
* \brief Return the number of file descriptors contained in
@@ -912,14 +498,8 @@
* \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
* \return The number of file descriptors contained in \p t.
*/
-inline size_t getFdCount(
- HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
- size_t numFds = 0;
- for (size_t i = 0; i < t.deltas.size(); ++i) {
- numFds += getFdCount(t.deltas[i]);
- }
- return numFds;
-}
+size_t getFdCount(
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t);
/**
* \brief Unflatten `FrameEventHistoryDelta`.
@@ -936,34 +516,10 @@
* newly created handles. The second dimension of \p nh will be 4. Each non-null
* slot in \p nh will need to be deleted manually with `native_handle_delete()`.
*/
-inline status_t unflatten(
+status_t unflatten(
HGraphicBufferProducer::FrameEventHistoryDelta* t,
std::vector<std::vector<native_handle_t*> >* nh,
- void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
- if (size < 4) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::read(buffer, size, t->compositorTiming);
-
- uint32_t deltaCount = 0;
- FlattenableUtils::read(buffer, size, deltaCount);
- if (static_cast<size_t>(deltaCount) >
- ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
- return BAD_VALUE;
- }
- t->deltas.resize(deltaCount);
- nh->resize(deltaCount);
- for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
- status_t status = unflatten(
- &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
- buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- return status;
- }
- }
- return NO_ERROR;
-}
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
/**
* \brief Flatten `FrameEventHistoryDelta`.
@@ -977,27 +533,9 @@
*
* This function will duplicate file descriptors contained in \p t.
*/
-inline status_t flatten(
+status_t flatten(
HGraphicBufferProducer::FrameEventHistoryDelta const& t,
- void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
- return BAD_VALUE;
- }
- if (size < getFlattenedSize(t)) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::write(buffer, size, t.compositorTiming);
-
- FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
- for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
- status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- return status;
- }
- }
- return NO_ERROR;
-}
+ void*& buffer, size_t& size, int*& fds, size_t& numFds);
/**
* \brief Wrap `::android::FrameEventHistoryData` in
@@ -1013,42 +551,9 @@
* native handle. All the non-`nullptr` elements must be deleted individually
* with `native_handle_delete()`.
*/
-inline bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
+bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
std::vector<std::vector<native_handle_t*> >* nh,
- ::android::FrameEventHistoryDelta const& l) {
-
- size_t const baseSize = l.getFlattenedSize();
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- size_t const baseNumFds = l.getFdCount();
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = baseFds.get();
- size_t numFds = baseNumFds;
- if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+ ::android::FrameEventHistoryDelta const& l);
/**
* \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
@@ -1059,42 +564,9 @@
*
* This function will duplicate all file descriptors contained in \p t.
*/
-inline bool convertTo(
+bool convertTo(
::android::FrameEventHistoryDelta* l,
- HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-
- size_t const baseSize = getFlattenedSize(t);
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- size_t const baseNumFds = getFdCount(t);
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = static_cast<int*>(baseFds.get());
- size_t numFds = baseNumFds;
- if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+ HGraphicBufferProducer::FrameEventHistoryDelta const& t);
// Ref: frameworks/native/libs/ui/Region.cpp
@@ -1104,9 +576,7 @@
* \param[in] t The input `Region`.
* \return The required size of the flat buffer.
*/
-inline size_t getFlattenedSize(Region const& t) {
- return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
-}
+size_t getFlattenedSize(Region const& t);
/**
* \brief Unflatten `Region`.
@@ -1116,36 +586,7 @@
* \param[in,out] size The size of the flat buffer.
* \return `NO_ERROR` on success; other value on failure.
*/
-inline status_t unflatten(Region* t, void const*& buffer, size_t& size) {
- if (size < sizeof(uint32_t)) {
- return NO_MEMORY;
- }
-
- uint32_t numRects = 0;
- FlattenableUtils::read(buffer, size, numRects);
- if (size < numRects * sizeof(Rect)) {
- return NO_MEMORY;
- }
- if (numRects > (UINT32_MAX / sizeof(Rect))) {
- return NO_MEMORY;
- }
-
- t->resize(numRects);
- for (size_t r = 0; r < numRects; ++r) {
- ::android::Rect rect(::android::Rect::EMPTY_RECT);
- status_t status = rect.unflatten(buffer, size);
- if (status != NO_ERROR) {
- return status;
- }
- FlattenableUtils::advance(buffer, size, sizeof(rect));
- (*t)[r] = Rect{
- static_cast<int32_t>(rect.left),
- static_cast<int32_t>(rect.top),
- static_cast<int32_t>(rect.right),
- static_cast<int32_t>(rect.bottom)};
- }
- return NO_ERROR;
-}
+status_t unflatten(Region* t, void const*& buffer, size_t& size);
/**
* \brief Flatten `Region`.
@@ -1155,26 +596,7 @@
* \param[in,out] size The size of the flat buffer.
* \return `NO_ERROR` on success; other value on failure.
*/
-inline status_t flatten(Region const& t, void*& buffer, size_t& size) {
- if (size < getFlattenedSize(t)) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
- for (size_t r = 0; r < t.size(); ++r) {
- ::android::Rect rect(
- static_cast<int32_t>(t[r].left),
- static_cast<int32_t>(t[r].top),
- static_cast<int32_t>(t[r].right),
- static_cast<int32_t>(t[r].bottom));
- status_t status = rect.flatten(buffer, size);
- if (status != NO_ERROR) {
- return status;
- }
- FlattenableUtils::advance(buffer, size, sizeof(rect));
- }
- return NO_ERROR;
-}
+status_t flatten(Region const& t, void*& buffer, size_t& size);
/**
* \brief Convert `::android::Region` to `Region`.
@@ -1183,28 +605,7 @@
* \param[in] l The source `::android::Region`.
*/
// convert: ::android::Region -> Region
-inline bool convertTo(Region* t, ::android::Region const& l) {
- size_t const baseSize = l.getFlattenedSize();
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- if (l.flatten(buffer, size) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- if (unflatten(t, constBuffer, size) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+bool convertTo(Region* t, ::android::Region const& l);
/**
* \brief Convert `Region` to `::android::Region`.
@@ -1213,64 +614,19 @@
* \param[in] t The source `Region`.
*/
// convert: Region -> ::android::Region
-inline bool convertTo(::android::Region* l, Region const& t) {
- size_t const baseSize = getFlattenedSize(t);
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- if (flatten(t, buffer, size) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- if (l->unflatten(constBuffer, size) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+bool convertTo(::android::Region* l, Region const& t);
// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
// BGraphicBufferProducer::QueueBufferInput
/**
- * \brief Return a lower bound on the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
- HGraphicBufferProducer::QueueBufferInput const& /* t */) {
- return sizeof(int64_t) + // timestamp
- sizeof(int) + // isAutoTimestamp
- sizeof(android_dataspace) + // dataSpace
- sizeof(::android::Rect) + // crop
- sizeof(int) + // scalingMode
- sizeof(uint32_t) + // transform
- sizeof(uint32_t) + // stickyTransform
- sizeof(bool); // getFrameTimestamps
-}
-
-/**
* \brief Return the size of the buffer required to flatten
* `HGraphicBufferProducer::QueueBufferInput`.
*
* \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
* \return The required size of the flat buffer.
*/
-inline size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
- return minFlattenedSize(t) +
- getFenceFlattenedSize(t.fence) +
- getFlattenedSize(t.surfaceDamage) +
- sizeof(HdrMetadata::validTypes);
-}
+size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t);
/**
* \brief Return the number of file descriptors contained in
@@ -1279,11 +635,8 @@
* \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
* \return The number of file descriptors contained in \p t.
*/
-inline size_t getFdCount(
- HGraphicBufferProducer::QueueBufferInput const& t) {
- return getFenceFdCount(t.fence);
-}
-
+size_t getFdCount(
+ HGraphicBufferProducer::QueueBufferInput const& t);
/**
* \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
*
@@ -1296,40 +649,9 @@
* \return `NO_ERROR` on success; other value on failure.
*
* This function will duplicate the file descriptor in `t.fence`. */
-inline status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
+status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
native_handle_t** nh,
- void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (size < getFlattenedSize(t)) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::write(buffer, size, t.timestamp);
- FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
- FlattenableUtils::write(buffer, size,
- static_cast<android_dataspace_t>(t.dataSpace));
- FlattenableUtils::write(buffer, size, ::android::Rect(
- static_cast<int32_t>(t.crop.left),
- static_cast<int32_t>(t.crop.top),
- static_cast<int32_t>(t.crop.right),
- static_cast<int32_t>(t.crop.bottom)));
- FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
- FlattenableUtils::write(buffer, size, t.transform);
- FlattenableUtils::write(buffer, size, t.stickyTransform);
- FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
-
- *nh = t.fence.getNativeHandle() == nullptr ?
- nullptr : native_handle_clone(t.fence);
- status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- return status;
- }
- status = flatten(t.surfaceDamage, buffer, size);
- if (status != NO_ERROR) {
- return status;
- }
- FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
- return NO_ERROR;
-}
+ void*& buffer, size_t& size, int*& fds, size_t& numFds);
/**
* \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
@@ -1347,42 +669,9 @@
* descriptor. \p nh needs to be deleted with `native_handle_delete()`
* afterwards.
*/
-inline status_t unflatten(
+status_t unflatten(
HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
- void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
- if (size < minFlattenedSize(*t)) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::read(buffer, size, t->timestamp);
- int lIsAutoTimestamp;
- FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
- t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
- android_dataspace_t lDataSpace;
- FlattenableUtils::read(buffer, size, lDataSpace);
- t->dataSpace = static_cast<Dataspace>(lDataSpace);
- Rect lCrop;
- FlattenableUtils::read(buffer, size, lCrop);
- t->crop = Rect{
- static_cast<int32_t>(lCrop.left),
- static_cast<int32_t>(lCrop.top),
- static_cast<int32_t>(lCrop.right),
- static_cast<int32_t>(lCrop.bottom)};
- int lScalingMode;
- FlattenableUtils::read(buffer, size, lScalingMode);
- t->scalingMode = static_cast<int32_t>(lScalingMode);
- FlattenableUtils::read(buffer, size, t->transform);
- FlattenableUtils::read(buffer, size, t->stickyTransform);
- FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
-
- status_t status = unflattenFence(&(t->fence), nh,
- buffer, size, fds, numFds);
- if (status != NO_ERROR) {
- return status;
- }
- // HdrMetadata ignored
- return unflatten(&(t->surfaceDamage), buffer, size);
-}
+ void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
/**
* \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
@@ -1398,43 +687,10 @@
* descriptor. \p nh needs to be deleted with `native_handle_delete()`
* afterwards.
*/
-inline bool wrapAs(
+bool wrapAs(
HGraphicBufferProducer::QueueBufferInput* t,
native_handle_t** nh,
- BGraphicBufferProducer::QueueBufferInput const& l) {
-
- size_t const baseSize = l.getFlattenedSize();
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- size_t const baseNumFds = l.getFdCount();
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = baseFds.get();
- size_t numFds = baseNumFds;
- if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
- return false;
- }
-
- return true;
-}
+ BGraphicBufferProducer::QueueBufferInput const& l);
/**
* \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
@@ -1445,48 +701,9 @@
*
* If `t.fence` has a valid file descriptor, it will be duplicated.
*/
-inline bool convertTo(
+bool convertTo(
BGraphicBufferProducer::QueueBufferInput* l,
- HGraphicBufferProducer::QueueBufferInput const& t) {
-
- size_t const baseSize = getFlattenedSize(t);
- std::unique_ptr<uint8_t[]> baseBuffer(
- new (std::nothrow) uint8_t[baseSize]);
- if (!baseBuffer) {
- return false;
- }
-
- size_t const baseNumFds = getFdCount(t);
- std::unique_ptr<int[]> baseFds(
- new (std::nothrow) int[baseNumFds]);
- if (!baseFds) {
- return false;
- }
-
- void* buffer = static_cast<void*>(baseBuffer.get());
- size_t size = baseSize;
- int* fds = baseFds.get();
- size_t numFds = baseNumFds;
- native_handle_t* nh;
- if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
- return false;
- }
-
- void const* constBuffer = static_cast<void const*>(baseBuffer.get());
- size = baseSize;
- int const* constFds = static_cast<int const*>(baseFds.get());
- numFds = baseNumFds;
- if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
- if (nh != nullptr) {
- native_handle_close(nh);
- native_handle_delete(nh);
- }
- return false;
- }
-
- native_handle_delete(nh);
- return true;
-}
+ HGraphicBufferProducer::QueueBufferInput const& t);
// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
// BGraphicBufferProducer::QueueBufferOutput
@@ -1507,20 +724,9 @@
*/
// wrap: BGraphicBufferProducer::QueueBufferOutput ->
// HGraphicBufferProducer::QueueBufferOutput
-inline bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
+bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
std::vector<std::vector<native_handle_t*> >* nh,
- BGraphicBufferProducer::QueueBufferOutput const& l) {
- if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
- return false;
- }
- t->width = l.width;
- t->height = l.height;
- t->transformHint = l.transformHint;
- t->numPendingBuffers = l.numPendingBuffers;
- t->nextFrameNumber = l.nextFrameNumber;
- t->bufferReplaced = l.bufferReplaced;
- return true;
-}
+ BGraphicBufferProducer::QueueBufferOutput const& l);
/**
* \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
@@ -1533,20 +739,9 @@
*/
// convert: HGraphicBufferProducer::QueueBufferOutput ->
// BGraphicBufferProducer::QueueBufferOutput
-inline bool convertTo(
+bool convertTo(
BGraphicBufferProducer::QueueBufferOutput* l,
- HGraphicBufferProducer::QueueBufferOutput const& t) {
- if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
- return false;
- }
- l->width = t.width;
- l->height = t.height;
- l->transformHint = t.transformHint;
- l->numPendingBuffers = t.numPendingBuffers;
- l->nextFrameNumber = t.nextFrameNumber;
- l->bufferReplaced = t.bufferReplaced;
- return true;
-}
+ HGraphicBufferProducer::QueueBufferOutput const& t);
/**
* \brief Convert `BGraphicBufferProducer::DisconnectMode` to
@@ -1555,16 +750,8 @@
* \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
* \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
*/
-inline HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
- BGraphicBufferProducer::DisconnectMode l) {
- switch (l) {
- case BGraphicBufferProducer::DisconnectMode::Api:
- return HGraphicBufferProducer::DisconnectMode::API;
- case BGraphicBufferProducer::DisconnectMode::AllLocal:
- return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
- }
- return HGraphicBufferProducer::DisconnectMode::API;
-}
+HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
+ BGraphicBufferProducer::DisconnectMode l);
/**
* \brief Convert `HGraphicBufferProducer::DisconnectMode` to
@@ -1573,18 +760,10 @@
* \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
* \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
*/
-inline BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
- HGraphicBufferProducer::DisconnectMode t) {
- switch (t) {
- case HGraphicBufferProducer::DisconnectMode::API:
- return BGraphicBufferProducer::DisconnectMode::Api;
- case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
- return BGraphicBufferProducer::DisconnectMode::AllLocal;
- }
- return BGraphicBufferProducer::DisconnectMode::Api;
-}
+BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
+ HGraphicBufferProducer::DisconnectMode t);
} // namespace conversion
} // namespace android
-#endif // MEDIA_STAGEFRIGHT_CONVERSION_H_
+#endif // MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
index 9ac2791..b62b526 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.h
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -44,7 +44,7 @@
private:
enum {
- kNumBuffers = 16
+ kNumBuffers = 10
};
enum {
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 8ef7620..cd0f75c 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -563,6 +563,10 @@
DescribeColorAspectsParams* colorAspectsParams =
(DescribeColorAspectsParams *)params;
+ if (!isValidOMXParam(colorAspectsParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (colorAspectsParams->nPortIndex != kOutputPortIndex) {
return OMX_ErrorBadParameter;
}
@@ -584,6 +588,10 @@
DescribeHDRStaticInfoParams* hdrStaticInfoParams =
(DescribeHDRStaticInfoParams *)params;
+ if (!isValidOMXParam(hdrStaticInfoParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
return OMX_ErrorBadPortIndex;
}
@@ -635,15 +643,17 @@
const DescribeHDRStaticInfoParams* hdrStaticInfoParams =
(DescribeHDRStaticInfoParams *)params;
+ if (!isValidOMXParam(hdrStaticInfoParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
return OMX_ErrorBadPortIndex;
}
- if (hdrStaticInfoParams != NULL) {
- mOutputFormat = OMX_COLOR_FormatYUV420Planar16;
- mHdrStaticInfo = hdrStaticInfoParams->sInfo;
- updatePortDefinitions(false);
- }
+ mOutputFormat = OMX_COLOR_FormatYUV420Planar16;
+ mHdrStaticInfo = hdrStaticInfoParams->sInfo;
+ updatePortDefinitions(false);
return OMX_ErrorNone;
}
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index b6480a2..b0d8e7d 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -40,9 +40,6 @@
LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
-# TODO: Enable proguard (b/74090741)
-LOCAL_PROGUARD_ENABLED := disabled
-
LOCAL_MULTILIB := first
LOCAL_JAVA_LIBRARIES += android-support-annotations
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index a4c6553..59c90ab 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -863,8 +863,7 @@
if (!mInstance.isConnected()) {
return;
}
- // TODO(jaewan): Fix public API not to take playlistAgent.
- mCallback.onPlaylistChanged(mInstance, null, playlist, metadata);
+ mCallback.onPlaylistChanged(mInstance, playlist, metadata);
});
}
@@ -876,8 +875,7 @@
if (!mInstance.isConnected()) {
return;
}
- // TODO(jaewan): Fix public API not to take playlistAgent.
- mCallback.onPlaylistMetadataChanged(mInstance, null, metadata);
+ mCallback.onPlaylistMetadataChanged(mInstance, metadata);
});
}
@@ -889,8 +887,7 @@
if (!mInstance.isConnected()) {
return;
}
- // TODO(jaewan): Fix public API not to take playlistAgent.
- mCallback.onShuffleModeChanged(mInstance, null, shuffleMode);
+ mCallback.onShuffleModeChanged(mInstance, shuffleMode);
});
}
@@ -902,8 +899,7 @@
if (!mInstance.isConnected()) {
return;
}
- // TODO(jaewan): Fix public API not to take playlistAgent.
- mCallback.onRepeatModeChanged(mInstance, null, repeatMode);
+ mCallback.onRepeatModeChanged(mInstance, repeatMode);
});
}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 2b7c72a..89c29e6 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -48,6 +48,7 @@
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
+import android.media.MediaSession2.OnDataSourceMissingHelper;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
import android.media.SessionToken2;
@@ -61,7 +62,6 @@
import android.os.ResultReceiver;
import android.support.annotation.GuardedBy;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
import java.lang.ref.WeakReference;
@@ -111,9 +111,13 @@
@GuardedBy("mLock")
private MediaPlaylistAgent mPlaylistAgent;
@GuardedBy("mLock")
+ private SessionPlaylistAgent mSessionPlaylistAgent;
+ @GuardedBy("mLock")
private VolumeProvider2 mVolumeProvider;
@GuardedBy("mLock")
private PlaybackInfo mPlaybackInfo;
+ @GuardedBy("mLock")
+ private OnDataSourceMissingHelper mDsmHelper;
/**
* Can be only called by the {@link Builder#build()}.
@@ -207,7 +211,7 @@
}
@Override
- public void updatePlayer_impl(MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
+ public void updatePlayer_impl(@NonNull MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
VolumeProvider2 volumeProvider) throws IllegalArgumentException {
ensureCallingThread();
if (player == null) {
@@ -225,9 +229,12 @@
oldPlayer = mPlayer;
oldAgent = mPlaylistAgent;
mPlayer = player;
- // TODO(jaewan): Replace this with the proper default agent (b/74090741)
if (agent == null) {
- agent = new MediaPlaylistAgent(mContext) {};
+ mSessionPlaylistAgent = new SessionPlaylistAgent(mContext, this, mPlayer);
+ if (mDsmHelper != null) {
+ mSessionPlaylistAgent.setOnDataSourceMissingHelper(mDsmHelper);
+ }
+ agent = mSessionPlaylistAgent;
}
mPlaylistAgent = agent;
mVolumeProvider = volumeProvider;
@@ -312,6 +319,7 @@
mPlayer = null;
agent = mPlaylistAgent;
mPlaylistAgent = null;
+ mSessionPlaylistAgent = null;
}
if (player != null) {
player.unregisterPlayerEventCallback(mPlayerEventCallback);
@@ -385,7 +393,7 @@
}
@Override
- public void skipToPlaylistItem_impl(MediaItem2 item) {
+ public void skipToPlaylistItem_impl(@NonNull MediaItem2 item) {
if (item == null) {
throw new IllegalArgumentException("item shouldn't be null");
}
@@ -418,7 +426,8 @@
}
@Override
- public void setCustomLayout_impl(ControllerInfo controller, List<CommandButton> layout) {
+ public void setCustomLayout_impl(@NonNull ControllerInfo controller,
+ @NonNull List<CommandButton> layout) {
ensureCallingThread();
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
@@ -434,7 +443,8 @@
//////////////////////////////////////////////////////////////////////////////////////
@Override
- public void setAllowedCommands_impl(ControllerInfo controller, CommandGroup commands) {
+ public void setAllowedCommands_impl(@NonNull ControllerInfo controller,
+ @NonNull CommandGroup commands) {
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
}
@@ -445,8 +455,8 @@
}
@Override
- public void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
- ResultReceiver receiver) {
+ public void sendCustomCommand_impl(@NonNull ControllerInfo controller, @NonNull Command command,
+ Bundle args, ResultReceiver receiver) {
if (controller == null) {
throw new IllegalArgumentException("controller shouldn't be null");
}
@@ -457,7 +467,7 @@
}
@Override
- public void sendCustomCommand_impl(Command command, Bundle args) {
+ public void sendCustomCommand_impl(@NonNull Command command, Bundle args) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
@@ -465,7 +475,7 @@
}
@Override
- public void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata) {
+ public void setPlaylist_impl(@NonNull List<MediaItem2> list, MediaMetadata2 metadata) {
if (list == null) {
throw new IllegalArgumentException("list shouldn't be null");
}
@@ -489,7 +499,7 @@
}
@Override
- public void addPlaylistItem_impl(int index, MediaItem2 item) {
+ public void addPlaylistItem_impl(int index, @NonNull MediaItem2 item) {
if (index < 0) {
throw new IllegalArgumentException("index shouldn't be negative");
}
@@ -505,7 +515,7 @@
}
@Override
- public void removePlaylistItem_impl(MediaItem2 item) {
+ public void removePlaylistItem_impl(@NonNull MediaItem2 item) {
if (item == null) {
throw new IllegalArgumentException("item shouldn't be null");
}
@@ -518,7 +528,7 @@
}
@Override
- public void replacePlaylistItem_impl(int index, MediaItem2 item) {
+ public void replacePlaylistItem_impl(int index, @NonNull MediaItem2 item) {
if (index < 0) {
throw new IllegalArgumentException("index shouldn't be negative");
}
@@ -685,6 +695,29 @@
mSessionStub.notifyError(errorCode, extras);
}
+ @Override
+ public void setOnDataSourceMissingHelper_impl(@NonNull OnDataSourceMissingHelper helper) {
+ if (helper == null) {
+ throw new IllegalArgumentException("helper shouldn't be null");
+ }
+ synchronized (mLock) {
+ mDsmHelper = helper;
+ if (mSessionPlaylistAgent != null) {
+ mSessionPlaylistAgent.setOnDataSourceMissingHelper(helper);
+ }
+ }
+ }
+
+ @Override
+ public void clearOnDataSourceMissingHelper_impl() {
+ synchronized (mLock) {
+ mDsmHelper = null;
+ if (mSessionPlaylistAgent != null) {
+ mSessionPlaylistAgent.clearOnDataSourceMissingHelper();
+ }
+ }
+ }
+
///////////////////////////////////////////////////
// Protected or private methods
///////////////////////////////////////////////////
@@ -1022,7 +1055,7 @@
/**
* @return a new Command instance from the Bundle
*/
- public static Command fromBundle_impl(Context context, Bundle command) {
+ public static Command fromBundle_impl(Context context, @NonNull Bundle command) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
@@ -1092,7 +1125,7 @@
}
@Override
- public void addCommand_impl(Command command) {
+ public void addCommand_impl(@NonNull Command command) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
@@ -1129,7 +1162,7 @@
}
@Override
- public void removeCommand_impl(Command command) {
+ public void removeCommand_impl(@NonNull Command command) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
@@ -1137,7 +1170,7 @@
}
@Override
- public boolean hasCommand_impl(Command command) {
+ public boolean hasCommand_impl(@NonNull Command command) {
if (command == null) {
throw new IllegalArgumentException("command shouldn't be null");
}
@@ -1217,7 +1250,7 @@
private final IMediaController2 mControllerBinder;
public ControllerInfoImpl(Context context, ControllerInfo instance, int uid,
- int pid, String packageName, IMediaController2 callback) {
+ int pid, @NonNull String packageName, @NonNull IMediaController2 callback) {
if (TextUtils.isEmpty(packageName)) {
throw new IllegalArgumentException("packageName shouldn't be empty");
}
@@ -1234,7 +1267,7 @@
// Ask server whether the controller is trusted.
// App cannot know this because apps cannot query enabled notification listener for
// another package, but system server can do.
- mIsTrusted = manager.isTrusted(uid, packageName);
+ mIsTrusted = manager.isTrusted(packageName, pid, uid);
}
@Override
@@ -1468,7 +1501,7 @@
* {@link MediaSession2} or {@link MediaController2}.
*/
// TODO(jaewan): Also need executor
- public BuilderBaseImpl(Context context) {
+ public BuilderBaseImpl(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("context shouldn't be null");
}
@@ -1478,7 +1511,7 @@
}
@Override
- public void setPlayer_impl(MediaPlayerBase player) {
+ public void setPlayer_impl(@NonNull MediaPlayerBase player) {
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
@@ -1486,7 +1519,7 @@
}
@Override
- public void setPlaylistAgent_impl(MediaPlaylistAgent playlistAgent) {
+ public void setPlaylistAgent_impl(@NonNull MediaPlaylistAgent playlistAgent) {
if (playlistAgent == null) {
throw new IllegalArgumentException("playlistAgent shouldn't be null");
}
@@ -1504,7 +1537,7 @@
}
@Override
- public void setId_impl(String id) {
+ public void setId_impl(@NonNull String id) {
if (id == null) {
throw new IllegalArgumentException("id shouldn't be null");
}
@@ -1512,7 +1545,7 @@
}
@Override
- public void setSessionCallback_impl(Executor executor, C callback) {
+ public void setSessionCallback_impl(@NonNull Executor executor, @NonNull C callback) {
if (executor == null) {
throw new IllegalArgumentException("executor shouldn't be null");
}
diff --git a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
index 6805dad..693e137 100644
--- a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
+++ b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
@@ -24,7 +24,6 @@
import android.media.MediaMetadata2;
import android.media.MediaPlayerBase;
import android.media.MediaPlaylistAgent;
-import android.media.MediaSession2;
import android.media.MediaSession2.OnDataSourceMissingHelper;
import android.util.ArrayMap;
@@ -47,14 +46,13 @@
private final PlayItem mEopPlayItem = new PlayItem(END_OF_PLAYLIST, null);
private final Object mLock = new Object();
- private final MediaSession2 mSession;
+ private final MediaSession2Impl mSessionImpl;
// TODO: Set data sources properly into mPlayer (b/74090741)
@GuardedBy("mLock")
private MediaPlayerBase mPlayer;
@GuardedBy("mLock")
- private OnDataSourceMissingHelper mDsdHelper;
-
+ private OnDataSourceMissingHelper mDsmHelper;
// TODO: Check if having the same item is okay (b/74090741)
@GuardedBy("mLock")
private ArrayList<MediaItem2> mPlaylist = new ArrayList<>();
@@ -118,16 +116,16 @@
}
}
- public SessionPlaylistAgent(@NonNull Context context, @NonNull MediaSession2 session,
+ public SessionPlaylistAgent(@NonNull Context context, @NonNull MediaSession2Impl sessionImpl,
@NonNull MediaPlayerBase player) {
super(context);
- if (session == null) {
- throw new IllegalArgumentException("session shouldn't be null");
+ if (sessionImpl == null) {
+ throw new IllegalArgumentException("sessionImpl shouldn't be null");
}
if (player == null) {
throw new IllegalArgumentException("player shouldn't be null");
}
- mSession = session;
+ mSessionImpl = sessionImpl;
mPlayer = player;
}
@@ -142,7 +140,13 @@
public void setOnDataSourceMissingHelper(OnDataSourceMissingHelper helper) {
synchronized (mLock) {
- mDsdHelper = helper;
+ mDsmHelper = helper;
+ }
+ }
+
+ public void clearOnDataSourceMissingHelper() {
+ synchronized (mLock) {
+ mDsmHelper = null;
}
}
@@ -154,8 +158,7 @@
}
@Override
- public void setPlaylist(@NonNull List<MediaItem2> list,
- @Nullable MediaMetadata2 metadata) {
+ public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
if (list == null) {
throw new IllegalArgumentException("list shouldn't be null");
}
@@ -359,10 +362,10 @@
if (dsd != null) {
return dsd;
}
- OnDataSourceMissingHelper helper = mDsdHelper;
+ OnDataSourceMissingHelper helper = mDsmHelper;
if (helper != null) {
// TODO: Do not call onDataSourceMissing with the lock (b/74090741).
- dsd = helper.onDataSourceMissing(mSession, item);
+ dsd = helper.onDataSourceMissing(mSessionImpl.getInstance(), item);
if (dsd != null) {
mItemDsdMap.put(item, dsd);
}
diff --git a/packages/MediaComponents/tests/Android.mk b/packages/MediaComponents/tests/Android.mk
index bf81efb..dddfd2a 100644
--- a/packages/MediaComponents/tests/Android.mk
+++ b/packages/MediaComponents/tests/Android.mk
@@ -20,6 +20,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
android.test.runner.stubs \
android.test.base.stubs \
+ mockito-target-minus-junit4 \
junit
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
index 80370ec..ca941ab 100644
--- a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
+++ b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
@@ -16,19 +16,21 @@
package com.android.media;
+import static org.mockito.Mockito.*;
+
import android.content.Context;
+import android.media.AudioAttributes;
import android.media.DataSourceDesc;
import android.media.MediaItem2;
import android.media.MediaMetadata2;
-import android.media.MediaPlayer2;
import android.media.MediaPlayerBase;
import android.media.MediaPlaylistAgent;
import android.media.MediaSession2;
+import android.media.MediaSession2.OnDataSourceMissingHelper;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.test.AndroidTestCase;
-import android.util.Log;
import org.junit.After;
import org.junit.Before;
@@ -52,10 +54,10 @@
private Object mWaitLock = new Object();
private Context mContext;
- private MediaSession2 mSession;
+ private MediaSession2Impl mSessionImpl;
private MediaPlayerBase mPlayer;
private SessionPlaylistAgent mAgent;
- private MyDataSourceHelper mDataSourceHelper;
+ private OnDataSourceMissingHelper mDataSourceHelper;
private MyPlaylistEventCallback mEventCallback;
public class MyPlaylistEventCallback extends MediaPlaylistAgent.PlaylistEventCallback {
@@ -108,7 +110,7 @@
}
}
- public class MyDataSourceHelper implements MediaSession2.OnDataSourceMissingHelper {
+ public class MyDataSourceHelper implements OnDataSourceMissingHelper {
@Override
public DataSourceDesc onDataSourceMissing(MediaSession2 session, MediaItem2 item) {
if (item.getMediaId().contains("WITHOUT_DSD")) {
@@ -121,8 +123,104 @@
}
}
+ public class MockPlayer extends MediaPlayerBase {
+ @Override
+ public void play() {
+ }
+
+ @Override
+ public void prepare() {
+ }
+
+ @Override
+ public void pause() {
+ }
+
+ @Override
+ public void reset() {
+ }
+
+ @Override
+ public void skipToNext() {
+ }
+
+ @Override
+ public void seekTo(long pos) {
+ }
+
+ @Override
+ public int getPlayerState() {
+ return 0;
+ }
+
+ @Override
+ public int getBufferingState() {
+ return 0;
+ }
+
+ @Override
+ public void setAudioAttributes(AudioAttributes attributes) {
+ }
+
+ @Override
+ public AudioAttributes getAudioAttributes() {
+ return null;
+ }
+
+ @Override
+ public void setDataSource(DataSourceDesc dsd) {
+ }
+
+ @Override
+ public void setNextDataSource(DataSourceDesc dsd) {
+ }
+
+ @Override
+ public void setNextDataSources(List<DataSourceDesc> dsds) {
+ }
+
+ @Override
+ public DataSourceDesc getCurrentDataSource() {
+ return null;
+ }
+
+ @Override
+ public void loopCurrent(boolean loop) {
+ }
+
+ @Override
+ public void setPlaybackSpeed(float speed) {
+ }
+
+ @Override
+ public void setPlayerVolume(float volume) {
+ }
+
+ @Override
+ public float getPlayerVolume() {
+ return 0;
+ }
+
+ @Override
+ public void registerPlayerEventCallback(Executor e, PlayerEventCallback cb) {
+ }
+
+ @Override
+ public void unregisterPlayerEventCallback(PlayerEventCallback cb) {
+ }
+
+ @Override
+ public void close() throws Exception {
+ }
+ }
+
@Before
public void setUp() throws Exception {
+ mContext = getContext();
+ // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
+ // Dexmaker is used by mockito.
+ System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
+
HandlerThread handlerThread = new HandlerThread("SessionPlaylistAgent");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
@@ -130,15 +228,10 @@
mHandler.post(runnable);
};
- mContext = getContext();
- mPlayer = MediaPlayer2.create();
- mSession = new MediaSession2.Builder(mContext)
- .setPlayer(mPlayer)
- .setSessionCallback(mHandlerExecutor,
- new MediaSession2.SessionCallback(mContext) {})
- .setId(TAG).build();
+ mPlayer = mock(MockPlayer.class);
+ mSessionImpl = mock(MediaSession2Impl.class);
mDataSourceHelper = new MyDataSourceHelper();
- mAgent = new SessionPlaylistAgent(mContext, mSession, mPlayer);
+ mAgent = new SessionPlaylistAgent(mContext, mSessionImpl, mPlayer);
mAgent.setOnDataSourceMissingHelper(mDataSourceHelper);
mEventCallback = new MyPlaylistEventCallback(mWaitLock);
mAgent.registerPlaylistEventCallback(mHandlerExecutor, mEventCallback);
@@ -146,8 +239,6 @@
@After
public void tearDown() throws Exception {
- mSession.close();
- mPlayer.close();
mHandler.getLooper().quitSafely();
mHandler = null;
mHandlerExecutor = null;
diff --git a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
index 31b7e0f..e4fd176 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
@@ -62,7 +62,8 @@
[AUDIO_POLICY_FORCE_FOR_DOCK] = "ForceUseForDock",
[AUDIO_POLICY_FORCE_FOR_SYSTEM] = "ForceUseForSystem",
[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] = "ForceUseForHdmiSystemAudio",
- [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] = "ForceUseForEncodedSurround"
+ [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] = "ForceUseForEncodedSurround",
+ [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] = "ForceUseForVibrateRinging"
};
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 977a396..be7f7ec 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -154,6 +154,13 @@
}
mForceUse[usage] = config;
break;
+ case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
+ if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
+ ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
+ return BAD_VALUE;
+ }
+ mForceUse[usage] = config;
+ break;
default:
ALOGW("setForceUse() invalid usage %d", usage);
break; // TODO return BAD_VALUE?
@@ -423,8 +430,7 @@
// if SCO headset is connected and we are told to use it, play ringtone over
// speaker and BT SCO
- if (((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) &&
- (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO)) {
+ if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
uint32_t device2 = AUDIO_DEVICE_NONE;
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
if (device2 == AUDIO_DEVICE_NONE) {
@@ -433,10 +439,23 @@
if (device2 == AUDIO_DEVICE_NONE) {
device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
}
-
- if (device2 != AUDIO_DEVICE_NONE) {
- device |= device2;
- break;
+ // Use ONLY Bluetooth SCO output when ringing in vibration mode
+ if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
+ && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
+ if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
+ == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (device2 != AUDIO_DEVICE_NONE) {
+ device = device2;
+ break;
+ }
+ }
+ }
+ // Use both Bluetooth SCO and phone default output when ringing in normal mode
+ if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (device2 != AUDIO_DEVICE_NONE) {
+ device |= device2;
+ break;
+ }
}
}
// The second device used for sonification is the same as the device used by media strategy
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 73d92ac..92a2030 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5141,7 +5141,8 @@
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) &&
+ AUDIO_DEVICE_OUT_USB_HEADSET |
+ AUDIO_DEVICE_OUT_HEARING_AID)) &&
((stream_strategy == STRATEGY_SONIFICATION)
|| (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
|| (stream == AUDIO_STREAM_SYSTEM)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index fb9b0ba..9ed6d73 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1999,14 +1999,17 @@
// A reference count is kept to determine when we will actually release the
// media players.
-MediaPlayer* CameraService::newMediaPlayer(const char *file) {
- MediaPlayer* mp = new MediaPlayer();
- if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
+sp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
+ sp<MediaPlayer> mp = new MediaPlayer();
+ status_t error;
+ if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
- mp->prepare();
- } else {
+ error = mp->prepare();
+ }
+ if (error != NO_ERROR) {
ALOGE("Failed to load CameraService sounds: %s", file);
- delete mp;
+ mp->disconnect();
+ mp.clear();
return nullptr;
}
return mp;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 86a2b81..a7a9264 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -736,7 +736,7 @@
std::vector<std::string> mNormalDeviceIds;
// sounds
- MediaPlayer* newMediaPlayer(const char *file);
+ sp<MediaPlayer> newMediaPlayer(const char *file);
Mutex mSoundLock;
sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS];
diff --git a/services/codec2/Android.bp b/services/codec2/Android.bp
deleted file mode 100644
index 4cfca1d..0000000
--- a/services/codec2/Android.bp
+++ /dev/null
@@ -1,101 +0,0 @@
-cc_binary {
- name: "vendor.google.media.c2@1.0-service",
- defaults: ["hidl_defaults"],
- soc_specific: true,
- relative_install_path: "hw",
- srcs: [
- "vendor.cpp",
- ],
-
- init_rc: ["vendor.google.media.c2@1.0-service.rc"],
-
- shared_libs: [
- "vendor.google.media.c2@1.0",
- "libavservices_minijail_vendor",
- "libhidlbase",
- "libhidltransport",
- "libhwbinder",
- "liblog",
- "libstagefright_codec2_hidl@1.0",
- "libstagefright_codec2_vndk",
- "libutils",
- ],
-
- arch: {
- arm: {
- required: ["codec2.vendor.base.policy"],
- },
- x86: {
- required: ["codec2.vendor.base.policy"],
- },
- },
-
- compile_multilib: "32",
-}
-
-cc_binary {
- name: "vendor.google.media.c2@1.0-service-system",
- defaults: ["hidl_defaults"],
- relative_install_path: "hw",
- srcs: [
- "system.cpp",
- ],
-
- init_rc: ["vendor.google.media.c2@1.0-service-system.rc"],
-
- shared_libs: [
- "vendor.google.media.c2@1.0",
- "libavservices_minijail",
- "libcutils",
- "libhidlbase",
- "libhidltransport",
- "libhwbinder",
- "liblog",
- "libstagefright_codec2_hidl@1.0",
- "libstagefright_codec2_vndk",
- "libutils",
- "libv4l2_c2componentstore",
- ],
-
- arch: {
- arm: {
- required: ["codec2.system.base.policy"],
- },
- x86: {
- required: ["codec2.system.base.policy"],
- },
- },
-
- required: [
- "libstagefright_soft_c2avcdec",
- "libstagefright_soft_c2avcenc",
- "libstagefright_soft_c2aacdec",
- "libstagefright_soft_c2aacenc",
- "libstagefright_soft_c2amrnbdec",
- "libstagefright_soft_c2amrnbenc",
- "libstagefright_soft_c2amrwbdec",
- "libstagefright_soft_c2amrwbenc",
- "libstagefright_soft_c2hevcdec",
- "libstagefright_soft_c2g711alawdec",
- "libstagefright_soft_c2g711mlawdec",
- "libstagefright_soft_c2mpeg2dec",
- "libstagefright_soft_c2h263dec",
- "libstagefright_soft_c2h263enc",
- "libstagefright_soft_c2mpeg4dec",
- "libstagefright_soft_c2mpeg4enc",
- "libstagefright_soft_c2mp3dec",
- "libstagefright_soft_c2vorbisdec",
- "libstagefright_soft_c2opusdec",
- "libstagefright_soft_c2vp8dec",
- "libstagefright_soft_c2vp9dec",
- "libstagefright_soft_c2vp8enc",
- "libstagefright_soft_c2vp9enc",
- "libstagefright_soft_c2rawdec",
- "libstagefright_soft_c2flacdec",
- "libstagefright_soft_c2flacenc",
- "libstagefright_soft_c2gsmdec",
- ],
-
- compile_multilib: "32",
-}
-
diff --git a/services/codec2/Android.mk b/services/codec2/Android.mk
deleted file mode 100644
index fa49875..0000000
--- a/services/codec2/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# vendor service seccomp policy
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := codec2.vendor.base.policy
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-ifdef TARGET_2ND_ARCH
- ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_2ND_ARCH).policy
- else
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
- endif
-else
- LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
-endif
-include $(BUILD_PREBUILT)
-endif
-
-# system service seccomp policy
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := codec2.system.base.policy
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-ifdef TARGET_2ND_ARCH
- ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
- LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_2ND_ARCH).policy
- else
- LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_ARCH).policy
- endif
-else
- LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_ARCH).policy
-endif
-include $(BUILD_PREBUILT)
-endif
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
-
diff --git a/services/codec2/seccomp_policy/codec2.system.base-arm.policy b/services/codec2/seccomp_policy/codec2.system.base-arm.policy
deleted file mode 100644
index d5871d1..0000000
--- a/services/codec2/seccomp_policy/codec2.system.base-arm.policy
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Organized by frequency of systemcall - in descending order for
-# best performance.
-futex: 1
-ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
-close: 1
-writev: 1
-dup: 1
-ppoll: 1
-mmap2: 1
-getrandom: 1
-
-# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
-# parser support for '<' is in this needs to be modified to also prevent
-# |old_address| and |new_address| from touching the exception vector page, which
-# on ARM is statically loaded at 0xffff 0000. See
-# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
-# for more details.
-mremap: arg3 == 3
-munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
-sigaltstack: 1
-clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
-exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
-lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
-getdents64: 1
-getrandom: 1
-
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.system.base-x86.policy b/services/codec2/seccomp_policy/codec2.system.base-x86.policy
deleted file mode 100644
index 20c7625..0000000
--- a/services/codec2/seccomp_policy/codec2.system.base-x86.policy
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-read: 1
-mprotect: 1
-prctl: 1
-openat: 1
-getuid32: 1
-writev: 1
-ioctl: 1
-close: 1
-mmap2: 1
-fstat64: 1
-madvise: 1
-fstatat64: 1
-futex: 1
-munmap: 1
-faccessat: 1
-_llseek: 1
-lseek: 1
-clone: 1
-sigaltstack: 1
-setpriority: 1
-restart_syscall: 1
-exit: 1
-exit_group: 1
-rt_sigreturn: 1
-ugetrlimit: 1
-readlinkat: 1
-_llseek: 1
-fstatfs64: 1
-pread64: 1
-mremap: 1
-dup: 1
-set_tid_address: 1
-write: 1
-nanosleep: 1
-
-# Required by AddressSanitizer
-gettid: 1
-sched_yield: 1
-getpid: 1
-gettid: 1
-
-@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy b/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy
deleted file mode 100644
index d5871d1..0000000
--- a/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Organized by frequency of systemcall - in descending order for
-# best performance.
-futex: 1
-ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
-close: 1
-writev: 1
-dup: 1
-ppoll: 1
-mmap2: 1
-getrandom: 1
-
-# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
-# parser support for '<' is in this needs to be modified to also prevent
-# |old_address| and |new_address| from touching the exception vector page, which
-# on ARM is statically loaded at 0xffff 0000. See
-# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
-# for more details.
-mremap: arg3 == 3
-munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
-sigaltstack: 1
-clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
-exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
-lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
-getdents64: 1
-getrandom: 1
-
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy b/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy
deleted file mode 100644
index 20c7625..0000000
--- a/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-read: 1
-mprotect: 1
-prctl: 1
-openat: 1
-getuid32: 1
-writev: 1
-ioctl: 1
-close: 1
-mmap2: 1
-fstat64: 1
-madvise: 1
-fstatat64: 1
-futex: 1
-munmap: 1
-faccessat: 1
-_llseek: 1
-lseek: 1
-clone: 1
-sigaltstack: 1
-setpriority: 1
-restart_syscall: 1
-exit: 1
-exit_group: 1
-rt_sigreturn: 1
-ugetrlimit: 1
-readlinkat: 1
-_llseek: 1
-fstatfs64: 1
-pread64: 1
-mremap: 1
-dup: 1
-set_tid_address: 1
-write: 1
-nanosleep: 1
-
-# Required by AddressSanitizer
-gettid: 1
-sched_yield: 1
-getpid: 1
-gettid: 1
-
-@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/services/codec2/system.cpp b/services/codec2/system.cpp
deleted file mode 100644
index d6ec644..0000000
--- a/services/codec2/system.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "vendor.google.media.c2@1.0-service"
-
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-#include <cutils/properties.h>
-
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <hidl/HidlTransportSupport.h>
-#include <minijail.h>
-
-// TODO: Remove this once "setenv()" call is removed.
-#include <stdlib.h>
-
-// This is created by module "codec2.system.base.policy". This can be modified.
-static constexpr char kBaseSeccompPolicyPath[] =
- "/system/etc/seccomp_policy/codec2.system.base.policy";
-
-// Additional device-specific seccomp permissions can be added in this file.
-static constexpr char kExtSeccompPolicyPath[] =
- "/system/etc/seccomp_policy/codec2.system.ext.policy";
-
-int main(int /* argc */, char** /* argv */) {
- ALOGD("vendor.google.media.c2@1.0-service-system starting...");
-
- // TODO: Remove this when all the build settings and sepolicies are in place.
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-
- signal(SIGPIPE, SIG_IGN);
- android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
-
- // Extra threads may be needed to handle a stacked IPC sequence that
- // contains alternating binder and hwbinder calls. (See b/35283480.)
- android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
-
- // Create IComponentStore service.
- {
- using namespace ::vendor::google::media::c2::V1_0;
- android::sp<IComponentStore> store =
- new implementation::ComponentStore(
- android::GetCodec2PlatformComponentStore());
- if (store == nullptr) {
- ALOGE("Cannot create Codec2's IComponentStore system service.");
- } else {
- if (store->registerAsService("system") != android::OK) {
- ALOGE("Cannot register Codec2's "
- "IComponentStore system service.");
- } else {
- ALOGI("Codec2's IComponentStore system service created.");
- }
- }
-
- // To enable the v4l2 service, set this sysprop and add "v4l2" instance
- // to the system manifest file.
- if (property_get_bool("debug.stagefright.ccodec_v4l2", false)) {
- store = new implementation::ComponentStore(
- android::GetCodec2VDAComponentStore());
- if (store == nullptr) {
- ALOGE("Cannot create Codec2's IComponentStore V4L2 service.");
- } else {
- if (store->registerAsService("v4l2") != android::OK) {
- ALOGE("Cannot register Codec2's "
- "IComponentStore V4L2 service.");
- } else {
- ALOGI("Codec2's IComponentStore V4L2 service created.");
- }
- }
- }
- }
-
- android::hardware::joinRpcThreadpool();
- return 0;
-}
-
diff --git a/services/codec2/vendor.cpp b/services/codec2/vendor.cpp
deleted file mode 100644
index 60b51e2..0000000
--- a/services/codec2/vendor.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "vendor.google.media.c2@1.0-service"
-
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <hidl/HidlTransportSupport.h>
-#include <minijail.h>
-
-#include <C2Component.h>
-
-// TODO: Remove this once "setenv()" call is removed.
-#include <stdlib.h>
-
-// This is created by module "codec2.vendor.base.policy". This can be modified.
-static constexpr char kBaseSeccompPolicyPath[] =
- "/vendor/etc/seccomp_policy/codec2.vendor.base.policy";
-
-// Additional device-specific seccomp permissions can be added in this file.
-static constexpr char kExtSeccompPolicyPath[] =
- "/vendor/etc/seccomp_policy/codec2.vendor.ext.policy";
-
-// TODO: Replace with a valid C2ComponentStore implementation.
-class DummyC2Store : public C2ComponentStore {
-public:
- DummyC2Store() = default;
-
- virtual ~DummyC2Store() override = default;
-
- virtual C2String getName() const override {
- return "default";
- }
-
- virtual c2_status_t createComponent(
- C2String /*name*/,
- std::shared_ptr<C2Component>* const /*component*/) override {
- return C2_NOT_FOUND;
- }
-
- virtual c2_status_t createInterface(
- C2String /* name */,
- std::shared_ptr<C2ComponentInterface>* const /* interface */) override {
- return C2_NOT_FOUND;
- }
-
- virtual std::vector<std::shared_ptr<const C2Component::Traits>>
- listComponents() override {
- return {};
- }
-
- virtual c2_status_t copyBuffer(
- std::shared_ptr<C2GraphicBuffer> /* src */,
- std::shared_ptr<C2GraphicBuffer> /* dst */) override {
- return C2_OMITTED;
- }
-
- virtual c2_status_t query_sm(
- const std::vector<C2Param*>& /* stackParams */,
- const std::vector<C2Param::Index>& /* heapParamIndices */,
- std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const override {
- return C2_OMITTED;
- }
-
- virtual c2_status_t config_sm(
- const std::vector<C2Param*>& /* params */,
- std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) override {
- return C2_OMITTED;
- }
-
- virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
- return nullptr;
- }
-
- virtual c2_status_t querySupportedParams_nb(
- std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const override {
- return C2_OMITTED;
- }
-
- virtual c2_status_t querySupportedValues_sm(
- std::vector<C2FieldSupportedValuesQuery>& /* fields */) const override {
- return C2_OMITTED;
- }
-};
-
-int main(int /* argc */, char** /* argv */) {
- ALOGD("vendor.google.media.c2@1.0-service starting...");
-
- // TODO: Remove this when all the build settings and sepolicies are in place.
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-
- signal(SIGPIPE, SIG_IGN);
- android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
-
- // Extra threads may be needed to handle a stacked IPC sequence that
- // contains alternating binder and hwbinder calls. (See b/35283480.)
- android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
-
- // Create IComponentStore service.
- {
- using namespace ::vendor::google::media::c2::V1_0;
- android::sp<IComponentStore> store =
- new implementation::ComponentStore(
- // TODO: Replace this with a valid C2ComponentStore
- // implementation.
- std::make_shared<DummyC2Store>());
- if (store == nullptr) {
- ALOGE("Cannot create Codec2's IComponentStore service.");
- } else {
- if (store->registerAsService("default") != android::OK) {
- ALOGE("Cannot register Codec2's "
- "IComponentStore service.");
- } else {
- ALOGI("Codec2's IComponentStore service created.");
- }
- }
- }
-
- android::hardware::joinRpcThreadpool();
- return 0;
-}
-
diff --git a/services/codec2/vendor.google.media.c2@1.0-service-system.rc b/services/codec2/vendor.google.media.c2@1.0-service-system.rc
deleted file mode 100644
index 0577a1d..0000000
--- a/services/codec2/vendor.google.media.c2@1.0-service-system.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor-google-media-c2-system-hal-1-0 /system/bin/hw/vendor.google.media.c2@1.0-service-system
- class hal
- user media
- group mediadrm drmrpc
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
-
diff --git a/services/codec2/vendor.google.media.c2@1.0-service.rc b/services/codec2/vendor.google.media.c2@1.0-service.rc
deleted file mode 100644
index 3e7e0a6..0000000
--- a/services/codec2/vendor.google.media.c2@1.0-service.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor-google-media-c2-hal-1-0 /vendor/bin/hw/vendor.google.media.c2@1.0-service
- class hal
- user media
- group mediadrm drmrpc
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
-
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 7b8d817..11fd9f6 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -201,14 +201,14 @@
if (endpoint.get() != nullptr) {
aaudio_result_t result = endpoint->open(request);
if (result != AAUDIO_OK) {
- ALOGE("openSharedEndpoint(), open failed");
+ ALOGE("%s(), open failed", __func__);
endpoint.clear();
} else {
mSharedStreams.push_back(endpoint);
}
}
- ALOGD("openSharedEndpoint(), created %p, requested device = %d, dir = %d",
- endpoint.get(), configuration.getDeviceId(), (int)direction);
+ ALOGD("%s(), created endpoint %p, requested device = %d, dir = %d",
+ __func__, endpoint.get(), configuration.getDeviceId(), (int)direction);
IPCThreadState::self()->restoreCallingIdentity(token);
}
@@ -244,8 +244,8 @@
mExclusiveStreams.end());
serviceEndpoint->close();
- ALOGD("closeExclusiveEndpoint() %p for device %d",
- serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+ ALOGD("%s() %p for device %d",
+ __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
}
}
@@ -266,7 +266,7 @@
mSharedStreams.end());
serviceEndpoint->close();
- ALOGD("closeSharedEndpoint() %p for device %d",
- serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+ ALOGD("%s() %p for device %d",
+ __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
}
}
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index c708fee..ad5bb3a 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -165,7 +165,6 @@
}
aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) {
- ALOGD("closeStream(0x%08X)", streamHandle);
// Check permission and ownership first.
sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 33439fc..96e621a 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -39,7 +39,7 @@
using namespace aaudio; // TODO just import names needed
AAudioServiceEndpoint::~AAudioServiceEndpoint() {
- ALOGD("AAudioServiceEndpoint::~AAudioServiceEndpoint() destroying endpoint %p", this);
+ ALOGD("%s(%p) destroyed", __func__, this);
}
std::string AAudioServiceEndpoint::dump() const {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index db01c88..52990da 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -98,8 +98,8 @@
.flags = AUDIO_FLAG_LOW_LATENCY,
.tags = ""
};
- ALOGV("open() MMAP attributes.usage = %d, content_type = %d, source = %d",
- attributes.usage, attributes.content_type, attributes.source);
+ ALOGD("%s(%p) MMAP attributes.usage = %d, content_type = %d, source = %d",
+ __func__, this, attributes.usage, attributes.content_type, attributes.source);
mMmapClient.clientUid = request.getUserId();
mMmapClient.clientPid = request.getProcessId();
@@ -135,7 +135,7 @@
mHardwareTimeOffsetNanos = INPUT_ESTIMATED_HARDWARE_OFFSET_NANOS; // frames at ADC earlier
} else {
- ALOGE("openMmapStream - invalid direction = %d", direction);
+ ALOGE("%s() invalid direction = %d", __func__, direction);
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
}
@@ -157,20 +157,20 @@
this, // callback
mMmapStream,
&mPortHandle);
- ALOGD("open() mMapClient.uid = %d, pid = %d => portHandle = %d\n",
- mMmapClient.clientUid, mMmapClient.clientPid, mPortHandle);
+ ALOGD("%s() mMapClient.uid = %d, pid = %d => portHandle = %d\n",
+ __func__, mMmapClient.clientUid, mMmapClient.clientPid, mPortHandle);
if (status != OK) {
- ALOGE("openMmapStream returned status %d", status);
+ ALOGE("%s() openMmapStream() returned status %d", __func__, status);
return AAUDIO_ERROR_UNAVAILABLE;
}
if (deviceId == AAUDIO_UNSPECIFIED) {
- ALOGW("open() - openMmapStream() failed to set deviceId");
+ ALOGW("%s() openMmapStream() failed to set deviceId", __func__);
}
setDeviceId(deviceId);
if (sessionId == AUDIO_SESSION_ALLOCATE) {
- ALOGW("open() - openMmapStream() failed to set sessionId");
+ ALOGW("%s() - openMmapStream() failed to set sessionId", __func__);
}
aaudio_session_id_t actualSessionId =
@@ -178,7 +178,7 @@
? AAUDIO_SESSION_ID_NONE
: (aaudio_session_id_t) sessionId;
setSessionId(actualSessionId);
- ALOGD("open() deviceId = %d, sessionId = %d", getDeviceId(), getSessionId());
+ ALOGD("%s() deviceId = %d, sessionId = %d", __func__, getDeviceId(), getSessionId());
// Create MMAP/NOIRQ buffer.
int32_t minSizeFrames = getBufferCapacity();
@@ -187,14 +187,14 @@
}
status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
if (status != OK) {
- ALOGE("open() - createMmapBuffer() failed with status %d %s",
- status, strerror(-status));
+ ALOGE("%s() - createMmapBuffer() failed with status %d %s",
+ __func__, status, strerror(-status));
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
} else {
- ALOGD("createMmapBuffer status = %d, buffer_size = %d, burst_size %d"
+ ALOGD("%s() createMmapBuffer() returned = %d, buffer_size = %d, burst_size %d"
", Sharable FD: %s",
- status,
+ __func__, status,
abs(mMmapBufferinfo.buffer_size_frames),
mMmapBufferinfo.burst_size_frames,
mMmapBufferinfo.buffer_size_frames < 0 ? "Yes" : "No");
@@ -214,7 +214,7 @@
// Fallback is handled by caller but indicate what is possible in case
// this is used in the future
setSharingMode(AAUDIO_SHARING_MODE_SHARED);
- ALOGW("open() - exclusive FD cannot be used by client");
+ ALOGW("%s() - exclusive FD cannot be used by client", __func__);
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
@@ -229,7 +229,7 @@
// Assume that AudioFlinger will close the original shared_memory_fd.
mAudioDataFileDescriptor.reset(dup(mMmapBufferinfo.shared_memory_fd));
if (mAudioDataFileDescriptor.get() == -1) {
- ALOGE("open() - could not dup shared_memory_fd");
+ ALOGE("%s() - could not dup shared_memory_fd", __func__);
result = AAUDIO_ERROR_INTERNAL;
goto error;
}
@@ -247,12 +247,12 @@
burstMicros = mFramesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
} while (burstMicros < burstMinMicros);
- ALOGD("open() original burst = %d, minMicros = %d, to burst = %d\n",
- mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
+ ALOGD("%s() original burst = %d, minMicros = %d, to burst = %d\n",
+ __func__, mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
- ALOGD("open() actual rate = %d, channels = %d"
+ ALOGD("%s() actual rate = %d, channels = %d"
", deviceId = %d, capacity = %d\n",
- getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
+ __func__, getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
return result;
@@ -262,9 +262,8 @@
}
aaudio_result_t AAudioServiceEndpointMMAP::close() {
-
if (mMmapStream != 0) {
- ALOGD("close() clear() endpoint");
+ ALOGD("%s() clear() endpoint", __func__);
// Needs to be explicitly cleared or CTS will fail but it is not clear why.
mMmapStream.clear();
// Apparently the above close is asynchronous. An attempt to open a new device
@@ -299,20 +298,18 @@
aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
audio_port_handle_t *clientHandle) {
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
- ALOGD("startClient(%p(uid=%d, pid=%d))",
- &client, client.clientUid, client.clientPid);
+ ALOGV("%s(%p(uid=%d, pid=%d))", __func__, &client, client.clientUid, client.clientPid);
audio_port_handle_t originalHandle = *clientHandle;
status_t status = mMmapStream->start(client, clientHandle);
aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
- ALOGD("startClient() , %d => %d returns %d",
- originalHandle, *clientHandle, result);
+ ALOGV("%s() , %d => %d returns %d", __func__, originalHandle, *clientHandle, result);
return result;
}
aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) {
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
aaudio_result_t result = AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
- ALOGD("stopClient(%d) returns %d", clientHandle, result);
+ ALOGV("%s(%d) returns %d", __func__, clientHandle, result);
return result;
}
@@ -324,13 +321,13 @@
return AAUDIO_ERROR_NULL;
}
status_t status = mMmapStream->getMmapPosition(&position);
- ALOGV("getFreeRunningPosition() status= %d, pos = %d, nanos = %lld\n",
- status, position.position_frames, (long long) position.time_nanoseconds);
+ ALOGV("%s() status= %d, pos = %d, nanos = %lld\n",
+ __func__, status, position.position_frames, (long long) position.time_nanoseconds);
aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
if (result == AAUDIO_ERROR_UNAVAILABLE) {
- ALOGW("sendCurrentTimestamp(): getMmapPosition() has no position data available");
+ ALOGW("%s(): getMmapPosition() has no position data available", __func__);
} else if (result != AAUDIO_OK) {
- ALOGE("sendCurrentTimestamp(): getMmapPosition() returned status %d", status);
+ ALOGE("%s(): getMmapPosition() returned status %d", __func__, status);
} else {
// Convert 32-bit position to 64-bit position.
mFramesTransferred.update32(position.position_frames);
@@ -347,15 +344,16 @@
void AAudioServiceEndpointMMAP::onTearDown() {
- ALOGD("onTearDown() called");
+ ALOGD("%s(%p) called", __func__, this);
disconnectRegisteredStreams();
};
void AAudioServiceEndpointMMAP::onVolumeChanged(audio_channel_mask_t channels,
android::Vector<float> values) {
- // TODO do we really need a different volume for each channel?
+ // TODO Do we really need a different volume for each channel?
+ // We get called with an array filled with a single value!
float volume = values[0];
- ALOGD("onVolumeChanged() volume[0] = %f", volume);
+ ALOGD("%s(%p) volume[0] = %f", __func__, this, volume);
std::lock_guard<std::mutex> lock(mLockStreams);
for(const auto stream : mRegisteredStreams) {
stream->onVolumeChanged(volume);
@@ -363,8 +361,7 @@
};
void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t deviceId) {
- ALOGD("onRoutingChanged() called with dev %d, old = %d",
- deviceId, getDeviceId());
+ ALOGD("%s(%p) called with dev %d, old = %d", __func__, this, deviceId, getDeviceId());
if (getDeviceId() != AUDIO_PORT_HANDLE_NONE && getDeviceId() != deviceId) {
disconnectRegisteredStreams();
}
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index 2601f3f..a274466 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -43,10 +43,12 @@
AAudioServiceEndpointPlay::AAudioServiceEndpointPlay(AAudioService &audioService)
: mStreamInternalPlay(audioService, true) {
+ ALOGD("%s(%p) created", __func__, this);
mStreamInternal = &mStreamInternalPlay;
}
AAudioServiceEndpointPlay::~AAudioServiceEndpointPlay() {
+ ALOGD("%s(%p) destroyed", __func__, this);
}
aaudio_result_t AAudioServiceEndpointPlay::open(const aaudio::AAudioStreamRequest &request) {
@@ -68,6 +70,7 @@
// Mix data from each application stream and write result to the shared MMAP stream.
void *AAudioServiceEndpointPlay::callbackLoop() {
+ ALOGD("%s() entering >>>>>>>>>>>>>>> MIXER", __func__);
aaudio_result_t result = AAUDIO_OK;
int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();
@@ -152,5 +155,7 @@
}
}
+ ALOGD("%s() exiting, enabled = %d, state = %d, result = %d <<<<<<<<<<<<< MIXER",
+ __func__, mCallbackEnabled.load(), getStreamInternal()->getState(), result);
return NULL; // TODO review
}
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 584efe5..f08a52f 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -89,18 +89,22 @@
}
// Glue between C and C++ callbacks.
-static void *aaudio_endpoint_thread_proc(void *context) {
- AAudioServiceEndpointShared *endpoint = (AAudioServiceEndpointShared *) context;
- if (endpoint != NULL) {
- void *result = endpoint->callbackLoop();
- // Close now so that the HW resource is freed and we can open a new device.
- if (!endpoint->isConnected()) {
- endpoint->close();
- }
- return result;
- } else {
- return NULL;
+static void *aaudio_endpoint_thread_proc(void *arg) {
+ assert(arg != nullptr);
+
+ // The caller passed in a smart pointer to prevent the endpoint from getting deleted
+ // while the thread was launching.
+ sp<AAudioServiceEndpointShared> *endpointForThread =
+ static_cast<sp<AAudioServiceEndpointShared> *>(arg);
+ sp<AAudioServiceEndpointShared> endpoint = *endpointForThread;
+ delete endpointForThread; // Just use scoped smart pointer. Don't need this anymore.
+ void *result = endpoint->callbackLoop();
+ // Close now so that the HW resource is freed and we can open a new device.
+ if (!endpoint->isConnected()) {
+ endpoint->close();
}
+
+ return result;
}
aaudio_result_t aaudio::AAudioServiceEndpointShared::startSharingThread_l() {
@@ -109,7 +113,16 @@
* AAUDIO_NANOS_PER_SECOND
/ getSampleRate();
mCallbackEnabled.store(true);
- return getStreamInternal()->createThread(periodNanos, aaudio_endpoint_thread_proc, this);
+ // Pass a smart pointer so the thread can hold a reference.
+ sp<AAudioServiceEndpointShared> *endpointForThread = new sp<AAudioServiceEndpointShared>(this);
+ aaudio_result_t result = getStreamInternal()->createThread(periodNanos,
+ aaudio_endpoint_thread_proc,
+ endpointForThread);
+ if (result != AAUDIO_OK) {
+ // The thread can't delete it so we have to do it here.
+ delete endpointForThread;
+ }
+ return result;
}
aaudio_result_t aaudio::AAudioServiceEndpointShared::stopSharingThread() {
diff --git a/services/oboeservice/AAudioServiceEndpointShared.h b/services/oboeservice/AAudioServiceEndpointShared.h
index 74cd817..227250c 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.h
+++ b/services/oboeservice/AAudioServiceEndpointShared.h
@@ -54,12 +54,13 @@
virtual void *callbackLoop() = 0;
+
+protected:
+
AudioStreamInternal *getStreamInternal() const {
return mStreamInternal;
};
-protected:
-
aaudio_result_t startSharingThread_l();
aaudio_result_t stopSharingThread();
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index e8c9e41..18f14ee 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -93,7 +93,7 @@
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
if (mUpMessageQueue != nullptr) {
- ALOGE("open() called twice");
+ ALOGE("%s() called twice", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -108,7 +108,7 @@
request,
sharingMode);
if (mServiceEndpoint == nullptr) {
- ALOGE("open() openEndpoint() failed");
+ ALOGE("%s() openEndpoint() failed", __func__);
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
@@ -167,7 +167,7 @@
}
if (mServiceEndpoint == nullptr) {
- ALOGE("start() missing endpoint");
+ ALOGE("%s() missing endpoint", __func__);
result = AAUDIO_ERROR_INVALID_STATE;
goto error;
}
@@ -201,7 +201,7 @@
return result;
}
if (mServiceEndpoint == nullptr) {
- ALOGE("pause() missing endpoint");
+ ALOGE("%s() missing endpoint", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -217,7 +217,7 @@
result = mServiceEndpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
- ALOGE("pause() mServiceEndpoint returned %d", result);
+ ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText());
disconnect(); // TODO should we return or pause Base first?
}
@@ -233,7 +233,7 @@
}
if (mServiceEndpoint == nullptr) {
- ALOGE("stop() missing endpoint");
+ ALOGE("%s() missing endpoint", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -251,7 +251,7 @@
// TODO wait for data to be played out
result = mServiceEndpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
- ALOGE("stop() mServiceEndpoint returned %d", result);
+ ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText());
disconnect();
// TODO what to do with result here?
}
@@ -284,7 +284,7 @@
// implement Runnable, periodically send timestamps to client
void AAudioServiceStreamBase::run() {
- ALOGD("run() entering ----------------");
+ ALOGD("%s() %s entering >>>>>>>>>>>>>> TIMESTAMPS", __func__, getTypeText());
TimestampScheduler timestampScheduler;
timestampScheduler.setBurstPeriod(mFramesPerBurst, getSampleRate());
timestampScheduler.start(AudioClock::getNanoseconds());
@@ -302,7 +302,7 @@
AudioClock::sleepUntilNanoTime(nextTime);
}
}
- ALOGD("run() exiting ----------------");
+ ALOGD("%s() %s exiting <<<<<<<<<<<<<< TIMESTAMPS", __func__, getTypeText());
}
void AAudioServiceStreamBase::disconnect() {
@@ -333,12 +333,12 @@
aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessage *command) {
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
if (mUpMessageQueue == nullptr) {
- ALOGE("writeUpMessageQueue(): mUpMessageQueue null! - stream not open");
+ ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
return AAUDIO_ERROR_NULL;
}
int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
if (count != 1) {
- ALOGE("writeUpMessageQueue(): Queue full. Did client die?");
+ ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
return AAUDIO_ERROR_WOULD_BLOCK;
} else {
return AAUDIO_OK;
@@ -355,7 +355,7 @@
aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
&command.timestamp.timestamp);
if (result == AAUDIO_OK) {
- ALOGV("sendCurrentTimestamp() SERVICE %8lld at %lld",
+ ALOGV("%s() SERVICE %8lld at %lld", __func__,
(long long) command.timestamp.position,
(long long) command.timestamp.timestamp);
command.what = AAudioServiceMessage::code::TIMESTAMP_SERVICE;
@@ -366,7 +366,7 @@
result = getHardwareTimestamp(&command.timestamp.position,
&command.timestamp.timestamp);
if (result == AAUDIO_OK) {
- ALOGV("sendCurrentTimestamp() HARDWARE %8lld at %lld",
+ ALOGV("%s() HARDWARE %8lld at %lld", __func__,
(long long) command.timestamp.position,
(long long) command.timestamp.timestamp);
command.what = AAudioServiceMessage::code::TIMESTAMP_HARDWARE;
@@ -389,7 +389,7 @@
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
if (mUpMessageQueue == nullptr) {
- ALOGE("getDescription(): mUpMessageQueue null! - stream not open");
+ ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
return AAUDIO_ERROR_NULL;
}
// Gather information on the message queue.
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 5f5bb98..3720596 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -55,7 +55,7 @@
, public Runnable {
public:
- AAudioServiceStreamBase(android::AAudioService &aAudioService);
+ explicit AAudioServiceStreamBase(android::AAudioService &aAudioService);
virtual ~AAudioServiceStreamBase();
@@ -219,6 +219,8 @@
mCloseNeeded.store(needed);
}
+ virtual const char *getTypeText() const { return "Base"; }
+
protected:
/**
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index e2415d0..1509f7d 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -69,9 +69,7 @@
aaudio_result_t close() override;
- /**
- * Send a MMAP/NOIRQ buffer timestamp to the client.
- */
+ const char *getTypeText() const override { return "MMAP"; }
protected:
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 3b12e61..61769b5 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -43,7 +43,7 @@
class AAudioServiceStreamShared : public AAudioServiceStreamBase {
public:
- AAudioServiceStreamShared(android::AAudioService &aAudioService);
+ explicit AAudioServiceStreamShared(android::AAudioService &aAudioService);
virtual ~AAudioServiceStreamShared() = default;
static std::string dumpHeader();
@@ -87,6 +87,8 @@
return mXRunCount.load();
}
+ const char *getTypeText() const override { return "Shared"; }
+
protected:
aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) override;
diff --git a/services/oboeservice/AAudioThread.h b/services/oboeservice/AAudioThread.h
index ffc9b7b..dcce68a 100644
--- a/services/oboeservice/AAudioThread.h
+++ b/services/oboeservice/AAudioThread.h
@@ -44,7 +44,7 @@
public:
AAudioThread();
- AAudioThread(const char *prefix);
+ explicit AAudioThread(const char *prefix);
virtual ~AAudioThread() = default;