Bug 817496 - Notify DeviceStorage when a new video file is finished recording. r=dougt

This commit is contained in:
Mike Habicher 2012-12-04 21:00:39 -05:00
parent 771adfe91f
commit c9d7e5ef7b
5 changed files with 83 additions and 38 deletions

View File

@ -6,6 +6,7 @@
#define DOM_CAMERA_CAMERA_RECORDER_PROFILES_H
#include "nsISupportsImpl.h"
#include "nsMimeTypes.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "jsapi.h"
@ -122,6 +123,14 @@ public:
default: return nullptr;
}
}
const char* GetFileMimeType() const
{
switch (mFileFormat) {
case THREE_GPP: return VIDEO_3GPP;
case MPEG4: return VIDEO_MP4;
default: return nullptr;
}
}
virtual nsresult GetJsObject(JSContext* aCx, JSObject** aObject) = 0;

View File

@ -31,8 +31,8 @@
#include "mozilla/FileUtils.h"
#include "nsAlgorithm.h"
#include <media/mediaplayer.h>
#include "nsDirectoryServiceDefs.h" // for NS_GetSpecialDirectory
#include "nsPrintfCString.h"
#include "nsIObserverService.h"
#include "DOMCameraManager.h"
#include "GonkCameraHwMgr.h"
#include "DOMCameraCapabilities.h"
@ -193,9 +193,9 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId, nsIThread* aCameraT
, mDiscardedFrameCount(0)
, mMediaProfiles(nullptr)
, mRecorder(nullptr)
, mVideoFile()
, mProfileManager(nullptr)
, mRecorderProfile(nullptr)
, mVideoFile(nullptr)
{
// Constructor runs on the main thread...
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
@ -842,11 +842,17 @@ nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
*/
nsCOMPtr<nsIFile> filename = aStartRecording->mFolder;
filename->AppendRelativePath(aStartRecording->mFilename);
mVideoFile = new DeviceStorageFile(NS_LITERAL_STRING("videos"), filename);
nsAutoCString nativeFilename;
filename->GetNativePath(nativeFilename);
DOM_CAMERA_LOGI("Video filename is '%s'\n", nativeFilename.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));
@ -864,13 +870,43 @@ nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
return NS_OK;
}
class RecordingComplete : public nsRunnable
{
public:
RecordingComplete(DeviceStorageFile* aFile, nsACString& aType)
: mFile(aFile)
, mType(aType)
{ }
~RecordingComplete() { }
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsString data;
CopyASCIItoUTF16(mType, data);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->NotifyObservers(mFile, "file-watcher-update", data.get());
return NS_OK;
}
private:
nsRefPtr<DeviceStorageFile> mFile;
nsCString mType;
};
nsresult
nsGonkCameraControl::StopRecordingImpl(StopRecordingTask* aStopRecording)
{
mRecorder->stop();
delete mRecorder;
mRecorder = nullptr;
return NS_OK;
// notify DeviceStorage that the new video file is closed and ready
nsCString type(mRecorderProfile->GetFileMimeType());
nsCOMPtr<nsIRunnable> recordingComplete = new RecordingComplete(mVideoFile, type);
return NS_DispatchToMainThread(recordingComplete, NS_DISPATCH_NORMAL);
}
void

View File

@ -20,13 +20,13 @@
#include "base/basictypes.h"
#include "prrwlock.h"
#include <media/MediaProfiles.h>
#include "DeviceStorage.h"
#include "nsIDOMCameraManager.h"
#include "DOMCameraControl.h"
#include "CameraControlImpl.h"
#include "CameraCommon.h"
#include "GonkRecorder.h"
namespace mozilla {
namespace layers {
@ -106,12 +106,12 @@ protected:
android::MediaProfiles* mMediaProfiles;
android::GonkRecorder* mRecorder;
nsString mVideoFile;
// camcorder profile settings for the desired quality level
nsRefPtr<GonkRecorderProfileManager> mProfileManager;
nsRefPtr<GonkRecorderProfile> mRecorderProfile;
nsRefPtr<DeviceStorageFile> mVideoFile;
private:
nsGonkCameraControl(const nsGonkCameraControl&) MOZ_DELETE;
nsGonkCameraControl& operator=(const nsGonkCameraControl&) MOZ_DELETE;

View File

@ -11,6 +11,38 @@
#include "nsIObserver.h"
#include "nsDOMEventTargetHelper.h"
class DeviceStorageFile MOZ_FINAL
: public nsISupports {
public:
nsCOMPtr<nsIFile> mFile;
nsString mPath;
nsString mStorageType;
bool mEditable;
DeviceStorageFile(const nsAString& aStorageType, nsIFile* aFile, const nsAString& aPath);
DeviceStorageFile(const nsAString& aStorageType, nsIFile* aFile);
void SetPath(const nsAString& aPath);
void SetEditable(bool aEditable);
NS_DECL_ISUPPORTS
// we want to make sure that the names of file can't reach
// outside of the type of storage the user asked for.
bool IsSafePath();
nsresult Remove();
nsresult Write(nsIInputStream* aInputStream);
nsresult Write(InfallibleTArray<uint8_t>& bits);
void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince = 0);
void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince, nsAString& aRootPath);
static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar, const nsAString& aStorageType);
private:
void NormalizeFilePath();
void AppendRelativePath();
};
class nsDOMDeviceStorage MOZ_FINAL
: public nsIDOMDeviceStorage
, public nsDOMEventTargetHelper

View File

@ -72,38 +72,6 @@ private:
static nsAutoPtr<DeviceStorageTypeChecker> sDeviceStorageTypeChecker;
};
class DeviceStorageFile MOZ_FINAL
: public nsISupports {
public:
nsCOMPtr<nsIFile> mFile;
nsString mPath;
nsString mStorageType;
bool mEditable;
DeviceStorageFile(const nsAString& aStorageType, nsIFile* aFile, const nsAString& aPath);
DeviceStorageFile(const nsAString& aStorageType, nsIFile* aFile);
void SetPath(const nsAString& aPath);
void SetEditable(bool aEditable);
NS_DECL_ISUPPORTS
// we want to make sure that the names of file can't reach
// outside of the type of storage the user asked for.
bool IsSafePath();
nsresult Remove();
nsresult Write(nsIInputStream* aInputStream);
nsresult Write(InfallibleTArray<uint8_t>& bits);
void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince = 0);
void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince, nsAString& aRootPath);
static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar, const nsAString& aStorageType);
private:
void NormalizeFilePath();
void AppendRelativePath();
};
class ContinueCursorEvent MOZ_FINAL : public nsRunnable
{
public: