Merge "Work around bug in offload driver" into mnc-dev
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 84e0d1c..3a9fb4c 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -71,13 +71,14 @@
// deadlock if we call any method of ICamera here.
}
-sp<Camera> Camera::connect(int cameraId, const String16& opPackageName, int clientUid)
+sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
+ int clientUid)
{
- return CameraBaseT::connect(cameraId, opPackageName, clientUid);
+ return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}
status_t Camera::connectLegacy(int cameraId, int halVersion,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
sp<Camera>& camera)
{
@@ -88,7 +89,7 @@
const sp<ICameraService>& cs = CameraBaseT::getCameraService();
if (cs != 0) {
- status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName,
+ status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
clientUid, /*out*/c->mCamera);
}
if (status == OK && c->mCamera != 0) {
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 0dc0276..5d50aa8 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -91,7 +91,7 @@
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid)
{
ALOGV("%s: connect", __FUNCTION__);
@@ -102,7 +102,7 @@
if (cs != 0) {
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
- status = (cs.get()->*fnConnectService)(cl, cameraId, opPackageName, clientUid,
+ status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
/*out*/ c->mCamera);
}
if (status == OK && c->mCamera != 0) {
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 192e40d..51a775b 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -164,7 +164,7 @@
// connect to camera service (android.hardware.Camera)
virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
- const String16& opPackageName, int clientUid,
+ const String16 &clientPackageName, int clientUid,
/*out*/
sp<ICamera>& device)
{
@@ -172,7 +172,7 @@
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(cameraClient));
data.writeInt32(cameraId);
- data.writeString16(opPackageName);
+ data.writeString16(clientPackageName);
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT, data, &reply);
@@ -187,7 +187,7 @@
// connect to camera service (android.hardware.Camera)
virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
int halVersion,
- const String16& opPackageName, int clientUid,
+ const String16 &clientPackageName, int clientUid,
/*out*/sp<ICamera>& device)
{
Parcel data, reply;
@@ -195,7 +195,7 @@
data.writeStrongBinder(IInterface::asBinder(cameraClient));
data.writeInt32(cameraId);
data.writeInt32(halVersion);
- data.writeString16(opPackageName);
+ data.writeString16(clientPackageName);
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
@@ -225,7 +225,7 @@
virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device)
@@ -234,7 +234,7 @@
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(cameraCb));
data.writeInt32(cameraId);
- data.writeString16(opPackageName);
+ data.writeString16(clientPackageName);
data.writeInt32(clientUid);
remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
@@ -374,11 +374,11 @@
sp<ICameraClient> cameraClient =
interface_cast<ICameraClient>(data.readStrongBinder());
int32_t cameraId = data.readInt32();
- const String16 opPackageName = data.readString16();
+ const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
sp<ICamera> camera;
status_t status = connect(cameraClient, cameraId,
- opPackageName, clientUid, /*out*/camera);
+ clientName, clientUid, /*out*/camera);
reply->writeNoException();
reply->writeInt32(status);
if (camera != NULL) {
@@ -394,11 +394,11 @@
sp<ICameraDeviceCallbacks> cameraClient =
interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
int32_t cameraId = data.readInt32();
- const String16 opPackageName = data.readString16();
+ const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
sp<ICameraDeviceUser> camera;
status_t status = connectDevice(cameraClient, cameraId,
- opPackageName, clientUid, /*out*/camera);
+ clientName, clientUid, /*out*/camera);
reply->writeNoException();
reply->writeInt32(status);
if (camera != NULL) {
@@ -454,11 +454,11 @@
interface_cast<ICameraClient>(data.readStrongBinder());
int32_t cameraId = data.readInt32();
int32_t halVersion = data.readInt32();
- const String16 opPackageName = data.readString16();
+ const String16 clientName = data.readString16();
int32_t clientUid = data.readInt32();
sp<ICamera> camera;
status_t status = connectLegacy(cameraClient, cameraId, halVersion,
- opPackageName, clientUid, /*out*/camera);
+ clientName, clientUid, /*out*/camera);
reply->writeNoException();
reply->writeInt32(status);
if (camera != NULL) {
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 25d75f7..2b60842 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -71,11 +71,11 @@
// construct a camera client from an existing remote
static sp<Camera> create(const sp<ICamera>& camera);
static sp<Camera> connect(int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid);
static status_t connectLegacy(int cameraId, int halVersion,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid, sp<Camera>& camera);
virtual ~Camera();
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index 38bff3e..cad275e 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -109,7 +109,7 @@
*/
virtual status_t connect(const sp<ICameraClient>& cameraClient,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) = 0;
@@ -117,7 +117,7 @@
virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device) = 0;
@@ -141,7 +141,7 @@
*/
virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient,
int cameraId, int halVersion,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) = 0;
diff --git a/services/camera/libcameraservice/utils/RingBuffer.h b/include/media/RingBuffer.h
similarity index 100%
rename from services/camera/libcameraservice/utils/RingBuffer.h
rename to include/media/RingBuffer.h
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 56d2523..82c768d 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -164,6 +164,11 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
private:
+ // used by ResourceManagerClient
+ status_t reclaim();
+ friend struct ResourceManagerClient;
+
+private:
enum State {
UNINITIALIZED,
INITIALIZING,
@@ -262,6 +267,7 @@
};
State mState;
+ bool mReleasedByResourceManager;
sp<ALooper> mLooper;
sp<ALooper> mCodecLooper;
sp<CodecBase> mCodec;
@@ -321,7 +327,7 @@
static status_t PostAndAwaitResponse(
const sp<AMessage> &msg, sp<AMessage> *response);
- static void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
+ void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
status_t init(const AString &name, bool nameIsType, bool encoder);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 0843ad1..b9ae125 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -972,44 +972,6 @@
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
- if (mLegacyAdaptiveExperiment) {
- // preallocate buffers
- static_cast<Surface *>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(true);
-
- ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
- "output port",
- mComponentName.c_str(), bufferCount, bufferSize);
-
- // Dequeue buffers then cancel them all
- for (OMX_U32 i = 0; i < bufferCount; i++) {
- ANativeWindowBuffer *buf;
- err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
- if (err != 0) {
- ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
- break;
- }
-
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- BufferInfo info;
- info.mStatus = BufferInfo::OWNED_BY_US;
- info.mGraphicBuffer = graphicBuffer;
- mBuffers[kPortIndexOutput].push(info);
- }
-
- for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
- status_t error = cancelBufferToNativeWindow(info);
- if (err == OK) {
- err = error;
- }
- }
-
- mBuffers[kPortIndexOutput].clear();
- static_cast<Surface*>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(false);
- }
-
ALOGV("[%s] Allocating %u meta buffers on output port",
mComponentName.c_str(), bufferCount);
@@ -1038,6 +1000,45 @@
mComponentName.c_str(), info.mBufferID, mem->pointer());
}
+ if (mLegacyAdaptiveExperiment) {
+ // preallocate and preregister buffers
+ static_cast<Surface *>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(true);
+
+ ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
+ "output port",
+ mComponentName.c_str(), bufferCount, bufferSize);
+
+ // Dequeue buffers then cancel them all
+ for (OMX_U32 i = 0; i < bufferCount; i++) {
+ BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
+
+ ANativeWindowBuffer *buf;
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
+ if (err != 0) {
+ ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
+ break;
+ }
+
+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
+ mOMX->updateGraphicBufferInMeta(
+ mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
+ info->mStatus = BufferInfo::OWNED_BY_US;
+ info->mGraphicBuffer = graphicBuffer;
+ }
+
+ for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
+ BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
+ status_t error = cancelBufferToNativeWindow(info);
+ if (err == OK) {
+ err = error;
+ }
+ }
+
+ static_cast<Surface*>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(false);
+ }
+
mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
return err;
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 44f6542..4080391 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -62,7 +62,7 @@
}
static bool isResourceError(status_t err) {
- return (err == OMX_ErrorInsufficientResources);
+ return (err == NO_MEMORY);
}
static const int kMaxRetry = 2;
@@ -76,7 +76,7 @@
// codec is already gone.
return true;
}
- status_t err = codec->release();
+ status_t err = codec->reclaim();
if (err != OK) {
ALOGW("ResourceManagerClient failed to release codec with err %d", err);
}
@@ -336,6 +336,7 @@
MediaCodec::MediaCodec(const sp<ALooper> &looper)
: mState(UNINITIALIZED),
+ mReleasedByResourceManager(false),
mLooper(looper),
mCodec(NULL),
mReplyID(0),
@@ -377,10 +378,15 @@
return err;
}
-// static
void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
+ int32_t finalErr = err;
+ if (mReleasedByResourceManager) {
+ // override the err code if MediaCodec has been released by ResourceManager.
+ finalErr = DEAD_OBJECT;
+ }
+
sp<AMessage> response = new AMessage;
- response->setInt32("err", err);
+ response->setInt32("err", finalErr);
response->postReply(replyID);
}
@@ -654,6 +660,14 @@
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::reclaim() {
+ sp<AMessage> msg = new AMessage(kWhatRelease, this);
+ msg->setInt32("reclaimed", 1);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
status_t MediaCodec::release() {
sp<AMessage> msg = new AMessage(kWhatRelease, this);
@@ -920,6 +934,10 @@
sp<ABuffer> *buffer, sp<AMessage> *format) {
// use mutex instead of a context switch
+ if (mReleasedByResourceManager) {
+ return DEAD_OBJECT;
+ }
+
buffer->clear();
format->clear();
if (!isExecuting()) {
@@ -1009,20 +1027,19 @@
}
bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
- sp<AMessage> response = new AMessage;
-
if (!isExecuting() || (mFlags & kFlagIsAsync)
|| (newRequest && (mFlags & kFlagDequeueOutputPending))) {
- response->setInt32("err", INVALID_OPERATION);
+ PostReplyWithError(replyID, INVALID_OPERATION);
} else if (mFlags & kFlagStickyError) {
- response->setInt32("err", getStickyError());
+ PostReplyWithError(replyID, getStickyError());
} else if (mFlags & kFlagOutputBuffersChanged) {
- response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
+ PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
mFlags &= ~kFlagOutputBuffersChanged;
} else if (mFlags & kFlagOutputFormatChanged) {
- response->setInt32("err", INFO_FORMAT_CHANGED);
+ PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
mFlags &= ~kFlagOutputFormatChanged;
} else {
+ sp<AMessage> response = new AMessage;
ssize_t index = dequeuePortBuffer(kPortIndexOutput);
if (index < 0) {
@@ -1057,10 +1074,9 @@
}
response->setInt32("flags", flags);
+ response->postReply(replyID);
}
- response->postReply(replyID);
-
return true;
}
@@ -1818,6 +1834,20 @@
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
+ // already stopped/released
+ if (mState == UNINITIALIZED && mReleasedByResourceManager) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", OK);
+ response->postReply(replyID);
+ break;
+ }
+
+ int32_t reclaimed = 0;
+ msg->findInt32("reclaimed", &reclaimed);
+ if (reclaimed) {
+ mReleasedByResourceManager = true;
+ }
+
if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
&& mState != INITIALIZED
&& mState != CONFIGURED && !isExecuting()) {
@@ -1831,6 +1861,8 @@
// and it should be in this case, no harm to allow a release()
// if we're already uninitialized.
sp<AMessage> response = new AMessage;
+ // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
+ // the previous stop/release completes and then reply with OK.
status_t err = mState == targetState ? OK : INVALID_OPERATION;
response->setInt32("err", err);
if (err == OK && targetState == UNINITIALIZED) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 5a0deec..4851528 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -1082,6 +1082,16 @@
mSeqNumber, firstSeqNumberInPlaylist,
firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1);
+ if (mTSParser != NULL) {
+ mTSParser->signalEOS(ERROR_END_OF_STREAM);
+ // Use an empty buffer; we don't have any new data, just want to extract
+ // potential new access units after flush. Reset mSeqNumber to
+ // lastSeqNumberInPlaylist such that we set the correct access unit
+ // properties in extractAndQueueAccessUnitsFromTs.
+ sp<ABuffer> buffer = new ABuffer(0);
+ mSeqNumber = lastSeqNumberInPlaylist;
+ extractAndQueueAccessUnitsFromTs(buffer);
+ }
notifyError(ERROR_END_OF_STREAM);
} else {
// It's possible that we were never able to download the playlist.
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 0d071b2..e8b2219 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -746,6 +746,7 @@
}
mPayloadStarted = false;
+ mEOSReached = false;
mBuffer->setRange(0, 0);
bool clearFormat = false;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 7b5b46a..baf3b15 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -56,6 +56,8 @@
if (clearFormat) {
mFormat.clear();
}
+
+ mEOSReached = false;
}
// Parse AC3 header assuming the current ptr is start position of syncframe,
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 485e320..93b1642 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -757,8 +757,12 @@
// assigned to HALs which do not have master volume support will apply
// master volume during the mix operation. Threads with HALs which do
// support master volume will simply ignore the setting.
- for (size_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
+ continue;
+ }
mPlaybackThreads.valueAt(i)->setMasterVolume(value);
+ }
return NO_ERROR;
}
@@ -875,8 +879,12 @@
// assigned to HALs which do not have master mute support will apply master
// mute during the mix operation. Threads with HALs which do support master
// mute will simply ignore the setting.
- for (size_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
+ continue;
+ }
mPlaybackThreads.valueAt(i)->setMasterMute(muted);
+ }
return NO_ERROR;
}
@@ -1894,11 +1902,10 @@
if (thread->type() == ThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
DuplicatingThread *dupThread =
(DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
dupThread->removeOutputTrack((MixerThread *)thread.get());
-
}
}
}
@@ -1927,7 +1934,7 @@
// The thread entity (active unit of execution) is no longer running here,
// but the ThreadBase container still exists.
- if (thread->type() != ThreadBase::DUPLICATING) {
+ if (!thread->isDuplicating()) {
closeOutputFinish(thread);
}
@@ -2375,6 +2382,9 @@
{
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ if(thread->isDuplicating()) {
+ continue;
+ }
AudioStreamOut *output = thread->getOutput();
if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
return thread;
@@ -2689,7 +2699,7 @@
// Check whether the destination thread has a channel count of FCC_2, which is
// currently required for (most) effects. Prevent moving the effect chain here rather
// than disabling the addEffect_l() call in dstThread below.
- if ((dstThread->type() == ThreadBase::MIXER || dstThread->type() == ThreadBase::DUPLICATING) &&
+ if ((dstThread->type() == ThreadBase::MIXER || dstThread->isDuplicating()) &&
dstThread->mChannelCount != FCC_2) {
ALOGW("moveEffectChain_l() effect chain failed because"
" destination thread %p channel count(%u) != %u",
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 193fd64..959c140 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -66,9 +66,9 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
#endif
-// Set kUseNewMixer to true to use the new mixer engine. Otherwise the
-// original code will be used. This is false for now.
-static const bool kUseNewMixer = false;
+// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
+// original code will be used for stereo sinks, the new mixer for multichannel.
+static const bool kUseNewMixer = true;
// Set kUseFloat to true to allow floating input into the mixer engine.
// If kUseNewMixer is false, this is ignored or may be overridden internally
@@ -775,7 +775,8 @@
{
if (useFloat) {
for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
- if (mVolumeInc[i] != 0 && fabs(mVolume[i] - mPrevVolume[i]) <= fabs(mVolumeInc[i])) {
+ if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
+ (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
volumeInc[i] = 0;
prevVolume[i] = volume[i] << 16;
mVolumeInc[i] = 0.;
diff --git a/services/audioflinger/BufferProviders.cpp b/services/audioflinger/BufferProviders.cpp
index 77bf4ac..8a580e8 100644
--- a/services/audioflinger/BufferProviders.cpp
+++ b/services/audioflinger/BufferProviders.cpp
@@ -292,46 +292,8 @@
ALOGV("RemixBufferProvider(%p)(%#x, %#x, %#x) %zu %zu",
this, format, inputChannelMask, outputChannelMask,
mInputChannels, mOutputChannels);
-
- const audio_channel_representation_t inputRepresentation =
- audio_channel_mask_get_representation(inputChannelMask);
- const audio_channel_representation_t outputRepresentation =
- audio_channel_mask_get_representation(outputChannelMask);
- const uint32_t inputBits = audio_channel_mask_get_bits(inputChannelMask);
- const uint32_t outputBits = audio_channel_mask_get_bits(outputChannelMask);
-
- switch (inputRepresentation) {
- case AUDIO_CHANNEL_REPRESENTATION_POSITION:
- switch (outputRepresentation) {
- case AUDIO_CHANNEL_REPRESENTATION_POSITION:
- memcpy_by_index_array_initialization(mIdxAry, ARRAY_SIZE(mIdxAry),
- outputBits, inputBits);
- return;
- case AUDIO_CHANNEL_REPRESENTATION_INDEX:
- // TODO: output channel index mask not currently allowed
- // fall through
- default:
- break;
- }
- break;
- case AUDIO_CHANNEL_REPRESENTATION_INDEX:
- switch (outputRepresentation) {
- case AUDIO_CHANNEL_REPRESENTATION_POSITION:
- memcpy_by_index_array_initialization_src_index(mIdxAry, ARRAY_SIZE(mIdxAry),
- outputBits, inputBits);
- return;
- case AUDIO_CHANNEL_REPRESENTATION_INDEX:
- // TODO: output channel index mask not currently allowed
- // fall through
- default:
- break;
- }
- break;
- default:
- break;
- }
- LOG_ALWAYS_FATAL("invalid channel mask conversion from %#x to %#x",
- inputChannelMask, outputChannelMask);
+ (void) memcpy_by_index_array_initialization_from_channel_mask(
+ mIdxAry, ARRAY_SIZE(mIdxAry), outputChannelMask, inputChannelMask);
}
void RemixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e02c79f..2722d32 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5225,10 +5225,13 @@
mOutputTracks[i]->destroy();
mOutputTracks.removeAt(i);
updateWaitTime_l();
+ if (thread->getOutput() == mOutput) {
+ mOutput = NULL;
+ }
return;
}
}
- ALOGV("removeOutputTrack(): unkonwn thread: %p", thread);
+ ALOGV("removeOutputTrack(): unknown thread: %p", thread);
}
// caller must hold mLock
@@ -6705,9 +6708,7 @@
(mInput->stream->common.get_sample_rate(&mInput->stream->common)
<= (AUDIO_RESAMPLER_DOWN_RATIO_MAX * samplingRate)) &&
audio_channel_count_from_in_mask(
- mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_2 &&
- (channelMask == AUDIO_CHANNEL_IN_MONO ||
- channelMask == AUDIO_CHANNEL_IN_STEREO)) {
+ mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_8) {
status = NO_ERROR;
}
if (status == NO_ERROR) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0a5597f..37bacae 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -230,6 +230,8 @@
// static externally-visible
type_t type() const { return mType; }
+ bool isDuplicating() const { return (mType == DUPLICATING); }
+
audio_io_handle_t id() const { return mId;}
// dynamic externally-visible
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 64f883a..2e4d423 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -272,6 +272,12 @@
(audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sOutChannelsNameToEnumTable,
ARRAY_SIZE(sOutChannelsNameToEnumTable),
str);
+ if (channelMask == 0) { // if not found, check the channel index table
+ channelMask = (audio_channel_mask_t)
+ ConfigParsingUtils::stringToEnum(sIndexChannelsNameToEnumTable,
+ ARRAY_SIZE(sIndexChannelsNameToEnumTable),
+ str);
+ }
if (channelMask != 0) {
mChannelMasks.add(channelMask);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 0c02d93..d1ee400 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -768,6 +768,9 @@
if (stream != AUDIO_STREAM_MUSIC) {
flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
}
+ if (stream == AUDIO_STREAM_TTS) {
+ flags = AUDIO_OUTPUT_FLAG_TTS;
+ }
sp<IOProfile> profile;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 3f80faf..8de8930 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1057,24 +1057,19 @@
status_t CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) {
- const status_t result = checkCameraAccess(opPackageName);
- if (result != NO_ERROR) {
- return result;
- }
-
status_t ret = NO_ERROR;
String8 id = String8::format("%d", cameraId);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
- opPackageName, clientUid, API_1, false, false, /*out*/client);
+ clientPackageName, clientUid, API_1, false, false, /*out*/client);
if(ret != NO_ERROR) {
- logRejected(id, getCallingPid(), String8(opPackageName),
+ logRejected(id, getCallingPid(), String8(clientPackageName),
String8::format("%s (%d)", strerror(-ret), ret));
return ret;
}
@@ -1086,16 +1081,11 @@
status_t CameraService::connectLegacy(
const sp<ICameraClient>& cameraClient,
int cameraId, int halVersion,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) {
- const status_t result = checkCameraAccess(opPackageName);
- if (result != NO_ERROR) {
- return result;
- }
-
String8 id = String8::format("%d", cameraId);
int apiVersion = mModule->getModuleApiVersion();
if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
@@ -1108,18 +1098,18 @@
*/
ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
__FUNCTION__, apiVersion);
- logRejected(id, getCallingPid(), String8(opPackageName),
+ logRejected(id, getCallingPid(), String8(clientPackageName),
String8("HAL module version doesn't support legacy HAL connections"));
return INVALID_OPERATION;
}
status_t ret = NO_ERROR;
sp<Client> client = nullptr;
- ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, opPackageName,
+ ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
clientUid, API_1, true, false, /*out*/client);
if(ret != NO_ERROR) {
- logRejected(id, getCallingPid(), String8(opPackageName),
+ logRejected(id, getCallingPid(), String8(clientPackageName),
String8::format("%s (%d)", strerror(-ret), ret));
return ret;
}
@@ -1131,25 +1121,20 @@
status_t CameraService::connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device) {
- const status_t result = checkCameraAccess(opPackageName);
- if (result != NO_ERROR) {
- return result;
- }
-
status_t ret = NO_ERROR;
String8 id = String8::format("%d", cameraId);
sp<CameraDeviceClient> client = nullptr;
ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
- CAMERA_HAL_API_VERSION_UNSPECIFIED, opPackageName, clientUid, API_2, false, false,
+ CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
/*out*/client);
if(ret != NO_ERROR) {
- logRejected(id, getCallingPid(), String8(opPackageName),
+ logRejected(id, getCallingPid(), String8(clientPackageName),
String8::format("%s (%d)", strerror(-ret), ret));
return ret;
}
@@ -1544,24 +1529,24 @@
}
void CameraService::logDisconnected(const char* cameraId, int clientPid,
- const char* opPackageName) {
+ const char* clientPackage) {
// Log the clients evicted
logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
- opPackageName, clientPid));
+ clientPackage, clientPid));
}
void CameraService::logConnected(const char* cameraId, int clientPid,
- const char* opPackageName) {
+ const char* clientPackage) {
// Log the clients evicted
logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
- opPackageName, clientPid));
+ clientPackage, clientPid));
}
void CameraService::logRejected(const char* cameraId, int clientPid,
- const char* opPackageName, const char* reason) {
+ const char* clientPackage, const char* reason) {
// Log the client rejected
logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
- cameraId, opPackageName, clientPid, reason));
+ cameraId, clientPackage, clientPid, reason));
}
void CameraService::logUserSwitch(int oldUserId, int newUserId) {
@@ -1598,6 +1583,21 @@
// Permission checks
switch (code) {
+ case BnCameraService::CONNECT:
+ case BnCameraService::CONNECT_DEVICE:
+ case BnCameraService::CONNECT_LEGACY: {
+ if (pid != selfPid) {
+ // we're called from a different process, do the real check
+ if (!checkCallingPermission(
+ String16("android.permission.CAMERA"))) {
+ const int uid = getCallingUid();
+ ALOGE("Permission Denial: "
+ "can't use the camera pid=%d, uid=%d", pid, uid);
+ return PERMISSION_DENIED;
+ }
+ }
+ break;
+ }
case BnCameraService::NOTIFY_SYSTEM_EVENT: {
if (pid != selfPid) {
// Ensure we're being called by system_server, or similar process with
@@ -1617,38 +1617,6 @@
return BnCameraService::onTransact(code, data, reply, flags);
}
-status_t CameraService::checkCameraAccess(const String16& opPackageName) {
- const int pid = getCallingPid();
-
- if (pid == getpid()) {
- return NO_ERROR;
- }
-
- const int uid = getCallingUid();
-
- if (!checkCallingPermission(String16("android.permission.CAMERA"))) {
- ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", pid, uid);
- return PERMISSION_DENIED;
- }
-
- AppOpsManager appOps;
- const int32_t result = appOps.noteOp(AppOpsManager::OP_CAMERA, uid, opPackageName);
-
- switch (result) {
- case AppOpsManager::MODE_ERRORED: {
- ALOGE("App op OP_CAMERA errored: can't use the camera pid=%d, uid=%d", pid, uid);
- return PERMISSION_DENIED;
- } break;
-
- case AppOpsManager::MODE_IGNORED: {
- ALOGE("App op OP_CAMERA ignored: can't use the camera pid=%d, uid=%d", pid, uid);
- return INVALID_OPERATION;
- } break;
- }
-
- return NO_ERROR;
-}
-
// We share the media players for shutter and recording sound for all clients.
// A reference count is kept to determine when we will actually release the
// media players.
@@ -1701,13 +1669,13 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
- const String16& opPackageName,
+ const String16& clientPackageName,
int cameraId, int cameraFacing,
int clientPid, uid_t clientUid,
int servicePid) :
CameraService::BasicClient(cameraService,
IInterface::asBinder(cameraClient),
- opPackageName,
+ clientPackageName,
cameraId, cameraFacing,
clientPid, clientUid,
servicePid)
@@ -1734,11 +1702,11 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& opPackageName,
+ const String16& clientPackageName,
int cameraId, int cameraFacing,
int clientPid, uid_t clientUid,
int servicePid):
- mOpPackageName(opPackageName), mDisconnected(false)
+ mClientPackageName(clientPackageName), mDisconnected(false)
{
mCameraService = cameraService;
mRemoteBinder = remoteCallback;
@@ -1766,7 +1734,7 @@
mCameraService->removeByClient(this);
mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
- String8(mOpPackageName));
+ String8(mClientPackageName));
sp<IBinder> remote = getRemote();
if (remote != nullptr) {
@@ -1781,7 +1749,7 @@
}
String16 CameraService::BasicClient::getPackageName() const {
- return mOpPackageName;
+ return mClientPackageName;
}
@@ -1801,20 +1769,26 @@
{
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
- __FUNCTION__, String8(mOpPackageName).string(), mClientUid);
+ __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
}
mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
- mOpPackageName, mOpsCallback);
+ mClientPackageName, mOpsCallback);
res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
- mClientUid, mOpPackageName);
+ mClientUid, mClientPackageName);
- if (res != AppOpsManager::MODE_ALLOWED) {
+ if (res == AppOpsManager::MODE_ERRORED) {
ALOGI("Camera %d: Access for \"%s\" has been revoked",
- mCameraId, String8(mOpPackageName).string());
+ mCameraId, String8(mClientPackageName).string());
return PERMISSION_DENIED;
}
+ if (res == AppOpsManager::MODE_IGNORED) {
+ ALOGI("Camera %d: Access for \"%s\" has been restricted",
+ mCameraId, String8(mClientPackageName).string());
+ return INVALID_OPERATION;
+ }
+
mOpsActive = true;
// Transition device availability listeners from PRESENT -> NOT_AVAILABLE
@@ -1829,7 +1803,7 @@
if (mOpsActive) {
// Notify app ops that the camera is available again
mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mOpPackageName);
+ mClientPackageName);
mOpsActive = false;
auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
@@ -1854,7 +1828,7 @@
void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
String8 name(packageName);
- String8 myName(mOpPackageName);
+ String8 myName(mClientPackageName);
if (op != AppOpsManager::OP_CAMERA) {
ALOGW("Unexpected app ops notification received: %d", op);
@@ -1863,7 +1837,7 @@
int32_t res;
res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
- mClientUid, mOpPackageName);
+ mClientUid, mClientPackageName);
ALOGV("checkOp returns: %d, %s ", res,
res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 502fcfa..8df746a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -38,9 +38,9 @@
#include "CameraFlashlight.h"
#include "common/CameraModule.h"
+#include "media/RingBuffer.h"
#include "utils/AutoConditionLock.h"
#include "utils/ClientManager.h"
-#include "utils/RingBuffer.h"
#include <set>
#include <string>
@@ -126,19 +126,19 @@
virtual status_t getCameraVendorTagDescriptor(/*out*/ sp<VendorTagDescriptor>& desc);
virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
- const String16& opPackageName, int clientUid,
+ const String16& clientPackageName, int clientUid,
/*out*/
sp<ICamera>& device);
virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
- int halVersion, const String16& opPackageName, int clientUid,
+ int halVersion, const String16& clientPackageName, int clientUid,
/*out*/
sp<ICamera>& device);
virtual status_t connectDevice(
const sp<ICameraDeviceCallbacks>& cameraCb,
int cameraId,
- const String16& opPackageName,
+ const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICameraDeviceUser>& device);
@@ -223,7 +223,7 @@
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
- const String16& opPackageName,
+ const String16& clientPackageName,
int cameraId,
int cameraFacing,
int clientPid,
@@ -242,7 +242,7 @@
sp<CameraService> mCameraService; // immutable after constructor
int mCameraId; // immutable after constructor
int mCameraFacing; // immutable after constructor
- const String16 mOpPackageName;
+ const String16 mClientPackageName;
pid_t mClientPid;
uid_t mClientUid; // immutable after constructor
pid_t mServicePid; // immutable after constructor
@@ -309,7 +309,7 @@
// Interface used by CameraService
Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
- const String16& opPackageName,
+ const String16& clientPackageName,
int cameraId,
int cameraFacing,
int clientPid,
@@ -480,7 +480,7 @@
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
status_t connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion,
- const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel,
+ const String16& clientPackageName, int clientUid, apiLevel effectiveApiLevel,
bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
@@ -713,8 +713,6 @@
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client);
-
- status_t checkCameraAccess(const String16& opPackageName);
};
template<class Func>
@@ -763,11 +761,11 @@
template<class CALLBACK, class CLIENT>
status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int halVersion, const String16& opPackageName, int clientUid,
+ int halVersion, const String16& clientPackageName, int clientUid,
apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
status_t ret = NO_ERROR;
- String8 clientName8(opPackageName);
+ String8 clientName8(clientPackageName);
int clientPid = getCallingPid();
ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
@@ -838,7 +836,7 @@
int facing = -1;
int deviceVersion = getDeviceVersion(id, /*out*/&facing);
sp<BasicClient> tmp = nullptr;
- if((ret = makeClient(this, cameraCb, opPackageName, cameraId, facing, clientPid,
+ if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)) != NO_ERROR) {
return ret;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 9b2e143..ba0b264 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -118,7 +118,7 @@
ALOGI("Closed Camera %d. Client was: %s (PID %d, UID %u)",
TClientBase::mCameraId,
- String8(TClientBase::mOpPackageName).string(),
+ String8(TClientBase::mClientPackageName).string(),
mInitialClientPid, TClientBase::mClientUid);
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 3c093f9..e2b6695 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -126,8 +126,8 @@
}
}
}
- result.append(" Logs:\n");
- result.append(mServiceLog->toString());
+ result.append(" Events logs (most recent at top):\n");
+ result.append(mServiceLog->toString(" " /* linePrefix */));
write(fd, result.string(), result.size());
return OK;
diff --git a/services/mediaresourcemanager/ServiceLog.cpp b/services/mediaresourcemanager/ServiceLog.cpp
index be7b308..791e797 100644
--- a/services/mediaresourcemanager/ServiceLog.cpp
+++ b/services/mediaresourcemanager/ServiceLog.cpp
@@ -27,28 +27,37 @@
namespace android {
-ServiceLog::ServiceLog() : mMaxNum(kDefaultMaxNum) {}
-ServiceLog::ServiceLog(size_t maxNum) : mMaxNum(maxNum) {}
+ServiceLog::ServiceLog() : mMaxNum(kDefaultMaxNum), mLogs(mMaxNum) {}
+ServiceLog::ServiceLog(size_t maxNum) : mMaxNum(maxNum), mLogs(mMaxNum) {}
void ServiceLog::add(const String8 &log) {
Mutex::Autolock lock(mLock);
time_t now = time(0);
char buf[64];
strftime(buf, sizeof(buf), "%m-%d %T", localtime(&now));
- String8 formattedLog = String8::format("%s %s", buf, log.string());
- if (mLogs.add(formattedLog) == mMaxNum) {
- mLogs.removeAt(0);
- }
+ mLogs.add(String8::format("%s %s", buf, log.string()));
}
-String8 ServiceLog::toString() const {
+String8 ServiceLog::toString(const char *linePrefix) const {
Mutex::Autolock lock(mLock);
String8 result;
- for (size_t i = 0; i < mLogs.size(); ++i) {
- result.append(mLogs[i]);
- result.append("\n");
+ for (const auto& log : mLogs) {
+ addLine(log.string(), linePrefix, &result);
+ }
+ if (mLogs.size() == mMaxNum) {
+ addLine("...", linePrefix, &result);
+ } else if (mLogs.size() == 0) {
+ addLine("[no events yet]", linePrefix, &result);
}
return result;
}
+void ServiceLog::addLine(const char *log, const char *prefix, String8 *result) const {
+ if (prefix != NULL) {
+ result->append(prefix);
+ }
+ result->append(log);
+ result->append("\n");
+}
+
} // namespace android
diff --git a/services/mediaresourcemanager/ServiceLog.h b/services/mediaresourcemanager/ServiceLog.h
index 14814ff..a6f16eb 100644
--- a/services/mediaresourcemanager/ServiceLog.h
+++ b/services/mediaresourcemanager/ServiceLog.h
@@ -23,6 +23,8 @@
#include <utils/threads.h>
#include <utils/Vector.h>
+#include "media/RingBuffer.h"
+
namespace android {
class ServiceLog : public RefBase {
@@ -31,12 +33,14 @@
ServiceLog(size_t maxNum);
void add(const String8 &log);
- String8 toString() const;
+ String8 toString(const char *linePrefix = NULL) const;
private:
- int mMaxNum;
+ size_t mMaxNum;
mutable Mutex mLock;
- Vector<String8> mLogs;
+ RingBuffer<String8> mLogs;
+
+ void addLine(const char *log, const char *prefix, String8 *result) const;
};
// ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/test/ServiceLog_test.cpp b/services/mediaresourcemanager/test/ServiceLog_test.cpp
index 6ddcb87..9172499 100644
--- a/services/mediaresourcemanager/test/ServiceLog_test.cpp
+++ b/services/mediaresourcemanager/test/ServiceLog_test.cpp
@@ -34,35 +34,48 @@
};
TEST_F(ServiceLogTest, addThenToString) {
+ String8 logString;
+
mServiceLog->add(String8("log1"));
- EXPECT_TRUE(mServiceLog->toString().contains("log1"));
- ALOGV("toString:\n%s", mServiceLog->toString().string());
+ logString = mServiceLog->toString();
+ EXPECT_TRUE(logString.contains("log1"));
+ ALOGV("toString:\n%s", logString.string());
+
+ static const char kTestLogPrefix[] = "testlogprefix: ";
+ logString = mServiceLog->toString(kTestLogPrefix);
+ EXPECT_TRUE(logString.contains(kTestLogPrefix));
+ EXPECT_TRUE(logString.contains("log1"));
+ ALOGV("toString:\n%s", logString.string());
mServiceLog->add(String8("log2"));
- EXPECT_TRUE(mServiceLog->toString().contains("log1"));
- EXPECT_TRUE(mServiceLog->toString().contains("log2"));
- ALOGV("toString:\n%s", mServiceLog->toString().string());
+ logString = mServiceLog->toString();
+ EXPECT_TRUE(logString.contains("log1"));
+ EXPECT_TRUE(logString.contains("log2"));
+ ALOGV("toString:\n%s", logString.string());
mServiceLog->add(String8("log3"));
- EXPECT_TRUE(mServiceLog->toString().contains("log1"));
- EXPECT_TRUE(mServiceLog->toString().contains("log2"));
- EXPECT_TRUE(mServiceLog->toString().contains("log3"));
- ALOGV("toString:\n%s", mServiceLog->toString().string());
+ logString = mServiceLog->toString();
+ EXPECT_TRUE(logString.contains("log1"));
+ EXPECT_TRUE(logString.contains("log2"));
+ EXPECT_TRUE(logString.contains("log3"));
+ ALOGV("toString:\n%s", logString.string());
mServiceLog->add(String8("log4"));
- EXPECT_FALSE(mServiceLog->toString().contains("log1"));
- EXPECT_TRUE(mServiceLog->toString().contains("log2"));
- EXPECT_TRUE(mServiceLog->toString().contains("log3"));
- EXPECT_TRUE(mServiceLog->toString().contains("log4"));
- ALOGV("toString:\n%s", mServiceLog->toString().string());
+ logString = mServiceLog->toString();
+ EXPECT_FALSE(logString.contains("log1"));
+ EXPECT_TRUE(logString.contains("log2"));
+ EXPECT_TRUE(logString.contains("log3"));
+ EXPECT_TRUE(logString.contains("log4"));
+ ALOGV("toString:\n%s", logString.string());
mServiceLog->add(String8("log5"));
- EXPECT_FALSE(mServiceLog->toString().contains("log1"));
- EXPECT_FALSE(mServiceLog->toString().contains("log2"));
- EXPECT_TRUE(mServiceLog->toString().contains("log3"));
- EXPECT_TRUE(mServiceLog->toString().contains("log4"));
- EXPECT_TRUE(mServiceLog->toString().contains("log5"));
- ALOGV("toString:\n%s", mServiceLog->toString().string());
+ logString = mServiceLog->toString();
+ EXPECT_FALSE(logString.contains("log1"));
+ EXPECT_FALSE(logString.contains("log2"));
+ EXPECT_TRUE(logString.contains("log3"));
+ EXPECT_TRUE(logString.contains("log4"));
+ EXPECT_TRUE(logString.contains("log5"));
+ ALOGV("toString:\n%s", logString.string());
}
} // namespace android