Compare commits

..

14 Commits
0.2.3 ... 0.2.5

Author SHA1 Message Date
Steven Gill
0d94289921 [CB-5565] Updated version and RELEASENOTES.md for release 0.2.5 2013-12-04 15:16:30 -08:00
James Long
3424ddb39c fix camera for firefox os 2013-12-03 13:10:25 -08:00
Piotr Zalewa
e8e420895e getPicture via web activities 2013-12-03 13:09:27 -08:00
Steven Gill
a6736cda71 added ubuntu support 2013-12-02 15:11:12 -08:00
Maxim Ermilov
885c6a7459 [ubuntu] specify policy_group 2013-11-11 17:59:22 +04:00
Archana Naik
d8a3d2ff3a 1. User Agent detection now detects AmazonWebView.
2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
2013-10-30 11:49:00 -07:00
Archana Naik
4590f2597c Added amazon-fireos platform. 2013-10-30 11:49:00 -07:00
Steven Gill
7c35f56a0d CB-5188: 2013-10-28 12:27:13 -07:00
Steven Gill
e0176cc61e [CB-5188] Updated version and RELEASENOTES.md for release 0.2.4 2013-10-28 10:58:16 -07:00
Maxim Ermilov
b44ea1c69f add ubuntu platform 2013-10-26 06:17:04 +04:00
hermwong
703f6c68d8 CB-5128: added repo + issue tag to plugin.xml for camera plugin 2013-10-21 15:33:45 -07:00
Shazron Abdullah
4e6cf5cc2e CB-4958 - iOS - Camera plugin should not show the status bar 2013-10-15 10:29:54 -07:00
hermwong
eab4822ae9 [CB-4919] updated plugin.xml for FxOS 2013-10-08 10:49:02 -07:00
Steven Gill
a600de41eb [CB-4915] Incremented plugin version on dev branch. 2013-09-25 18:34:12 -07:00
15 changed files with 495 additions and 32 deletions

View File

@@ -41,3 +41,17 @@
* CB-4633: We really should close cursors. It's just the right thing to do.
* No longer causes a stack trace, but it doesn't cause the error to be called.
* CB-4889 renaming org.apache.cordova.core.camera to org.apache.cordova.camera
### 0.2.4 (Oct 28, 2013)
* CB-5128: added repo + issue tag to plugin.xml for camera plugin
* CB-4958 - iOS - Camera plugin should not show the status bar
* [CB-4919] updated plugin.xml for FxOS
* [CB-4915] Incremented plugin version on dev branch.
### 0.2.5 (Dec 4, 2013)
* fix camera for firefox os
* getPicture via web activities
* [ubuntu] specify policy_group
* add ubuntu platform
* 1. User Agent detection now detects AmazonWebView. 2. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
* Added amazon-fireos platform.

View File

@@ -3,11 +3,13 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="org.apache.cordova.camera"
version="0.2.3">
version="0.2.5">
<name>Camera</name>
<description>Cordova Camera Plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,camera</keywords>
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git</repo>
<issue>https://issues.apache.org/jira/browse/CB/component/12320645</issue>
<js-module src="www/CameraConstants.js" name="Camera">
<clobbers target="Camera" />
@@ -23,6 +25,18 @@
<clobbers target="navigator.camera" />
</js-module>
<!-- firefoxos -->
<platform name="firefoxos">
<config-file target="config.xml" parent="/*">
<feature name="Camera">
<param name="firefoxos-package" value="Camera" />
</feature>
</config-file>
<js-module src="src/firefoxos/camera.js" name="camera-impl">
<runs />
</js-module>
</platform>
<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
@@ -44,6 +58,48 @@
</platform>
<!-- amazon-fireos -->
<platform name="amazon-fireos">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Camera">
<param name="android-package" value="org.apache.cordova.camera.CameraLauncher"/>
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>
<source-file src="src/android/CameraLauncher.java" target-dir="src/org/apache/cordova/camera" />
<source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/camera" />
<source-file src="src/android/ExifHelper.java" target-dir="src/org/apache/cordova/camera" />
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
<clobbers target="CameraPopoverHandle" />
</js-module>
</platform>
<!-- ubuntu -->
<platform name="ubuntu">
<config-file target="config.xml" parent="/*">
<feature name="Camera">
<param policy_group="camera" policy_version="1" />
</feature>
</config-file>
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
<clobbers target="CameraPopoverHandle" />
</js-module>
<header-file src="src/ubuntu/camera.h" />
<source-file src="src/ubuntu/camera.cpp" />
<resource-file src="src/ubuntu/back.png" />
<resource-file src="src/ubuntu/CaptureWidget.qml" />
<resource-file src="src/ubuntu/shoot.png" />
<resource-file src="src/ubuntu/toolbar-left.png" />
<resource-file src="src/ubuntu/toolbar-middle.png" />
<resource-file src="src/ubuntu/toolbar-right.png" />
</platform>
<!-- ios -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
@@ -144,7 +200,10 @@
<feature name="Camera">
<param name="firefoxos-package" value="Camera" />
</feature>
</config-file>
</config-file>
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
<clobbers target="CameraPopoverHandle" />
</js-module>
<js-module src="src/firefoxos/CameraProxy.js" name="CameraProxy">
<runs />
</js-module>

View File

@@ -17,36 +17,35 @@
* specific language governing permissions and limitations
* under the License.
*
*/
*/
function takePicture(success, error, opts) {
var pick = new MozActivity({
name: "pick",
data: {
type: ["image/*"]
}
});
pick.onerror = error || function() {};
function getPicture(cameraSuccess, cameraError, cameraOptions) {
cameraError = cameraError || function(){};
var pick = new MozActivity({
name: "pick",
data: {
type: ["image/png", "image/jpg", "image/jpeg"]
}
});
pick.onerror = cameraError;
pick.onsuccess = function() {
// image is returned as Blob in this.result.blob
// we need to call cameraSuccess with url or base64 encoded image
if (cameraOptions && cameraOptions.destinationType == 0) {
// TODO: base64
return;
}
if (!cameraOptions || !cameraOptions.destinationType || cameraOptions.destinationType > 0) {
// url
return cameraSuccess(window.URL.createObjectURL(this.result.blob));
}
};
pick.onsuccess = function() {
// image is returned as Blob in this.result.blob
// we need to call success with url or base64 encoded image
if (opts && opts.destinationType == 0) {
// TODO: base64
return;
}
if (!opts || !opts.destinationType || opts.destinationType > 0) {
// url
return success(window.URL.createObjectURL(this.result.blob));
}
};
}
module.exports = {
getPicture: getPicture,
cleanup: function(){}
takePicture: takePicture,
cleanup: function(){}
};
require("cordova/firefoxos/commandProxy").add("Camera", module.exports);
require("cordova/firefoxos/commandProxy").add("Camera", module.exports);

32
src/firefoxos/camera.js Normal file
View File

@@ -0,0 +1,32 @@
var firefoxos = require('cordova/platform');
function getPicture(cameraSuccess, cameraError, cameraOptions) {
cameraError = cameraError || function(){};
var pick = new MozActivity({
name: "pick",
data: {
type: ["image/png", "image/jpg", "image/jpeg"]
}
});
pick.onerror = cameraError;
pick.onsuccess = function() {
// image is returned as Blob in this.result.blob
// we need to call cameraSuccess with url or base64 encoded image
if (cameraOptions && cameraOptions.destinationType == 0) {
// TODO: base64
return;
}
if (!cameraOptions || !cameraOptions.destinationTyoe || cameraOptions.destinationType > 0) {
// url
return cameraSuccess(window.URL.createObjectURL(this.result.blob));
}
};
}
var Camera = {
takePicture: getPicture,
cleanup: function(){}
};
firefoxos.registerPlugin('Camera', Camera);

View File

@@ -736,4 +736,21 @@ static NSSet* org_apache_cordova_validArrowDirections;
@synthesize webView;
@synthesize popoverSupported;
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (UIViewController*)childViewControllerForStatusBarHidden {
return nil;
}
- (void)viewWillAppear:(BOOL)animated {
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
if ([self respondsToSelector:sel]) {
[self performSelector:sel withObject:nil afterDelay:0];
}
[super viewWillAppear:animated];
}
@end

View File

@@ -0,0 +1,119 @@
/*
*
* Copyright 2013 Canonical Ltd.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
*/
import QtQuick 2.0
import QtMultimedia 5.0
Rectangle {
property string shootImagePath: "shoot.png"
function isSuffix(str, suffix) {
return String(str).substr(String(str).length - suffix.length) == suffix
}
id: ui
color: "#252423"
anchors.fill: parent
Camera {
objectName: "camera"
id: camera
onError: {
console.log(errorString);
}
videoRecorder.audioBitRate: 128000
videoRecorder.mediaContainer: "mp4"
imageCapture {
onImageSaved: {
root.exec("Camera", "onImageSaved", [path]);
ui.destroy();
}
}
}
VideoOutput {
id: output
source: camera
width: parent.width
height: parent.height
}
Item {
anchors.bottom: parent.bottom
width: parent.width
height: shootButton.height
BorderImage {
id: leftBackground
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: middle.left
anchors.topMargin: units.dp(2)
anchors.bottomMargin: units.dp(2)
source: "toolbar-left.png"
Image {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: parent.iconSpacing
source: "back.png"
width: units.gu(6)
height: units.gu(5)
MouseArea {
anchors.fill: parent
onClicked: {
root.exec("Camera", "cancel");
}
}
}
}
BorderImage {
id: middle
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: shootButton.height + units.gu(1)
width: shootButton.width
source: "toolbar-middle.png"
Image {
id: shootButton
width: units.gu(8)
height: width
anchors.horizontalCenter: parent.horizontalCenter
source: shootImagePath
MouseArea {
anchors.fill: parent
onClicked: {
camera.imageCapture.capture();
}
}
}
}
BorderImage {
id: rightBackground
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: middle.right
anchors.topMargin: units.dp(2)
anchors.bottomMargin: units.dp(2)
source: "toolbar-right.png"
}
}
}

BIN
src/ubuntu/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

143
src/ubuntu/camera.cpp Normal file
View File

@@ -0,0 +1,143 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 "camera.h"
#include <cordova.h>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QGraphicsObject>
#include <QCloseEvent>
#include <QQuickItem>
const char code[] = "\
var component, object; \
function createObject() { \
component = Qt.createComponent(%1); \
if (component.status == Component.Ready) \
finishCreation(); \
else \
component.statusChanged.connect(finishCreation); \
} \
function finishCreation() { \
CordovaWrapper.object = component.createObject(root, \
{root: root, cordova: cordova}); \
} \
createObject()";
Camera::Camera(Cordova *cordova):
CPlugin(cordova),
_lastScId(0),
_lastEcId(0) {
}
bool Camera::preprocessImage(QString &path) {
bool convertToPNG = (*_options.find("encodingType")).toInt() == Camera::PNG;
int quality = (*_options.find("quality")).toInt();
int width = (*_options.find("targetWidth")).toInt();
int height = (*_options.find("targetHeight")).toInt();
QImage image(path);
if (width <= 0)
width = image.width();
if (height <= 0)
height = image.height();
image = image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QFile oldImage(path);
QTemporaryFile newImage;
const char *type;
if (convertToPNG) {
newImage.setFileTemplate("imgXXXXXX.png");
type = "png";
} else {
newImage.setFileTemplate("imgXXXXXX.jpg");
type = "jpg";
}
newImage.open();
newImage.setAutoRemove(false);
image.save(newImage.fileName(), type, quality);
path = newImage.fileName();
oldImage.remove();
return true;
}
void Camera::onImageSaved(QString path) {
bool dataURL = _options.find("destinationType")->toInt() == Camera::DATA_URL;
QString cbParams;
if (preprocessImage(path)) {
QString absolutePath = QFileInfo(path).absoluteFilePath();
if (dataURL) {
QFile image(absolutePath);
image.open(QIODevice::ReadOnly);
QByteArray content = image.readAll().toBase64();
cbParams = QString("\"%1\"").arg(content.data());
image.remove();
} else {
cbParams = CordovaInternal::format(QUrl::fromLocalFile(absolutePath).toString());
}
}
this->callback(_lastScId, cbParams);
_lastEcId = _lastScId = 0;
}
void Camera::takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType,
int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &/*popoverOptions*/, int/*cameraDirection*/) {
if (_camera.isNull()) {
_camera = QSharedPointer<QCamera>(new QCamera());
}
if (((_lastScId || _lastEcId) && (_lastScId != scId && _lastEcId != ecId)) || !_camera->isAvailable() || _camera->lockStatus() != QCamera::Unlocked) {
this->cb(_lastEcId, "Device is busy");
return;
}
_options.clear();
_options.insert("quality", quality);
_options.insert("destinationType", destinationType);
_options.insert("targetWidth", targetWidth);
_options.insert("targetHeight", targetHeight);
_options.insert("encodingType", encodingType);
_lastScId = scId;
_lastEcId = ecId;
QString path = m_cordova->get_app_dir() + "/../qml/CaptureWidget.qml";
// TODO: relative url
QString qml = QString(code).arg(CordovaInternal::format(path));
m_cordova->execQML(qml);
}
void Camera::cancel() {
m_cordova->execQML("CordovaWrapper.object.destroy()");
this->cb(_lastEcId, "canceled");
_lastEcId = _lastScId = 0;
}

76
src/ubuntu/camera.h Normal file
View File

@@ -0,0 +1,76 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 CAMERA_H
#define CAMERA_H
#include <cplugin.h>
#include <QtCore>
#include <QQuickView>
#include <QCamera>
#include <QtMultimediaWidgets/QCameraViewfinder>
#include <QCameraImageCapture>
class Camera: public CPlugin {
Q_OBJECT
public:
explicit Camera(Cordova *cordova);
virtual const QString fullName() override {
return Camera::fullID();
}
virtual const QString shortName() override {
return "Camera";
}
static const QString fullID() {
return "Camera";
}
public slots:
void takePicture(int scId, int ecId, int quality, int destinationType, int/*sourceType*/, int targetWidth, int targetHeight, int encodingType,
int/*mediaType*/, bool/*allowEdit*/, bool/*correctOrientation*/, bool/*saveToPhotoAlbum*/, const QVariantMap &popoverOptions, int cameraDirection);
void cancel();
void onImageSaved(QString path);
private:
bool preprocessImage(QString &path);
int _lastScId;
int _lastEcId;
QSharedPointer<QCamera> _camera;
QVariantMap _options;
protected:
enum DestinationType {
DATA_URL = 0,
FILE_URI = 1
};
enum EncodingType {
JPEG = 0,
PNG = 1
};
};
#endif // CAMERA_H

BIN
src/ubuntu/shoot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/ubuntu/toolbar-left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -20,7 +20,9 @@
*/
var PLAT;
if (/Android/.exec(navigator.userAgent)) {
if (/cordova-amazon-fireos/.exec(navigator.userAgent)) {
PLAT = 'amazon-fireos';
}else if (/Android/.exec(navigator.userAgent)) {
PLAT = 'android';
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
PLAT = 'ios';
@@ -61,7 +63,7 @@ if (!window._doNotWriteCordovaScript) {
}
function backHome() {
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
if (window.device && device.platform && (device.platform.toLowerCase() == 'android' || device.platform.toLowerCase() == 'amazon-fireos')) {
navigator.app.backHistory();
}
else {

View File

@@ -21,8 +21,9 @@
var argscheck = require('cordova/argscheck'),
exec = require('cordova/exec'),
Camera = require('./Camera'),
CameraPopoverHandle = require('./CameraPopoverHandle');
Camera = require('./Camera');
// XXX: commented out
//CameraPopoverHandle = require('./CameraPopoverHandle');
var cameraExport = {};
@@ -63,7 +64,8 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
exec(successCallback, errorCallback, "Camera", "takePicture", args);
return new CameraPopoverHandle();
// XXX: commented out
//return new CameraPopoverHandle();
};
cameraExport.cleanup = function(successCallback, errorCallback) {