зеркало из https://github.com/mozilla/gecko-dev.git
Bug 910498 - Camera changes to use CreateFd. r=mikeh
This commit is contained in:
Родитель
00a803aa36
Коммит
9cf076ba4e
|
@ -450,12 +450,9 @@ CameraControlImpl::TakePicture(const CameraSize& aSize, int32_t aRotation, const
|
|||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::StartRecording(CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
CameraControlImpl::StartRecording(CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor* aFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
{
|
||||
nsCOMPtr<nsIFile> clone;
|
||||
aFolder->Clone(getter_AddRefs(clone));
|
||||
|
||||
nsCOMPtr<nsIRunnable> startRecordingTask = new StartRecordingTask(this, *aOptions, clone, aFilename, onSuccess, onError, mWindowId);
|
||||
nsCOMPtr<nsIRunnable> startRecordingTask = new StartRecordingTask(this, *aOptions, aFileDescriptor, onSuccess, onError, mWindowId);
|
||||
return mCameraThread->Dispatch(startRecordingTask, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include "DOMCameraPreview.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "DeviceStorage.h"
|
||||
|
||||
class DeviceStorageFileDescriptor;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -54,7 +57,7 @@ public:
|
|||
void StopPreview();
|
||||
nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor *aDSFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StopRecording();
|
||||
nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult ReleaseHardware(nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
|
@ -452,11 +455,15 @@ protected:
|
|||
class StartRecordingTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
StartRecordingTask(CameraControlImpl* aCameraControl, idl::CameraStartRecordingOptions aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
|
||||
StartRecordingTask(CameraControlImpl* aCameraControl,
|
||||
idl::CameraStartRecordingOptions aOptions,
|
||||
DeviceStorageFileDescriptor *aDSFileDescriptor,
|
||||
nsICameraStartRecordingCallback* onSuccess,
|
||||
nsICameraErrorCallback* onError,
|
||||
uint64_t aWindowId)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mOptions(aOptions)
|
||||
, mFolder(aFolder)
|
||||
, mFilename(aFilename)
|
||||
, mDSFileDescriptor(aDSFileDescriptor)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraStartRecordingCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mWindowId(aWindowId)
|
||||
|
@ -491,8 +498,7 @@ public:
|
|||
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
idl::CameraStartRecordingOptions mOptions;
|
||||
nsCOMPtr<nsIFile> mFolder;
|
||||
nsString mFilename;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
uint64_t mWindowId;
|
||||
|
|
|
@ -349,13 +349,12 @@ nsDOMCameraControl::StartRecording(JSContext* aCx,
|
|||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(onSuccess, "no onSuccess handler passed");
|
||||
mozilla::idl::CameraStartRecordingOptions options;
|
||||
|
||||
// Default values, until the dictionary parser can handle them.
|
||||
options.rotation = 0;
|
||||
options.maxFileSizeBytes = 0;
|
||||
options.maxVideoLengthMs = 0;
|
||||
aRv = options.Init(aCx, aOptions.address());
|
||||
mOptions.rotation = 0;
|
||||
mOptions.maxFileSizeBytes = 0;
|
||||
mOptions.maxVideoLengthMs = 0;
|
||||
aRv = mOptions.Init(aCx, aOptions.address());
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
@ -375,13 +374,53 @@ nsDOMCameraControl::StartRecording(JSContext* aCx,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIFile> folder;
|
||||
aRv = storageArea.GetRootDirectoryForFile(filename, getter_AddRefs(folder));
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
mDSFileDescriptor = new DeviceStorageFileDescriptor();
|
||||
aRv = storageArea.CreateFileDescriptor(filename, mDSFileDescriptor.get(),
|
||||
getter_AddRefs(request));
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
aRv = mCameraControl->StartRecording(&options, folder, filename, onSuccess,
|
||||
onError.WasPassed() ? onError.Value() : nullptr);
|
||||
|
||||
mOnSuccessCb = onSuccess;
|
||||
mOnErrorCb = onError.WasPassed() ? onError.Value() : nullptr;
|
||||
|
||||
request->AddEventListener(NS_LITERAL_STRING("success"), this, false);
|
||||
request->AddEventListener(NS_LITERAL_STRING("error"), this, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMCameraControl::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
ErrorResult rv;
|
||||
|
||||
if ((eventType.EqualsLiteral("success")) &&
|
||||
mDSFileDescriptor->mFileDescriptor.IsValid()) {
|
||||
|
||||
rv = mCameraControl->StartRecording(&mOptions,
|
||||
mDSFileDescriptor.get(),
|
||||
mOnSuccessCb.get(),
|
||||
mOnErrorCb.get());
|
||||
if (!rv.Failed()) {
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
// An error happened. Fall through and call the error callback.
|
||||
}
|
||||
|
||||
// We're already be on the main thread, so go ahead and call the
|
||||
// error callback directly.
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnErrorCb &&
|
||||
nsDOMCameraManager::IsWindowStillActive(mWindow->WindowID())) {
|
||||
mOnErrorCb->HandleEvent(NS_LITERAL_STRING("FAILURE"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "DOMCameraPreview.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "AudioChannelAgent.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
#include "DeviceStorage.h"
|
||||
|
||||
class nsDOMDeviceStorage;
|
||||
class nsPIDOMWindow;
|
||||
|
@ -28,11 +30,12 @@ template<typename T> class Optional;
|
|||
class ErrorResult;
|
||||
|
||||
// Main camera control.
|
||||
class nsDOMCameraControl MOZ_FINAL : public nsISupports,
|
||||
class nsDOMCameraControl MOZ_FINAL : public nsIDOMEventListener,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMCameraControl)
|
||||
|
||||
nsDOMCameraControl(uint32_t aCameraId, nsIThread* aCameraThread,
|
||||
|
@ -107,6 +110,11 @@ private:
|
|||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
nsresult NotifyRecordingStatusChange(const nsString& aMsg);
|
||||
|
||||
mozilla::idl::CameraStartRecordingOptions mOptions;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
|
||||
protected:
|
||||
/* additional members */
|
||||
nsRefPtr<ICameraControl> mCameraControl; // non-DOM camera control
|
||||
|
|
|
@ -1023,7 +1023,7 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
|
|||
// is meant to be stored as a local time. Since we are given seconds from
|
||||
// Epoch GMT, we use localtime_r() to handle the conversion.
|
||||
time_t time = aTakePicture->mDateTime;
|
||||
if (time != aTakePicture->mDateTime) {
|
||||
if ((uint64_t)time != aTakePicture->mDateTime) {
|
||||
DOM_CAMERA_LOGE("picture date/time '%llu' is too far in the future\n", aTakePicture->mDateTime);
|
||||
} else {
|
||||
struct tm t;
|
||||
|
@ -1097,42 +1097,24 @@ nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
|
|||
* The camera app needs to provide the file extension '.3gp' for now.
|
||||
* See bug 795202.
|
||||
*/
|
||||
nsCOMPtr<nsIFile> filename = aStartRecording->mFolder;
|
||||
filename->AppendRelativePath(aStartRecording->mFilename);
|
||||
|
||||
nsString fullpath;
|
||||
filename->GetPath(fullpath);
|
||||
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIVolume> vol;
|
||||
nsresult rv = vs->GetVolumeByPath(fullpath, getter_AddRefs(vol));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsString volName;
|
||||
vol->GetName(volName);
|
||||
|
||||
mVideoFile = new DeviceStorageFile(NS_LITERAL_STRING("videos"),
|
||||
volName,
|
||||
aStartRecording->mFilename);
|
||||
|
||||
nsAutoCString nativeFilename;
|
||||
filename->GetNativePath(nativeFilename);
|
||||
DOM_CAMERA_LOGI("Video filename is '%s'\n", nativeFilename.get());
|
||||
nsRefPtr<DeviceStorageFileDescriptor> dsfd = aStartRecording->mDSFileDescriptor;
|
||||
NS_ENSURE_TRUE(dsfd, NS_ERROR_FAILURE);
|
||||
nsAutoString fullPath;
|
||||
mVideoFile = dsfd->mDSFile;
|
||||
mVideoFile->GetFullPath(fullPath);
|
||||
DOM_CAMERA_LOGI("Video filename is '%s'\n",
|
||||
NS_LossyConvertUTF16toASCII(fullPath).get());
|
||||
|
||||
if (!mVideoFile->IsSafePath()) {
|
||||
DOM_CAMERA_LOGE("Invalid video file name\n");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedClose fd(open(nativeFilename.get(), O_RDWR | O_CREAT, 0644));
|
||||
if (fd < 0) {
|
||||
DOM_CAMERA_LOGE("Couldn't create file '%s': (%d) %s\n", nativeFilename.get(), errno, strerror(errno));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = SetupRecording(fd, aStartRecording->mOptions.rotation, aStartRecording->mOptions.maxFileSizeBytes, aStartRecording->mOptions.maxVideoLengthMs);
|
||||
nsresult rv;
|
||||
rv = SetupRecording(dsfd->mFileDescriptor.PlatformHandle(),
|
||||
aStartRecording->mOptions.rotation,
|
||||
aStartRecording->mOptions.maxFileSizeBytes,
|
||||
aStartRecording->mOptions.maxVideoLengthMs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mRecorder->start() != OK) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "DictionaryHelpers.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
class DeviceStorageFileDescriptor;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class DOMCameraPreview;
|
||||
|
@ -25,7 +27,7 @@ public:
|
|||
virtual void StopPreview() = 0;
|
||||
virtual nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor *aFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StopRecording() = 0;
|
||||
virtual nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult ReleaseHardware(nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче