diff options
21 files changed, 191 insertions, 60 deletions
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp index 0029aec..0d04760 100644 --- a/cmds/stagefright/muxer.cpp +++ b/cmds/stagefright/muxer.cpp @@ -142,8 +142,13 @@ static int muxing( CHECK_EQ(err, (status_t)OK); ssize_t newTrackIndex = muxer->addTrack(format); - CHECK_GE(newTrackIndex, 0); - trackIndexMap.add(i, newTrackIndex); + if (newTrackIndex < 0) { + fprintf(stderr, "%s track (%d) unsupported by muxer\n", + isAudio ? "audio" : "video", + i); + } else { + trackIndexMap.add(i, newTrackIndex); + } } int64_t muxerStartTimeUs = ALooper::GetNowUs(); @@ -162,7 +167,12 @@ static int muxing( ALOGV("saw input eos, err %d", err); sawInputEOS = true; break; + } else if (trackIndexMap.indexOfKey(trackIndex) < 0) { + // ALOGV("skipping input from unsupported track %zu", trackIndex); + extractor->advance(); + continue; } else { + // ALOGV("reading sample from track index %zu\n", trackIndex); err = extractor->readSampleData(newBuffer); CHECK_EQ(err, (status_t)OK); diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 0403e1a..c4c7b0e 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -178,6 +178,8 @@ public: int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, + int uid = -1, + pid_t pid = -1, const audio_attributes_t* pAttributes = NULL); /* Terminates the AudioRecord and unregisters it from AudioFlinger. @@ -214,6 +216,8 @@ public: int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, + int uid = -1, + pid_t pid = -1, const audio_attributes_t* pAttributes = NULL); /* Result of constructing the AudioRecord. This must be checked for successful initialization @@ -610,6 +614,8 @@ private: sp<DeathNotifier> mDeathNotifier; uint32_t mSequence; // incremented for each new IAudioRecord attempt + int mClientUid; + pid_t mClientPid; audio_attributes_t mAttributes; // For Device Selection API diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 046345c..3f7fd09 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -89,6 +89,7 @@ public: size_t *pFrameCount, track_flags_t *flags, pid_t tid, // -1 means unused, otherwise must be valid non-0 + int clientUid, int *sessionId, size_t *notificationFrames, sp<IMemory>& cblk, diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h index a349986..d1d634d 100644 --- a/include/media/stagefright/MediaSync.h +++ b/include/media/stagefright/MediaSync.h @@ -75,11 +75,11 @@ public: // Called when MediaSync is used to render video. It should be called // before createInputSurface(). - status_t configureSurface(const sp<IGraphicBufferProducer> &output); + status_t setSurface(const sp<IGraphicBufferProducer> &output); // Called when audio track is used as media clock source. It should be // called before updateQueuedAudioData(). - status_t configureAudioTrack(const sp<AudioTrack> &audioTrack); + status_t setAudioTrack(const sp<AudioTrack> &audioTrack); // Create a surface for client to render video frames. This is the surface // on which the client should render video frames. Those video frames will diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 73fd3cb..3868f13 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -85,6 +85,8 @@ AudioRecord::AudioRecord( int sessionId, transfer_type transferType, audio_input_flags_t flags, + int uid, + pid_t pid, const audio_attributes_t* pAttributes) : mStatus(NO_INIT), mOpPackageName(opPackageName), @@ -96,7 +98,7 @@ AudioRecord::AudioRecord( { mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags, - pAttributes); + uid, pid, pAttributes); } AudioRecord::~AudioRecord() @@ -140,12 +142,15 @@ status_t AudioRecord::set( int sessionId, transfer_type transferType, audio_input_flags_t flags, + int uid, + pid_t pid, const audio_attributes_t* pAttributes) { ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " - "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s", + "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s " + "uid %d, pid %d", inputSource, sampleRate, format, channelMask, frameCount, notificationFrames, - sessionId, transferType, flags, String8(mOpPackageName).string()); + sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid); switch (transferType) { case TRANSFER_DEFAULT: @@ -232,6 +237,19 @@ status_t AudioRecord::set( } ALOGV("set(): mSessionId %d", mSessionId); + int callingpid = IPCThreadState::self()->getCallingPid(); + int mypid = getpid(); + if (uid == -1 || (callingpid != mypid)) { + mClientUid = IPCThreadState::self()->getCallingUid(); + } else { + mClientUid = uid; + } + if (pid == -1 || (callingpid != mypid)) { + mClientPid = callingpid; + } else { + mClientPid = pid; + } + mFlags = flags; mCbf = cbf; @@ -536,6 +554,7 @@ status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) &temp, &trackFlags, tid, + mClientUid, &mSessionId, ¬ificationFrames, iMem, diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index d48532e..d722fe9 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -178,6 +178,7 @@ public: size_t *pFrameCount, track_flags_t *flags, pid_t tid, + int clientUid, int *sessionId, size_t *notificationFrames, sp<IMemory>& cblk, @@ -197,6 +198,7 @@ public: track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT; data.writeInt32(lFlags); data.writeInt32((int32_t) tid); + data.writeInt32((int32_t) clientUid); int lSessionId = AUDIO_SESSION_ALLOCATE; if (sessionId != NULL) { lSessionId = *sessionId; @@ -958,6 +960,7 @@ status_t BnAudioFlinger::onTransact( size_t frameCount = data.readInt64(); track_flags_t flags = (track_flags_t) data.readInt32(); pid_t tid = (pid_t) data.readInt32(); + int clientUid = data.readInt32(); int sessionId = data.readInt32(); size_t notificationFrames = data.readInt64(); sp<IMemory> cblk; @@ -965,7 +968,7 @@ status_t BnAudioFlinger::onTransact( status_t status; sp<IAudioRecord> record = openRecord(input, sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid, - &sessionId, ¬ificationFrames, cblk, buffers, &status); + clientUid, &sessionId, ¬ificationFrames, cblk, buffers, &status); LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR)); reply->writeInt64(frameCount); reply->writeInt32(flags); diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp index 9246a7c..2f440fe 100644 --- a/media/libmedia/ICrypto.cpp +++ b/media/libmedia/ICrypto.cpp @@ -142,7 +142,7 @@ struct BpCrypto : public BpInterface<ICrypto> { ssize_t result = reply.readInt32(); - if (result >= ERROR_DRM_VENDOR_MIN && result <= ERROR_DRM_VENDOR_MAX) { + if (isCryptoError(result)) { errorDetailMsg->setTo(reply.readCString()); } @@ -319,8 +319,7 @@ status_t BnCrypto::onTransact( reply->writeInt32(result); - if (result >= ERROR_DRM_VENDOR_MIN - && result <= ERROR_DRM_VENDOR_MAX) { + if (isCryptoError(result)) { reply->writeCString(errorDetailMsg.c_str()); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 9963353..4f64426 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -704,9 +704,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } if (mVideoDecoder != NULL) { - sp<MetaData> meta = getFileMeta(); - int32_t rate; - if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { + float rate = getFrameRate(); + if (rate > 0) { sp<AMessage> params = new AMessage(); params->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed); mVideoDecoder->setParameters(params); @@ -1265,10 +1264,8 @@ void NuPlayer::onStart() { return; } - sp<MetaData> meta = getFileMeta(); - int32_t rate; - if (meta != NULL - && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { + float rate = getFrameRate(); + if (rate > 0) { mRenderer->setVideoFrameRate(rate); } @@ -1426,9 +1423,8 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) { format->setInt32("protected", true); } - sp<MetaData> meta = getFileMeta(); - int32_t rate; - if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { + float rate = getFrameRate(); + if (rate > 0) { format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed); } } @@ -1702,6 +1698,28 @@ sp<MetaData> NuPlayer::getFileMeta() { return mSource->getFileFormatMeta(); } +float NuPlayer::getFrameRate() { + sp<MetaData> meta = mSource->getFormatMeta(false /* audio */); + if (meta == NULL) { + return 0; + } + int32_t rate; + if (!meta->findInt32(kKeyFrameRate, &rate)) { + // fall back to try file meta + sp<MetaData> fileMeta = getFileMeta(); + if (fileMeta == NULL) { + ALOGW("source has video meta but not file meta"); + return -1; + } + int32_t fileMetaRate; + if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) { + return -1; + } + return fileMetaRate; + } + return rate; +} + void NuPlayer::schedulePollDuration() { sp<AMessage> msg = new AMessage(kWhatPollDuration, this); msg->setInt32("generation", mPollDurationGeneration); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index fcf6841..6b7d71e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -80,6 +80,7 @@ struct NuPlayer : public AHandler { void getStats(int64_t *mNumFramesTotal, int64_t *mNumFramesDropped); sp<MetaData> getFileMeta(); + float getFrameRate(); protected: virtual ~NuPlayer(); diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index beb12ec..3bc22f2 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -94,6 +94,7 @@ public: void addChunkOffset(off64_t offset); int32_t getTrackId() const { return mTrackId; } status_t dump(int fd, const Vector<String16>& args) const; + static const char *getFourCCForMime(const char *mime); private: enum { @@ -426,6 +427,33 @@ status_t MPEG4Writer::Track::dump( return OK; } +// static +const char *MPEG4Writer::Track::getFourCCForMime(const char *mime) { + if (mime == NULL) { + return NULL; + } + if (!strncasecmp(mime, "audio/", 6)) { + if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { + return "samr"; + } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { + return "sawb"; + } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { + return "mp4a"; + } + } else if (!strncasecmp(mime, "video/", 6)) { + if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { + return "mp4v"; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { + return "s263"; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { + return "avc1"; + } + } else { + ALOGE("Track (%s) other than video or audio is not supported", mime); + } + return NULL; +} + status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { Mutex::Autolock l(mLock); if (mStarted) { @@ -441,14 +469,11 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { CHECK(source.get() != NULL); - // A track of type other than video or audio is not supported. const char *mime; source->getFormat()->findCString(kKeyMIMEType, &mime); bool isAudio = !strncasecmp(mime, "audio/", 6); - bool isVideo = !strncasecmp(mime, "video/", 6); - if (!isAudio && !isVideo) { - ALOGE("Track (%s) other than video or audio is not supported", - mime); + if (Track::getFourCCForMime(mime) == NULL) { + ALOGE("Unsupported mime '%s'", mime); return ERROR_UNSUPPORTED; } @@ -2730,17 +2755,13 @@ void MPEG4Writer::Track::writeVideoFourCCBox() { const char *mime; bool success = mMeta->findCString(kKeyMIMEType, &mime); CHECK(success); - if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { - mOwner->beginBox("mp4v"); - } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { - mOwner->beginBox("s263"); - } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { - mOwner->beginBox("avc1"); - } else { + const char *fourcc = getFourCCForMime(mime); + if (fourcc == NULL) { ALOGE("Unknown mime type '%s'.", mime); CHECK(!"should not be here, unknown mime type."); } + mOwner->beginBox(fourcc); // video format mOwner->writeInt32(0); // reserved mOwner->writeInt16(0); // reserved mOwner->writeInt16(1); // data ref index @@ -2784,14 +2805,8 @@ void MPEG4Writer::Track::writeAudioFourCCBox() { const char *mime; bool success = mMeta->findCString(kKeyMIMEType, &mime); CHECK(success); - const char *fourcc = NULL; - if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { - fourcc = "samr"; - } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { - fourcc = "sawb"; - } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { - fourcc = "mp4a"; - } else { + const char *fourcc = getFourCCForMime(mime); + if (fourcc == NULL) { ALOGE("Unknown mime type '%s'.", mime); CHECK(!"should not be here, unknown mime type."); } diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp index ad4b7a3..97264fb 100644 --- a/media/libstagefright/MediaSync.cpp +++ b/media/libstagefright/MediaSync.cpp @@ -79,17 +79,17 @@ MediaSync::~MediaSync() { } } -status_t MediaSync::configureSurface(const sp<IGraphicBufferProducer> &output) { +status_t MediaSync::setSurface(const sp<IGraphicBufferProducer> &output) { Mutex::Autolock lock(mMutex); // TODO: support suface change. if (mOutput != NULL) { - ALOGE("configureSurface: output surface has already been configured."); + ALOGE("setSurface: output surface has already been configured."); return INVALID_OPERATION; } if (output == NULL && mSyncSettings.mSource == AVSYNC_SOURCE_VSYNC) { - ALOGE("configureSurface: output surface is used as sync source and cannot be removed."); + ALOGE("setSurface: output surface is used as sync source and cannot be removed."); return INVALID_OPERATION; } @@ -103,7 +103,7 @@ status_t MediaSync::configureSurface(const sp<IGraphicBufferProducer> &output) { true /* producerControlledByApp */, &queueBufferOutput); if (status != NO_ERROR) { - ALOGE("configureSurface: failed to connect (%d)", status); + ALOGE("setSurface: failed to connect (%d)", status); return status; } @@ -114,17 +114,17 @@ status_t MediaSync::configureSurface(const sp<IGraphicBufferProducer> &output) { } // |audioTrack| is used only for querying information. -status_t MediaSync::configureAudioTrack(const sp<AudioTrack> &audioTrack) { +status_t MediaSync::setAudioTrack(const sp<AudioTrack> &audioTrack) { Mutex::Autolock lock(mMutex); // TODO: support audio track change. if (mAudioTrack != NULL) { - ALOGE("configureAudioTrack: audioTrack has already been configured."); + ALOGE("setAudioTrack: audioTrack has already been configured."); return INVALID_OPERATION; } if (audioTrack == NULL && mSyncSettings.mSource == AVSYNC_SOURCE_AUDIO) { - ALOGE("configureAudioTrack: audioTrack is used as sync source and cannot be removed."); + ALOGE("setAudioTrack: audioTrack is used as sync source and cannot be removed."); return INVALID_OPERATION; } @@ -137,7 +137,7 @@ status_t MediaSync::configureAudioTrack(const sp<AudioTrack> &audioTrack) { } uint32_t nativeSampleRateInHz = audioTrack->getOriginalSampleRate(); if (nativeSampleRateInHz <= 0) { - ALOGE("configureAudioTrack: native sample rate should be positive."); + ALOGE("setAudioTrack: native sample rate should be positive."); return BAD_VALUE; } mAudioTrack = audioTrack; diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index d577034..4297549 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -753,7 +753,9 @@ status_t MyVorbisExtractor::verifyHeader( oggpack_buffer bits; oggpack_readinit(&bits, &ref); - CHECK_EQ(oggpack_read(&bits, 8), type); + if (oggpack_read(&bits, 8) != type) { + return ERROR_MALFORMED; + } for (size_t i = 0; i < 6; ++i) { oggpack_read(&bits, 8); // skip 'vorbis' } @@ -761,7 +763,9 @@ status_t MyVorbisExtractor::verifyHeader( switch (type) { case 1: { - CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits)); + if (0 != _vorbis_unpack_info(&mVi, &bits)) { + return ERROR_MALFORMED; + } mMeta->setData(kKeyVorbisInfo, 0, data, size); mMeta->setInt32(kKeySampleRate, mVi.rate); diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp index 06b2163..6afac74 100644..100755 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp @@ -625,7 +625,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { return errType; } - mStride = ALIGN16(mWidth); + mStride = mWidth; if (mInputDataIsMeta) { if (mConversionBuffer) { diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index 970acf3..e654843 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -661,7 +661,8 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) { BufferInfo *outputBufferInfo = *outputBufferInfoQueue.begin(); OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader; - if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + if ((inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) && + inputBufferHeader->nFilledLen == 0) { inputBufferInfoQueue.erase(inputBufferInfoQueue.begin()); inputBufferInfo->mOwnedByUs = false; notifyEmptyBufferDone(inputBufferHeader); @@ -762,6 +763,9 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) { encoded_packet->data.frame.sz); outputBufferInfo->mOwnedByUs = false; outputBufferInfoQueue.erase(outputBufferInfoQueue.begin()); + if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS; + } notifyFillBufferDone(outputBufferHeader); } } diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index f31af7b..03c9a8a 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -29,6 +29,8 @@ class IOMXObserver; struct OMXMaster; class GraphicBufferSource; +status_t StatusFromOMXError(OMX_ERRORTYPE err); + struct OMXNodeInstance { OMXNodeInstance( OMX *owner, const sp<IOMXObserver> &observer, const char *name); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index b9e2f9c..876abb8 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -32,6 +32,7 @@ #include "OMXMaster.h" +#include <OMX_AsString.h> #include <OMX_Component.h> namespace android { @@ -233,11 +234,11 @@ status_t OMX::allocateNode( instance, &handle); if (err != OMX_ErrorNone) { - ALOGE("FAILED to allocate omx component '%s'", name); + ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err); instance->onGetHandleFailed(); - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } *node = makeNodeID(instance); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 5bc1972..04293d6 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -220,13 +220,15 @@ OMX::node_id OMXNodeInstance::nodeID() { return mNodeID; } -static status_t StatusFromOMXError(OMX_ERRORTYPE err) { +status_t StatusFromOMXError(OMX_ERRORTYPE err) { switch (err) { case OMX_ErrorNone: return OK; case OMX_ErrorUnsupportedSetting: case OMX_ErrorUnsupportedIndex: return ERROR_UNSUPPORTED; + case OMX_ErrorInsufficientResources: + return NO_MEMORY; default: return UNKNOWN_ERROR; } diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index bd6889d..485e320 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1425,6 +1425,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( size_t *frameCount, IAudioFlinger::track_flags_t *flags, pid_t tid, + int clientUid, int *sessionId, size_t *notificationFrames, sp<IMemory>& cblk, @@ -1494,8 +1495,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( // TODO: the uid should be passed in as a parameter to openRecord recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask, frameCount, lSessionId, notificationFrames, - IPCThreadState::self()->getCallingUid(), - flags, tid, &lStatus); + clientUid, flags, tid, &lStatus); LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0)); if (lStatus == NO_ERROR) { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 8085ec2..51b2610 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -124,6 +124,7 @@ public: size_t *pFrameCount, IAudioFlinger::track_flags_t *flags, pid_t tid, + int clientUid, int *sessionId, size_t *notificationFrames, sp<IMemory>& cblk, diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp index ac4d9a6..064ff71 100644 --- a/services/camera/libcameraservice/common/CameraModule.cpp +++ b/services/camera/libcameraservice/common/CameraModule.cpp @@ -36,12 +36,47 @@ void CameraModule::deriveCameraCharacteristicsKeys( chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1); data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE; chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/1); - controlModes.push(ANDROID_CONTROL_MODE_OFF); controlModes.push(ANDROID_CONTROL_MODE_AUTO); camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES); if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) { controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE); } + + // Only advertise CONTROL_OFF mode if 3A manual controls are supported. + bool isManualAeSupported = false; + bool isManualAfSupported = false; + bool isManualAwbSupported = false; + entry = chars.find(ANDROID_CONTROL_AE_AVAILABLE_MODES); + if (entry.count > 0) { + for (size_t i = 0; i < entry.count; i++) { + if (entry.data.u8[i] == ANDROID_CONTROL_AE_MODE_OFF) { + isManualAeSupported = true; + break; + } + } + } + entry = chars.find(ANDROID_CONTROL_AF_AVAILABLE_MODES); + if (entry.count > 0) { + for (size_t i = 0; i < entry.count; i++) { + if (entry.data.u8[i] == ANDROID_CONTROL_AF_MODE_OFF) { + isManualAfSupported = true; + break; + } + } + } + entry = chars.find(ANDROID_CONTROL_AWB_AVAILABLE_MODES); + if (entry.count > 0) { + for (size_t i = 0; i < entry.count; i++) { + if (entry.data.u8[i] == ANDROID_CONTROL_AWB_MODE_OFF) { + isManualAwbSupported = true; + break; + } + } + } + if (isManualAeSupported && isManualAfSupported && isManualAwbSupported) { + controlModes.push(ANDROID_CONTROL_MODE_OFF); + } + chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes); } return; @@ -86,7 +121,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { if (ret != 0) { return ret; } - int deviceVersion = cameraInfo.device_version; + int deviceVersion = rawInfo.device_version; if (deviceVersion < CAMERA_DEVICE_API_VERSION_2_0) { // static_camera_characteristics is invalid *info = rawInfo; diff --git a/soundtrigger/ISoundTriggerHwService.cpp b/soundtrigger/ISoundTriggerHwService.cpp index 75f68b8..e14a771 100644 --- a/soundtrigger/ISoundTriggerHwService.cpp +++ b/soundtrigger/ISoundTriggerHwService.cpp @@ -40,6 +40,8 @@ enum { SET_CAPTURE_STATE, }; +#define MAX_ITEMS_PER_LIST 1024 + class BpSoundTriggerHwService: public BpInterface<ISoundTriggerHwService> { public: @@ -116,10 +118,18 @@ status_t BnSoundTriggerHwService::onTransact( case LIST_MODULES: { CHECK_INTERFACE(ISoundTriggerHwService, data, reply); unsigned int numModulesReq = data.readInt32(); + if (numModulesReq > MAX_ITEMS_PER_LIST) { + numModulesReq = MAX_ITEMS_PER_LIST; + } unsigned int numModules = numModulesReq; struct sound_trigger_module_descriptor *modules = (struct sound_trigger_module_descriptor *)calloc(numModulesReq, sizeof(struct sound_trigger_module_descriptor)); + if (modules == NULL) { + reply->writeInt32(NO_MEMORY); + reply->writeInt32(0); + return NO_ERROR; + } status_t status = listModules(modules, &numModules); reply->writeInt32(status); reply->writeInt32(numModules); |