diff options
Diffstat (limited to 'services')
5 files changed, 131 insertions, 102 deletions
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp index 425ca31..65d9ef7 100644 --- a/services/audioflinger/AudioPolicyManagerBase.cpp +++ b/services/audioflinger/AudioPolicyManagerBase.cpp @@ -1017,8 +1017,8 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien #ifdef AUDIO_POLICY_TEST Thread(false), #endif //AUDIO_POLICY_TEST - mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), - mLimitRingtoneVolume(false), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0) + mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false), + mLastVoiceVolume(-1.0f), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0) { mpClientInterface = clientInterface; @@ -1835,29 +1835,38 @@ status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_ } float volume = computeVolume(stream, index, output, device); - // do not set volume if the float value did not change - if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || force) { + // We actually change the volume if: + // - the float value returned by computeVolume() changed + // - the force flag is set + if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || + force) { mOutputs.valueFor(output)->mCurVolume[stream] = volume; LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); if (stream == AudioSystem::VOICE_CALL || stream == AudioSystem::DTMF || stream == AudioSystem::BLUETOOTH_SCO) { - float voiceVolume = -1.0; // offset value to reflect actual hardware volume that never reaches 0 // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) volume = 0.01 + 0.99 * volume; - if (stream == AudioSystem::VOICE_CALL) { - voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; - } else if (stream == AudioSystem::BLUETOOTH_SCO) { - voiceVolume = 1.0; - } - if (voiceVolume >= 0 && output == mHardwareOutput) { - mpClientInterface->setVoiceVolume(voiceVolume, delayMs); - } } mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); } + if (stream == AudioSystem::VOICE_CALL || + stream == AudioSystem::BLUETOOTH_SCO) { + float voiceVolume; + // Force voice volume to max for bluetooth SCO as volume is managed by the headset + if (stream == AudioSystem::VOICE_CALL) { + voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; + } else { + voiceVolume = 1.0; + } + if (voiceVolume != mLastVoiceVolume && output == mHardwareOutput) { + mpClientInterface->setVoiceVolume(voiceVolume, delayMs); + mLastVoiceVolume = voiceVolume; + } + } + return NO_ERROR; } diff --git a/services/camera/libcameraservice/CameraHardwareStub.cpp b/services/camera/libcameraservice/CameraHardwareStub.cpp index b3e0ee6..07b5a37 100644 --- a/services/camera/libcameraservice/CameraHardwareStub.cpp +++ b/services/camera/libcameraservice/CameraHardwareStub.cpp @@ -101,9 +101,9 @@ CameraHardwareStub::~CameraHardwareStub() mFakeCamera = 0; // paranoia } -sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const +status_t CameraHardwareStub::setPreviewWindow(const sp<ANativeWindow>& buf) { - return mPreviewHeap; + return NO_ERROR; } sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const diff --git a/services/camera/libcameraservice/CameraHardwareStub.h b/services/camera/libcameraservice/CameraHardwareStub.h index d3427ba..9b66a76 100644 --- a/services/camera/libcameraservice/CameraHardwareStub.h +++ b/services/camera/libcameraservice/CameraHardwareStub.h @@ -29,7 +29,7 @@ namespace android { class CameraHardwareStub : public CameraHardwareInterface { public: - virtual sp<IMemoryHeap> getPreviewHeap() const; + virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf); virtual sp<IMemoryHeap> getRawHeap() const; virtual void setCallbacks(notify_callback notify_cb, diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 58209fd..d09dfff 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -26,6 +26,7 @@ #include <binder/MemoryBase.h> #include <binder/MemoryHeapBase.h> #include <cutils/atomic.h> +#include <cutils/properties.h> #include <hardware/hardware.h> #include <media/AudioSystem.h> #include <media/mediaplayer.h> @@ -319,7 +320,9 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; mOrientation = 0; + mPreviewWindowFlag = 0; mOrientationChanged = false; + mPlayShutterSound = true; cameraService->setCameraBusy(cameraId); cameraService->loadSound(); LOG1("Client::Client X (pid %d)", callingPid); @@ -337,18 +340,6 @@ CameraService::Client::~Client() { int callingPid = getCallingPid(); LOG1("Client::~Client E (pid %d, this %p)", callingPid, this); - if (mSurface != 0 && !mUseOverlay) { - pthread_t thr; - // We unregister the buffers in a different thread because binder does - // not let us make sychronous transactions in a binder destructor (that - // is, upon our reaching a refcount of zero.) - pthread_create(&thr, - NULL, // attr - unregister_surface, - mSurface.get()); - pthread_join(thr, NULL); - } - // set mClientPid to let disconnet() tear down the hardware mClientPid = callingPid; disconnect(); @@ -466,6 +457,11 @@ void CameraService::Client::disconnect() { if (mUseOverlay) { mOverlayRef = 0; } + // Release the held ANativeWindow resources. + if (mPreviewWindow != 0) { + mPreviewWindow = 0; + mHardware->setPreviewWindow(mPreviewWindow); + } mHardware.clear(); mCameraService->removeClient(mCameraClient); @@ -476,8 +472,8 @@ void CameraService::Client::disconnect() { // ---------------------------------------------------------------------------- -// set the ISurface that the preview will use -status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { +// set the Surface that the preview will use +status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); @@ -487,7 +483,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { // return if no change in surface. // asBinder() is safe on NULL (returns NULL) - if (surface->asBinder() == mSurface->asBinder()) { + if (getISurface(surface)->asBinder() == mSurface->asBinder()) { return result; } @@ -498,44 +494,30 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { sp<Overlay> dummy; mHardware->setOverlay(dummy); mOverlayRef = 0; - } else { - mSurface->unregisterBuffers(); } } - mSurface = surface; + if (surface != 0) { + mSurface = getISurface(surface); + } else { + mSurface = 0; + } + mPreviewWindow = surface; mOverlayRef = 0; // If preview has been already started, set overlay or register preview // buffers now. if (mHardware->previewEnabled()) { if (mUseOverlay) { result = setOverlay(); - } else if (mSurface != 0) { - result = registerPreviewBuffers(); + } else if (mPreviewWindow != 0) { + native_window_set_buffers_transform(mPreviewWindow.get(), + mPreviewWindowFlag); + result = mHardware->setPreviewWindow(mPreviewWindow); } } return result; } -status_t CameraService::Client::registerPreviewBuffers() { - int w, h; - CameraParameters params(mHardware->getParameters()); - params.getPreviewSize(&w, &h); - - // FIXME: don't use a hardcoded format here. - ISurface::BufferHeap buffers(w, h, w, h, - HAL_PIXEL_FORMAT_YCrCb_420_SP, - mOrientation, - 0, - mHardware->getPreviewHeap()); - - status_t result = mSurface->registerBuffers(buffers); - if (result != NO_ERROR) { - LOGE("registerBuffers failed with status %d", result); - } - return result; -} - status_t CameraService::Client::setOverlay() { int w, h; CameraParameters params(mHardware->getParameters()); @@ -593,16 +575,10 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag) { if (checkPidAndHardware() != NO_ERROR) return; mPreviewCallbackFlag = callback_flag; - - // If we don't use overlay, we always need the preview frame for display. - // If we do use overlay, we only need the preview frame if the user - // wants the data. - if (mUseOverlay) { - if(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) { - enableMsgType(CAMERA_MSG_PREVIEW_FRAME); - } else { - disableMsgType(CAMERA_MSG_PREVIEW_FRAME); - } + if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) { + enableMsgType(CAMERA_MSG_PREVIEW_FRAME); + } else { + disableMsgType(CAMERA_MSG_PREVIEW_FRAME); } } @@ -627,14 +603,14 @@ status_t CameraService::Client::startCameraMode(camera_mode mode) { switch(mode) { case CAMERA_PREVIEW_MODE: - if (mSurface == 0) { + if (mSurface == 0 && mPreviewWindow == 0) { LOG1("mSurface is not set yet."); // still able to start preview in this case. } return startPreviewMode(); case CAMERA_RECORDING_MODE: - if (mSurface == 0) { - LOGE("mSurface must be set before startRecordingMode."); + if (mSurface == 0 && mPreviewWindow == 0) { + LOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); return INVALID_OPERATION; } return startRecordingMode(); @@ -660,16 +636,12 @@ status_t CameraService::Client::startPreviewMode() { if (result != NO_ERROR) return result; result = mHardware->startPreview(); } else { - enableMsgType(CAMERA_MSG_PREVIEW_FRAME); - result = mHardware->startPreview(); - if (result != NO_ERROR) return result; - // If preview display has been set, register preview buffers now. - if (mSurface != 0) { - // Unregister here because the surface may be previously registered - // with the raw (snapshot) heap. - mSurface->unregisterBuffers(); - result = registerPreviewBuffers(); + if (mPreviewWindow != 0) { + native_window_set_buffers_transform(mPreviewWindow.get(), + mPreviewWindowFlag); } + mHardware->setPreviewWindow(mPreviewWindow); + result = mHardware->startPreview(); } return result; } @@ -707,13 +679,10 @@ void CameraService::Client::stopPreview() { Mutex::Autolock lock(mLock); if (checkPidAndHardware() != NO_ERROR) return; + disableMsgType(CAMERA_MSG_PREVIEW_FRAME); mHardware->stopPreview(); - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); - } - mPreviewBuffer.clear(); } @@ -811,6 +780,35 @@ String8 CameraService::Client::getParameters() const { return params; } +// enable shutter sound +status_t CameraService::Client::enableShutterSound(bool enable) { + LOG1("enableShutterSound (pid %d)", getCallingPid()); + + status_t result = checkPidAndHardware(); + if (result != NO_ERROR) return result; + + if (enable) { + mPlayShutterSound = true; + return OK; + } + + // Disabling shutter sound may not be allowed. In that case only + // allow the mediaserver process to disable the sound. + char value[PROPERTY_VALUE_MAX]; + property_get("ro.camera.sound.forced", value, "0"); + if (strcmp(value, "0") != 0) { + // Disabling shutter sound is not allowed. Deny if the current + // process is not mediaserver. + if (getCallingPid() != getpid()) { + LOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid()); + return PERMISSION_DENIED; + } + } + + mPlayShutterSound = false; + return OK; +} + status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { LOG1("sendCommand (pid %d)", getCallingPid()); int orientation; @@ -826,15 +824,19 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a switch (arg1) { case 0: orientation = ISurface::BufferHeap::ROT_0; + mPreviewWindowFlag = 0; break; case 90: orientation = ISurface::BufferHeap::ROT_90; + mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_90; break; case 180: orientation = ISurface::BufferHeap::ROT_180; + mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_180; break; case 270: orientation = ISurface::BufferHeap::ROT_270; + mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_270; break; default: return BAD_VALUE; @@ -844,6 +846,20 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a if (mOverlayRef != 0) mOrientationChanged = true; } return OK; + } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) { + switch (arg1) { + case 0: + enableShutterSound(false); + break; + case 1: + enableShutterSound(true); + break; + default: + return BAD_VALUE; + } + return OK; + } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) { + mCameraService->playSound(SOUND_RECORDING); } return mHardware->sendCommand(cmd, arg1, arg2); @@ -1004,11 +1020,8 @@ void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, // "size" is the width and height of yuv picture for registerBuffer. // If it is NULL, use the picture size from parameters. void CameraService::Client::handleShutter(image_rect_type *size) { - mCameraService->playSound(SOUND_SHUTTER); - - // Screen goes black after the buffer is unregistered. - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); + if (mPlayShutterSound) { + mCameraService->playSound(SOUND_SHUTTER); } sp<ICameraClient> c = mCameraClient; @@ -1038,7 +1051,6 @@ void CameraService::Client::handleShutter(image_rect_type *size) { HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0, mHardware->getRawHeap()); - mSurface->registerBuffers(buffers); IPCThreadState::self()->flushCommands(); } @@ -1051,12 +1063,6 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - if (!mUseOverlay) { - if (mSurface != 0) { - mSurface->postBuffer(offset); - } - } - // local copy of the callback flags int flags = mPreviewCallbackFlag; @@ -1077,9 +1083,7 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK | FRAME_CALLBACK_FLAG_ENABLE_MASK); - if (mUseOverlay) { - disableMsgType(CAMERA_MSG_PREVIEW_FRAME); - } + disableMsgType(CAMERA_MSG_PREVIEW_FRAME); } if (c != 0) { @@ -1116,11 +1120,6 @@ void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - // Put the YUV version of the snapshot in the preview display. - if (mSurface != 0 && !mUseOverlay) { - mSurface->postBuffer(offset); - } - sp<ICameraClient> c = mCameraClient; mLock.unlock(); if (c != 0) { @@ -1278,4 +1277,12 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } +sp<ISurface> CameraService::getISurface(const sp<Surface>& surface) { + if (surface != 0) { + return surface->getISurface(); + } else { + return sp<ISurface>(0); + } +} + }; // namespace android diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 8f0ed75..c8e0c88 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -79,6 +79,12 @@ private: sp<MediaPlayer> mSoundPlayer[NUM_SOUNDS]; int mSoundRef; // reference count (release all MediaPlayer when 0) + // Used by Client objects to extract the ISurface from a Surface object. + // This is used because making Client a friend class of Surface would + // require including this header in Surface.h since Client is a nested + // class. + static sp<ISurface> getISurface(const sp<Surface>& surface); + class Client : public BnCamera { public: @@ -87,7 +93,7 @@ private: virtual status_t connect(const sp<ICameraClient>& client); virtual status_t lock(); virtual status_t unlock(); - virtual status_t setPreviewDisplay(const sp<ISurface>& surface); + virtual status_t setPreviewDisplay(const sp<Surface>& surface); virtual void setPreviewCallbackFlag(int flag); virtual status_t startPreview(); virtual void stopPreview(); @@ -132,6 +138,9 @@ private: status_t startPreviewMode(); status_t startRecordingMode(); + // internal function used by sendCommand to enable/disable shutter sound. + status_t enableShutterSound(bool enable); + // these are static callback functions static void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user); static void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user); @@ -157,6 +166,7 @@ private: sp<CameraService> mCameraService; // immutable after constructor sp<ICameraClient> mCameraClient; int mCameraId; // immutable after constructor + int mCameraFacing; // immutable after constructor pid_t mClientPid; sp<CameraHardwareInterface> mHardware; // cleared after disconnect() bool mUseOverlay; // immutable after constructor @@ -167,10 +177,13 @@ private: int mOrientation; // Current display orientation // True if display orientation has been changed. This is only used in overlay. int mOrientationChanged; + int mPreviewWindowFlag; + bool mPlayShutterSound; // Ensures atomicity among the public methods mutable Mutex mLock; sp<ISurface> mSurface; + sp<ANativeWindow> mPreviewWindow; // If the user want us to return a copy of the preview frame (instead // of the original one), we allocate mPreviewBuffer and reuse it if possible. |