Bug 819835 - add support for setting the EXIF DateTime field, r=sotaro

This commit is contained in:
Mike Habicher 2013-01-18 16:06:28 -05:00
Родитель a1d14d0e97
Коммит 3fb12b17e4
6 изменённых файлов: 36 добавлений и 7 удалений

Просмотреть файл

@ -333,7 +333,7 @@ CameraControlImpl::AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErr
}
nsresult
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
{
MOZ_ASSERT(NS_IsMainThread());
bool cancel = false;
@ -349,7 +349,7 @@ CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAStr
cancel = true;
}
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, cancel, aSize, aRotation, aFileFormat, aPosition, onSuccess, onError);
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, cancel, aSize, aRotation, aFileFormat, aPosition, aDateTime, onSuccess, onError);
return mCameraThread->Dispatch(takePictureTask, NS_DISPATCH_NORMAL);
}

Просмотреть файл

@ -52,7 +52,7 @@ public:
nsresult StartPreview(DOMCameraPreview* aDOMPreview);
void StopPreview();
nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult StartRecording(dom::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
nsresult StopRecording();
nsresult GetPreviewStreamVideoMode(dom::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError);
@ -361,13 +361,14 @@ protected:
class TakePictureTask : public nsRunnable
{
public:
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mCancel(aCancel)
, mSize(aSize)
, mRotation(aRotation)
, mFileFormat(aFileFormat)
, mPosition(aPosition)
, mDateTime(aDateTime)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraTakePictureCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{
@ -399,6 +400,7 @@ public:
int32_t mRotation;
nsString mFileFormat;
dom::CameraPosition mPosition;
uint64_t mDateTime;
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};

Просмотреть файл

@ -357,7 +357,7 @@ nsDOMCameraControl::TakePicture(const JS::Value& aOptions, nsICameraTakePictureC
rv = pos.Init(cx, &options.position);
NS_ENSURE_SUCCESS(rv, rv);
return mCameraControl->TakePicture(size, options.rotation, options.fileFormat, pos, onSuccess, onError);
return mCameraControl->TakePicture(size, options.rotation, options.fileFormat, pos, options.dateTime, onSuccess, onError);
}
/* [implicit_jscontext] void GetPreviewStreamVideoMode (in jsval aOptions, in nsICameraPreviewStreamCallback onSuccess, [optional] in nsICameraErrorCallback onError); */

Просмотреть файл

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <time.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -797,6 +798,28 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
SetParameter(CameraParameters::KEY_GPS_TIMESTAMP, nsPrintfCString("%lf", aTakePicture->mPosition.timestamp).get());
}
// Add the non-GPS timestamp. The EXIF date/time field is formatted as
// "YYYY:MM:DD HH:MM:SS", without room for a time-zone; as such, the time
// 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) {
DOM_CAMERA_LOGE("picture date/time '%llu' is too far in the future\n", aTakePicture->mDateTime);
} else {
struct tm t;
if (localtime_r(&time, &t)) {
char dateTime[20];
if (strftime(dateTime, sizeof(dateTime), "%Y:%m:%d %T", &t)) {
DOM_CAMERA_LOGI("setting picture date/time to %s\n", dateTime);
SetParameter(CameraParameters::KEY_EXIF_DATETIME, dateTime);
} else {
DOM_CAMERA_LOGE("picture date/time couldn't be converted to string\n");
}
} else {
DOM_CAMERA_LOGE("picture date/time couldn't be converted to local time: (%d) %s\n", errno, strerror(errno));
}
}
mDeferConfigUpdate = false;
PushParameters();

Просмотреть файл

@ -26,7 +26,7 @@ public:
virtual nsresult StartPreview(DOMCameraPreview* aDOMPreview) = 0;
virtual void StopPreview() = 0;
virtual nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult StartRecording(dom::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
virtual nsresult StopRecording() = 0;
virtual nsresult GetPreviewStreamVideoMode(dom::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError) = 0;

Просмотреть файл

@ -150,6 +150,10 @@ dictionary CameraPictureOptions
January 1, 1970.
*/
jsval position;
/* the number of seconds from January 1, 1970 UTC. This can be
different from the positional timestamp (above). */
long long dateTime;
};
/* These properties affect the video recording preview, e.g.
@ -163,7 +167,7 @@ dictionary CameraPictureOptions
an arbitrary profile will be chosen.
'rotation' is the degrees clockwise to rotate the preview; if
this options is not supported, it will be ignored; if this option
this option is not supported, it will be ignored; if this option
is missing, the default is 0.
*/
dictionary CameraRecorderOptions