summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h7
-rw-r--r--services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h1
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp23
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp12
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h5
-rw-r--r--services/audiopolicy/service/AudioPolicyClientImpl.cpp6
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp22
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp12
-rw-r--r--services/audiopolicy/service/AudioPolicyService.cpp55
-rw-r--r--services/audiopolicy/service/AudioPolicyService.h22
-rw-r--r--services/camera/libcameraservice/CameraService.cpp33
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp34
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.h2
-rw-r--r--services/camera/libcameraservice/common/CameraModule.cpp6
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp6
-rw-r--r--services/camera/libcameraservice/device3/Camera3Stream.cpp6
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;