Merge "FLAC: add flac decoder in omx and support flac in Matroska extractor"
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index e1718eb..e56f675 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -958,11 +958,9 @@
void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
{
- mEventLock.lock();
- mListener.clear();
- mEventLock.unlock();
-
Mutex::Autolock autoLock(mLock);
+ setListener(NULL);
+ mPlugin->setListener(NULL);
mPlugin.clear();
}
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 4b8da79..f11f1fa 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -42,7 +42,6 @@
* and would accept whatever it was given.
*/
#define AAUDIO_UNSPECIFIED 0
-#define AAUDIO_DEVICE_UNSPECIFIED 0
enum {
AAUDIO_DIRECTION_OUTPUT,
@@ -191,11 +190,11 @@
* Request an audio device identified device using an ID.
* On Android, for example, the ID could be obtained from the Java AudioManager.
*
- * The default, if you do not call this function, is AAUDIO_DEVICE_UNSPECIFIED,
+ * The default, if you do not call this function, is AAUDIO_UNSPECIFIED,
* in which case the primary device will be used.
*
* @param builder reference provided by AAudio_createStreamBuilder()
- * @param deviceId device identifier or AAUDIO_DEVICE_UNSPECIFIED
+ * @param deviceId device identifier or AAUDIO_UNSPECIFIED
*/
AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
int32_t deviceId);
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.h b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
index acb6744..144595a 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.h
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
@@ -91,7 +91,7 @@
void dump() const;
private:
- int32_t mDeviceId = AAUDIO_DEVICE_UNSPECIFIED;
+ int32_t mDeviceId = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index ca36e1a..f71404d 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -81,7 +81,7 @@
}
// We have to do volume scaling. So we prefer FLOAT format.
- if (getFormat() == AAUDIO_UNSPECIFIED) {
+ if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) {
setFormat(AAUDIO_FORMAT_PCM_FLOAT);
}
// Request FLOAT for the shared mixer.
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index 476f909..fd416c4 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -168,7 +168,7 @@
private:
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
- int32_t mDeviceId = AAUDIO_DEVICE_UNSPECIFIED;
+ int32_t mDeviceId = AAUDIO_UNSPECIFIED;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
bool mSharingModeMatchRequired = false; // must match sharing mode requested
aaudio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED;
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 0918c2b..156e83d 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -64,7 +64,7 @@
: builder.getBufferCapacity();
// TODO implement an unspecified Android format then use that.
- audio_format_t format = (getFormat() == AAUDIO_UNSPECIFIED)
+ audio_format_t format = (getFormat() == AAUDIO_FORMAT_UNSPECIFIED)
? AUDIO_FORMAT_PCM_FLOAT
: AAudioConvert_aaudioToAndroidDataFormat(getFormat());
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 605b19e..409c9a3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1247,9 +1247,27 @@
return mStreamType;
}
+uint32_t AudioTrack::latency()
+{
+ AutoMutex lock(mLock);
+ updateLatency_l();
+ return mLatency;
+}
+
// -------------------------------------------------------------------------
// must be called with mLock held
+void AudioTrack::updateLatency_l()
+{
+ status_t status = AudioSystem::getLatency(mOutput, &mAfLatency);
+ if (status != NO_ERROR) {
+ ALOGW("getLatency(%d) failed status %d", mOutput, status);
+ } else {
+ // FIXME don't believe this lie
+ mLatency = mAfLatency + (1000 * mFrameCount) / mSampleRate;
+ }
+}
+
status_t AudioTrack::createTrack_l()
{
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -1544,9 +1562,7 @@
}
mAudioTrack->attachAuxEffect(mAuxEffectId);
- // FIXME doesn't take into account speed or future sample rate changes (until restoreTrack)
- // FIXME don't believe this lie
- mLatency = mAfLatency + (1000*frameCount) / mSampleRate;
+ updateLatency_l(); // this refetches mAfLatency and sets mLatency
mFrameCount = frameCount;
// If IAudioTrack is re-created, don't let the requested frameCount
@@ -2318,8 +2334,9 @@
return mPosition;
}
-bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const
+bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed)
{
+ updateLatency_l();
// applicable for mixing tracks only (not offloaded or direct)
if (mStaticProxy != 0) {
return true; // static tracks do not have issues with buffer sizing.
@@ -2327,9 +2344,14 @@
const size_t minFrameCount =
calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed
/*, 0 mNotificationsPerBufferReq*/);
- ALOGV("isSampleRateSpeedAllowed_l mFrameCount %zu minFrameCount %zu",
+ const bool allowed = mFrameCount >= minFrameCount;
+ ALOGD_IF(!allowed,
+ "isSampleRateSpeedAllowed_l denied "
+ "mAfLatency:%u mAfFrameCount:%zu mAfSampleRate:%u sampleRate:%u speed:%f "
+ "mFrameCount:%zu < minFrameCount:%zu",
+ mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed,
mFrameCount, minFrameCount);
- return mFrameCount >= minFrameCount;
+ return allowed;
}
status_t AudioTrack::setParameters(const String8& keyValuePairs)
@@ -2473,6 +2495,7 @@
status = ets.getBestTimestamp(×tamp, &location);
if (status == OK) {
+ updateLatency_l();
// It is possible that the best location has moved from the kernel to the server.
// In this case we adjust the position from the previous computed latency.
if (location == ExtendedTimestamp::LOCATION_SERVER) {
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index a4c8d53..5d73df3 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -326,7 +326,7 @@
* This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
* and audio hardware driver.
*/
- uint32_t latency() const { return mLatency; }
+ uint32_t latency();
/* Returns the number of application-level buffer underruns
* since the AudioTrack was created.
@@ -927,6 +927,8 @@
// caller must hold lock on mLock for all _l methods
+ void updateLatency_l(); // updates mAfLatency and mLatency from AudioSystem cache
+
status_t createTrack_l();
// can only be called when mState != STATE_ACTIVE
@@ -962,7 +964,7 @@
Modulo<uint32_t> updateAndGetPosition_l();
// check sample rate and speed is compatible with AudioTrack
- bool isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const;
+ bool isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed);
void restartIfDisabled();
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 0bb4dbb..bbdcf0b 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -2967,8 +2967,10 @@
int32_t delay, padding;
if (sscanf(mLastCommentData,
" %*x %x %x %*x", &delay, &padding) == 2) {
- if (mLastTrack == NULL)
+ if (mLastTrack == NULL) {
+ delete[] buffer;
return ERROR_MALFORMED;
+ }
mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 99b3ba8..8c8b97a 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -156,6 +156,86 @@
return OK;
}
+void Camera3BufferManager::notifyBufferRemoved(int streamId, int streamSetId) {
+ Mutex::Autolock l(mLock);
+ StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ size_t& attachedBufferCount =
+ streamSet.attachedBufferCountMap.editValueFor(streamId);
+ attachedBufferCount--;
+}
+
+status_t Camera3BufferManager::checkAndFreeBufferOnOtherStreamsLocked(
+ int streamId, int streamSetId) {
+ StreamId firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
+ StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ if (streamSet.streamInfoMap.size() == 1) {
+ ALOGV("StreamSet %d has no other stream available to free", streamSetId);
+ return OK;
+ }
+
+ bool freeBufferIsAttached = false;
+ for (size_t i = 0; i < streamSet.streamInfoMap.size(); i++) {
+ firstOtherStreamId = streamSet.streamInfoMap[i].streamId;
+ if (firstOtherStreamId != streamId) {
+
+ size_t otherBufferCount =
+ streamSet.handoutBufferCountMap.valueFor(firstOtherStreamId);
+ size_t otherAttachedBufferCount =
+ streamSet.attachedBufferCountMap.valueFor(firstOtherStreamId);
+ if (otherAttachedBufferCount > otherBufferCount) {
+ freeBufferIsAttached = true;
+ break;
+ }
+ }
+ firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
+ }
+ if (firstOtherStreamId == CAMERA3_STREAM_ID_INVALID || !freeBufferIsAttached) {
+ ALOGV("StreamSet %d has no buffer available to free", streamSetId);
+ return OK;
+ }
+
+
+ // This will drop the reference to one free buffer, which will effectively free one
+ // buffer (from the free buffer list) for the inactive streams.
+ size_t totalAllocatedBufferCount = 0;
+ for (size_t i = 0; i < streamSet.attachedBufferCountMap.size(); i++) {
+ totalAllocatedBufferCount += streamSet.attachedBufferCountMap[i];
+ }
+ if (totalAllocatedBufferCount > streamSet.allocatedBufferWaterMark) {
+ ALOGV("Stream %d: Freeing buffer: detach", firstOtherStreamId);
+ sp<Camera3OutputStream> stream =
+ mStreamMap.valueFor(firstOtherStreamId).promote();
+ if (stream == nullptr) {
+ ALOGE("%s: unable to promote stream %d to detach buffer", __FUNCTION__,
+ firstOtherStreamId);
+ return INVALID_OPERATION;
+ }
+
+ // Detach and then drop the buffer.
+ //
+ // Need to unlock because the stream may also be calling
+ // into the buffer manager in parallel to signal buffer
+ // release, or acquire a new buffer.
+ bool bufferFreed = false;
+ {
+ mLock.unlock();
+ sp<GraphicBuffer> buffer;
+ stream->detachBuffer(&buffer, /*fenceFd*/ nullptr);
+ mLock.lock();
+ if (buffer.get() != nullptr) {
+ bufferFreed = true;
+ }
+ }
+ if (bufferFreed) {
+ size_t& otherAttachedBufferCount =
+ streamSet.attachedBufferCountMap.editValueFor(firstOtherStreamId);
+ otherAttachedBufferCount--;
+ }
+ }
+
+ return OK;
+}
+
status_t Camera3BufferManager::getBufferForStream(int streamId, int streamSetId,
sp<GraphicBuffer>* gb, int* fenceFd) {
ATRACE_CALL();
@@ -228,61 +308,15 @@
// in returnBufferForStream() if we want to free buffer more quickly.
// TODO: probably should find out all the inactive stream IDs, and free the firstly found
// buffers for them.
- StreamId firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
- if (streamSet.streamInfoMap.size() > 1) {
- bool freeBufferIsAttached = false;
- for (size_t i = 0; i < streamSet.streamInfoMap.size(); i++) {
- firstOtherStreamId = streamSet.streamInfoMap[i].streamId;
- if (firstOtherStreamId != streamId) {
- size_t otherBufferCount =
- streamSet.handoutBufferCountMap.valueFor(firstOtherStreamId);
- size_t otherAttachedBufferCount =
- streamSet.attachedBufferCountMap.valueFor(firstOtherStreamId);
- if (otherAttachedBufferCount > otherBufferCount) {
- freeBufferIsAttached = true;
- break;
- }
- }
- firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
- }
- if (firstOtherStreamId == CAMERA3_STREAM_ID_INVALID) {
- return OK;
- }
-
- // This will drop the reference to one free buffer, which will effectively free one
- // buffer for the inactive streams.
- size_t totalAllocatedBufferCount = 0;
- for (size_t i = 0; i < streamSet.attachedBufferCountMap.size(); i++) {
- totalAllocatedBufferCount += streamSet.attachedBufferCountMap[i];
- }
- if (totalAllocatedBufferCount > streamSet.allocatedBufferWaterMark) {
- ALOGV("%s: free a buffer from stream %d", __FUNCTION__, firstOtherStreamId);
- if (freeBufferIsAttached) {
- ALOGV("Stream %d: Freeing buffer: detach", firstOtherStreamId);
- sp<Camera3OutputStream> stream =
- mStreamMap.valueFor(firstOtherStreamId).promote();
- if (stream == nullptr) {
- ALOGE("%s: unable to promote stream %d to detach buffer", __FUNCTION__,
- firstOtherStreamId);
- return INVALID_OPERATION;
- }
-
- // Detach and then drop the buffer.
- //
- // Need to unlock because the stream may also be calling
- // into the buffer manager in parallel to signal buffer
- // release, or acquire a new buffer.
- {
- mLock.unlock();
- sp<GraphicBuffer> buffer;
- stream->detachBuffer(&buffer, /*fenceFd*/ nullptr);
- mLock.lock();
- }
- size_t& otherAttachedBufferCount =
- streamSet.attachedBufferCountMap.editValueFor(firstOtherStreamId);
- otherAttachedBufferCount--;
- }
- }
+ res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetId);
+ if (res != OK) {
+ return res;
+ }
+ // Since we just allocated one new buffer above, try free one more buffer from other streams
+ // to prevent total buffer count from growing
+ res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetId);
+ if (res != OK) {
+ return res;
}
} else {
// TODO: implement this.
@@ -292,11 +326,18 @@
return OK;
}
-status_t Camera3BufferManager::onBufferReleased(int streamId, int streamSetId) {
+status_t Camera3BufferManager::onBufferReleased(
+ int streamId, int streamSetId, bool* shouldFreeBuffer) {
ATRACE_CALL();
- Mutex::Autolock l(mLock);
+ if (shouldFreeBuffer == nullptr) {
+ ALOGE("%s: shouldFreeBuffer is null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock l(mLock);
ALOGV("Stream %d set %d: Buffer released", streamId, streamSetId);
+ *shouldFreeBuffer = false;
if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
ALOGV("%s: signaling buffer release for an already unregistered stream "
@@ -311,6 +352,36 @@
bufferCount--;
ALOGV("%s: Stream %d set %d: Buffer count now %zu", __FUNCTION__, streamId, streamSetId,
bufferCount);
+
+ size_t totalAllocatedBufferCount = 0;
+ size_t totalHandOutBufferCount = 0;
+ for (size_t i = 0; i < streamSet.attachedBufferCountMap.size(); i++) {
+ totalAllocatedBufferCount += streamSet.attachedBufferCountMap[i];
+ totalHandOutBufferCount += streamSet.handoutBufferCountMap[i];
+ }
+
+ size_t newWaterMark = totalHandOutBufferCount + BUFFER_WATERMARK_DEC_THRESHOLD;
+ if (totalAllocatedBufferCount > newWaterMark &&
+ streamSet.allocatedBufferWaterMark > newWaterMark) {
+ // BufferManager got more than enough buffers, so decrease watermark
+ // to trigger more buffers free operation.
+ streamSet.allocatedBufferWaterMark = newWaterMark;
+ ALOGV("%s: Stream %d set %d: watermark--; now %zu",
+ __FUNCTION__, streamId, streamSetId, streamSet.allocatedBufferWaterMark);
+ }
+
+ size_t attachedBufferCount = streamSet.attachedBufferCountMap.valueFor(streamId);
+ if (attachedBufferCount <= bufferCount) {
+ ALOGV("%s: stream %d has no buffer available to free.", __FUNCTION__, streamId);
+ }
+
+ bool freeBufferIsAttached = (attachedBufferCount > bufferCount);
+ if (freeBufferIsAttached &&
+ totalAllocatedBufferCount > streamSet.allocatedBufferWaterMark &&
+ attachedBufferCount > bufferCount + BUFFER_FREE_THRESHOLD) {
+ ALOGV("%s: free a buffer from stream %d", __FUNCTION__, streamId);
+ *shouldFreeBuffer = true;
+ }
} else {
// TODO: implement gralloc V1 support
return BAD_VALUE;
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index 549bd99..025062e 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -137,14 +137,17 @@
* buffer has been reused. The manager will call detachBuffer on the stream
* if it needs the released buffer otherwise.
*
+ * When shouldFreeBuffer is set to true, caller must detach and free one buffer from the
+ * buffer queue, and then call notifyBufferRemoved to update the manager.
+ *
* Return values:
*
* OK: Buffer release was processed succesfully
* BAD_VALUE: stream ID or streamSetId are invalid, or stream ID and stream set ID
* combination doesn't match what was registered, or this stream wasn't registered
- * to this buffer manager before.
+ * to this buffer manager before, or shouldFreeBuffer is null/
*/
- status_t onBufferReleased(int streamId, int streamSetId);
+ status_t onBufferReleased(int streamId, int streamSetId, /*out*/bool* shouldFreeBuffer);
/**
* This method notifies the manager that certain buffers has been removed from the
@@ -165,11 +168,29 @@
status_t onBuffersRemoved(int streamId, int streamSetId, size_t count);
/**
+ * This method notifiers the manager that a buffer is freed from the buffer queue, usually
+ * because onBufferReleased signals the caller to free a buffer via the shouldFreeBuffer flag.
+ */
+ void notifyBufferRemoved(int streamId, int streamSetId);
+
+ /**
* Dump the buffer manager statistics.
*/
void dump(int fd, const Vector<String16> &args) const;
private:
+ // allocatedBufferWaterMark will be decreased when:
+ // numAllocatedBuffersThisSet > numHandoutBuffersThisSet + BUFFER_WATERMARK_DEC_THRESHOLD
+ // This allows the watermark go back down after a burst of buffer requests
+ static const int BUFFER_WATERMARK_DEC_THRESHOLD = 3;
+
+ // onBufferReleased will set shouldFreeBuffer to true when:
+ // numAllocatedBuffersThisSet > allocatedBufferWaterMark AND
+ // numAllocatedBuffersThisStream > numHandoutBuffersThisStream + BUFFER_FREE_THRESHOLD
+ // So after a burst of buffer requests and back to steady state, the buffer queue should have
+ // (BUFFER_FREE_THRESHOLD + steady state handout buffer count) buffers.
+ static const int BUFFER_FREE_THRESHOLD = 3;
+
/**
* Lock to synchronize the access to the methods of this class.
*/
@@ -279,6 +300,11 @@
*/
bool checkIfStreamRegisteredLocked(int streamId, int streamSetId) const;
+ /**
+ * Check if other streams in the stream set has extra buffer available to be freed, and
+ * free one if so.
+ */
+ status_t checkAndFreeBufferOnOtherStreamsLocked(int streamId, int streamSetId);
};
} // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 56174fa..ec0f508 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -691,13 +691,24 @@
}
ALOGV("Stream %d: Buffer released", stream->getId());
+ bool shouldFreeBuffer = false;
status_t res = stream->mBufferManager->onBufferReleased(
- stream->getId(), stream->getStreamSetId());
+ stream->getId(), stream->getStreamSetId(), &shouldFreeBuffer);
if (res != OK) {
ALOGE("%s: signaling buffer release to buffer manager failed: %s (%d).", __FUNCTION__,
strerror(-res), res);
stream->mState = STATE_ERROR;
}
+
+ if (shouldFreeBuffer) {
+ sp<GraphicBuffer> buffer;
+ // Detach and free a buffer (when buffer goes out of scope)
+ stream->detachBufferLocked(&buffer, /*fenceFd*/ nullptr);
+ if (buffer.get() != nullptr) {
+ stream->mBufferManager->notifyBufferRemoved(
+ stream->getId(), stream->getStreamSetId());
+ }
+ }
}
void Camera3OutputStream::onBuffersRemovedLocked(
@@ -712,7 +723,10 @@
status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) {
Mutex::Autolock l(mLock);
+ return detachBufferLocked(buffer, fenceFd);
+}
+status_t Camera3OutputStream::detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd) {
ALOGV("Stream %d: detachBuffer", getId());
if (buffer == nullptr) {
return BAD_VALUE;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 86676e4..98ffb73 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -263,7 +263,11 @@
virtual status_t getEndpointUsage(uint32_t *usage) const;
+ /**
+ * Private methods
+ */
void onBuffersRemovedLocked(const std::vector<sp<GraphicBuffer>>&);
+ status_t detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd);
}; // class Camera3OutputStream
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 6b59e81..494b18e 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -76,7 +76,7 @@
}
mSampleRate = configurationInput.getSampleRate();
- if (mSampleRate == AAUDIO_FORMAT_UNSPECIFIED) {
+ if (mSampleRate == AAUDIO_UNSPECIFIED) {
mSampleRate = mServiceEndpoint->getSampleRate();
} else if (mSampleRate != mServiceEndpoint->getSampleRate()) {
ALOGE("AAudioServiceStreamShared::open(), mAudioFormat = %d, need %d",
@@ -85,7 +85,7 @@
}
mSamplesPerFrame = configurationInput.getSamplesPerFrame();
- if (mSamplesPerFrame == AAUDIO_FORMAT_UNSPECIFIED) {
+ if (mSamplesPerFrame == AAUDIO_UNSPECIFIED) {
mSamplesPerFrame = mServiceEndpoint->getSamplesPerFrame();
} else if (mSamplesPerFrame != mServiceEndpoint->getSamplesPerFrame()) {
ALOGE("AAudioServiceStreamShared::open(), mSamplesPerFrame = %d, need %d",
diff --git a/services/radio/RadioService.cpp b/services/radio/RadioService.cpp
index f7a73c3..beb7c09 100644
--- a/services/radio/RadioService.cpp
+++ b/services/radio/RadioService.cpp
@@ -34,6 +34,7 @@
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
+#include <binder/PermissionCache.h>
#include <hardware/radio.h>
#include <media/AudioSystem.h>
#include "RadioService.h"
@@ -43,6 +44,8 @@
static const char kRadioTunerAudioDeviceName[] = "Radio tuner source";
+static const String16 RADIO_PERMISSION("android.permission.ACCESS_FM_RADIO");
+
RadioService::RadioService()
: BnRadioService(), mNextUniqueId(1)
{
@@ -84,6 +87,9 @@
status_t RadioService::listModules(struct radio_properties *properties,
uint32_t *numModules)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
ALOGV("listModules");
AutoMutex lock(mServiceLock);
@@ -104,6 +110,9 @@
bool withAudio,
sp<IRadio>& radio)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
ALOGV("%s %d config %p withAudio %d", __FUNCTION__, handle, config, withAudio);
AutoMutex lock(mServiceLock);
@@ -717,6 +726,9 @@
status_t RadioService::ModuleClient::setConfiguration(const struct radio_band_config *config)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
status_t status = NO_ERROR;
ALOGV("%s locked", __FUNCTION__);
@@ -738,6 +750,9 @@
status_t RadioService::ModuleClient::getConfiguration(struct radio_band_config *config)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
status_t status = NO_ERROR;
ALOGV("%s locked", __FUNCTION__);
@@ -756,6 +771,9 @@
status_t RadioService::ModuleClient::setMute(bool mute)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
sp<Module> module;
{
Mutex::Autolock _l(mLock);
@@ -774,6 +792,9 @@
status_t RadioService::ModuleClient::getMute(bool *mute)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
sp<Module> module;
{
Mutex::Autolock _l(mLock);
@@ -788,6 +809,9 @@
status_t RadioService::ModuleClient::scan(radio_direction_t direction, bool skipSubChannel)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
ALOGV("%s locked", __FUNCTION__);
status_t status;
@@ -801,6 +825,9 @@
status_t RadioService::ModuleClient::step(radio_direction_t direction, bool skipSubChannel)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
ALOGV("%s locked", __FUNCTION__);
status_t status;
@@ -814,6 +841,9 @@
status_t RadioService::ModuleClient::tune(uint32_t channel, uint32_t subChannel)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
ALOGV("%s locked", __FUNCTION__);
status_t status;
@@ -827,6 +857,9 @@
status_t RadioService::ModuleClient::cancel()
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
ALOGV("%s locked", __FUNCTION__);
status_t status;
@@ -840,6 +873,9 @@
status_t RadioService::ModuleClient::getProgramInformation(struct radio_program_info *info)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
AutoMutex lock(mLock);
ALOGV("%s locked", __FUNCTION__);
status_t status;
@@ -854,6 +890,9 @@
status_t RadioService::ModuleClient::hasControl(bool *hasControl)
{
+ if (!PermissionCache::checkCallingPermission(RADIO_PERMISSION)) {
+ return PERMISSION_DENIED;
+ }
Mutex::Autolock lock(mLock);
ALOGV("%s locked", __FUNCTION__);
*hasControl = mTuner != 0;