Merge "Whitelist getTimestamp from integer sanitization"
am: 51cd9a441e
* commit '51cd9a441ed0acf6e3b9c221e9b7f9424073191f':
Whitelist getTimestamp from integer sanitization
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index c10963d..cdfa159 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -176,7 +176,7 @@
private:
// used by ResourceManagerClient
- status_t reclaim();
+ status_t reclaim(bool force = false);
friend struct ResourceManagerClient;
private:
@@ -385,6 +385,9 @@
uint64_t getGraphicBufferSize();
void addResource(const String8 &type, const String8 &subtype, uint64_t value);
+ bool hasPendingBuffer(int portIndex);
+ bool hasPendingBuffer();
+
/* called to get the last codec error when the sticky flag is set.
* if no such codec error is found, returns UNKNOWN_ERROR.
*/
diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h
index 3aaa032..bf4db87 100644
--- a/include/media/stagefright/MediaCodecList.h
+++ b/include/media/stagefright/MediaCodecList.h
@@ -47,6 +47,10 @@
virtual size_t countCodecs() const;
virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const {
+ if (index >= mCodecInfos.size()) {
+ ALOGE("b/24445127");
+ return NULL;
+ }
return mCodecInfos.itemAt(index);
}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 7380418..82b6736 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1852,7 +1852,11 @@
case NO_ERROR:
case DEAD_OBJECT:
case TIMED_OUT:
- mCbf(EVENT_STREAM_END, mUserData, NULL);
+ if (status != DEAD_OBJECT) {
+ // for DEAD_OBJECT, we do not send a EVENT_STREAM_END after stop();
+ // instead, the application should handle the EVENT_NEW_IAUDIOTRACK.
+ mCbf(EVENT_STREAM_END, mUserData, NULL);
+ }
{
AutoMutex lock(mLock);
// The previously assigned value of waitStreamEnd is no longer valid,
@@ -1976,7 +1980,8 @@
if (err != NO_ERROR) {
if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR ||
(isOffloaded() && (err == DEAD_OBJECT))) {
- return 0;
+ // FIXME bug 25195759
+ return 1000000;
}
ALOGE("Error %d obtaining an audio buffer, giving up.", err);
return NS_NEVER;
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 5e45c85..666b747 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -933,7 +933,7 @@
return (ssize_t) mState.mPosition;
}
-status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush __unused)
+status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
{
if (mIsShutdown) {
buffer->mFrameCount = 0;
@@ -971,7 +971,9 @@
// it is always larger or equal to avail.
LOG_ALWAYS_FATAL_IF(mFramesReady < (int64_t) avail);
buffer->mNonContig = mFramesReady == INT64_MAX ? SIZE_MAX : clampToSize(mFramesReady - avail);
- mUnreleased = avail;
+ if (!ackFlush) {
+ mUnreleased = avail;
+ }
return NO_ERROR;
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index b3eb5fd..45da218 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -474,6 +474,8 @@
{
Mutex::Autolock _l(mDisconnectLock);
mDataSource.clear();
+ mDecryptHandle = NULL;
+ mDrmManagerClient = NULL;
mCachedSource.clear();
mHttpSource.clear();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index eee7cf8..b1eb696 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1076,6 +1076,12 @@
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
+ if (audio) {
+ mAudioEOS = false;
+ } else {
+ mVideoEOS = false;
+ }
+
ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
|| mFlushingAudio == SHUT_DOWN)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 3646828..c005f3f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -635,8 +635,11 @@
flags = AUDIO_OUTPUT_FLAG_NONE;
}
- mRenderer->openAudioSink(
+ status_t err = mRenderer->openAudioSink(
format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
+ if (err != OK) {
+ handleError(err);
+ }
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 6419be0..f288c36 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -362,9 +362,9 @@
}
status_t NuPlayerDriver::setPlaybackSettings(const AudioPlaybackRate &rate) {
- Mutex::Autolock autoLock(mLock);
status_t err = mPlayer->setPlaybackSettings(rate);
if (err == OK) {
+ Mutex::Autolock autoLock(mLock);
if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
mState = STATE_PAUSED;
// try to update position
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 776dba8..4d25294 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -111,6 +111,7 @@
mVideoRenderingStarted(false),
mVideoRenderingStartGeneration(0),
mAudioRenderingStartGeneration(0),
+ mRenderingDataDelivered(false),
mAudioOffloadPauseTimeoutGeneration(0),
mAudioTornDown(false),
mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
@@ -648,11 +649,16 @@
void NuPlayer::Renderer::prepareForMediaRenderingStart_l() {
mAudioRenderingStartGeneration = mAudioDrainGeneration;
mVideoRenderingStartGeneration = mVideoDrainGeneration;
+ mRenderingDataDelivered = false;
}
void NuPlayer::Renderer::notifyIfMediaRenderingStarted_l() {
if (mVideoRenderingStartGeneration == mVideoDrainGeneration &&
mAudioRenderingStartGeneration == mAudioDrainGeneration) {
+ mRenderingDataDelivered = true;
+ if (mPaused) {
+ return;
+ }
mVideoRenderingStartGeneration = -1;
mAudioRenderingStartGeneration = -1;
@@ -910,6 +916,13 @@
{
Mutex::Autolock autoLock(mLock);
+ int64_t maxTimeMedia;
+ maxTimeMedia =
+ mAnchorTimeMediaUs +
+ (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
+ * 1000LL * mAudioSink->msecsPerFrame());
+ mMediaClock->updateMaxTimeMedia(maxTimeMedia);
+
notifyIfMediaRenderingStarted_l();
}
@@ -936,15 +949,6 @@
break;
}
}
- int64_t maxTimeMedia;
- {
- Mutex::Autolock autoLock(mLock);
- maxTimeMedia =
- mAnchorTimeMediaUs +
- (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
- * 1000LL * mAudioSink->msecsPerFrame());
- }
- mMediaClock->updateMaxTimeMedia(maxTimeMedia);
// calculate whether we need to reschedule another write.
bool reschedule = !mAudioQueue.empty()
@@ -1506,7 +1510,10 @@
{
Mutex::Autolock autoLock(mLock);
mPaused = false;
-
+ // rendering started message may have been delayed if we were paused.
+ if (mRenderingDataDelivered) {
+ notifyIfMediaRenderingStarted_l();
+ }
// configure audiosink as we did not do it when pausing
if (mAudioSink != NULL && mAudioSink->ready()) {
mAudioSink->setPlaybackRate(mPlaybackSettings);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 87bcbf9..9479c31 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -176,6 +176,7 @@
bool mVideoRenderingStarted;
int32_t mVideoRenderingStartGeneration;
int32_t mAudioRenderingStartGeneration;
+ bool mRenderingDataDelivered;
int64_t mLastPositionUpdateUs;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7019537..c2ffdf2 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -63,6 +63,7 @@
}
static const int kMaxRetry = 2;
+static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s
struct ResourceManagerClient : public BnResourceManagerClient {
ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
@@ -74,6 +75,12 @@
return true;
}
status_t err = codec->reclaim();
+ if (err == WOULD_BLOCK) {
+ ALOGD("Wait for the client to release codec.");
+ usleep(kMaxReclaimWaitTimeInUs);
+ ALOGD("Try to reclaim again.");
+ err = codec->reclaim(true /* force */);
+ }
if (err != OK) {
ALOGW("ResourceManagerClient failed to release codec with err %d", err);
}
@@ -571,13 +578,34 @@
return PostAndAwaitResponse(msg, &response);
}
-status_t MediaCodec::reclaim() {
+bool MediaCodec::hasPendingBuffer(int portIndex) {
+ const Vector<BufferInfo> &buffers = mPortBuffers[portIndex];
+ for (size_t i = 0; i < buffers.size(); ++i) {
+ const BufferInfo &info = buffers.itemAt(i);
+ if (info.mOwnedByClient) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MediaCodec::hasPendingBuffer() {
+ return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
+}
+
+status_t MediaCodec::reclaim(bool force) {
ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
sp<AMessage> msg = new AMessage(kWhatRelease, this);
msg->setInt32("reclaimed", 1);
+ msg->setInt32("force", force ? 1 : 0);
sp<AMessage> response;
- return PostAndAwaitResponse(msg, &response);
+ status_t ret = PostAndAwaitResponse(msg, &response);
+ if (ret == -ENOENT) {
+ ALOGD("MediaCodec looper is gone, skip reclaim");
+ ret = OK;
+ }
+ return ret;
}
status_t MediaCodec::release() {
@@ -1787,6 +1815,23 @@
msg->findInt32("reclaimed", &reclaimed);
if (reclaimed) {
mReleasedByResourceManager = true;
+
+ int32_t force = 0;
+ msg->findInt32("force", &force);
+ if (!force && hasPendingBuffer()) {
+ ALOGW("Can't reclaim codec right now due to pending buffers.");
+
+ // return WOULD_BLOCK to ask resource manager to retry later.
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", WOULD_BLOCK);
+ response->postReply(replyID);
+
+ // notify the async client
+ if (mFlags & kFlagIsAsync) {
+ onError(DEAD_OBJECT, ACTION_CODE_FATAL);
+ }
+ break;
+ }
}
if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 90b5f68..5c2e9f9 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -151,6 +151,10 @@
}
mQueueChangedCondition.signal();
+ {
+ Mutex::Autolock autoLock(mRepliesLock);
+ mRepliesCondition.broadcast();
+ }
if (!runningLocally && !thread->isCurrentThread()) {
// If not running locally and this thread _is_ the looper thread,
@@ -230,13 +234,31 @@
// to be called by AMessage::postAndAwaitResponse only
status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
+ {
+ Mutex::Autolock autoLock(mLock);
+ if (mThread == NULL) {
+ return -ENOENT;
+ }
+ }
+
// return status in case we want to handle an interrupted wait
Mutex::Autolock autoLock(mRepliesLock);
CHECK(replyToken != NULL);
- while (!replyToken->retrieveReply(response)) {
+ bool gotReply;
+ bool shouldContinue = true;
+ while (!(gotReply = replyToken->retrieveReply(response)) && shouldContinue) {
mRepliesCondition.wait(mRepliesLock);
+
+ {
+ Mutex::Autolock autoLock(mLock);
+ if (mThread == NULL) {
+ shouldContinue = false;
+ // continue and try to get potential reply one more time before break the loop
+ }
+ }
}
- return OK;
+
+ return gotReply ? OK : -ENOENT;
}
status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 9ec5802..fab1ef5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1352,12 +1352,16 @@
AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
: RefBase(),
mAudioFlinger(audioFlinger),
- // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
- mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
mPid(pid),
mTimedTrackCount(0)
{
- // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+ size_t heapSize = kClientSharedHeapSizeBytes;
+ // Increase heap size on non low ram devices to limit risk of reconnection failure for
+ // invalidated tracks
+ if (!audioFlinger->isLowRamDevice()) {
+ heapSize *= kClientSharedHeapSizeMultiplier;
+ }
+ mMemoryDealer = new MemoryDealer(heapSize, "AudioFlinger::Client");
}
// Client destructor must be called with AudioFlinger::mClientLock held
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 20c34ef..08fa70d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -88,6 +88,12 @@
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
+
+// Max shared memory size for audio tracks and audio records per client process
+static const size_t kClientSharedHeapSizeBytes = 1024*1024;
+// Shared memory size multiplier for non low ram devices
+static const size_t kClientSharedHeapSizeMultiplier = 4;
+
#define INCLUDING_FROM_AUDIOFLINGER_H
class AudioFlinger :
@@ -423,7 +429,7 @@
Client(const Client&);
Client& operator = (const Client&);
const sp<AudioFlinger> mAudioFlinger;
- const sp<MemoryDealer> mMemoryDealer;
+ sp<MemoryDealer> mMemoryDealer;
const pid_t mPid;
Mutex mTimedTrackLock;
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index 79ac12b..1bba5f6 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -131,7 +131,9 @@
// FIXME new may block for unbounded time at internal mutex of the heap
// implementation; it would be better to have normal capture thread allocate for
// us to avoid blocking here and to prevent possible priority inversion
- (void)posix_memalign(&mReadBuffer, 32, frameCount * Format_frameSize(mFormat));
+ size_t bufferSize = frameCount * Format_frameSize(mFormat);
+ (void)posix_memalign(&mReadBuffer, 32, bufferSize);
+ memset(mReadBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f586291..71fc498 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6932,6 +6932,7 @@
mRsmpInFrames = mFrameCount * 7;
mRsmpInFramesP2 = roundup(mRsmpInFrames);
free(mRsmpInBuffer);
+ mRsmpInBuffer = NULL;
// TODO optimize audio capture buffer sizes ...
// Here we calculate the size of the sliding buffer used as a source
@@ -6941,7 +6942,9 @@
// The current value is higher than necessary. However it should not add to latency.
// Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer
- (void)posix_memalign(&mRsmpInBuffer, 32, (mRsmpInFramesP2 + mFrameCount - 1) * mFrameSize);
+ size_t bufferSize = (mRsmpInFramesP2 + mFrameCount - 1) * mFrameSize;
+ (void)posix_memalign(&mRsmpInBuffer, 32, bufferSize);
+ memset(mRsmpInBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
// AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints.
// But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks?
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index b3fac0b..0e24b52 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -715,6 +715,7 @@
// But in this case we know the mixer thread (whether normal mixer or fast mixer)
// isn't looking at this track yet: we still hold the normal mixer thread lock,
// and for fast tracks the track is not yet in the fast mixer thread's active set.
+ // For static tracks, this is used to acknowledge change in position or loop.
ServerProxy::Buffer buffer;
buffer.mFrameCount = 1;
(void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8419ed5..5ff1c0b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -402,6 +402,20 @@
patch.num_sources = 2;
}
+ // terminate active capture if on the same HW module as the call TX source device
+ // FIXME: would be better to refine to only inputs whose profile connects to the
+ // call TX device but this information is not in the audio patch and logic here must be
+ // symmetric to the one in startInput()
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ if (activeDesc->getModuleHandle() == txSourceDeviceDesc->getModuleHandle()) {
+ audio_session_t activeSession = activeDesc->mSessions.itemAt(0);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
+ }
+ }
+
afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
@@ -566,9 +580,15 @@
audio_io_handle_t activeInput = mInputs.getActiveInput();
if (activeInput != 0) {
- setInputDevice(activeInput, getNewInputDevice(activeInput));
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ audio_devices_t newDevice = getNewInputDevice(activeInput);
+ // Force new input selection if the new device can not be reached via current input
+ if (activeDesc->mProfile->mSupportedDevices.types() & (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+ setInputDevice(activeInput, newDevice);
+ } else {
+ closeInput(activeInput);
+ }
}
-
}
void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
@@ -1499,6 +1519,15 @@
return INVALID_OPERATION;
}
}
+
+ // Do not allow capture if an active voice call is using a software patch and
+ // the call TX source device is on the same HW module.
+ // FIXME: would be better to refine to only inputs whose profile connects to the
+ // call TX device but this information is not in the audio patch
+ if (mCallTxPatch != 0 &&
+ inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
+ return INVALID_OPERATION;
+ }
}
// Routing?
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index e42c596..406c1c4 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -99,7 +99,8 @@
status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
if (!mFlashlightMapInitialized) {
- ALOGE("%s: findFlashUnits() must be called before this method.");
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
return NO_INIT;
}
@@ -200,7 +201,8 @@
bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
if (!mFlashlightMapInitialized) {
- ALOGE("%s: findFlashUnits() must be called before this method.");
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
return false;
}
@@ -219,7 +221,8 @@
Mutex::Autolock l(mLock);
if (!mFlashlightMapInitialized) {
- ALOGE("%s: findFlashUnits() must be called before this method.");
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
return NO_INIT;
}
@@ -256,7 +259,8 @@
Mutex::Autolock l(mLock);
if (!mFlashlightMapInitialized) {
- ALOGE("%s: findFlashUnits() must be called before this method.");
+ ALOGE("%s: findFlashUnits() must be called before this method.",
+ __FUNCTION__);
return NO_INIT;
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 013250b..3deb396 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -173,6 +173,13 @@
mNumberOfCameras = mModule->getNumberOfCameras();
mNumberOfNormalCameras = mNumberOfCameras;
+ // Setup vendor tags before we call get_camera_info the first time
+ // because HAL might need to setup static vendor keys in get_camera_info
+ VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+ if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
+ setUpVendorTags();
+ }
+
mFlashlight = new CameraFlashlight(*mModule, *this);
status_t res = mFlashlight->findFlashUnits();
if (res) {
@@ -239,12 +246,6 @@
mModule->setCallbacks(this);
}
- VendorTagDescriptor::clearGlobalVendorTagDescriptor();
-
- if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) {
- setUpVendorTags();
- }
-
CameraDeviceFactory::registerService(this);
CameraService::pingCameraServiceProxy();
@@ -1833,7 +1834,8 @@
if (mSoundRef++) return;
mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
- mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
+ mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
+ mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
}
void CameraService::releaseSound() {
@@ -2084,7 +2086,11 @@
void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
const CaptureResultExtras& resultExtras) {
- mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
+ if (mRemoteCallback != NULL) {
+ mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
+ } else {
+ ALOGE("mRemoteCallback is NULL!!");
+ }
}
// NOTE: function is idempotent
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index cd97b08..4b0eeb7 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -159,7 +159,8 @@
enum sound_kind {
SOUND_SHUTTER = 0,
- SOUND_RECORDING = 1,
+ SOUND_RECORDING_START = 1,
+ SOUND_RECORDING_STOP = 2,
NUM_SOUNDS
};
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 48b5a26..4338d64 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1040,7 +1040,7 @@
}
if (!restart) {
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_START);
mStreamingProcessor->updateRecordingRequest(params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
@@ -1212,7 +1212,7 @@
return;
};
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
// Remove recording stream to prevent it from slowing down takePicture later
if (!l.mParameters.recordingHint && l.mParameters.isJpegSizeOverridden()) {
@@ -1638,7 +1638,7 @@
}
status_t Camera2Client::commandPlayRecordingSoundL() {
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_START);
return OK;
}
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 38e35cd..30b462b 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -439,7 +439,7 @@
// start recording mode
enableMsgType(CAMERA_MSG_VIDEO_FRAME);
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_START);
result = mHardware->startRecording();
if (result != NO_ERROR) {
ALOGE("mHardware->startRecording() failed with status %d", result);
@@ -470,7 +470,7 @@
disableMsgType(CAMERA_MSG_VIDEO_FRAME);
mHardware->stopRecording();
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
mPreviewBuffer.clear();
}
@@ -648,7 +648,7 @@
}
return OK;
} else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
- mCameraService->playSound(CameraService::SOUND_RECORDING);
+ mCameraService->playSound(CameraService::SOUND_RECORDING_START);
} else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
// Silently ignore this command
return INVALID_OPERATION;
diff --git a/soundtrigger/ISoundTrigger.cpp b/soundtrigger/ISoundTrigger.cpp
index eecc1ea..4df2068 100644
--- a/soundtrigger/ISoundTrigger.cpp
+++ b/soundtrigger/ISoundTrigger.cpp
@@ -60,11 +60,13 @@
data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(modelMemory));
status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply);
- if (status != NO_ERROR ||
- (status = (status_t)reply.readInt32()) != NO_ERROR) {
+ if (status != NO_ERROR) {
return status;
}
- reply.read(handle, sizeof(sound_model_handle_t));
+ status = (status_t)reply.readInt32();
+ if (status == NO_ERROR) {
+ reply.read(handle, sizeof(sound_model_handle_t));
+ }
return status;
}
@@ -74,7 +76,7 @@
data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
data.write(&handle, sizeof(sound_model_handle_t));
status_t status = remote()->transact(UNLOAD_SOUND_MODEL, data, &reply);
- if (status != NO_ERROR) {
+ if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
}
return status;
@@ -93,7 +95,7 @@
}
data.writeStrongBinder(IInterface::asBinder(dataMemory));
status_t status = remote()->transact(START_RECOGNITION, data, &reply);
- if (status != NO_ERROR) {
+ if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
}
return status;
@@ -105,7 +107,7 @@
data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor());
data.write(&handle, sizeof(sound_model_handle_t));
status_t status = remote()->transact(STOP_RECOGNITION, data, &reply);
- if (status != NO_ERROR) {
+ if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
}
return status;
diff --git a/soundtrigger/ISoundTriggerHwService.cpp b/soundtrigger/ISoundTriggerHwService.cpp
index e14a771..e37bae3 100644
--- a/soundtrigger/ISoundTriggerHwService.cpp
+++ b/soundtrigger/ISoundTriggerHwService.cpp
@@ -85,8 +85,11 @@
data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor());
data.write(&handle, sizeof(sound_trigger_module_handle_t));
data.writeStrongBinder(IInterface::asBinder(client));
- remote()->transact(ATTACH, data, &reply);
- status_t status = reply.readInt32();
+ status_t status = remote()->transact(ATTACH, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = reply.readInt32();
if (reply.readInt32() != 0) {
module = interface_cast<ISoundTrigger>(reply.readStrongBinder());
}