mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge b2g-inbound to mozilla-central
This commit is contained in:
commit
edbdb02e8e
@ -12,7 +12,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "b9f86acc02f79d37ad0e10e9ee3b9cc75f870126",
|
||||
"revision": "973662e5df416f77550a9cdbc7ec597c623489c3",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="3d5c964015967ca8c86abe6dbbebee3cb82b1609"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6e71ab4da1b08586ea0c758edb7aa199ee34cd2f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bb2e2f3d03f258c84d633b7767bc95d9546d39fe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="78b908b493bfe0b477e3d4f6edec8c46a2c0d096"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
@ -154,12 +154,16 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef MOZ_B2G_CAMERA
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#else
|
||||
// We are subclassed from CameraControlListener, which implements a
|
||||
// threadsafe reference-count for us.
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
void OnHardwareStateChange(HardwareState aState);
|
||||
void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration);
|
||||
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
||||
void OnError(CameraErrorContext aContext, const nsACString& aError);
|
||||
void OnError(CameraErrorContext aContext, CameraError aError);
|
||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
|
||||
|
||||
void AllocImpl();
|
||||
|
@ -25,7 +25,13 @@ extern PRLogModuleInfo* GetMediaManagerLog();
|
||||
/**
|
||||
* Webrtc video source.
|
||||
*/
|
||||
#ifndef MOZ_B2G_CAMERA
|
||||
NS_IMPL_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
|
||||
#else
|
||||
NS_IMPL_QUERY_INTERFACE1(MediaEngineWebRTCVideoSource, nsIRunnable)
|
||||
NS_IMPL_ADDREF_INHERITED(MediaEngineWebRTCVideoSource, CameraControlListener)
|
||||
NS_IMPL_RELEASE_INHERITED(MediaEngineWebRTCVideoSource, CameraControlListener)
|
||||
#endif
|
||||
|
||||
// ViEExternalRenderer Callback.
|
||||
#ifndef MOZ_B2G_CAMERA
|
||||
@ -494,15 +500,21 @@ void
|
||||
MediaEngineWebRTCVideoSource::AllocImpl() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mCameraControl = ICameraControl::Create(mCaptureIndex, nullptr);
|
||||
mCameraControl->AddListener(this);
|
||||
mCameraControl = ICameraControl::Create(mCaptureIndex);
|
||||
if (mCameraControl) {
|
||||
mState = kAllocated;
|
||||
// Add this as a listener for CameraControl events. We don't need
|
||||
// to explicitly remove this--destroying the CameraControl object
|
||||
// in DeallocImpl() will do that for us.
|
||||
mCameraControl->AddListener(this);
|
||||
}
|
||||
mCallbackMonitor.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineWebRTCVideoSource::DeallocImpl() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mCameraControl->ReleaseHardware();
|
||||
mCameraControl = nullptr;
|
||||
}
|
||||
|
||||
@ -514,7 +526,7 @@ MediaEngineWebRTCVideoSource::StartImpl(webrtc::CaptureCapability aCapability) {
|
||||
config.mMode = ICameraControl::kPictureMode;
|
||||
config.mPreviewSize.width = aCapability.width;
|
||||
config.mPreviewSize.height = aCapability.height;
|
||||
mCameraControl->SetConfiguration(config);
|
||||
mCameraControl->Start(&config);
|
||||
mCameraControl->Set(CAMERA_PARAM_PICTURESIZE, config.mPreviewSize);
|
||||
}
|
||||
|
||||
@ -522,7 +534,7 @@ void
|
||||
MediaEngineWebRTCVideoSource::StopImpl() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mCameraControl->StopPreview();
|
||||
mCameraControl->Stop();
|
||||
}
|
||||
|
||||
void
|
||||
@ -535,25 +547,23 @@ void
|
||||
MediaEngineWebRTCVideoSource::OnHardwareStateChange(HardwareState aState)
|
||||
{
|
||||
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
|
||||
if (aState == CameraControlListener::kHardwareOpen) {
|
||||
mState = kAllocated;
|
||||
if (aState == CameraControlListener::kHardwareClosed) {
|
||||
// When the first CameraControl listener is added, it gets pushed
|
||||
// the current state of the camera--normally 'closed'. We only
|
||||
// pay attention to that state if we've progressed out of the
|
||||
// allocated state.
|
||||
if (mState != kAllocated) {
|
||||
mState = kReleased;
|
||||
mCallbackMonitor.Notify();
|
||||
}
|
||||
} else {
|
||||
mState = kReleased;
|
||||
mCameraControl->RemoveListener(this);
|
||||
mState = kStarted;
|
||||
mCallbackMonitor.Notify();
|
||||
}
|
||||
mCallbackMonitor.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineWebRTCVideoSource::OnConfigurationChange(const CameraListenerConfiguration& aConfiguration)
|
||||
{
|
||||
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
|
||||
mState = kStarted;
|
||||
mCallbackMonitor.Notify();
|
||||
}
|
||||
|
||||
void
|
||||
MediaEngineWebRTCVideoSource::OnError(CameraErrorContext aContext, const nsACString& aError)
|
||||
MediaEngineWebRTCVideoSource::OnError(CameraErrorContext aContext, CameraError aError)
|
||||
{
|
||||
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
|
||||
mCallbackMonitor.Notify();
|
||||
|
@ -41,7 +41,7 @@ function runTest() {
|
||||
iframe.src = browserElementTestHelpers.emptyPage1;
|
||||
}
|
||||
|
||||
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
||||
addEventListener('testready', runTest);
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -42,7 +42,7 @@ function runTest() {
|
||||
iframe.src = browserElementTestHelpers.emptyPage1;
|
||||
}
|
||||
|
||||
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
||||
addEventListener('testready', runTest);
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -235,12 +235,33 @@ CameraControlImpl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
RwLockAutoEnterRead lock(mListenerLock);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
const char* error[] = { "camera-service-failed", "unknown" };
|
||||
if (static_cast<unsigned int>(aError) < sizeof(error) / sizeof(error[0])) {
|
||||
DOM_CAMERA_LOGW("CameraControlImpl::OnError : aContext=%u, msg='%s'\n",
|
||||
aContext, error[aError]);
|
||||
const char* error[] = {
|
||||
"api-failed",
|
||||
"init-failed",
|
||||
"invalid-configuration",
|
||||
"service-failed",
|
||||
"set-picture-size-failred",
|
||||
"set-thumbnail-size-failed",
|
||||
"unknown"
|
||||
};
|
||||
const char* context[] = {
|
||||
"StartCamera",
|
||||
"StopCamera",
|
||||
"AutoFocus",
|
||||
"TakePicture",
|
||||
"StartRecording",
|
||||
"StopRecording",
|
||||
"SetConfiguration",
|
||||
"StartPreview",
|
||||
"StopPreview",
|
||||
"Unspecified"
|
||||
};
|
||||
if (static_cast<unsigned int>(aError) < sizeof(error) / sizeof(error[0]) &&
|
||||
static_cast<unsigned int>(aContext) < sizeof(context) / sizeof(context[0])) {
|
||||
DOM_CAMERA_LOGW("CameraControlImpl::OnError : aContext='%s' (%u), aError='%s' (%u)\n",
|
||||
context[aContext], aContext, error[aError], aError);
|
||||
} else {
|
||||
DOM_CAMERA_LOGE("CameraControlImpl::OnError : aContext=%u, unknown error=%d\n",
|
||||
DOM_CAMERA_LOGE("CameraControlImpl::OnError : aContext=%u, aError=%d\n",
|
||||
aContext, aError);
|
||||
}
|
||||
#endif
|
||||
@ -293,6 +314,42 @@ protected:
|
||||
CameraControlListener::CameraErrorContext mContext;
|
||||
};
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::Start(const Configuration* aConfig)
|
||||
{
|
||||
class Message : public ControlMessage
|
||||
{
|
||||
public:
|
||||
Message(CameraControlImpl* aCameraControl,
|
||||
CameraControlListener::CameraErrorContext aContext,
|
||||
const Configuration* aConfig)
|
||||
: ControlMessage(aCameraControl, aContext)
|
||||
, mHaveInitialConfig(false)
|
||||
{
|
||||
if (aConfig) {
|
||||
mConfig = *aConfig;
|
||||
mHaveInitialConfig = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
RunImpl() MOZ_OVERRIDE
|
||||
{
|
||||
if (mHaveInitialConfig) {
|
||||
return mCameraControl->StartImpl(&mConfig);
|
||||
}
|
||||
return mCameraControl->StartImpl();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mHaveInitialConfig;
|
||||
Configuration mConfig;
|
||||
};
|
||||
|
||||
return mCameraThread->Dispatch(
|
||||
new Message(this, CameraControlListener::kInStartCamera, aConfig), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::SetConfiguration(const Configuration& aConfig)
|
||||
{
|
||||
@ -475,7 +532,7 @@ CameraControlImpl::StopPreview()
|
||||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::ReleaseHardware()
|
||||
CameraControlImpl::Stop()
|
||||
{
|
||||
class Message : public ControlMessage
|
||||
{
|
||||
@ -488,12 +545,12 @@ CameraControlImpl::ReleaseHardware()
|
||||
nsresult
|
||||
RunImpl() MOZ_OVERRIDE
|
||||
{
|
||||
return mCameraControl->ReleaseHardwareImpl();
|
||||
return mCameraControl->StopImpl();
|
||||
}
|
||||
};
|
||||
|
||||
return mCameraThread->Dispatch(
|
||||
new Message(this, CameraControlListener::kInReleaseHardware), NS_DISPATCH_NORMAL);
|
||||
new Message(this, CameraControlListener::kInStopCamera), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
class CameraControlImpl::ListenerMessage : public CameraControlImpl::ControlMessage
|
||||
@ -515,6 +572,7 @@ CameraControlImpl::AddListenerImpl(already_AddRefed<CameraControlListener> aList
|
||||
RwLockAutoEnterWrite lock(mListenerLock);
|
||||
|
||||
CameraControlListener* l = *mListeners.AppendElement() = aListener;
|
||||
DOM_CAMERA_LOGI("Added camera control listener %p\n", l);
|
||||
|
||||
// Update the newly-added listener's state
|
||||
l->OnConfigurationChange(mCurrentConfiguration);
|
||||
@ -551,6 +609,7 @@ CameraControlImpl::RemoveListenerImpl(CameraControlListener* aListener)
|
||||
|
||||
nsRefPtr<CameraControlListener> l(aListener);
|
||||
mListeners.RemoveElement(l);
|
||||
DOM_CAMERA_LOGI("Removed camera control listener %p\n", l.get());
|
||||
// XXXmikeh - do we want to notify the listener that it has been removed?
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,9 @@ public:
|
||||
virtual void AddListener(CameraControlListener* aListener) MOZ_OVERRIDE;
|
||||
virtual void RemoveListener(CameraControlListener* aListener) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult Start(const Configuration* aConfig = nullptr) MOZ_OVERRIDE;
|
||||
virtual nsresult Stop() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult SetConfiguration(const Configuration& aConfig) MOZ_OVERRIDE;
|
||||
virtual nsresult StartPreview() MOZ_OVERRIDE;
|
||||
virtual nsresult StopPreview() MOZ_OVERRIDE;
|
||||
@ -44,7 +47,6 @@ public:
|
||||
virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions) MOZ_OVERRIDE;
|
||||
virtual nsresult StopRecording() MOZ_OVERRIDE;
|
||||
virtual nsresult ReleaseHardware() MOZ_OVERRIDE;
|
||||
|
||||
already_AddRefed<RecorderProfileManager> GetRecorderProfileManager();
|
||||
uint32_t GetCameraId() { return mCameraId; }
|
||||
@ -63,7 +65,7 @@ protected:
|
||||
|
||||
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
||||
void OnRecorderStateChange(CameraControlListener::RecorderState aState,
|
||||
int32_t aStatus, int32_t aTrackNumber);
|
||||
int32_t aStatus = -1, int32_t aTrackNumber = -1);
|
||||
void OnPreviewStateChange(CameraControlListener::PreviewState aState);
|
||||
void OnHardwareStateChange(CameraControlListener::HardwareState aState);
|
||||
void OnConfigurationChange();
|
||||
@ -90,6 +92,8 @@ protected:
|
||||
class ControlMessage;
|
||||
class ListenerMessage;
|
||||
|
||||
virtual nsresult StartImpl(const Configuration* aConfig = nullptr) = 0;
|
||||
virtual nsresult StopImpl() = 0;
|
||||
virtual nsresult SetConfigurationImpl(const Configuration& aConfig) = 0;
|
||||
virtual nsresult StartPreviewImpl() = 0;
|
||||
virtual nsresult StopPreviewImpl() = 0;
|
||||
@ -100,7 +104,6 @@ protected:
|
||||
virtual nsresult StopRecordingImpl() = 0;
|
||||
virtual nsresult PushParametersImpl() = 0;
|
||||
virtual nsresult PullParametersImpl() = 0;
|
||||
virtual nsresult ReleaseHardwareImpl() = 0;
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() = 0;
|
||||
|
||||
void OnShutterInternal();
|
||||
|
@ -17,7 +17,15 @@ namespace layers {
|
||||
class CameraControlListener
|
||||
{
|
||||
public:
|
||||
virtual ~CameraControlListener() { }
|
||||
CameraControlListener()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CameraControlListener);
|
||||
}
|
||||
|
||||
virtual ~CameraControlListener()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CameraControlListener);
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CameraControlListener);
|
||||
|
||||
@ -71,13 +79,13 @@ public:
|
||||
|
||||
enum CameraErrorContext
|
||||
{
|
||||
kInGetCamera,
|
||||
kInStartCamera,
|
||||
kInStopCamera,
|
||||
kInAutoFocus,
|
||||
kInTakePicture,
|
||||
kInStartRecording,
|
||||
kInStopRecording,
|
||||
kInSetConfiguration,
|
||||
kInReleaseHardware,
|
||||
kInStartPreview,
|
||||
kInStopPreview,
|
||||
kInUnspecified
|
||||
|
@ -201,7 +201,7 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||
config.mPreviewSize.height = aInitialConfig.mPreviewSize.mHeight;
|
||||
config.mRecorderProfile = aInitialConfig.mRecorderProfile;
|
||||
|
||||
mCameraControl = ICameraControl::Create(aCameraId, &config);
|
||||
mCameraControl = ICameraControl::Create(aCameraId);
|
||||
mCurrentConfiguration = initialConfig.forget();
|
||||
|
||||
// Attach our DOM-facing media stream to our viewfinder stream.
|
||||
@ -214,6 +214,13 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||
// Register a listener for camera events.
|
||||
mListener = new DOMCameraControlListener(this, mInput);
|
||||
mCameraControl->AddListener(mListener);
|
||||
|
||||
// Start the camera...
|
||||
nsresult rv = mCameraControl->Start(&config);
|
||||
if (NS_FAILED(rv)) {
|
||||
mListener->OnError(DOMCameraControlListener::kInStartCamera,
|
||||
DOMCameraControlListener::kErrorApiFailed);
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMCameraControl::~nsDOMCameraControl()
|
||||
@ -911,7 +918,7 @@ nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCa
|
||||
mReleaseOnErrorCb = &aOnError.Value();
|
||||
}
|
||||
|
||||
aRv = mCameraControl->ReleaseHardware();
|
||||
aRv = mCameraControl->Stop();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1157,11 +1164,16 @@ nsDOMCameraControl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
|
||||
nsCOMPtr<CameraErrorCallback>* errorCb;
|
||||
switch (aContext) {
|
||||
case CameraControlListener::kInGetCamera:
|
||||
case CameraControlListener::kInStartCamera:
|
||||
mGetCameraOnSuccessCb = nullptr;
|
||||
errorCb = &mGetCameraOnErrorCb;
|
||||
break;
|
||||
|
||||
case CameraControlListener::kInStopCamera:
|
||||
mReleaseOnSuccessCb = nullptr;
|
||||
errorCb = &mReleaseOnErrorCb;
|
||||
break;
|
||||
|
||||
case CameraControlListener::kInSetConfiguration:
|
||||
mSetConfigurationOnSuccessCb = nullptr;
|
||||
errorCb = &mSetConfigurationOnErrorCb;
|
||||
@ -1182,11 +1194,6 @@ nsDOMCameraControl::OnError(CameraControlListener::CameraErrorContext aContext,
|
||||
errorCb = &mStartRecordingOnErrorCb;
|
||||
break;
|
||||
|
||||
case CameraControlListener::kInReleaseHardware:
|
||||
mReleaseOnSuccessCb = nullptr;
|
||||
errorCb = &mReleaseOnErrorCb;
|
||||
break;
|
||||
|
||||
case CameraControlListener::kInStopRecording:
|
||||
NS_WARNING("Failed to stop recording (which shouldn't happen)!");
|
||||
MOZ_CRASH();
|
||||
|
@ -13,14 +13,33 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
DOMCameraControlListener::DOMCameraControlListener(nsDOMCameraControl* aDOMCameraControl,
|
||||
CameraPreviewMediaStream* aStream)
|
||||
: mDOMCameraControl(new nsMainThreadPtrHolder<nsDOMCameraControl>(aDOMCameraControl))
|
||||
, mStream(aStream)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, camera=%p, stream=%p\n",
|
||||
__func__, __LINE__, this, aDOMCameraControl, aStream);
|
||||
}
|
||||
|
||||
DOMCameraControlListener::~DOMCameraControlListener()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
// Boilerplate callback runnable
|
||||
class DOMCameraControlListener::DOMCallback : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DOMCallback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl)
|
||||
: mDOMCameraControl(aDOMCameraControl)
|
||||
{ }
|
||||
virtual ~DOMCallback() { }
|
||||
{
|
||||
MOZ_COUNT_CTOR(DOMCameraControlListener::DOMCallback);
|
||||
}
|
||||
virtual ~DOMCallback()
|
||||
{
|
||||
MOZ_COUNT_DTOR(DOMCameraControlListener::DOMCallback);
|
||||
}
|
||||
|
||||
virtual void RunCallback(nsDOMCameraControl* aDOMCameraControl) = 0;
|
||||
|
||||
@ -178,7 +197,8 @@ DOMCameraControlListener::OnConfigurationChange(const CameraListenerConfiguratio
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("Unanticipated camera mode!");
|
||||
DOM_CAMERA_LOGI("Camera mode still unspecified, nothing to do\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Map CameraControl parameters to their DOM-facing equivalents
|
||||
@ -298,7 +318,7 @@ DOMCameraControlListener::OnError(CameraErrorContext aContext, CameraError aErro
|
||||
, mError(aError)
|
||||
{ }
|
||||
|
||||
void
|
||||
virtual void
|
||||
RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
|
||||
{
|
||||
nsString error;
|
||||
|
@ -15,29 +15,28 @@ class CameraPreviewMediaStream;
|
||||
|
||||
class DOMCameraControlListener : public CameraControlListener
|
||||
{
|
||||
public:
|
||||
DOMCameraControlListener(nsDOMCameraControl* aDOMCameraControl, CameraPreviewMediaStream* aStream);
|
||||
|
||||
virtual void OnAutoFocusComplete(bool aAutoFocusSucceeded) MOZ_OVERRIDE;
|
||||
virtual void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType) MOZ_OVERRIDE;
|
||||
|
||||
virtual void OnHardwareStateChange(HardwareState aState) MOZ_OVERRIDE;
|
||||
virtual void OnPreviewStateChange(PreviewState aState) MOZ_OVERRIDE;
|
||||
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) MOZ_OVERRIDE;
|
||||
virtual void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration) MOZ_OVERRIDE;
|
||||
virtual void OnShutter() MOZ_OVERRIDE;
|
||||
virtual bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) MOZ_OVERRIDE;
|
||||
virtual void OnError(CameraErrorContext aContext, CameraError aError) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual ~DOMCameraControlListener();
|
||||
|
||||
nsMainThreadPtrHandle<nsDOMCameraControl> mDOMCameraControl;
|
||||
CameraPreviewMediaStream* mStream;
|
||||
|
||||
class DOMCallback;
|
||||
|
||||
public:
|
||||
DOMCameraControlListener(nsDOMCameraControl* aDOMCameraControl, CameraPreviewMediaStream* aStream)
|
||||
: mDOMCameraControl(new nsMainThreadPtrHolder<nsDOMCameraControl>(aDOMCameraControl))
|
||||
, mStream(aStream)
|
||||
{ }
|
||||
|
||||
void OnAutoFocusComplete(bool aAutoFocusSucceeded);
|
||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
|
||||
|
||||
void OnHardwareStateChange(HardwareState aState);
|
||||
void OnPreviewStateChange(PreviewState aState);
|
||||
void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum);
|
||||
void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration);
|
||||
void OnShutter();
|
||||
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
||||
void OnError(CameraErrorContext aContext, CameraError aError);
|
||||
|
||||
private:
|
||||
DOMCameraControlListener(const DOMCameraControlListener&) MOZ_DELETE;
|
||||
DOMCameraControlListener& operator=(const DOMCameraControlListener&) MOZ_DELETE;
|
||||
|
@ -26,7 +26,7 @@ ICameraControl::GetListOfCameras(nsTArray<nsString>& aList)
|
||||
}
|
||||
|
||||
already_AddRefed<ICameraControl>
|
||||
ICameraControl::Create(uint32_t aCameraId, const Configuration* aInitialConfig)
|
||||
ICameraControl::Create(uint32_t aCameraId)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -77,90 +77,50 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::Init(const Configuration* aInitialConfig)
|
||||
nsGonkCameraControl::StartImpl(const Configuration* aInitialConfig)
|
||||
{
|
||||
class InitGonkCameraControl : public nsRunnable
|
||||
{
|
||||
public:
|
||||
InitGonkCameraControl(nsGonkCameraControl* aCameraControl,
|
||||
const Configuration* aConfig)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mHaveInitialConfig(false)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
if (aConfig) {
|
||||
mConfig = *aConfig;
|
||||
mHaveInitialConfig = true;
|
||||
}
|
||||
/**
|
||||
* For initialization, we try to return the camera control to the upper
|
||||
* upper layer (i.e. the DOM) as quickly as possible. To do this, the
|
||||
* camera is initialized in the following stages:
|
||||
*
|
||||
* 0. Initialize() initializes the hardware;
|
||||
* 1. SetConfigurationInternal() does the minimal configuration
|
||||
* required so that we can start the preview -and- report a valid
|
||||
* configuration to the upper layer;
|
||||
* 2. OnHardwareStateChange() reports that the hardware is ready,
|
||||
* which the upper (e.g. DOM) layer can (and does) use to return
|
||||
* the camera control object;
|
||||
* 3. StartPreviewImpl() starts the flow of preview frames from the
|
||||
* camera hardware.
|
||||
*
|
||||
* The intent of the above flow is to let the Main Thread do as much work
|
||||
* up-front as possible without waiting for blocking Camera Thread calls
|
||||
* to complete.
|
||||
*/
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
nsresult rv = Initialize();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aInitialConfig) {
|
||||
rv = SetConfigurationInternal(*aInitialConfig);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// The initial configuration failed, close up the hardware
|
||||
StopImpl();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
~InitGonkCameraControl()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* For initialization, we try to return the camera control to the upper
|
||||
* upper layer (i.e. the DOM) as quickly as possible. To do this, the
|
||||
* camera is initialized in the following stages:
|
||||
*
|
||||
* 0. InitImpl() initializes the hardware;
|
||||
* 1. SetConfigurationInternal() does the minimal configuration
|
||||
* required so that we can start the preview -and- report a valid
|
||||
* configuration to the upper layer;
|
||||
* 2. OnHardwareStateChange() reports that the hardware is ready,
|
||||
* which the upper layer can (and does) use to return the camera
|
||||
* control object;
|
||||
* 3. StartPreviewImpl() starts the flow of preview frames from the
|
||||
* camera hardware.
|
||||
*
|
||||
* The intent of the above flow is to let the Main Thread do as much work
|
||||
* up-front as possible without waiting for blocking Camera Thread calls
|
||||
* to complete.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
Run() MOZ_OVERRIDE
|
||||
{
|
||||
nsresult rv = mCameraControl->InitImpl();
|
||||
if (NS_FAILED(rv)) {
|
||||
mCameraControl->OnError(CameraControlListener::kInGetCamera,
|
||||
CameraControlListener::kErrorInitFailed);
|
||||
// The hardware failed to initialize, so close it up
|
||||
mCameraControl->ReleaseHardware();
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mHaveInitialConfig) {
|
||||
rv = mCameraControl->SetConfigurationInternal(mConfig);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCameraControl->OnError(CameraControlListener::kInGetCamera,
|
||||
CameraControlListener::kErrorInvalidConfiguration);
|
||||
// The initial configuration failed, close up the hardware
|
||||
mCameraControl->ReleaseHardware();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
mCameraControl->OnHardwareStateChange(CameraControlListener::kHardwareOpen);
|
||||
return mCameraControl->StartPreviewImpl();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<nsGonkCameraControl> mCameraControl;
|
||||
Configuration mConfig;
|
||||
bool mHaveInitialConfig;
|
||||
};
|
||||
|
||||
// Initialization is carried out on the camera thread.
|
||||
return mCameraThread->Dispatch(
|
||||
new InitGonkCameraControl(this, aInitialConfig), NS_DISPATCH_NORMAL);
|
||||
OnHardwareStateChange(CameraControlListener::kHardwareOpen);
|
||||
return StartPreviewImpl();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::InitImpl()
|
||||
nsGonkCameraControl::Initialize()
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
mCameraHw = GonkCameraHardware::Connect(this, mCameraId);
|
||||
if (!mCameraHw.get()) {
|
||||
DOM_CAMERA_LOGE("Failed to connect to camera %d (this=%p)\n", mCameraId, this);
|
||||
@ -211,7 +171,7 @@ nsGonkCameraControl::~nsGonkCameraControl()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraHw = %p\n", __func__, __LINE__, this, mCameraHw.get());
|
||||
|
||||
ReleaseHardwareImpl();
|
||||
StopImpl();
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
@ -255,11 +215,18 @@ nsGonkCameraControl::SetConfigurationImpl(const Configuration& aConfig)
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
// Stop any currently running preview
|
||||
StopPreviewImpl();
|
||||
nsresult rv = PausePreview();
|
||||
if (NS_FAILED(rv)) {
|
||||
// warn, but plow ahead
|
||||
NS_WARNING("PausePreview() in SetConfigurationImpl() failed");
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
nsresult rv = SetConfigurationInternal(aConfig);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = SetConfigurationInternal(aConfig);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
StopPreviewImpl();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Restart the preview
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
@ -546,11 +513,22 @@ nsGonkCameraControl::StopPreviewImpl()
|
||||
DOM_CAMERA_LOGI("Stopping preview (this=%p)\n", this);
|
||||
|
||||
mCameraHw->StopPreview();
|
||||
|
||||
OnPreviewStateChange(CameraControlListener::kPreviewStopped);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::PausePreview()
|
||||
{
|
||||
RETURN_IF_NO_CAMERA_HW();
|
||||
|
||||
DOM_CAMERA_LOGI("Pausing preview (this=%p)\n", this);
|
||||
|
||||
mCameraHw->StopPreview();
|
||||
OnPreviewStateChange(CameraControlListener::kPreviewPaused);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::AutoFocusImpl(bool aCancelExistingCall)
|
||||
{
|
||||
@ -892,7 +870,7 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStarted, -1, -1);
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStarted);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -929,7 +907,7 @@ nsGonkCameraControl::StopRecordingImpl()
|
||||
|
||||
mRecorder->stop();
|
||||
mRecorder = nullptr;
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStopped, -1, -1);
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStopped);
|
||||
|
||||
// notify DeviceStorage that the new video file is closed and ready
|
||||
return NS_DispatchToMainThread(new RecordingComplete(mVideoFile), NS_DISPATCH_NORMAL);
|
||||
@ -1339,15 +1317,16 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation, int64_t aMaxFileSize
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::ReleaseHardwareImpl()
|
||||
nsGonkCameraControl::StopImpl()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
|
||||
// if we're recording, stop recording
|
||||
if (mRecorder) {
|
||||
DOM_CAMERA_LOGI("shutting down existing video recorder\n");
|
||||
DOM_CAMERA_LOGI("Stopping existing video recorder\n");
|
||||
mRecorder->stop();
|
||||
mRecorder = nullptr;
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStopped);
|
||||
}
|
||||
|
||||
// stop the preview
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Mozilla Foundation
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -47,8 +47,6 @@ class nsGonkCameraControl : public CameraControlImpl
|
||||
{
|
||||
public:
|
||||
nsGonkCameraControl(uint32_t aCameraId);
|
||||
nsresult Init(const Configuration* aInitialConfig);
|
||||
nsresult InitImpl();
|
||||
|
||||
void OnAutoFocusComplete(bool aSuccess);
|
||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength);
|
||||
@ -92,6 +90,10 @@ protected:
|
||||
virtual void BeginBatchParameterSet() MOZ_OVERRIDE;
|
||||
virtual void EndBatchParameterSet() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult StartImpl(const Configuration* aInitialConfig = nullptr) MOZ_OVERRIDE;
|
||||
virtual nsresult StopImpl() MOZ_OVERRIDE;
|
||||
nsresult Initialize();
|
||||
|
||||
virtual nsresult SetConfigurationImpl(const Configuration& aConfig) MOZ_OVERRIDE;
|
||||
nsresult SetConfigurationInternal(const Configuration& aConfig);
|
||||
nsresult SetPictureConfiguration(const Configuration& aConfig);
|
||||
@ -108,13 +110,13 @@ protected:
|
||||
virtual nsresult StopRecordingImpl() MOZ_OVERRIDE;
|
||||
virtual nsresult PushParametersImpl() MOZ_OVERRIDE;
|
||||
virtual nsresult PullParametersImpl() MOZ_OVERRIDE;
|
||||
virtual nsresult ReleaseHardwareImpl() MOZ_OVERRIDE;
|
||||
virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE;
|
||||
already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
|
||||
|
||||
nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
|
||||
nsresult SetupVideoMode(const nsAString& aProfile);
|
||||
nsresult SetPreviewSize(const Size& aSize);
|
||||
nsresult PausePreview();
|
||||
|
||||
friend class SetPictureSize;
|
||||
friend class SetThumbnailSize;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Mozilla Foundation
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -15,12 +15,14 @@
|
||||
*/
|
||||
|
||||
#include "GonkCameraHwMgr.h"
|
||||
#include "TestGonkCameraHardware.h"
|
||||
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "nsDebug.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "GonkCameraControl.h"
|
||||
#include "GonkNativeWindow.h"
|
||||
#include "CameraCommon.h"
|
||||
@ -35,11 +37,9 @@ GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, ui
|
||||
, mNumFrames(0)
|
||||
, mCamera(aCamera)
|
||||
, mTarget(aTarget)
|
||||
, mInitialized(false)
|
||||
, mSensorOrientation(0)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
|
||||
Init();
|
||||
}
|
||||
|
||||
void
|
||||
@ -127,7 +127,7 @@ GonkCameraHardware::postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, cons
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
GonkCameraHardware::Init()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s: this=%p\n", __func__, (void* )this);
|
||||
@ -136,7 +136,7 @@ GonkCameraHardware::Init()
|
||||
int rv = Camera::getCameraInfo(mCameraId, &info);
|
||||
if (rv != 0) {
|
||||
DOM_CAMERA_LOGE("%s: failed to get CameraInfo mCameraId %d\n", __func__, mCameraId);
|
||||
return;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mRawSensorOrientation = info.orientation;
|
||||
@ -168,7 +168,8 @@ GonkCameraHardware::Init()
|
||||
#else
|
||||
mCamera->setPreviewTexture(mNativeWindow);
|
||||
#endif
|
||||
mInitialized = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
sp<GonkCameraHardware>
|
||||
@ -180,18 +181,33 @@ GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCam
|
||||
sp<Camera> camera = Camera::connect(aCameraId);
|
||||
#endif
|
||||
|
||||
|
||||
if (camera.get() == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
sp<GonkCameraHardware> cameraHardware = new GonkCameraHardware(aTarget, aCameraId, camera);
|
||||
|
||||
const nsAdoptingCString& test =
|
||||
mozilla::Preferences::GetCString("camera.control.test.enabled");
|
||||
sp<GonkCameraHardware> cameraHardware;
|
||||
if (test.EqualsASCII("hardware")) {
|
||||
NS_WARNING("Using test Gonk hardware layer");
|
||||
cameraHardware = new TestGonkCameraHardware(aTarget, aCameraId, camera);
|
||||
} else {
|
||||
cameraHardware = new GonkCameraHardware(aTarget, aCameraId, camera);
|
||||
}
|
||||
|
||||
nsresult rv = cameraHardware->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to initialize camera hardware (0x%X)\n", rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cameraHardware;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GonkCameraHardware::Close()
|
||||
{
|
||||
DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, (void*)this);
|
||||
|
||||
mClosing = true;
|
||||
mCamera->stopPreview();
|
||||
@ -208,7 +224,7 @@ GonkCameraHardware::Close()
|
||||
|
||||
GonkCameraHardware::~GonkCameraHardware()
|
||||
{
|
||||
DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, (void*)this);
|
||||
mCamera.clear();
|
||||
mNativeWindow.clear();
|
||||
|
||||
@ -308,7 +324,7 @@ void
|
||||
GonkCameraHardware::StopPreview()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
return mCamera->stopPreview();
|
||||
mCamera->stopPreview();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Mozilla Foundation
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -43,14 +43,14 @@ class GonkCameraHardware : public GonkNativeWindowNewFrameCallback
|
||||
protected:
|
||||
GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera);
|
||||
virtual ~GonkCameraHardware();
|
||||
void Init();
|
||||
virtual nsresult Init();
|
||||
|
||||
public:
|
||||
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
|
||||
void Close();
|
||||
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
|
||||
virtual void Close();
|
||||
|
||||
// derived from GonkNativeWindowNewFrameCallback
|
||||
virtual void OnNewFrame() MOZ_OVERRIDE;
|
||||
virtual void OnNewFrame() MOZ_OVERRIDE;
|
||||
|
||||
// derived from CameraListener
|
||||
virtual void notify(int32_t aMsgType, int32_t ext1, int32_t ext2);
|
||||
@ -75,26 +75,25 @@ public:
|
||||
RAW_SENSOR_ORIENTATION,
|
||||
OFFSET_SENSOR_ORIENTATION
|
||||
};
|
||||
int GetSensorOrientation(uint32_t aType = RAW_SENSOR_ORIENTATION);
|
||||
virtual int GetSensorOrientation(uint32_t aType = RAW_SENSOR_ORIENTATION);
|
||||
|
||||
int AutoFocus();
|
||||
void CancelAutoFocus();
|
||||
int TakePicture();
|
||||
void CancelTakePicture();
|
||||
int StartPreview();
|
||||
void StopPreview();
|
||||
int PushParameters(const mozilla::GonkCameraParameters& aParams);
|
||||
int PushParameters(const CameraParameters& aParams);
|
||||
nsresult PullParameters(mozilla::GonkCameraParameters& aParams);
|
||||
void PullParameters(CameraParameters& aParams);
|
||||
int StartRecording();
|
||||
int StopRecording();
|
||||
int SetListener(const sp<GonkCameraListener>& aListener);
|
||||
void ReleaseRecordingFrame(const sp<IMemory>& aFrame);
|
||||
int StoreMetaDataInBuffers(bool aEnabled);
|
||||
virtual int AutoFocus();
|
||||
virtual void CancelAutoFocus();
|
||||
virtual int TakePicture();
|
||||
virtual void CancelTakePicture();
|
||||
virtual int StartPreview();
|
||||
virtual void StopPreview();
|
||||
virtual int PushParameters(const mozilla::GonkCameraParameters& aParams);
|
||||
virtual int PushParameters(const CameraParameters& aParams);
|
||||
virtual nsresult PullParameters(mozilla::GonkCameraParameters& aParams);
|
||||
virtual void PullParameters(CameraParameters& aParams);
|
||||
virtual int StartRecording();
|
||||
virtual int StopRecording();
|
||||
virtual int SetListener(const sp<GonkCameraListener>& aListener);
|
||||
virtual void ReleaseRecordingFrame(const sp<IMemory>& aFrame);
|
||||
virtual int StoreMetaDataInBuffers(bool aEnabled);
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t mCameraId;
|
||||
bool mClosing;
|
||||
uint32_t mNumFrames;
|
||||
@ -102,15 +101,9 @@ protected:
|
||||
mozilla::nsGonkCameraControl* mTarget;
|
||||
sp<GonkNativeWindow> mNativeWindow;
|
||||
sp<GonkCameraListener> mListener;
|
||||
bool mInitialized;
|
||||
int mRawSensorOrientation;
|
||||
int mSensorOrientation;
|
||||
|
||||
bool IsInitialized()
|
||||
{
|
||||
return mInitialized;
|
||||
}
|
||||
|
||||
private:
|
||||
GonkCameraHardware(const GonkCameraHardware&) MOZ_DELETE;
|
||||
GonkCameraHardware& operator=(const GonkCameraHardware&) MOZ_DELETE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Mozilla Foundation
|
||||
* Copyright (C) 2012-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -115,18 +115,8 @@ ICameraControl::GetListOfCameras(nsTArray<nsString>& aList)
|
||||
|
||||
// implementation-specific camera factory
|
||||
already_AddRefed<ICameraControl>
|
||||
ICameraControl::Create(uint32_t aCameraId, const Configuration* aInitialConfig)
|
||||
ICameraControl::Create(uint32_t aCameraId)
|
||||
{
|
||||
if (aInitialConfig) {
|
||||
DOM_CAMERA_LOGI("Creating camera %d control, initial mode '%s'\n",
|
||||
aCameraId, aInitialConfig->mMode == kVideoMode ? "video" : "picture");
|
||||
} else {
|
||||
DOM_CAMERA_LOGI("Creating camera %d control, no intial configuration\n", aCameraId);
|
||||
}
|
||||
|
||||
nsRefPtr<nsGonkCameraControl> control = new nsGonkCameraControl(aCameraId);
|
||||
nsresult rv = control->Init(aInitialConfig);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return control.forget();
|
||||
}
|
||||
|
@ -117,8 +117,11 @@ public:
|
||||
Size mPreviewSize;
|
||||
nsString mRecorderProfile;
|
||||
};
|
||||
static already_AddRefed<ICameraControl> Create(uint32_t aCameraId,
|
||||
const Configuration* aInitialConfig);
|
||||
static already_AddRefed<ICameraControl> Create(uint32_t aCameraId);
|
||||
|
||||
virtual nsresult Start(const Configuration* aInitialConfig = nullptr) = 0;
|
||||
virtual nsresult Stop() = 0;
|
||||
|
||||
virtual nsresult SetConfiguration(const Configuration& aConfig) = 0;
|
||||
|
||||
virtual void AddListener(CameraControlListener* aListener) = 0;
|
||||
@ -131,7 +134,6 @@ public:
|
||||
virtual nsresult StartRecording(DeviceStorageFileDescriptor *aFileDescriptor,
|
||||
const StartRecordingOptions* aOptions = nullptr) = 0;
|
||||
virtual nsresult StopRecording() = 0;
|
||||
virtual nsresult ReleaseHardware() = 0;
|
||||
|
||||
virtual nsresult Set(uint32_t aKey, const nsAString& aValue) = 0;
|
||||
virtual nsresult Get(uint32_t aKey, nsAString& aValue) = 0;
|
||||
|
218
dom/camera/TestGonkCameraHardware.cpp
Normal file
218
dom/camera/TestGonkCameraHardware.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "TestGonkCameraHardware.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace android;
|
||||
using namespace mozilla;
|
||||
|
||||
TestGonkCameraHardware::TestGonkCameraHardware(nsGonkCameraControl* aTarget,
|
||||
uint32_t aCameraId,
|
||||
const sp<Camera>& aCamera)
|
||||
: GonkCameraHardware(aTarget, aCameraId, aCamera)
|
||||
{
|
||||
DOM_CAMERA_LOGA("+===== Created TestGonkCameraHardware =====+\n");
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n",
|
||||
__func__, __LINE__, this, aTarget);
|
||||
MOZ_COUNT_CTOR(TestGonkCameraHardware);
|
||||
}
|
||||
|
||||
TestGonkCameraHardware::~TestGonkCameraHardware()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestGonkCameraHardware);
|
||||
DOM_CAMERA_LOGA("+===== Destroyed TestGonkCameraHardware =====+\n");
|
||||
}
|
||||
|
||||
nsresult
|
||||
TestGonkCameraHardware::Init()
|
||||
{
|
||||
if (IsTestCase("init-failure")) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return GonkCameraHardware::Init();
|
||||
}
|
||||
|
||||
const nsCString
|
||||
TestGonkCameraHardware::TestCase()
|
||||
{
|
||||
const nsCString test = Preferences::GetCString("camera.control.test.hardware");
|
||||
return test;
|
||||
}
|
||||
|
||||
bool
|
||||
TestGonkCameraHardware::IsTestCaseInternal(const char* aTest, const char* aFile, int aLine)
|
||||
{
|
||||
if (TestCase().EqualsASCII(aTest)) {
|
||||
DOM_CAMERA_LOGA("TestGonkCameraHardware : test-case '%s' (%s:%d)\n",
|
||||
aTest, aFile, aLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::TestCaseError(int aDefaultError)
|
||||
{
|
||||
// for now, just return the default error
|
||||
return aDefaultError;
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::AutoFocus()
|
||||
{
|
||||
class AutoFocusFailure : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AutoFocusFailure(nsGonkCameraControl* aTarget)
|
||||
: mTarget(aTarget)
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
OnAutoFocusComplete(mTarget, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsGonkCameraControl* mTarget;
|
||||
};
|
||||
|
||||
if (IsTestCase("auto-focus-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
if (IsTestCase("auto-focus-process-failure")) {
|
||||
nsresult rv = NS_DispatchToCurrentThread(new AutoFocusFailure(mTarget));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return OK;
|
||||
}
|
||||
DOM_CAMERA_LOGE("Failed to dispatch AutoFocusFailure runnable (0x%08x)\n", rv);
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
return GonkCameraHardware::AutoFocus();
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::TakePicture()
|
||||
{
|
||||
class TakePictureFailure : public nsRunnable
|
||||
{
|
||||
public:
|
||||
TakePictureFailure(nsGonkCameraControl* aTarget)
|
||||
: mTarget(aTarget)
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
OnTakePictureError(mTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsGonkCameraControl* mTarget;
|
||||
};
|
||||
|
||||
if (IsTestCase("take-picture-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
if (IsTestCase("take-picture-process-failure")) {
|
||||
nsresult rv = NS_DispatchToCurrentThread(new TakePictureFailure(mTarget));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return OK;
|
||||
}
|
||||
DOM_CAMERA_LOGE("Failed to dispatch TakePictureFailure runnable (0x%08x)\n", rv);
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
return GonkCameraHardware::TakePicture();
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::StartPreview()
|
||||
{
|
||||
if (IsTestCase("start-preview-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::StartPreview();
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::PushParameters(const GonkCameraParameters& aParams)
|
||||
{
|
||||
if (IsTestCase("push-parameters-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::PushParameters(aParams);
|
||||
}
|
||||
|
||||
nsresult
|
||||
TestGonkCameraHardware::PullParameters(GonkCameraParameters& aParams)
|
||||
{
|
||||
if (IsTestCase("pull-parameters-failure")) {
|
||||
return static_cast<nsresult>(TestCaseError(UNKNOWN_ERROR));
|
||||
}
|
||||
|
||||
return GonkCameraHardware::PullParameters(aParams);
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::StartRecording()
|
||||
{
|
||||
if (IsTestCase("start-recording-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::StartRecording();
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::StopRecording()
|
||||
{
|
||||
if (IsTestCase("stop-recording-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::StopRecording();
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
|
||||
{
|
||||
if (IsTestCase("set-listener-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::SetListener(aListener);
|
||||
}
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
|
||||
{
|
||||
if (IsTestCase("store-metadata-in-buffers-failure")) {
|
||||
return TestCaseError(UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return GonkCameraHardware::StoreMetaDataInBuffers(aEnabled);
|
||||
}
|
70
dom/camera/TestGonkCameraHardware.h
Normal file
70
dom/camera/TestGonkCameraHardware.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DOM_CAMERA_TESTGONKCAMERAHARDWARE_H
|
||||
#define DOM_CAMERA_TESTGONKCAMERAHARDWARE_H
|
||||
|
||||
#include "GonkCameraHwMgr.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class TestGonkCameraHardware : public android::GonkCameraHardware
|
||||
{
|
||||
public:
|
||||
virtual int AutoFocus() MOZ_OVERRIDE;
|
||||
virtual int TakePicture() MOZ_OVERRIDE;
|
||||
virtual int StartPreview() MOZ_OVERRIDE;
|
||||
virtual int PushParameters(const mozilla::GonkCameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual nsresult PullParameters(mozilla::GonkCameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual int StartRecording() MOZ_OVERRIDE;
|
||||
virtual int StopRecording() MOZ_OVERRIDE;
|
||||
virtual int SetListener(const sp<GonkCameraListener>& aListener) MOZ_OVERRIDE;
|
||||
virtual int StoreMetaDataInBuffers(bool aEnabled) MOZ_OVERRIDE;
|
||||
|
||||
virtual int
|
||||
PushParameters(const CameraParameters& aParams) MOZ_OVERRIDE
|
||||
{
|
||||
return GonkCameraHardware::PushParameters(aParams);
|
||||
}
|
||||
|
||||
virtual void
|
||||
PullParameters(CameraParameters& aParams) MOZ_OVERRIDE
|
||||
{
|
||||
GonkCameraHardware::PullParameters(aParams);
|
||||
}
|
||||
|
||||
TestGonkCameraHardware(mozilla::nsGonkCameraControl* aTarget,
|
||||
uint32_t aCameraId,
|
||||
const sp<Camera>& aCamera);
|
||||
virtual ~TestGonkCameraHardware();
|
||||
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
const nsCString TestCase();
|
||||
bool IsTestCaseInternal(const char* aTest, const char* aFile, int aLine);
|
||||
int TestCaseError(int aDefaultError);
|
||||
|
||||
private:
|
||||
TestGonkCameraHardware(const TestGonkCameraHardware&) MOZ_DELETE;
|
||||
TestGonkCameraHardware& operator=(const TestGonkCameraHardware&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
#define IsTestCase(test) IsTestCaseInternal((test), __FILE__, __LINE__)
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // DOM_CAMERA_TESTGONKCAMERAHARDWARE_H
|
@ -33,6 +33,7 @@ if CONFIG['MOZ_B2G_CAMERA']:
|
||||
'GonkCameraSource.cpp',
|
||||
'GonkRecorder.cpp',
|
||||
'GonkRecorderProfiles.cpp',
|
||||
'TestGonkCameraHardware.cpp',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
|
105
dom/camera/test/camera_common.js
Normal file
105
dom/camera/test/camera_common.js
Normal file
@ -0,0 +1,105 @@
|
||||
var CameraTest = (function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 'camera.control.test.enabled' is queried in Gecko to enable different
|
||||
* test modes in the camera stack. The only currently-supported setting
|
||||
* is 'hardware', which wraps the Gonk camera abstraction class in a
|
||||
* shim class that supports injecting hardware camera API failures into
|
||||
* the execution path.
|
||||
*
|
||||
* The affected API is specified by the 'camera.control.test.hardware'
|
||||
* pref. Currently supported values should be determined by inspecting
|
||||
* TestGonkCameraHardware.cpp.
|
||||
*
|
||||
* Some API calls are simple: e.g. 'start-recording-failure' will cause
|
||||
* the DOM-facing startRecording() call to fail. More complex tests like
|
||||
* 'take-picture-failure' will cause the takePicture() API to fail, while
|
||||
* 'take-picture-process-failure' will simulate a failure of the
|
||||
* asynchronous picture-taking process, even if the initial API call
|
||||
* path seems to have succeeded.
|
||||
*/
|
||||
const PREF_TEST_ENABLED = "camera.control.test.enabled";
|
||||
const PREF_TEST_HARDWARE = "camera.control.test.hardware";
|
||||
var oldTestEnabled;
|
||||
var oldTestHw;
|
||||
var testMode;
|
||||
|
||||
function testHardwareSet(test, callback) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, test]]}, function() {
|
||||
var setTest = SpecialPowers.getCharPref(PREF_TEST_HARDWARE);
|
||||
ise(setTest, test, "Test subtype set to " + setTest);
|
||||
if (callback) {
|
||||
callback(setTest);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testHardwareDone(callback) {
|
||||
testMode = null;
|
||||
if (oldTestHw) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, oldTestHw]]}, callback);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_HARDWARE]]}, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function testBegin(mode, callback) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
try {
|
||||
oldTestEnabled = SpecialPowers.getCharPref(PREF_TEST_ENABLED);
|
||||
} catch(e) { }
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, mode]]}, function() {
|
||||
var setMode = SpecialPowers.getCharPref(PREF_TEST_ENABLED);
|
||||
ise(setMode, mode, "Test mode set to " + setMode);
|
||||
if (setMode === "hardware") {
|
||||
try {
|
||||
oldTestHw = SpecialPowers.getCharPref(PREF_TEST_HARDWARE);
|
||||
} catch(e) { }
|
||||
testMode = {
|
||||
set: testHardwareSet,
|
||||
done: testHardwareDone
|
||||
};
|
||||
if (callback) {
|
||||
callback(testMode);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testEnd(callback) {
|
||||
function allDone(cb) {
|
||||
function cb2() {
|
||||
SimpleTest.finish();
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
if (oldTestEnabled) {
|
||||
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, oldTestEnabled]]}, cb2);
|
||||
} else {
|
||||
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_ENABLED]]}, cb2);
|
||||
}
|
||||
}
|
||||
|
||||
if (testMode) {
|
||||
testMode.done(function() {
|
||||
allDone(callback);
|
||||
});
|
||||
testMode = null;
|
||||
} else {
|
||||
allDone(function() {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ise(SpecialPowers.sanityCheck(), "foo", "SpecialPowers passed sanity check");
|
||||
return {
|
||||
begin: testBegin,
|
||||
end: testEnd
|
||||
};
|
||||
|
||||
})();
|
@ -1,4 +1,8 @@
|
||||
[DEFAULT]
|
||||
support-files = camera_common.js
|
||||
|
||||
[test_camera.html]
|
||||
[test_camera_2.html]
|
||||
[test_camera_3.html]
|
||||
[test_camera_hardware_init_failure.html]
|
||||
[test_camera_hardware_failures.html]
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<video id="viewfinder" |width = "200" height = "200| autoplay></video>
|
||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
@ -30,9 +30,6 @@ var config = {
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
}
|
||||
|
||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
||||
@ -105,10 +102,6 @@ var Camera = {
|
||||
Camera._testsCompleted++;
|
||||
if(Camera._testsCompleted == Camera._tests.length) {
|
||||
ok(true, "test finishing");
|
||||
Camera.cameraObj.release(function() {
|
||||
Camera.cameraObj = null;
|
||||
}, onError);
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
Camera.runTests();
|
||||
@ -200,6 +193,8 @@ SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
});
|
||||
|
||||
Camera.setUp();
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<video id="viewfinder" |width = "200" height = "200| autoplay></video>
|
||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
@ -30,9 +30,6 @@ var config = {
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
}
|
||||
|
||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
||||
@ -105,10 +102,6 @@ var Camera = {
|
||||
Camera._testsCompleted++;
|
||||
if(Camera._testsCompleted == Camera._tests.length) {
|
||||
ok(true, "test finishing");
|
||||
Camera.cameraObj.release(function() {
|
||||
Camera.cameraObj = null;
|
||||
}, onError);
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
Camera.runTests();
|
||||
@ -195,6 +188,8 @@ SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
});
|
||||
|
||||
Camera.setUp();
|
||||
|
76
dom/camera/test/test_camera_3.html
Normal file
76
dom/camera/test/test_camera_3.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for multiple calls to mozCameras.getCamera()</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var options = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'cif',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
}
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
onReady: function take_two() {
|
||||
function onSuccess(camera, config) {
|
||||
ok(false, "Unexpectedly got second camera instance: " + config.toSource);
|
||||
}
|
||||
function onFailure(error) {
|
||||
ok(true, "Correctly failed to get camera again");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onFailure);
|
||||
},
|
||||
release: function release() {
|
||||
cameraObj = null;
|
||||
},
|
||||
start: function run_test() {
|
||||
function onSuccess(camera, config) {
|
||||
Camera.cameraObj = camera;
|
||||
Camera.viewfinder.mozSrcObject = camera;
|
||||
Camera.viewfinder.play();
|
||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
||||
if (state === 'started') {
|
||||
ok(true, "viewfinder is ready and playing");
|
||||
Camera.cameraObj.onPreviewStateChange = null;
|
||||
Camera.onReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onError);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
145
dom/camera/test/test_camera_hardware_failures.html
Normal file
145
dom/camera/test/test_camera_hardware_failures.html
Normal file
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 940424 - Test camera hardware API failure handling</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="camera_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
|
||||
<video id="viewfinder" width = "200" height = "200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'cif',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
|
||||
var cameraObj;
|
||||
|
||||
// Shorthand functions
|
||||
function end() {
|
||||
CameraTest.end();
|
||||
}
|
||||
function next() {
|
||||
CameraTest.next();
|
||||
}
|
||||
|
||||
// The array of tests
|
||||
var tests = [
|
||||
{
|
||||
key: "auto-focus-failure",
|
||||
func: function testAutoFocusApiFailure(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(false, "autoFocus() succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "autoFocus() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.autoFocus(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "auto-focus-process-failure",
|
||||
func: function testAutoFocusProcessFailure(camera) {
|
||||
function onSuccess(success) {
|
||||
if (success) {
|
||||
ok(false, "autoFocus() process succeeded incorrectly");
|
||||
end();
|
||||
} else {
|
||||
ok(true, "autoFocus() process failed correctly");
|
||||
next();
|
||||
}
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "autoFocus() process failed incorrectly with: " + error);
|
||||
end();
|
||||
}
|
||||
camera.autoFocus(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-failure",
|
||||
func: function testTakePictureApiFailure(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "takePicture() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null, onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-process-failure",
|
||||
func: function testTakePictureProcessFailure(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() process succeeded incorrectly");
|
||||
end();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "takePicture() process failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null, onSuccess, onError);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
}
|
||||
}();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
document.getElementById('viewfinder').mozSrcObject = null;
|
||||
cameraObj.release();
|
||||
cameraObj = null;
|
||||
});
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
function onSuccess(camera, config) {
|
||||
document.getElementById('viewfinder').mozSrcObject = camera;
|
||||
cameraObj = camera;
|
||||
CameraTest.next = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
test.set(t.key, t.func.bind(undefined, camera));
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
end();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
53
dom/camera/test/test_camera_hardware_init_failure.html
Normal file
53
dom/camera/test/test_camera_hardware_init_failure.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 940424 - Test camera hardware init failure handling</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="camera_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
|
||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var initialConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'cif',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
|
||||
function end() {
|
||||
CameraTest.end();
|
||||
}
|
||||
|
||||
CameraTest.begin("hardware", function(test) {
|
||||
test.set("init-failure", function(type) {
|
||||
function onSuccess(camera, config) {
|
||||
ok(false, "onSuccess called incorrectly");
|
||||
camera.release();
|
||||
test.done(end);
|
||||
}
|
||||
function onError(error) {
|
||||
ok(true, "onError called correctly on init failure");
|
||||
test.done(end);
|
||||
}
|
||||
info("Running test: " + type);
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1075,8 +1075,8 @@ var WifiManager = (function() {
|
||||
manager.getConfiguredNetworks = function(callback) {
|
||||
wifiCommand.listNetworks(function (reply) {
|
||||
var networks = Object.create(null);
|
||||
var lines = reply.split("\n");
|
||||
if (lines.length === 1) {
|
||||
var lines = reply ? reply.split("\n") : 0;
|
||||
if (lines.length <= 1) {
|
||||
// We need to make sure we call the callback even if there are no
|
||||
// configured networks.
|
||||
callback(networks);
|
||||
|
@ -249,9 +249,6 @@
|
||||
"dom/browser-element/mochitest/test_browserElement_inproc_OpenWindowRejected.html":"",
|
||||
"dom/browser-element/mochitest/test_browserElement_inproc_SecurityChange.html":"",
|
||||
"dom/browser-element/mochitest/test_browserElement_inproc_TargetBlank.html":"",
|
||||
|
||||
"dom/browser-element/mochitest/test_browserElement_NoPref.html":"bug 970290 - Should not send mozbrowserloadstart event.",
|
||||
"dom/browser-element/mochitest/test_browserElement_NoWhitelist.html":"bug 970290 - Should not send mozbrowserloadstart event.",
|
||||
|
||||
"dom/browser-element/mochitest/test_browserElement_oop_AppFramePermission.html":"",
|
||||
"dom/browser-element/mochitest/test_browserElement_oop_AppWindowNamespace.html":"",
|
||||
|
Loading…
Reference in New Issue
Block a user