diff options
Diffstat (limited to 'services')
16 files changed, 226 insertions, 26 deletions
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 48d0e29..58c65fa 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -218,6 +218,11 @@ public: virtual status_t registerPolicyMixes(Vector<AudioMix> mixes) = 0; virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes) = 0; + + virtual status_t startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle) = 0; + virtual status_t stopAudioSource(audio_io_handle_t handle) = 0; }; @@ -320,6 +325,8 @@ public: virtual void onAudioPatchListUpdate() = 0; virtual audio_unique_id_t newAudioUniqueId() = 0; + + virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index f1aee46..50f622d 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -123,6 +123,7 @@ public: sp<SwAudioOutputDescriptor> mOutput1; // used by duplicated outputs: first output sp<SwAudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only) + uint32_t mGlobalRefCount; // non-stream-specific ref count }; class SwAudioOutputCollection : diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 596aa1d..144d8ad 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -225,7 +225,7 @@ SwAudioOutputDescriptor::SwAudioOutputDescriptor( : AudioOutputDescriptor(profile, clientInterface), mProfile(profile), mIoHandle(0), mLatency(0), mFlags((audio_output_flags_t)0), mPolicyMix(NULL), - mOutput1(0), mOutput2(0), mDirectOpenCount(0) + mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) { if (profile != NULL) { mFlags = (audio_output_flags_t)profile->mFlags; @@ -305,6 +305,27 @@ void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, mOutput2->changeRefCount(stream, delta); } AudioOutputDescriptor::changeRefCount(stream, delta); + + // handle stream-independent ref count + uint32_t oldGlobalRefCount = mGlobalRefCount; + if ((delta + (int)mGlobalRefCount) < 0) { + ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); + mGlobalRefCount = 0; + } else { + mGlobalRefCount += delta; + } + if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { + if ((mPolicyMix != NULL) && ((mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) { + mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, + MIX_STATE_MIXING); + } + + } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { + if ((mPolicyMix != NULL) && ((mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) { + mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, + MIX_STATE_IDLE); + } + } } diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index ba9f996..3ea6a11 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -2462,6 +2462,18 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session return mSoundTriggerSessions.acquireSession(*session, *ioHandle); } +status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle) +{ + return INVALID_OPERATION; +} + // ---------------------------------------------------------------------------- // AudioPolicyManager // ---------------------------------------------------------------------------- diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index fe6b986..146a7af 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -220,6 +220,11 @@ public: virtual status_t registerPolicyMixes(Vector<AudioMix> mixes); virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes); + virtual status_t startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle); + virtual status_t stopAudioSource(audio_io_handle_t handle); + // Audio policy configuration file parsing (audio_policy.conf) // TODO candidates to be moved to ConfigParsingUtils void defaultAudioPolicyConfig(void); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index 3e090e9..489a9be 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -213,6 +213,12 @@ void AudioPolicyService::AudioPolicyClient::onAudioPatchListUpdate() mAudioPolicyService->onAudioPatchListUpdate(); } +void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate( + String8 regId, int32_t state) +{ + mAudioPolicyService->onDynamicPolicyMixStateUpdate(regId, state); +} + audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId() { return AudioSystem::newAudioUniqueId(); diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 9510727..5f501a5 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -661,4 +661,26 @@ status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes, bool re } } +status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle) +{ + Mutex::Autolock _l(mLock); + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + + return mAudioPolicyManager->startAudioSource(source, attributes, handle); +} + +status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle) +{ + Mutex::Autolock _l(mLock); + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + + return mAudioPolicyManager->stopAudioSource(handle); +} + }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index e4ca5dc..f783437 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -604,4 +604,16 @@ status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes __unused return INVALID_OPERATION; } +status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle) +{ + return INVALID_OPERATION; +} + }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 00f188f..ccf9f9b 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -222,6 +222,21 @@ void AudioPolicyService::doOnAudioPatchListUpdate() } } +void AudioPolicyService::onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) +{ + ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)", + regId.string(), state); + mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state); +} + +void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state) +{ + Mutex::Autolock _l(mNotificationClientsLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state); + } +} + status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, int delayMs) { @@ -262,6 +277,14 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } } +void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( + String8 regId, int32_t state) +{ + if (mAudioPolicyServiceClient != 0) { + mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state); + } +} + void AudioPolicyService::binderDied(const wp<IBinder>& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), IPCThreadState::self()->getCallingPid()); @@ -511,6 +534,20 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() command->mStatus = af->setAudioPortConfig(&data->mConfig); } } break; + case DYN_POLICY_MIX_STATE_UPDATE: { + DynPolicyMixStateUpdateData *data = + (DynPolicyMixStateUpdateData *)command->mParam.get(); + //###ALOGV("AudioCommandThread() processing dyn policy mix state update"); + ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d", + data->mRegId.string(), data->mState); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); + mLock.lock(); + } break; default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -747,6 +784,20 @@ status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( return sendCommand(command, delayMs); } +void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( + String8 regId, int32_t state) +{ + sp<AudioCommand> command = new AudioCommand(); + command->mCommand = DYN_POLICY_MIX_STATE_UPDATE; + DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData(); + data->mRegId = regId; + data->mState = state; + command->mParam = data; + ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d", + regId.string(), state); + sendCommand(command); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) { { @@ -888,6 +939,10 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& c delayMs = 1; } break; + case DYN_POLICY_MIX_STATE_UPDATE: { + + } break; + case START_TONE: case STOP_TONE: default: diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index f8dabd3..4e25d33 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -192,6 +192,11 @@ public: virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration); + virtual status_t startAudioSource(const struct audio_port_config *source, + const audio_attributes_t *attributes, + audio_io_handle_t *handle); + virtual status_t stopAudioSource(audio_io_handle_t handle); + status_t doStopOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -213,6 +218,9 @@ public: void onAudioPatchListUpdate(); void doOnAudioPatchListUpdate(); + void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + private: AudioPolicyService() ANDROID_API; virtual ~AudioPolicyService(); @@ -243,6 +251,7 @@ private: UPDATE_AUDIOPORT_LIST, UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, + DYN_POLICY_MIX_STATE_UPDATE }; AudioCommandThread (String8 name, const wp<AudioPolicyService>& service); @@ -280,6 +289,7 @@ private: void updateAudioPatchListCommand(); status_t setAudioPortConfigCommand(const struct audio_port_config *config, int delayMs); + void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); private: @@ -364,6 +374,12 @@ private: struct audio_port_config mConfig; }; + class DynPolicyMixStateUpdateData : public AudioCommandData { + public: + String8 mRegId; + int32_t mState; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands @@ -469,6 +485,7 @@ private: virtual void onAudioPortListUpdate(); virtual void onAudioPatchListUpdate(); + virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); virtual audio_unique_id_t newAudioUniqueId(); @@ -484,8 +501,9 @@ private: uid_t uid); virtual ~NotificationClient(); - void onAudioPortListUpdate(); - void onAudioPatchListUpdate(); + void onAudioPortListUpdate(); + void onAudioPatchListUpdate(); + void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); // IBinder::DeathRecipient virtual void binderDied(const wp<IBinder>& who); diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 67a1d5d..8c5c43a 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -313,12 +313,11 @@ void CameraService::onTorchStatusChangedLocked(const String8& cameraId, ICameraServiceListener::TorchStatus status; status_t res = getTorchStatusLocked(cameraId, &status); if (res) { - ALOGE("%s: cannot get torch status of camera %s", cameraId.string()); + ALOGE("%s: cannot get torch status of camera %s: %s (%d)", + __FUNCTION__, cameraId.string(), strerror(-res), res); return; } if (status == newStatus) { - ALOGE("%s: Torch state transition to the same status 0x%x not allowed", - __FUNCTION__, (uint32_t)newStatus); return; } @@ -1153,14 +1152,14 @@ status_t CameraService::setTorchMode(const String16& cameraId, bool enabled, // verify id is valid. auto state = getCameraState(id); if (state == nullptr) { - ALOGE("%s: camera id is invalid %s", id.string()); + ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string()); return -EINVAL; } ICameraServiceListener::Status cameraStatus = state->getStatus(); if (cameraStatus != ICameraServiceListener::STATUS_PRESENT && cameraStatus != ICameraServiceListener::STATUS_NOT_AVAILABLE) { - ALOGE("%s: camera id is invalid %s", id.string()); + ALOGE("%s: camera id is invalid %s", __FUNCTION__, id.string()); return -EINVAL; } @@ -2232,16 +2231,20 @@ void CameraService::updateStatus(ICameraServiceListener::Status status, const St state->updateStatus(status, cameraId, rejectSourceStates, [this] (const String8& cameraId, ICameraServiceListener::Status status) { - // Update torch status - if (status == ICameraServiceListener::STATUS_NOT_PRESENT || - status == ICameraServiceListener::STATUS_NOT_AVAILABLE) { - // Update torch status to not available when the camera device becomes not present - // or not available. - onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE); - } else if (status == ICameraServiceListener::STATUS_PRESENT) { - // Update torch status to available when the camera device becomes present or - // available - onTorchStatusChanged(cameraId, ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF); + if (status != ICameraServiceListener::STATUS_ENUMERATING) { + // Update torch status if it has a flash unit. + Mutex::Autolock al(mTorchStatusMutex); + ICameraServiceListener::TorchStatus torchStatus; + if (getTorchStatusLocked(cameraId, &torchStatus) != + NAME_NOT_FOUND) { + ICameraServiceListener::TorchStatus newTorchStatus = + status == ICameraServiceListener::STATUS_PRESENT ? + ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF : + ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; + if (torchStatus != newTorchStatus) { + onTorchStatusChangedLocked(cameraId, newTorchStatus); + } + } } Mutex::Autolock lock(mStatusListenerLock); diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index f53f425..05ede92 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -1710,6 +1710,40 @@ status_t Camera2Client::commandSetVideoBufferCountL(size_t count) { return mStreamingProcessor->setRecordingBufferCount(count); } +void Camera2Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) { + int32_t err = CAMERA_ERROR_UNKNOWN; + switch(errorCode) { + case ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED: + err = CAMERA_ERROR_RELEASED; + break; + case ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE: + err = CAMERA_ERROR_UNKNOWN; + break; + case ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE: + err = CAMERA_ERROR_SERVER_DIED; + break; + case ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST: + case ICameraDeviceCallbacks::ERROR_CAMERA_RESULT: + case ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER: + ALOGW("%s: Received recoverable error %d from HAL - ignoring, requestId %" PRId32, + __FUNCTION__, errorCode, resultExtras.requestId); + return; + default: + err = CAMERA_ERROR_UNKNOWN; + break; + } + + ALOGE("%s: Error condition %d reported by HAL, requestId %" PRId32, __FUNCTION__, errorCode, + resultExtras.requestId); + + SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); + if (l.mRemoteCallback != nullptr) { + l.mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, err, 0); + } +} + + /** Device-related methods */ void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) { ALOGV("%s: Autofocus state now %d, last trigger %d", diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h index 5a8241f..a988037 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.h +++ b/services/camera/libcameraservice/api1/Camera2Client.h @@ -77,6 +77,8 @@ public: virtual status_t setParameters(const String8& params); virtual String8 getParameters() const; virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras); /** * Interface used by CameraService diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp index 5e0ac9f..ac4d9a6 100644 --- a/services/camera/libcameraservice/common/CameraModule.cpp +++ b/services/camera/libcameraservice/common/CameraModule.cpp @@ -86,6 +86,12 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { if (ret != 0) { return ret; } + int deviceVersion = cameraInfo.device_version; + if (deviceVersion < CAMERA_DEVICE_API_VERSION_2_0) { + // static_camera_characteristics is invalid + *info = rawInfo; + return ret; + } CameraMetadata m; m = rawInfo.static_camera_characteristics; deriveCameraCharacteristicsKeys(rawInfo.device_version, m); diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index ec9c70c..d2c2482 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -1082,9 +1082,9 @@ status_t Camera3Device::createDefaultRequest(int templateId, mHal3Device, templateId); ATRACE_END(); if (rawRequest == NULL) { - SET_ERR_L("HAL is unable to construct default settings for template %d", - templateId); - return DEAD_OBJECT; + ALOGI("%s: template %d is not supported on this camera device", + __FUNCTION__, templateId); + return BAD_VALUE; } *request = rawRequest; mRequestTemplateCache[templateId] = rawRequest; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 3821da1..4c40bb6 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -109,11 +109,7 @@ camera3_stream* Camera3Stream::startConfiguration() { // oldUsage/oldMaxBuffers return this; case STATE_CONFIGURED: - if (stream_type == CAMERA3_STREAM_INPUT) { - ALOGE("%s: Cannot configure an input stream twice", - __FUNCTION__); - return NULL; - } else if (hasOutstandingBuffersLocked()) { + if (hasOutstandingBuffersLocked()) { ALOGE("%s: Cannot configure stream; has outstanding buffers", __FUNCTION__); return NULL; |