зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound a=merge
--HG-- extra : rebase_source : 243776ce01fcd38161dd94411e0bc1cbfb2f7cb2
This commit is contained in:
Коммит
b7ae2e9516
|
@ -33,6 +33,9 @@ Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Screenshot",
|
||||
"resource://gre/modules/Screenshot.jsm");
|
||||
|
||||
Cu.import('resource://gre/modules/Webapps.jsm');
|
||||
DOMApplicationRegistry.allAppsLaunchable = true;
|
||||
|
||||
|
@ -827,30 +830,9 @@ window.addEventListener('ContentStart', function ss_onContentStart() {
|
|||
return;
|
||||
|
||||
try {
|
||||
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml',
|
||||
'canvas');
|
||||
var docRect = document.body.getBoundingClientRect();
|
||||
var width = docRect.width;
|
||||
var height = docRect.height;
|
||||
|
||||
// Convert width and height from CSS pixels (potentially fractional)
|
||||
// to device pixels (integer).
|
||||
var scale = window.devicePixelRatio;
|
||||
canvas.setAttribute('width', Math.round(width * scale));
|
||||
canvas.setAttribute('height', Math.round(height * scale));
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
var flags =
|
||||
context.DRAWWINDOW_DRAW_CARET |
|
||||
context.DRAWWINDOW_DRAW_VIEW |
|
||||
context.DRAWWINDOW_USE_WIDGET_LAYERS;
|
||||
context.scale(scale, scale);
|
||||
context.drawWindow(window, 0, 0, width, height,
|
||||
'rgb(255,255,255)', flags);
|
||||
|
||||
shell.sendChromeEvent({
|
||||
type: 'take-screenshot-success',
|
||||
file: canvas.mozGetAsFile('screenshot', 'image/png')
|
||||
file: Screenshot.get()
|
||||
});
|
||||
} catch (e) {
|
||||
dump('exception while creating screenshot: ' + e + '\n');
|
||||
|
|
|
@ -13,6 +13,7 @@ const Cc = Components.classes;
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Screenshot", "resource://gre/modules/Screenshot.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["LogCapture"];
|
||||
|
||||
|
@ -185,6 +186,26 @@ let LogCapture = {
|
|||
deferred.resolve(file);
|
||||
}, null, false);
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Dumping screenshot, returning a Promise. Will be resolved with the content
|
||||
* as an ArrayBuffer.
|
||||
*/
|
||||
getScreenshot: function() {
|
||||
this.ensureLoaded();
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let fr = Cc["@mozilla.org/files/filereader;1"]
|
||||
.createInstance(Ci.nsIDOMFileReader);
|
||||
|
||||
fr.onload = function(evt) {
|
||||
deferred.resolve(new Uint8Array(evt.target.result));
|
||||
};
|
||||
|
||||
fr.readAsArrayBuffer(Screenshot.get());
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -240,6 +240,14 @@ let LogShake = {
|
|||
Cu.reportError("Unable to get about:memory dump: " + ex);
|
||||
}
|
||||
|
||||
try {
|
||||
LogCapture.getScreenshot().then(screenshot => {
|
||||
logArrays["logshake-screenshot.png"] = screenshot;
|
||||
});
|
||||
} catch (ex) {
|
||||
Cu.reportError("Unable to get screenshot dump: " + ex);
|
||||
}
|
||||
|
||||
for (let loc in this.LOGS_WITH_PARSERS) {
|
||||
let logArray;
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['Screenshot'];
|
||||
|
||||
let Screenshot = {
|
||||
get: function screenshot_get() {
|
||||
let systemAppFrame = SystemAppProxy.getFrame();
|
||||
let window = systemAppFrame.contentWindow;
|
||||
let document = window.document;
|
||||
|
||||
var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
|
||||
var docRect = document.body.getBoundingClientRect();
|
||||
var width = docRect.width;
|
||||
var height = docRect.height;
|
||||
|
||||
// Convert width and height from CSS pixels (potentially fractional)
|
||||
// to device pixels (integer).
|
||||
var scale = window.devicePixelRatio;
|
||||
canvas.setAttribute('width', Math.round(width * scale));
|
||||
canvas.setAttribute('height', Math.round(height * scale));
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
var flags =
|
||||
context.DRAWWINDOW_DRAW_CARET |
|
||||
context.DRAWWINDOW_DRAW_VIEW |
|
||||
context.DRAWWINDOW_USE_WIDGET_LAYERS;
|
||||
context.scale(scale, scale);
|
||||
context.drawWindow(window, 0, 0, width, height, 'rgb(255,255,255)', flags);
|
||||
|
||||
return canvas.mozGetAsFile('screenshot', 'image/png');
|
||||
}
|
||||
};
|
||||
this.Screenshot = Screenshot;
|
|
@ -29,6 +29,11 @@ let SystemAppProxy = {
|
|||
this._pendingListeners = [];
|
||||
},
|
||||
|
||||
// Get the system app frame
|
||||
getFrame: function () {
|
||||
return this._frame;
|
||||
},
|
||||
|
||||
// To call when it is ready to receive events
|
||||
setIsReady: function () {
|
||||
if (this._isReady) {
|
||||
|
|
|
@ -60,6 +60,7 @@ EXTRA_JS_MODULES += [
|
|||
'LogParser.jsm',
|
||||
'LogShake.jsm',
|
||||
'OrientationChangeHandler.jsm',
|
||||
'Screenshot.jsm',
|
||||
'SignInToWebsite.jsm',
|
||||
'SystemAppProxy.jsm',
|
||||
'TelURIParser.jsm',
|
||||
|
|
|
@ -4,6 +4,7 @@ support-files =
|
|||
permission_handler_chrome.js
|
||||
SandboxPromptTest.html
|
||||
filepicker_path_handler_chrome.js
|
||||
screenshot_helper.js
|
||||
systemapp_helper.js
|
||||
presentation_prompt_handler_chrome.js
|
||||
|
||||
|
@ -12,5 +13,6 @@ support-files =
|
|||
[test_permission_gum_remember.html]
|
||||
skip-if = true # Bug 1019572 - frequent timeouts
|
||||
[test_sandbox_permission.html]
|
||||
[test_screenshot.html]
|
||||
[test_systemapp.html]
|
||||
[test_presentation_device_prompt.html]
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Load a duplicated copy of the jsm to prevent messing with the currently running one
|
||||
let scope = {};
|
||||
Services.scriptloader.loadSubScript("resource://gre/modules/Screenshot.jsm", scope);
|
||||
const { Screenshot } = scope;
|
||||
|
||||
let index = -1;
|
||||
function next() {
|
||||
index++;
|
||||
if (index >= steps.length) {
|
||||
assert.ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
steps[index]();
|
||||
} catch(ex) {
|
||||
assert.ok(false, "Caught exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
let steps = [
|
||||
function getScreenshot() {
|
||||
let screenshot = Screenshot.get();
|
||||
assert.ok(screenshot instanceof Ci.nsIDOMFile,
|
||||
"Screenshot.get() returns a File");
|
||||
next();
|
||||
},
|
||||
|
||||
function endOfTest() {
|
||||
sendAsyncMessage("finish");
|
||||
}
|
||||
];
|
||||
|
||||
next();
|
|
@ -113,6 +113,9 @@ let steps = [
|
|||
SystemAppProxy.setIsReady();
|
||||
assert.ok(true, "Frame declared as loaded");
|
||||
|
||||
let gotFrame = SystemAppProxy.getFrame();
|
||||
assert.equal(gotFrame, frame, "getFrame returns the frame we passed");
|
||||
|
||||
// Once pending events are received,
|
||||
// we will run checkEventDispatching from `listener` function
|
||||
});
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1136784
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Screenshot Test</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1136784">Screenshot.jsm</a>
|
||||
<script type="application/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
var gUrl = SimpleTest.getTestFileURL("screenshot_helper.js");
|
||||
var gScript = SpecialPowers.loadChromeScript(gUrl);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
gScript.addMessageListener("finish", function () {
|
||||
SimpleTest.ok(true, "chrome test script finished");
|
||||
gScript.destroy();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -45,7 +45,6 @@ add_test(function test_readAppIni() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
|
||||
add_test(function test_get_about_memory() {
|
||||
let memLog = LogCapture.readAboutMemory();
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
<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="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="97c3d9b8b87774ca7a08c89145e95b55652459ef"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
<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="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="97c3d9b8b87774ca7a08c89145e95b55652459ef"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "2b87ee8e7e2ec30a9851b6b59a899006a98767ab",
|
||||
"git_revision": "0c4e8b0b330757e261b031b7e7f326ef419c9808",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "a3f060d46f5e179164fe9435f30878ebdf58eb49",
|
||||
"revision": "f8a8e3a65150eaf7a870a4e75ad6bbea833390ee",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ddf33f81e9a60f8110fcfd6b51b5dff2db676183"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="2b87ee8e7e2ec30a9851b6b59a899006a98767ab"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0c4e8b0b330757e261b031b7e7f326ef419c9808"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c82a532ee1f14b9733214022b1e2d55a0b030be8"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
|
|
@ -95,29 +95,43 @@ BluetoothInterface*
|
|||
BluetoothInterface::GetInstance()
|
||||
{
|
||||
#if ANDROID_VERSION >= 17
|
||||
/* We pick a default backend from the available ones. The branches
|
||||
* are ordered by preference.
|
||||
/* We pick a default backend from the available ones. The options are
|
||||
* ordered by preference. If a backend is supported but not available
|
||||
* on the current system, we pick the next one. The selected default
|
||||
* can be overriden manually by storing the respective string in the
|
||||
* system property 'ro.moz.bluetooth.backend'.
|
||||
*/
|
||||
#ifdef MOZ_B2G_BT_BLUEDROID
|
||||
static const char sDefaultBackend[] = "bluedroid";
|
||||
#else
|
||||
#ifdef MOZ_B2G_BT_DAEMON
|
||||
static const char sDefaultBackend[] = "bluetoothd";
|
||||
#else
|
||||
static const char* const sDefaultBackend = nullptr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Here's where we decide which implementation to use. Currently
|
||||
* there is only Bluedroid and the Bluetooth daemon, but others are
|
||||
* possible. Having multiple interfaces built-in and selecting the
|
||||
* correct one at runtime is also an option.
|
||||
*/
|
||||
static const char* const sDefaultBackend[] = {
|
||||
#ifdef MOZ_B2G_BT_DAEMON
|
||||
"bluetoothd",
|
||||
#endif
|
||||
#ifdef MOZ_B2G_BT_BLUEDROID
|
||||
"bluedroid",
|
||||
#endif
|
||||
nullptr // no default backend; must be final element in array
|
||||
};
|
||||
|
||||
const char* defaultBackend;
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDefaultBackend); ++i) {
|
||||
|
||||
/* select current backend */
|
||||
defaultBackend = sDefaultBackend[i];
|
||||
|
||||
if (defaultBackend) {
|
||||
if (!strcmp(defaultBackend, "bluetoothd") &&
|
||||
access("/init.bluetooth.rc", F_OK) == -1) {
|
||||
continue; /* bluetoothd not available */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
int len;
|
||||
|
||||
len = property_get("ro.moz.bluetooth.backend", value, sDefaultBackend);
|
||||
len = property_get("ro.moz.bluetooth.backend", value, defaultBackend);
|
||||
if (len < 0) {
|
||||
BT_WARNING("No Bluetooth backend available.");
|
||||
return nullptr;
|
||||
|
@ -125,6 +139,12 @@ BluetoothInterface::GetInstance()
|
|||
|
||||
const nsDependentCString backend(value, len);
|
||||
|
||||
/* Here's where we decide which implementation to use. Currently
|
||||
* there is only Bluedroid and the Bluetooth daemon, but others are
|
||||
* possible. Having multiple interfaces built-in and selecting the
|
||||
* correct one at runtime is also an option.
|
||||
*/
|
||||
|
||||
#ifdef MOZ_B2G_BT_BLUEDROID
|
||||
if (backend.LowerCaseEqualsLiteral("bluedroid")) {
|
||||
return BluetoothHALInterface::GetInstance();
|
||||
|
|
|
@ -31,6 +31,8 @@ uint32_t CameraPreferences::sPrefCameraControlLowMemoryThresholdMB = 0;
|
|||
|
||||
bool CameraPreferences::sPrefCameraParametersIsLowMemory = false;
|
||||
|
||||
bool CameraPreferences::sPrefCameraParametersPermission = false;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
StaticRefPtr<CameraPreferences> CameraPreferences::sObserver;
|
||||
|
||||
|
@ -113,6 +115,11 @@ CameraPreferences::Pref CameraPreferences::sPrefs[] = {
|
|||
kPrefValueIsCString,
|
||||
{ &sPrefHardwareTest }
|
||||
},
|
||||
{
|
||||
"camera.control.test.permission",
|
||||
kPrefValueIsBoolean,
|
||||
{ &sPrefCameraParametersPermission }
|
||||
},
|
||||
#ifdef MOZ_B2G
|
||||
{
|
||||
"camera.control.test.hardware.gonk.parameters",
|
||||
|
|
|
@ -80,6 +80,8 @@ protected:
|
|||
|
||||
static bool sPrefCameraParametersIsLowMemory;
|
||||
|
||||
static bool sPrefCameraParametersPermission;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
static StaticRefPtr<CameraPreferences> sObserver;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "DOMCameraControl.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "CameraPreferences.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
|
||||
|
@ -298,7 +299,11 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
|||
// which gets us a performance win.
|
||||
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
principal->GetAppStatus(&status);
|
||||
if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
|
||||
// Unprivileged mochitests always fail the dispatched permission check,
|
||||
// even if permission to the camera has been granted.
|
||||
bool immediateCheck = false;
|
||||
CameraPreferences::GetPref("camera.control.test.permission", immediateCheck);
|
||||
if ((status == nsIPrincipal::APP_STATUS_CERTIFIED || immediateCheck) && CheckPermission(mWindow)) {
|
||||
PermissionAllowed(cameraId, aInitialConfig, promise);
|
||||
return promise.forget();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2015 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 "FallbackCameraPlatform.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
MediaProfiles* MediaProfiles::sMediaProfiles = nullptr;
|
||||
|
||||
const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
|
||||
const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
|
||||
const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
|
||||
const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
|
||||
const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
|
||||
const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
|
||||
const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
|
||||
const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
|
||||
const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
|
||||
const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
|
||||
const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
|
||||
const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
|
||||
const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
|
||||
const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
|
||||
const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
|
||||
const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
|
||||
const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
|
||||
const char CameraParameters::KEY_ROTATION[] = "rotation";
|
||||
const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
|
||||
const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
|
||||
const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
|
||||
const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
|
||||
const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
|
||||
const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
|
||||
const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
|
||||
const char CameraParameters::KEY_EFFECT[] = "effect";
|
||||
const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
|
||||
const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
|
||||
const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
|
||||
const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
|
||||
const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
|
||||
const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
|
||||
const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
|
||||
const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
|
||||
const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
|
||||
const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
|
||||
const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
|
||||
const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
|
||||
const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
|
||||
const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
|
||||
const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
|
||||
const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
|
||||
const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
|
||||
const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
|
||||
const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
|
||||
const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
|
||||
const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
|
||||
const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported";
|
||||
const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
|
||||
const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
|
||||
const char CameraParameters::KEY_ZOOM[] = "zoom";
|
||||
const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
|
||||
const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
|
||||
const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
|
||||
const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
|
||||
const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
|
||||
const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
|
||||
const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
|
||||
const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
|
||||
const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
|
||||
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
|
||||
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
|
||||
const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
|
||||
const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
|
||||
const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
|
||||
const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
|
||||
const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2015 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_FALLBACKCAMERAPLATFORM_H
|
||||
#define DOM_CAMERA_FALLBACKCAMERAPLATFORM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int32_t id;
|
||||
int32_t score;
|
||||
int32_t rect[4];
|
||||
int32_t left_eye[2];
|
||||
int32_t right_eye[2];
|
||||
int32_t mouth[2];
|
||||
} camera_face_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t number_of_faces;
|
||||
camera_face_t* faces;
|
||||
} camera_frame_metadata_t;
|
||||
|
||||
namespace android {
|
||||
enum camcorder_quality {
|
||||
CAMCORDER_QUALITY_LOW,
|
||||
CAMCORDER_QUALITY_HIGH,
|
||||
CAMCORDER_QUALITY_QCIF,
|
||||
CAMCORDER_QUALITY_CIF,
|
||||
CAMCORDER_QUALITY_480P,
|
||||
CAMCORDER_QUALITY_720P,
|
||||
CAMCORDER_QUALITY_1080P,
|
||||
CAMCORDER_QUALITY_QVGA,
|
||||
CAMCORDER_QUALITY_VGA,
|
||||
CAMCORDER_QUALITY_LIST_START = CAMCORDER_QUALITY_LOW,
|
||||
CAMCORDER_QUALITY_LIST_END = CAMCORDER_QUALITY_VGA
|
||||
};
|
||||
|
||||
enum output_format {
|
||||
OUTPUT_FORMAT_THREE_GPP,
|
||||
OUTPUT_FORMAT_MPEG_4
|
||||
};
|
||||
|
||||
enum video_encoder {
|
||||
VIDEO_ENCODER_H263,
|
||||
VIDEO_ENCODER_H264,
|
||||
VIDEO_ENCODER_MPEG_4_SP
|
||||
};
|
||||
|
||||
enum audio_encoder {
|
||||
AUDIO_ENCODER_AMR_WB,
|
||||
AUDIO_ENCODER_AMR_NB,
|
||||
AUDIO_ENCODER_AAC
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class sp MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
sp()
|
||||
: mPtr(nullptr)
|
||||
{ }
|
||||
|
||||
sp(T *aPtr)
|
||||
: mPtr(aPtr)
|
||||
{ }
|
||||
|
||||
virtual ~sp() { }
|
||||
T* get() const { return mPtr; }
|
||||
void clear() { mPtr = nullptr; }
|
||||
T* operator->() const { return get(); }
|
||||
|
||||
private:
|
||||
nsRefPtr<T> mPtr;
|
||||
};
|
||||
|
||||
typedef uint64_t nsecs_t;
|
||||
|
||||
enum error_t {
|
||||
OK = 0,
|
||||
UNKNOWN_ERROR,
|
||||
INVALID_OPERATION
|
||||
};
|
||||
|
||||
enum camera_msg_t {
|
||||
CAMERA_MSG_SHUTTER,
|
||||
CAMERA_MSG_COMPRESSED_IMAGE
|
||||
};
|
||||
|
||||
class String8 MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
String8() { }
|
||||
String8(const char* aData) { mData.AssignASCII(aData); }
|
||||
virtual ~String8() { }
|
||||
const char* string() const { return mData.Data(); }
|
||||
|
||||
private:
|
||||
nsCString mData;
|
||||
};
|
||||
|
||||
enum camera_facing_t {
|
||||
CAMERA_FACING_BACK,
|
||||
CAMERA_FACING_FRONT
|
||||
};
|
||||
|
||||
struct CameraInfo {
|
||||
camera_facing_t facing;
|
||||
};
|
||||
|
||||
class Camera MOZ_FINAL : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS;
|
||||
|
||||
void disconnect() { }
|
||||
String8 getParameters() { return String8(); }
|
||||
int setParameters(const String8& aParams) { return UNKNOWN_ERROR; }
|
||||
int storeMetaDataInBuffers(bool aEnabled) { return UNKNOWN_ERROR; }
|
||||
int autoFocus() { return UNKNOWN_ERROR; }
|
||||
int cancelAutoFocus() { return UNKNOWN_ERROR; }
|
||||
int takePicture(uint32_t flags) { return UNKNOWN_ERROR; }
|
||||
int startPreview() { return UNKNOWN_ERROR; }
|
||||
int stopPreview() { return UNKNOWN_ERROR; }
|
||||
int startRecording() { return UNKNOWN_ERROR; }
|
||||
int stopRecording() { return UNKNOWN_ERROR; }
|
||||
int startFaceDetection() { return UNKNOWN_ERROR; }
|
||||
int stopFaceDetection() { return UNKNOWN_ERROR; }
|
||||
static int32_t getNumberOfCameras() { return 2; }
|
||||
|
||||
static int getCameraInfo(int32_t aDevice, CameraInfo* aInfo)
|
||||
{
|
||||
switch (aDevice) {
|
||||
case 0:
|
||||
aInfo->facing = CAMERA_FACING_BACK;
|
||||
break;
|
||||
case 1:
|
||||
aInfo->facing = CAMERA_FACING_FRONT;
|
||||
break;
|
||||
default:
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
Camera() { }
|
||||
virtual ~Camera() { }
|
||||
|
||||
private:
|
||||
Camera(const Camera&) = delete;
|
||||
Camera& operator=(const Camera&) = delete;
|
||||
};
|
||||
|
||||
class CameraParameters MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
static const char KEY_PREVIEW_SIZE[];
|
||||
static const char KEY_SUPPORTED_PREVIEW_SIZES[];
|
||||
static const char KEY_PREVIEW_FPS_RANGE[];
|
||||
static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
|
||||
static const char KEY_PREVIEW_FORMAT[];
|
||||
static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
|
||||
static const char KEY_PREVIEW_FRAME_RATE[];
|
||||
static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
|
||||
static const char KEY_PICTURE_SIZE[];
|
||||
static const char KEY_SUPPORTED_PICTURE_SIZES[];
|
||||
static const char KEY_PICTURE_FORMAT[];
|
||||
static const char KEY_SUPPORTED_PICTURE_FORMATS[];
|
||||
static const char KEY_JPEG_THUMBNAIL_WIDTH[];
|
||||
static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
|
||||
static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
|
||||
static const char KEY_JPEG_THUMBNAIL_QUALITY[];
|
||||
static const char KEY_JPEG_QUALITY[];
|
||||
static const char KEY_ROTATION[];
|
||||
static const char KEY_GPS_LATITUDE[];
|
||||
static const char KEY_GPS_LONGITUDE[];
|
||||
static const char KEY_GPS_ALTITUDE[];
|
||||
static const char KEY_GPS_TIMESTAMP[];
|
||||
static const char KEY_GPS_PROCESSING_METHOD[];
|
||||
static const char KEY_WHITE_BALANCE[];
|
||||
static const char KEY_SUPPORTED_WHITE_BALANCE[];
|
||||
static const char KEY_EFFECT[];
|
||||
static const char KEY_SUPPORTED_EFFECTS[];
|
||||
static const char KEY_ANTIBANDING[];
|
||||
static const char KEY_SUPPORTED_ANTIBANDING[];
|
||||
static const char KEY_SCENE_MODE[];
|
||||
static const char KEY_SUPPORTED_SCENE_MODES[];
|
||||
static const char KEY_FLASH_MODE[];
|
||||
static const char KEY_SUPPORTED_FLASH_MODES[];
|
||||
static const char KEY_FOCUS_MODE[];
|
||||
static const char KEY_SUPPORTED_FOCUS_MODES[];
|
||||
static const char KEY_MAX_NUM_FOCUS_AREAS[];
|
||||
static const char KEY_FOCUS_AREAS[];
|
||||
static const char KEY_FOCAL_LENGTH[];
|
||||
static const char KEY_HORIZONTAL_VIEW_ANGLE[];
|
||||
static const char KEY_VERTICAL_VIEW_ANGLE[];
|
||||
static const char KEY_EXPOSURE_COMPENSATION[];
|
||||
static const char KEY_MAX_EXPOSURE_COMPENSATION[];
|
||||
static const char KEY_MIN_EXPOSURE_COMPENSATION[];
|
||||
static const char KEY_EXPOSURE_COMPENSATION_STEP[];
|
||||
static const char KEY_AUTO_EXPOSURE_LOCK[];
|
||||
static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
|
||||
static const char KEY_AUTO_WHITEBALANCE_LOCK[];
|
||||
static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
|
||||
static const char KEY_MAX_NUM_METERING_AREAS[];
|
||||
static const char KEY_METERING_AREAS[];
|
||||
static const char KEY_ZOOM[];
|
||||
static const char KEY_MAX_ZOOM[];
|
||||
static const char KEY_ZOOM_RATIOS[];
|
||||
static const char KEY_ZOOM_SUPPORTED[];
|
||||
static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
|
||||
static const char KEY_FOCUS_DISTANCES[];
|
||||
static const char KEY_VIDEO_SIZE[];
|
||||
static const char KEY_SUPPORTED_VIDEO_SIZES[];
|
||||
static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
|
||||
static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
|
||||
static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
|
||||
static const char KEY_VIDEO_FRAME_FORMAT[];
|
||||
static const char KEY_RECORDING_HINT[];
|
||||
static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
|
||||
static const char KEY_VIDEO_STABILIZATION[];
|
||||
static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
|
||||
static const char KEY_LIGHTFX[];
|
||||
};
|
||||
|
||||
class MediaProfiles MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
static MediaProfiles* getInstance() {
|
||||
if (!sMediaProfiles) {
|
||||
sMediaProfiles = new MediaProfiles();
|
||||
}
|
||||
return sMediaProfiles;
|
||||
}
|
||||
|
||||
bool hasCamcorderProfile(int aCameraId, camcorder_quality aQuality) const {
|
||||
switch (aQuality) {
|
||||
case CAMCORDER_QUALITY_LOW:
|
||||
case CAMCORDER_QUALITY_HIGH:
|
||||
case CAMCORDER_QUALITY_QVGA:
|
||||
case CAMCORDER_QUALITY_VGA:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int getCamcorderProfileParamByName(const char* aParameter, int aCameraId, camcorder_quality aQuality) const {
|
||||
switch (aQuality) {
|
||||
case CAMCORDER_QUALITY_LOW:
|
||||
case CAMCORDER_QUALITY_QVGA:
|
||||
if (strcmp(aParameter, "vid.width") == 0) {
|
||||
return 320;
|
||||
} else if (strcmp(aParameter, "vid.height") == 0) {
|
||||
return 240;
|
||||
}
|
||||
return 0;
|
||||
case CAMCORDER_QUALITY_HIGH:
|
||||
case CAMCORDER_QUALITY_VGA:
|
||||
if (strcmp(aParameter, "vid.width") == 0) {
|
||||
return 640;
|
||||
} else if (strcmp(aParameter, "vid.height") == 0) {
|
||||
return 480;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
MediaProfiles() { }
|
||||
virtual ~MediaProfiles() { }
|
||||
|
||||
private:
|
||||
MediaProfiles(const MediaProfiles&) = delete;
|
||||
MediaProfiles& operator=(const MediaProfiles&) = delete;
|
||||
|
||||
static MediaProfiles* sMediaProfiles;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -22,25 +22,24 @@
|
|||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include "base/basictypes.h"
|
||||
#include "camera/CameraParameters.h"
|
||||
#include "Layers.h"
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <media/mediaplayer.h>
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "GrallocImages.h"
|
||||
#endif
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsThread.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include <media/mediaplayer.h>
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIVolume.h"
|
||||
#include "nsIVolumeService.h"
|
||||
#include "AutoRwLock.h"
|
||||
#include "GonkCameraHwMgr.h"
|
||||
#include "GonkRecorderProfiles.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "GonkCameraParameters.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
|
@ -71,7 +70,9 @@ nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId)
|
|||
, mAutoFlashModeOverridden(false)
|
||||
, mSeparateVideoAndPreviewSizesSupported(false)
|
||||
, mDeferConfigUpdate(0)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
, mRecorder(nullptr)
|
||||
#endif
|
||||
, mRecorderMonitor("GonkCameraControl::mRecorder.Monitor")
|
||||
, mVideoFile(nullptr)
|
||||
, mReentrantMonitor("GonkCameraControl::OnTakePicture.Monitor")
|
||||
|
@ -1165,7 +1166,9 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
|||
ReentrantMonitorAutoEnter mon(mRecorderMonitor);
|
||||
|
||||
NS_ENSURE_TRUE(!mCurrentConfiguration.mRecorderProfile.IsEmpty(), NS_ERROR_NOT_INITIALIZED);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_ENSURE_FALSE(mRecorder, NS_ERROR_FAILURE);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the base path from device storage and append the app-specified
|
||||
|
@ -1212,6 +1215,7 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
|||
return rv;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (mRecorder->start() != OK) {
|
||||
DOM_CAMERA_LOGE("mRecorder->start() failed\n");
|
||||
// important: we MUST destroy the recorder if start() fails!
|
||||
|
@ -1222,6 +1226,7 @@ nsGonkCameraControl::StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescri
|
|||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
OnRecorderStateChange(CameraControlListener::kRecorderStarted);
|
||||
return NS_OK;
|
||||
|
@ -1255,6 +1260,7 @@ nsGonkCameraControl::StopRecordingImpl()
|
|||
|
||||
ReentrantMonitorAutoEnter mon(mRecorderMonitor);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// nothing to do if we have no mRecorder
|
||||
if (!mRecorder) {
|
||||
return NS_OK;
|
||||
|
@ -1277,6 +1283,9 @@ nsGonkCameraControl::StopRecordingImpl()
|
|||
|
||||
// notify DeviceStorage that the new video file is closed and ready
|
||||
return NS_DispatchToMainThread(new RecordingComplete(mVideoFile));
|
||||
#else
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1697,6 +1706,7 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
class GonkRecorderListener : public IMediaRecorderClient
|
||||
{
|
||||
public:
|
||||
|
@ -1843,6 +1853,7 @@ nsGonkCameraControl::OnRecorderEvent(int msg, int ext1, int ext2)
|
|||
// All unhandled cases wind up here
|
||||
DOM_CAMERA_LOGW("recorder-event : unhandled: msg=%d, ext1=%d, ext2=%d\n", msg, ext1, ext2);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetupRecording(int aFd, int aRotation,
|
||||
|
@ -1851,6 +1862,7 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation,
|
|||
{
|
||||
RETURN_IF_NO_CAMERA_HW();
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// choosing a size big enough to hold the params
|
||||
const size_t SIZE = 256;
|
||||
char buffer[SIZE];
|
||||
|
@ -1911,6 +1923,7 @@ nsGonkCameraControl::SetupRecording(int aFd, int aRotation,
|
|||
// recording API needs file descriptor of output file
|
||||
CHECK_SETARG_RETURN(mRecorder->setOutputFile(aFd, 0, 0), NS_ERROR_FAILURE);
|
||||
CHECK_SETARG_RETURN(mRecorder->prepare(), NS_ERROR_FAILURE);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2046,6 +2059,7 @@ nsGonkCameraControl::OnRateLimitPreview(bool aLimit)
|
|||
void
|
||||
nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsRefPtr<Image> frame = mImageContainer->CreateImage(ImageFormat::GRALLOC_PLANAR_YCBCR);
|
||||
|
||||
GrallocImage* videoImage = static_cast<GrallocImage*>(frame.get());
|
||||
|
@ -2058,6 +2072,7 @@ nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
|||
|
||||
OnNewPreviewFrame(frame, mCurrentConfiguration.mPreviewSize.width,
|
||||
mCurrentConfiguration.mPreviewSize.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -19,18 +19,24 @@
|
|||
|
||||
#include "base/basictypes.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "DeviceStorage.h"
|
||||
#include "CameraControlImpl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "GonkRecorder.h"
|
||||
#include "GonkCameraHwMgr.h"
|
||||
#include "GonkCameraParameters.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <media/MediaProfiles.h>
|
||||
#include <camera/Camera.h>
|
||||
#include "GonkRecorder.h"
|
||||
#else
|
||||
#include "FallbackCameraPlatform.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace android {
|
||||
class GonkCameraHardware;
|
||||
class MediaProfiles;
|
||||
class GonkRecorder;
|
||||
class GonkCameraSource;
|
||||
}
|
||||
|
@ -56,7 +62,9 @@ public:
|
|||
void OnTakePictureError();
|
||||
void OnRateLimitPreview(bool aLimit);
|
||||
void OnNewPreviewFrame(layers::TextureClient* aBuffer);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void OnRecorderEvent(int msg, int ext1, int ext2);
|
||||
#endif
|
||||
void OnSystemError(CameraControlListener::SystemContext aWhere, nsresult aError);
|
||||
|
||||
// See ICameraControl.h for getter/setter return values.
|
||||
|
@ -177,7 +185,9 @@ protected:
|
|||
|
||||
nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsRefPtr<android::GonkRecorder> mRecorder;
|
||||
#endif
|
||||
// Touching mRecorder happens inside this monitor because the destructor
|
||||
// can run on any thread, and we need to be able to clean up properly if
|
||||
// GonkCameraControl goes away.
|
||||
|
|
|
@ -17,8 +17,11 @@
|
|||
#include "GonkCameraHwMgr.h"
|
||||
#include "TestGonkCameraHardware.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <sys/system_properties.h>
|
||||
#include "GonkNativeWindow.h"
|
||||
#endif
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "nsDebug.h"
|
||||
|
@ -29,19 +32,26 @@
|
|||
#include "GonkBufferQueueProducer.h"
|
||||
#endif
|
||||
#include "GonkCameraControl.h"
|
||||
#include "GonkNativeWindow.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
using namespace android;
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
NS_IMPL_ISUPPORTS0(GonkCameraHardware);
|
||||
NS_IMPL_ISUPPORTS0(android::Camera);
|
||||
#endif
|
||||
|
||||
GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera)
|
||||
: mCameraId(aCameraId)
|
||||
, mClosing(false)
|
||||
, mNumFrames(0)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
, mCamera(aCamera)
|
||||
#endif
|
||||
, mTarget(aTarget)
|
||||
, mRawSensorOrientation(0)
|
||||
, mSensorOrientation(0)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
|
||||
|
@ -53,6 +63,7 @@ GonkCameraHardware::OnRateLimitPreview(bool aLimit)
|
|||
::OnRateLimitPreview(mTarget, aLimit);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void
|
||||
GonkCameraHardware::OnNewFrame()
|
||||
{
|
||||
|
@ -150,12 +161,14 @@ GonkCameraHardware::postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, cons
|
|||
mCamera->releaseRecordingFrame(aDataPtr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
GonkCameraHardware::Init()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s: this=%p\n", __func__, (void* )this);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
CameraInfo info;
|
||||
int rv = Camera::getCameraInfo(mCameraId, &info);
|
||||
if (rv != 0) {
|
||||
|
@ -184,8 +197,6 @@ GonkCameraHardware::Init()
|
|||
// Disable shutter sound in android CameraService because gaia camera app will play it
|
||||
mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
|
||||
#if ANDROID_VERSION >= 21
|
||||
sp<IGraphicBufferProducer> producer;
|
||||
sp<IGonkGraphicBufferConsumer> consumer;
|
||||
|
@ -231,10 +242,12 @@ GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCam
|
|||
CameraPreferences::GetPref("camera.control.test.enabled", test);
|
||||
|
||||
if (!test.EqualsASCII("hardware")) {
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#if ANDROID_VERSION >= 18
|
||||
camera = Camera::connect(aCameraId, /* clientPackageName */String16("gonk.camera"), Camera::USE_CALLING_UID);
|
||||
#else
|
||||
camera = Camera::connect(aCameraId);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (camera.get() == nullptr) {
|
||||
|
@ -270,21 +283,25 @@ GonkCameraHardware::Close()
|
|||
mCamera->stopPreview();
|
||||
mCamera->disconnect();
|
||||
}
|
||||
mCamera.clear();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (mNativeWindow.get()) {
|
||||
mNativeWindow->abandon();
|
||||
}
|
||||
mCamera.clear();
|
||||
mNativeWindow.clear();
|
||||
|
||||
// Ensure that ICamera's destructor is actually executed
|
||||
IPCThreadState::self()->flushCommands();
|
||||
#endif
|
||||
}
|
||||
|
||||
GonkCameraHardware::~GonkCameraHardware()
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, (void*)this);
|
||||
mCamera.clear();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
mNativeWindow.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -370,13 +387,6 @@ GonkCameraHardware::PushParameters(const GonkCameraParameters& aParams)
|
|||
return mCamera->setParameters(s);
|
||||
}
|
||||
|
||||
int
|
||||
GonkCameraHardware::PushParameters(const CameraParameters& aParams)
|
||||
{
|
||||
String8 s = aParams.flatten();
|
||||
return mCamera->setParameters(s);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkCameraHardware::PullParameters(GonkCameraParameters& aParams)
|
||||
{
|
||||
|
@ -384,12 +394,21 @@ GonkCameraHardware::PullParameters(GonkCameraParameters& aParams)
|
|||
return aParams.Unflatten(s);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
int
|
||||
GonkCameraHardware::PushParameters(const CameraParameters& aParams)
|
||||
{
|
||||
String8 s = aParams.flatten();
|
||||
return mCamera->setParameters(s);
|
||||
}
|
||||
|
||||
void
|
||||
GonkCameraHardware::PullParameters(CameraParameters& aParams)
|
||||
{
|
||||
const String8 s = mCamera->getParameters();
|
||||
aParams.unflatten(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
GonkCameraHardware::StartPreview()
|
||||
|
@ -426,6 +445,7 @@ GonkCameraHardware::StopRecording()
|
|||
return OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
int
|
||||
GonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
|
||||
{
|
||||
|
@ -438,6 +458,7 @@ GonkCameraHardware::ReleaseRecordingFrame(const sp<IMemory>& aFrame)
|
|||
{
|
||||
mCamera->releaseRecordingFrame(aFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
GonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
|
||||
|
|
|
@ -17,18 +17,21 @@
|
|||
#ifndef DOM_CAMERA_GONKCAMERAHWMGR_H
|
||||
#define DOM_CAMERA_GONKCAMERAHWMGR_H
|
||||
|
||||
#include "GonkCameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "GonkCameraParameters.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <binder/IMemory.h>
|
||||
#include <camera/Camera.h>
|
||||
#include <camera/CameraParameters.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
#include "GonkCameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
#include "GonkCameraListener.h"
|
||||
#include "GonkNativeWindow.h"
|
||||
#include "GonkCameraParameters.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#else
|
||||
#include "FallbackCameraPlatform.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
class nsGonkCameraControl;
|
||||
|
@ -37,9 +40,18 @@ namespace mozilla {
|
|||
|
||||
namespace android {
|
||||
|
||||
class GonkCameraHardware : public GonkNativeWindowNewFrameCallback
|
||||
, public CameraListener
|
||||
class GonkCameraHardware
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
: public GonkNativeWindowNewFrameCallback
|
||||
, public CameraListener
|
||||
#else
|
||||
: public nsISupports
|
||||
#endif
|
||||
{
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
NS_DECL_ISUPPORTS
|
||||
#endif
|
||||
|
||||
protected:
|
||||
GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera);
|
||||
virtual ~GonkCameraHardware();
|
||||
|
@ -57,6 +69,7 @@ public:
|
|||
|
||||
virtual void OnRateLimitPreview(bool aLimit);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// derived from GonkNativeWindowNewFrameCallback
|
||||
virtual void OnNewFrame() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -64,6 +77,7 @@ public:
|
|||
virtual void notify(int32_t aMsgType, int32_t ext1, int32_t ext2);
|
||||
virtual void postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata);
|
||||
virtual void postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The physical orientation of the camera sensor: 0, 90, 180, or 270.
|
||||
|
@ -103,13 +117,15 @@ public:
|
|||
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);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
virtual int PushParameters(const CameraParameters& 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);
|
||||
#endif
|
||||
virtual int StartRecording();
|
||||
virtual int StopRecording();
|
||||
virtual int StoreMetaDataInBuffers(bool aEnabled);
|
||||
|
||||
protected:
|
||||
|
@ -118,8 +134,10 @@ protected:
|
|||
uint32_t mNumFrames;
|
||||
sp<Camera> mCamera;
|
||||
mozilla::nsGonkCameraControl* mTarget;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
sp<GonkNativeWindow> mNativeWindow;
|
||||
sp<GonkCameraListener> mListener;
|
||||
#endif
|
||||
int mRawSensorOrientation;
|
||||
int mSensorOrientation;
|
||||
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
*/
|
||||
|
||||
#include "ICameraControl.h"
|
||||
|
||||
#include <camera/Camera.h>
|
||||
|
||||
#include "CameraCommon.h"
|
||||
#include "GonkCameraControl.h"
|
||||
#include "CameraPreferences.h"
|
||||
#include "TestGonkCameraControl.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <camera/Camera.h>
|
||||
#else
|
||||
#include "FallbackCameraPlatform.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// From ICameraControl, gonk-specific management functions
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
|
||||
#include "GonkCameraParameters.h"
|
||||
#include "camera/CameraParameters.h"
|
||||
#include "CameraPreferences.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace android;
|
||||
|
@ -52,13 +52,13 @@ GonkCameraParameters::IsLowMemoryPlatform()
|
|||
}
|
||||
|
||||
const char*
|
||||
GonkCameraParameters::Parameters::FindVendorSpecificKey(const char* aPotentialKeys[],
|
||||
size_t aPotentialKeyCount)
|
||||
GonkCameraParameters::FindVendorSpecificKey(const char* aPotentialKeys[],
|
||||
size_t aPotentialKeyCount)
|
||||
{
|
||||
const char* val;
|
||||
|
||||
for (size_t i = 0; i < aPotentialKeyCount; ++i) {
|
||||
get(aPotentialKeys[i], val);
|
||||
GetImpl(aPotentialKeys[i], val);
|
||||
if (val) {
|
||||
// We received a value (potentially an empty-string one),
|
||||
// which indicates that this key exists.
|
||||
|
@ -69,59 +69,122 @@ GonkCameraParameters::Parameters::FindVendorSpecificKey(const char* aPotentialKe
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
GonkCameraParameters::EnumerateFlatten(const nsACString& aKey,
|
||||
nsCString* aValue,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCString* data = static_cast<nsCString*>(aUserArg);
|
||||
if (!data->IsEmpty()) {
|
||||
data->Append(';');
|
||||
}
|
||||
data->Append(aKey);
|
||||
data->Append('=');
|
||||
data->Append(*aValue);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
String8
|
||||
GonkCameraParameters::Flatten() const
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
nsCString data;
|
||||
mParams.EnumerateRead(EnumerateFlatten, static_cast<void*>(&data));
|
||||
return String8(data.Data());
|
||||
}
|
||||
|
||||
nsresult
|
||||
GonkCameraParameters::Unflatten(const String8& aFlatParameters)
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mParams.Clear();
|
||||
|
||||
const char* data = aFlatParameters.string();
|
||||
while (data && *data) {
|
||||
const char* pos = strchr(data, '=');
|
||||
if (!pos) {
|
||||
break;
|
||||
}
|
||||
|
||||
nsAutoCString key(data, pos - data);
|
||||
data = pos + 1;
|
||||
|
||||
nsCString* value;
|
||||
pos = strchr(data, ';');
|
||||
if (pos) {
|
||||
value = new nsCString(data, pos - data);
|
||||
data = pos + 1;
|
||||
} else {
|
||||
value = new nsCString(data);
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
mParams.Put(key, value);
|
||||
}
|
||||
|
||||
if (mInitialized) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We call Initialize() once when the parameter set is first loaded,
|
||||
// to set up any constant values this class requires internally,
|
||||
// e.g. the exposure compensation step and limits.
|
||||
return Initialize();
|
||||
}
|
||||
|
||||
const char*
|
||||
GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
||||
GonkCameraParameters::GetTextKey(uint32_t aKey)
|
||||
{
|
||||
switch (aKey) {
|
||||
case CAMERA_PARAM_PREVIEWSIZE:
|
||||
return KEY_PREVIEW_SIZE;
|
||||
return CameraParameters::KEY_PREVIEW_SIZE;
|
||||
case CAMERA_PARAM_PREVIEWFORMAT:
|
||||
return KEY_PREVIEW_FORMAT;
|
||||
return CameraParameters::KEY_PREVIEW_FORMAT;
|
||||
case CAMERA_PARAM_PREVIEWFRAMERATE:
|
||||
return KEY_PREVIEW_FRAME_RATE;
|
||||
return CameraParameters::KEY_PREVIEW_FRAME_RATE;
|
||||
case CAMERA_PARAM_EFFECT:
|
||||
return KEY_EFFECT;
|
||||
return CameraParameters::KEY_EFFECT;
|
||||
case CAMERA_PARAM_WHITEBALANCE:
|
||||
return KEY_WHITE_BALANCE;
|
||||
return CameraParameters::KEY_WHITE_BALANCE;
|
||||
case CAMERA_PARAM_SCENEMODE:
|
||||
return KEY_SCENE_MODE;
|
||||
return CameraParameters::KEY_SCENE_MODE;
|
||||
case CAMERA_PARAM_FLASHMODE:
|
||||
return KEY_FLASH_MODE;
|
||||
return CameraParameters::KEY_FLASH_MODE;
|
||||
case CAMERA_PARAM_FOCUSMODE:
|
||||
return KEY_FOCUS_MODE;
|
||||
return CameraParameters::KEY_FOCUS_MODE;
|
||||
case CAMERA_PARAM_ZOOM:
|
||||
return KEY_ZOOM;
|
||||
return CameraParameters::KEY_ZOOM;
|
||||
case CAMERA_PARAM_METERINGAREAS:
|
||||
return KEY_METERING_AREAS;
|
||||
return CameraParameters::KEY_METERING_AREAS;
|
||||
case CAMERA_PARAM_FOCUSAREAS:
|
||||
return KEY_FOCUS_AREAS;
|
||||
return CameraParameters::KEY_FOCUS_AREAS;
|
||||
case CAMERA_PARAM_FOCALLENGTH:
|
||||
return KEY_FOCAL_LENGTH;
|
||||
return CameraParameters::KEY_FOCAL_LENGTH;
|
||||
case CAMERA_PARAM_FOCUSDISTANCENEAR:
|
||||
return KEY_FOCUS_DISTANCES;
|
||||
return CameraParameters::KEY_FOCUS_DISTANCES;
|
||||
case CAMERA_PARAM_FOCUSDISTANCEOPTIMUM:
|
||||
return KEY_FOCUS_DISTANCES;
|
||||
return CameraParameters::KEY_FOCUS_DISTANCES;
|
||||
case CAMERA_PARAM_FOCUSDISTANCEFAR:
|
||||
return KEY_FOCUS_DISTANCES;
|
||||
return CameraParameters::KEY_FOCUS_DISTANCES;
|
||||
case CAMERA_PARAM_EXPOSURECOMPENSATION:
|
||||
return KEY_EXPOSURE_COMPENSATION;
|
||||
return CameraParameters::KEY_EXPOSURE_COMPENSATION;
|
||||
case CAMERA_PARAM_THUMBNAILQUALITY:
|
||||
return KEY_JPEG_THUMBNAIL_QUALITY;
|
||||
return CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY;
|
||||
case CAMERA_PARAM_PICTURE_SIZE:
|
||||
return KEY_PICTURE_SIZE;
|
||||
return CameraParameters::KEY_PICTURE_SIZE;
|
||||
case CAMERA_PARAM_PICTURE_FILEFORMAT:
|
||||
return KEY_PICTURE_FORMAT;
|
||||
return CameraParameters::KEY_PICTURE_FORMAT;
|
||||
case CAMERA_PARAM_PICTURE_ROTATION:
|
||||
return KEY_ROTATION;
|
||||
return CameraParameters::KEY_ROTATION;
|
||||
case CAMERA_PARAM_PICTURE_DATETIME:
|
||||
// Not every platform defines a KEY_EXIF_DATETIME;
|
||||
// Not every platform defines a CameraParameters::EXIF_DATETIME;
|
||||
// for those that don't, we use the raw string key, and if the platform
|
||||
// doesn't support it, it will be ignored.
|
||||
//
|
||||
// See bug 832494.
|
||||
return "exif-datetime";
|
||||
case CAMERA_PARAM_VIDEOSIZE:
|
||||
return KEY_VIDEO_SIZE;
|
||||
return CameraParameters::KEY_VIDEO_SIZE;
|
||||
case CAMERA_PARAM_ISOMODE:
|
||||
if (!mVendorSpecificKeyIsoMode) {
|
||||
const char* isoModeKeys[] = {
|
||||
|
@ -135,55 +198,55 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
|||
case CAMERA_PARAM_LUMINANCE:
|
||||
return "luminance-condition";
|
||||
case CAMERA_PARAM_SCENEMODE_HDR_RETURNNORMALPICTURE:
|
||||
// Not every platform defines KEY_QC_HDR_NEED_1X;
|
||||
// Not every platform defines CameraParameters::QC_HDR_NEED_1X;
|
||||
// for those that don't, we use the raw string key.
|
||||
return "hdr-need-1x";
|
||||
case CAMERA_PARAM_RECORDINGHINT:
|
||||
return KEY_RECORDING_HINT;
|
||||
return CameraParameters::KEY_RECORDING_HINT;
|
||||
case CAMERA_PARAM_PICTURE_QUALITY:
|
||||
return KEY_JPEG_QUALITY;
|
||||
return CameraParameters::KEY_JPEG_QUALITY;
|
||||
case CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO:
|
||||
return KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO;
|
||||
return CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO;
|
||||
case CAMERA_PARAM_METERINGMODE:
|
||||
// Not every platform defines KEY_AUTO_EXPOSURE.
|
||||
// Not every platform defines CameraParameters::AUTO_EXPOSURE.
|
||||
return "auto-exposure";
|
||||
|
||||
case CAMERA_PARAM_SUPPORTED_PREVIEWSIZES:
|
||||
return KEY_SUPPORTED_PREVIEW_SIZES;
|
||||
return CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES;
|
||||
case CAMERA_PARAM_SUPPORTED_PICTURESIZES:
|
||||
return KEY_SUPPORTED_PICTURE_SIZES;
|
||||
return CameraParameters::KEY_SUPPORTED_PICTURE_SIZES;
|
||||
case CAMERA_PARAM_SUPPORTED_VIDEOSIZES:
|
||||
return KEY_SUPPORTED_VIDEO_SIZES;
|
||||
return CameraParameters::KEY_SUPPORTED_VIDEO_SIZES;
|
||||
case CAMERA_PARAM_SUPPORTED_PICTUREFORMATS:
|
||||
return KEY_SUPPORTED_PICTURE_FORMATS;
|
||||
return CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS;
|
||||
case CAMERA_PARAM_SUPPORTED_WHITEBALANCES:
|
||||
return KEY_SUPPORTED_WHITE_BALANCE;
|
||||
return CameraParameters::KEY_SUPPORTED_WHITE_BALANCE;
|
||||
case CAMERA_PARAM_SUPPORTED_SCENEMODES:
|
||||
return KEY_SUPPORTED_SCENE_MODES;
|
||||
return CameraParameters::KEY_SUPPORTED_SCENE_MODES;
|
||||
case CAMERA_PARAM_SUPPORTED_EFFECTS:
|
||||
return KEY_SUPPORTED_EFFECTS;
|
||||
return CameraParameters::KEY_SUPPORTED_EFFECTS;
|
||||
case CAMERA_PARAM_SUPPORTED_FLASHMODES:
|
||||
return KEY_SUPPORTED_FLASH_MODES;
|
||||
return CameraParameters::KEY_SUPPORTED_FLASH_MODES;
|
||||
case CAMERA_PARAM_SUPPORTED_FOCUSMODES:
|
||||
return KEY_SUPPORTED_FOCUS_MODES;
|
||||
return CameraParameters::KEY_SUPPORTED_FOCUS_MODES;
|
||||
case CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS:
|
||||
return KEY_MAX_NUM_FOCUS_AREAS;
|
||||
return CameraParameters::KEY_MAX_NUM_FOCUS_AREAS;
|
||||
case CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS:
|
||||
return KEY_MAX_NUM_METERING_AREAS;
|
||||
return CameraParameters::KEY_MAX_NUM_METERING_AREAS;
|
||||
case CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION:
|
||||
return KEY_MIN_EXPOSURE_COMPENSATION;
|
||||
return CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION;
|
||||
case CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION:
|
||||
return KEY_MAX_EXPOSURE_COMPENSATION;
|
||||
return CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION;
|
||||
case CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP:
|
||||
return KEY_EXPOSURE_COMPENSATION_STEP;
|
||||
return CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP;
|
||||
case CAMERA_PARAM_SUPPORTED_ZOOM:
|
||||
return KEY_ZOOM_SUPPORTED;
|
||||
return CameraParameters::KEY_ZOOM_SUPPORTED;
|
||||
case CAMERA_PARAM_SUPPORTED_ZOOMRATIOS:
|
||||
return KEY_ZOOM_RATIOS;
|
||||
return CameraParameters::KEY_ZOOM_RATIOS;
|
||||
case CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES:
|
||||
return KEY_MAX_NUM_DETECTED_FACES_HW;
|
||||
return CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW;
|
||||
case CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES:
|
||||
return KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES;
|
||||
return CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES;
|
||||
case CAMERA_PARAM_SUPPORTED_ISOMODES:
|
||||
if (!mVendorSpecificKeySupportedIsoModes) {
|
||||
const char* supportedIsoModesKeys[] = {
|
||||
|
@ -196,7 +259,7 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
|||
}
|
||||
return mVendorSpecificKeySupportedIsoModes;
|
||||
case CAMERA_PARAM_SUPPORTED_METERINGMODES:
|
||||
// Not every platform defines KEY_SUPPORTED_AUTO_EXPOSURE.
|
||||
// Not every platform defines CameraParameters::SUPPORTED_AUTO_EXPOSURE.
|
||||
return "auto-exposure-values";
|
||||
default:
|
||||
DOM_CAMERA_LOGE("Unhandled camera parameter value %u\n", aKey);
|
||||
|
@ -205,26 +268,20 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
|||
}
|
||||
|
||||
GonkCameraParameters::GonkCameraParameters()
|
||||
: mLock(PR_NewRWLock(PR_RWLOCK_RANK_NONE, "GonkCameraParameters.Lock"))
|
||||
: mLock("mozilla::camera::GonkCameraParameters")
|
||||
, mDirty(false)
|
||||
, mInitialized(false)
|
||||
, mExposureCompensationStep(0.0)
|
||||
, mVendorSpecificKeyIsoMode(nullptr)
|
||||
, mVendorSpecificKeySupportedIsoModes(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GonkCameraParameters);
|
||||
if (!mLock) {
|
||||
MOZ_CRASH("Out of memory getting new PRRWLock");
|
||||
}
|
||||
}
|
||||
|
||||
GonkCameraParameters::~GonkCameraParameters()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GonkCameraParameters);
|
||||
mIsoModeMap.Clear();
|
||||
MOZ_ASSERT(mLock, "mLock missing in ~GonkCameraParameters()");
|
||||
if (mLock) {
|
||||
PR_DestroyRWLock(mLock);
|
||||
mLock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -278,17 +335,17 @@ GonkCameraParameters::Initialize()
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = GetImpl(Parameters::KEY_EXPOSURE_COMPENSATION_STEP, mExposureCompensationStep);
|
||||
rv = GetImpl(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mExposureCompensationStep);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to initialize exposure compensation step size");
|
||||
mExposureCompensationStep = 0.0;
|
||||
}
|
||||
rv = GetImpl(Parameters::KEY_MIN_EXPOSURE_COMPENSATION, mExposureCompensationMinIndex);
|
||||
rv = GetImpl(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mExposureCompensationMinIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to initialize minimum exposure compensation index");
|
||||
mExposureCompensationMinIndex = 0;
|
||||
}
|
||||
rv = GetImpl(Parameters::KEY_MAX_EXPOSURE_COMPENSATION, mExposureCompensationMaxIndex);
|
||||
rv = GetImpl(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mExposureCompensationMaxIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to initialize maximum exposure compensation index");
|
||||
mExposureCompensationMaxIndex = 0;
|
||||
|
@ -425,9 +482,9 @@ GonkCameraParameters::SetTranslated(uint32_t aKey, const ICameraControl::Size& a
|
|||
// This is a special case--for some reason the thumbnail size
|
||||
// is accessed as two separate values instead of a tuple.
|
||||
// XXXmikeh - make this restore the original values on error
|
||||
rv = SetImpl(Parameters::KEY_JPEG_THUMBNAIL_WIDTH, static_cast<int>(aSize.width));
|
||||
rv = SetImpl(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, static_cast<int>(aSize.width));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = SetImpl(Parameters::KEY_JPEG_THUMBNAIL_HEIGHT, static_cast<int>(aSize.height));
|
||||
rv = SetImpl(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, static_cast<int>(aSize.height));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -461,14 +518,14 @@ GonkCameraParameters::GetTranslated(uint32_t aKey, ICameraControl::Size& aSize)
|
|||
int width;
|
||||
int height;
|
||||
|
||||
rv = GetImpl(Parameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
|
||||
rv = GetImpl(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (width < 0) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = GetImpl(Parameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
|
||||
rv = GetImpl(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -572,27 +629,27 @@ GonkCameraParameters::SetTranslated(uint32_t aKey, const ICameraControl::Positio
|
|||
// Add any specified location information -- we don't care if these fail.
|
||||
if (!isnan(aPosition.latitude)) {
|
||||
DOM_CAMERA_LOGI("setting picture latitude to %lf\n", aPosition.latitude);
|
||||
SetImpl(Parameters::KEY_GPS_LATITUDE, nsPrintfCString("%lf", aPosition.latitude).get());
|
||||
SetImpl(CameraParameters::KEY_GPS_LATITUDE, nsPrintfCString("%lf", aPosition.latitude).get());
|
||||
} else {
|
||||
ClearImpl(Parameters::KEY_GPS_LATITUDE);
|
||||
ClearImpl(CameraParameters::KEY_GPS_LATITUDE);
|
||||
}
|
||||
if (!isnan(aPosition.longitude)) {
|
||||
DOM_CAMERA_LOGI("setting picture longitude to %lf\n", aPosition.longitude);
|
||||
SetImpl(Parameters::KEY_GPS_LONGITUDE, nsPrintfCString("%lf", aPosition.longitude).get());
|
||||
SetImpl(CameraParameters::KEY_GPS_LONGITUDE, nsPrintfCString("%lf", aPosition.longitude).get());
|
||||
} else {
|
||||
ClearImpl(Parameters::KEY_GPS_LONGITUDE);
|
||||
ClearImpl(CameraParameters::KEY_GPS_LONGITUDE);
|
||||
}
|
||||
if (!isnan(aPosition.altitude)) {
|
||||
DOM_CAMERA_LOGI("setting picture altitude to %lf\n", aPosition.altitude);
|
||||
SetImpl(Parameters::KEY_GPS_ALTITUDE, nsPrintfCString("%lf", aPosition.altitude).get());
|
||||
SetImpl(CameraParameters::KEY_GPS_ALTITUDE, nsPrintfCString("%lf", aPosition.altitude).get());
|
||||
} else {
|
||||
ClearImpl(Parameters::KEY_GPS_ALTITUDE);
|
||||
ClearImpl(CameraParameters::KEY_GPS_ALTITUDE);
|
||||
}
|
||||
if (!isnan(aPosition.timestamp)) {
|
||||
DOM_CAMERA_LOGI("setting picture timestamp to %lf\n", aPosition.timestamp);
|
||||
SetImpl(Parameters::KEY_GPS_TIMESTAMP, nsPrintfCString("%lf", aPosition.timestamp).get());
|
||||
SetImpl(CameraParameters::KEY_GPS_TIMESTAMP, nsPrintfCString("%lf", aPosition.timestamp).get());
|
||||
} else {
|
||||
ClearImpl(Parameters::KEY_GPS_TIMESTAMP);
|
||||
ClearImpl(CameraParameters::KEY_GPS_TIMESTAMP);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -18,14 +18,18 @@
|
|||
#define DOM_CAMERA_GONKCAMERAPARAMETERS_H
|
||||
|
||||
#include <math.h>
|
||||
#include "camera/CameraParameters.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "AutoRwLock.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "ICameraControl.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <camera/CameraParameters.h>
|
||||
#else
|
||||
#include "FallbackCameraPlatform.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class GonkCameraParameters
|
||||
|
@ -44,7 +48,7 @@ public:
|
|||
template<class T> nsresult
|
||||
Set(uint32_t aKey, const T& aValue)
|
||||
{
|
||||
RwLockAutoEnterWrite lock(mLock);
|
||||
MutexAutoLock lock(mLock);
|
||||
nsresult rv = SetTranslated(aKey, aValue);
|
||||
mDirty = mDirty || NS_SUCCEEDED(rv);
|
||||
return rv;
|
||||
|
@ -53,7 +57,7 @@ public:
|
|||
template<class T> nsresult
|
||||
Get(uint32_t aKey, T& aValue)
|
||||
{
|
||||
RwLockAutoEnterRead lock(mLock);
|
||||
MutexAutoLock lock(mLock);
|
||||
return GetTranslated(aKey, aValue);
|
||||
}
|
||||
|
||||
|
@ -62,36 +66,17 @@ public:
|
|||
{
|
||||
bool dirty;
|
||||
|
||||
RwLockAutoEnterWrite lock(mLock);
|
||||
MutexAutoLock lock(mLock);
|
||||
dirty = mDirty;
|
||||
mDirty = false;
|
||||
return dirty;
|
||||
}
|
||||
|
||||
android::String8
|
||||
Flatten() const
|
||||
{
|
||||
RwLockAutoEnterRead lock(mLock);
|
||||
return mParams.flatten();
|
||||
}
|
||||
|
||||
nsresult
|
||||
Unflatten(const android::String8& aFlatParameters)
|
||||
{
|
||||
RwLockAutoEnterWrite lock(mLock);
|
||||
mParams.unflatten(aFlatParameters);
|
||||
if (mInitialized) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We call Initialize() once when the parameter set is first loaded,
|
||||
// to set up any constant values this class requires internally,
|
||||
// e.g. the exposure compensation step and limits.
|
||||
return Initialize();
|
||||
}
|
||||
android::String8 Flatten() const;
|
||||
nsresult Unflatten(const android::String8& aFlatParameters);
|
||||
|
||||
protected:
|
||||
PRRWLock* mLock;
|
||||
mutable Mutex mLock;
|
||||
bool mDirty;
|
||||
bool mInitialized;
|
||||
|
||||
|
@ -99,55 +84,123 @@ protected:
|
|||
double mExposureCompensationStep;
|
||||
int32_t mExposureCompensationMinIndex;
|
||||
int32_t mExposureCompensationMaxIndex;
|
||||
const char* mVendorSpecificKeyIsoMode;
|
||||
const char* mVendorSpecificKeySupportedIsoModes;
|
||||
nsTArray<int> mZoomRatios;
|
||||
nsTArray<nsString> mIsoModes;
|
||||
nsTArray<nsString> mSceneModes;
|
||||
nsTArray<nsString> mMeteringModes;
|
||||
nsClassHashtable<nsStringHashKey, nsCString> mIsoModeMap;
|
||||
nsClassHashtable<nsCStringHashKey, nsCString> mParams;
|
||||
|
||||
// This subclass of android::CameraParameters just gives
|
||||
// all of the AOSP getters and setters the same signature.
|
||||
class Parameters : public android::CameraParameters
|
||||
static PLDHashOperator EnumerateFlatten(const nsACString& aKey, nsCString* aValue, void* aUserArg);
|
||||
|
||||
nsresult SetImpl(const char* aKey, const char* aValue)
|
||||
{
|
||||
public:
|
||||
Parameters()
|
||||
: mVendorSpecificKeyIsoMode(nullptr)
|
||||
, mVendorSpecificKeySupportedIsoModes(nullptr)
|
||||
{ }
|
||||
virtual ~Parameters() { }
|
||||
nsCString key(aKey);
|
||||
mParams.Put(key, new nsCString(aValue));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
using android::CameraParameters::set;
|
||||
using android::CameraParameters::get;
|
||||
using android::CameraParameters::TRUE;
|
||||
using android::CameraParameters::FALSE;
|
||||
nsresult SetImpl(const char* aKey, int aValue)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value = new nsCString();
|
||||
value->AppendInt(aValue);
|
||||
mParams.Put(key, value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void set(const char* aKey, float aValue) { setFloat(aKey, aValue); }
|
||||
void set(const char* aKey, double aValue) { setFloat(aKey, aValue); }
|
||||
void set(const char* aKey, bool aValue) { set(aKey, aValue ? TRUE : FALSE); }
|
||||
void get(const char* aKey, float& aRet) { aRet = getFloat(aKey); }
|
||||
void get(const char* aKey, double& aRet) { aRet = getFloat(aKey); }
|
||||
void get(const char* aKey, const char*& aRet) { aRet = get(aKey); }
|
||||
void get(const char* aKey, int& aRet) { aRet = getInt(aKey); }
|
||||
nsresult SetImpl(const char* aKey, double aValue)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value = new nsCString();
|
||||
value->AppendFloat(aValue);
|
||||
mParams.Put(key, value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
get(const char* aKey, bool& aRet)
|
||||
{
|
||||
const char* value = get(aKey);
|
||||
aRet = value ? strcmp(value, TRUE) == 0 : false;
|
||||
nsresult SetImpl(const char* aKey, float aValue)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value = new nsCString();
|
||||
value->AppendFloat(aValue);
|
||||
mParams.Put(key, value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SetImpl(const char* aKey, bool aValue)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
mParams.Put(key, new nsCString(aValue ? "true" : "false"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetImpl(const char* aKey, const char*& aRet)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value;
|
||||
if (!mParams.Get(key, &value)) {
|
||||
aRet = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aRet = value->Data();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void remove(const char* aKey) { android::CameraParameters::remove(aKey); }
|
||||
nsresult GetImpl(const char* aKey, float& aRet)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mParams.Get(key, &value)) {
|
||||
aRet = value->ToFloat(&rv);
|
||||
} else {
|
||||
aRet = 0.0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char* GetTextKey(uint32_t aKey);
|
||||
nsresult GetImpl(const char* aKey, double& aRet)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mParams.Get(key, &value)) {
|
||||
aRet = value->ToFloat(&rv);
|
||||
} else {
|
||||
aRet = 0.0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* FindVendorSpecificKey(const char* aPotentialKeys[], size_t aPotentialKeyCount);
|
||||
nsresult GetImpl(const char* aKey, int& aRet)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mParams.Get(key, &value)) {
|
||||
aRet = value->ToInteger(&rv);
|
||||
} else {
|
||||
aRet = 0.0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char* mVendorSpecificKeyIsoMode;
|
||||
const char* mVendorSpecificKeySupportedIsoModes;
|
||||
};
|
||||
nsresult GetImpl(const char* aKey, bool& aRet)
|
||||
{
|
||||
nsCString key(aKey);
|
||||
nsCString* value;
|
||||
if (!mParams.Get(key, &value)) {
|
||||
aRet = false;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aRet = value->EqualsLiteral("true");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Parameters mParams;
|
||||
const char* GetTextKey(uint32_t aKey);
|
||||
const char* FindVendorSpecificKey(const char* aPotentialKeys[], size_t aPotentialKeyCount);
|
||||
|
||||
// The *Impl() templates handle converting the parameter keys from
|
||||
// their enum values to string types, if necessary. These are the
|
||||
|
@ -159,41 +212,24 @@ protected:
|
|||
template<typename T> nsresult
|
||||
SetImpl(uint32_t aKey, const T& aValue)
|
||||
{
|
||||
const char* key = mParams.GetTextKey(aKey);
|
||||
const char* key = GetTextKey(aKey);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
mParams.set(key, aValue);
|
||||
return NS_OK;
|
||||
return SetImpl(key, aValue);
|
||||
}
|
||||
|
||||
template<typename T> nsresult
|
||||
GetImpl(uint32_t aKey, T& aValue)
|
||||
{
|
||||
const char* key = mParams.GetTextKey(aKey);
|
||||
const char* key = GetTextKey(aKey);
|
||||
NS_ENSURE_TRUE(key, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
mParams.get(key, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<class T> nsresult
|
||||
SetImpl(const char* aKey, const T& aValue)
|
||||
{
|
||||
mParams.set(aKey, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<class T> nsresult
|
||||
GetImpl(const char* aKey, T& aValue)
|
||||
{
|
||||
mParams.get(aKey, aValue);
|
||||
return NS_OK;
|
||||
return GetImpl(key, aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ClearImpl(const char* aKey)
|
||||
{
|
||||
mParams.remove(aKey);
|
||||
nsCString key(aKey);
|
||||
mParams.Remove(key);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
*/
|
||||
|
||||
#include "GonkRecorderProfiles.h"
|
||||
#include <media/MediaProfiles.h>
|
||||
#include "nsMimeTypes.h"
|
||||
#include "GonkRecorder.h"
|
||||
#include "CameraControlImpl.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "GonkRecorder.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace android;
|
||||
|
||||
|
@ -374,10 +376,11 @@ GonkRecorderProfile::GetAll(uint32_t aCameraId,
|
|||
|
||||
aProfiles.Clear();
|
||||
profiles->EnumerateRead(Enumerate, static_cast<void*>(&aProfiles));
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsresult
|
||||
GonkRecorderProfile::ConfigureRecorder(GonkRecorder& aRecorder)
|
||||
{
|
||||
|
@ -425,3 +428,4 @@ GonkRecorderProfile::ConfigureRecorder(android::GonkRecorder& aRecorder,
|
|||
|
||||
return profile->ConfigureRecorder(aRecorder);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
#ifndef DOM_CAMERA_GONK_RECORDER_PROFILES_H
|
||||
#define DOM_CAMERA_GONK_RECORDER_PROFILES_H
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <media/MediaProfiles.h>
|
||||
#else
|
||||
#include "FallbackCameraPlatform.h"
|
||||
#endif
|
||||
|
||||
#include "ICameraControl.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
@ -109,6 +114,7 @@ public:
|
|||
static nsresult GetAll(uint32_t aCameraId,
|
||||
nsTArray<nsRefPtr<ICameraControl::RecorderProfile>>& aProfiles);
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Configures the specified recorder using the specified profile.
|
||||
//
|
||||
// Return values:
|
||||
|
@ -118,6 +124,7 @@ public:
|
|||
static nsresult ConfigureRecorder(android::GonkRecorder& aRecorder,
|
||||
uint32_t aCameraId,
|
||||
const nsAString& aProfileName);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
GonkRecorderProfile(uint32_t aCameraId,
|
||||
|
@ -129,7 +136,9 @@ protected:
|
|||
bool GetMimeType(android::output_format aContainer, nsAString& aMimeType);
|
||||
bool IsValid() const { return mIsValid; };
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsresult ConfigureRecorder(android::GonkRecorder& aRecorder);
|
||||
#endif
|
||||
static already_AddRefed<GonkRecorderProfile> CreateProfile(uint32_t aCameraId,
|
||||
int aQuality);
|
||||
static ProfileHashtable* GetProfileHashtable(uint32_t aCameraId);
|
||||
|
|
|
@ -31,6 +31,10 @@ using namespace android;
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(TestGonkCameraHardware, GonkCameraHardware);
|
||||
#endif
|
||||
|
||||
static void
|
||||
CopyFaceFeature(int32_t (&aDst)[2], bool aExists, const DOMPoint* aSrc)
|
||||
{
|
||||
|
@ -633,6 +637,7 @@ TestGonkCameraHardware::PullParameters(GonkCameraParameters& aParams)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
int
|
||||
TestGonkCameraHardware::PushParameters(const CameraParameters& aParams)
|
||||
{
|
||||
|
@ -658,6 +663,7 @@ TestGonkCameraHardware::PullParameters(CameraParameters& aParams)
|
|||
String8 s(NS_LossyConvertUTF16toASCII(as).get());
|
||||
aParams.unflatten(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
TestGonkCameraHardware::StartRecording()
|
||||
|
|
|
@ -26,6 +26,10 @@ namespace mozilla {
|
|||
|
||||
class TestGonkCameraHardware : public android::GonkCameraHardware
|
||||
{
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
virtual int AutoFocus() MOZ_OVERRIDE;
|
||||
|
@ -40,8 +44,10 @@ public:
|
|||
virtual int StartRecording() MOZ_OVERRIDE;
|
||||
virtual int StopRecording() MOZ_OVERRIDE;
|
||||
virtual int StoreMetaDataInBuffers(bool aEnabled) MOZ_OVERRIDE;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
virtual int PushParameters(const android::CameraParameters& aParams) MOZ_OVERRIDE;
|
||||
virtual void PullParameters(android::CameraParameters& aParams) MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
TestGonkCameraHardware(mozilla::nsGonkCameraControl* aTarget,
|
||||
uint32_t aCameraId,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
if CONFIG['MOZ_B2G_CAMERA']:
|
||||
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
|
||||
|
||||
EXPORTS += [
|
||||
|
@ -36,13 +36,21 @@ if CONFIG['MOZ_B2G_CAMERA']:
|
|||
'GonkCameraHwMgr.cpp',
|
||||
'GonkCameraManager.cpp',
|
||||
'GonkCameraParameters.cpp',
|
||||
'GonkCameraSource.cpp',
|
||||
'GonkRecorder.cpp',
|
||||
'GonkRecorderProfiles.cpp',
|
||||
'TestGonkCameraControl.cpp',
|
||||
'TestGonkCameraHardware.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
UNIFIED_SOURCES += [
|
||||
'GonkCameraSource.cpp',
|
||||
'GonkRecorder.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'FallbackCameraPlatform.cpp',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'CameraTestHardware.js',
|
||||
'CameraTestHardware.manifest',
|
||||
|
|
|
@ -68,12 +68,18 @@ function CameraTestSuite() {
|
|||
this.logError = this._logError.bind(this);
|
||||
this.expectedError = this._expectedError.bind(this);
|
||||
this.expectedRejectGetCamera = this._expectedRejectGetCamera.bind(this);
|
||||
this.expectedRejectConfigure = this._expectedRejectConfigure.bind(this);
|
||||
this.expectedRejectAutoFocus = this._expectedRejectAutoFocus.bind(this);
|
||||
this.expectedRejectTakePicture = this._expectedRejectTakePicture.bind(this);
|
||||
this.expectedRejectStartRecording = this._expectedRejectStartRecording.bind(this);
|
||||
this.expectedRejectStopRecording = this._expectedRejectStopRecording.bind(this);
|
||||
this.rejectGetCamera = this._rejectGetCamera.bind(this);
|
||||
this.rejectConfigure = this._rejectConfigure.bind(this);
|
||||
this.rejectRelease = this._rejectRelease.bind(this);
|
||||
this.rejectAutoFocus = this._rejectAutoFocus.bind(this);
|
||||
this.rejectTakePicture = this._rejectTakePicture.bind(this);
|
||||
this.rejectStartRecording = this._rejectStartRecording.bind(this);
|
||||
this.rejectStopRecording = this._rejectStopRecording.bind(this);
|
||||
this.rejectPreviewStarted = this._rejectPreviewStarted.bind(this);
|
||||
|
||||
var self = this;
|
||||
|
@ -95,20 +101,35 @@ CameraTestSuite.prototype = {
|
|||
camera: null,
|
||||
hw: null,
|
||||
_lowMemSet: false,
|
||||
_reloading: false,
|
||||
|
||||
/* Returns a promise which is resolved when the test suite is ready
|
||||
to be executing individual test cases. One may provide the expected
|
||||
hardware type here if desired; the default is to use the JS test
|
||||
hardware. Use '' for the native emulated camera hardware. */
|
||||
_setup: function(hwType) {
|
||||
/* Depending on how we run the mochitest, we may not have the necessary
|
||||
permissions yet. If we do need to request them, then we have to reload
|
||||
the window to ensure the reconfiguration propogated properly. */
|
||||
if (!SpecialPowers.hasPermission("camera", document)) {
|
||||
info("requesting camera permission");
|
||||
this._reloading = true;
|
||||
SpecialPowers.addPermission("camera", true, document);
|
||||
window.location.reload();
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
info("has camera permission");
|
||||
if (!isDefined(hwType)) {
|
||||
hwType = 'hardware';
|
||||
}
|
||||
|
||||
this._hwType = hwType;
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({'set': [['camera.control.test.enabled', hwType]]}, function() {
|
||||
resolve();
|
||||
SpecialPowers.pushPrefEnv({'set': [['camera.control.test.permission', true]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({'set': [['camera.control.test.enabled', hwType]]}, function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -158,6 +179,10 @@ CameraTestSuite.prototype = {
|
|||
|
||||
/* Execute all test cases (after setup is called). */
|
||||
_run: function() {
|
||||
if (this._reloading) {
|
||||
return;
|
||||
}
|
||||
|
||||
var test = this._tests.shift();
|
||||
var self = this;
|
||||
if (test) {
|
||||
|
@ -348,6 +373,10 @@ CameraTestSuite.prototype = {
|
|||
return this.logError('get camera failed', e);
|
||||
},
|
||||
|
||||
_rejectConfigure: function(e) {
|
||||
return this.logError('set configuration failed', e);
|
||||
},
|
||||
|
||||
_rejectRelease: function(e) {
|
||||
return this.logError('release camera failed', e);
|
||||
},
|
||||
|
@ -360,6 +389,14 @@ CameraTestSuite.prototype = {
|
|||
return this.logError('take picture failed', e);
|
||||
},
|
||||
|
||||
_rejectStartRecording: function(e) {
|
||||
return this.logError('start recording failed', e);
|
||||
},
|
||||
|
||||
_rejectStopRecording: function(e) {
|
||||
return this.logError('stop recording failed', e);
|
||||
},
|
||||
|
||||
_rejectPreviewStarted: function(e) {
|
||||
return this.logError('preview start failed', e);
|
||||
},
|
||||
|
@ -384,6 +421,10 @@ CameraTestSuite.prototype = {
|
|||
return this.expectedError('expected get camera to fail');
|
||||
},
|
||||
|
||||
_expectedRejectConfigure: function(p) {
|
||||
return this.expectedError('expected set configuration to fail');
|
||||
},
|
||||
|
||||
_expectedRejectAutoFocus: function(p) {
|
||||
return this.expectedError('expected auto focus to fail');
|
||||
},
|
||||
|
@ -391,6 +432,14 @@ CameraTestSuite.prototype = {
|
|||
_expectedRejectTakePicture: function(p) {
|
||||
return this.expectedError('expected take picture to fail');
|
||||
},
|
||||
|
||||
_expectedRejectStartRecording: function(p) {
|
||||
return this.expectedError('expected start recording to fail');
|
||||
},
|
||||
|
||||
_expectedRejectStopRecording: function(p) {
|
||||
return this.expectedError('expected stop recording to fail');
|
||||
},
|
||||
};
|
||||
|
||||
ise(SpecialPowers.sanityCheck(), "foo", "SpecialPowers passed sanity check");
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
support-files = camera_common.js
|
||||
|
||||
[test_camera.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_camera_2.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_camera_3.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_camera_hardware_init_failure.html]
|
||||
[test_camera_hardware_failures.html]
|
||||
[test_bug975472.html]
|
||||
|
@ -14,4 +17,5 @@ support-files = camera_common.js
|
|||
[test_bug1037322.html]
|
||||
[test_bug1099390.html]
|
||||
[test_bug1104913.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_camera_bad_initial_config.html]
|
||||
|
|
|
@ -12,76 +12,56 @@
|
|||
<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 config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 320,
|
||||
height: 240
|
||||
}
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error: " + JSON.stringify(e));
|
||||
}
|
||||
suite.test('bug-1037322', function() {
|
||||
var cameraManager = navigator.mozCameras;
|
||||
var whichCamera = cameraManager.getListOfCameras()[0];
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
|
||||
start: function test_start() {
|
||||
function setConfig_onSuccess(cfg) {
|
||||
// Check our specific configuration
|
||||
ok(cfg.mode === config.mode, "Configured mode = " + cfg.mode);
|
||||
ok(cfg.previewSize.width === config.previewSize.width &&
|
||||
cfg.previewSize.height === config.previewSize.height,
|
||||
"Configured preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
|
||||
ok(cfg.recorderProfile === config.recorderProfile,
|
||||
"Configured recorder profile = '" + cfg.recorderProfile + "'");
|
||||
|
||||
SimpleTest.finish();
|
||||
var postConfig = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'low',
|
||||
previewSize: {
|
||||
width: 320,
|
||||
height: 240
|
||||
}
|
||||
};
|
||||
|
||||
function getCamera_onSuccess(d) {
|
||||
var camera = d.camera;
|
||||
var cfg = d.configuration;
|
||||
Camera.cameraObj = camera;
|
||||
Camera.viewfinder.mozSrcObject = camera;
|
||||
Camera.viewfinder.play();
|
||||
function resolveGetCamera(p) {
|
||||
suite.camera = p.camera;
|
||||
|
||||
// Check the default configuration
|
||||
ok(cfg.mode === "unspecified", "Initial mode = " + cfg.mode);
|
||||
ok(cfg.previewSize.width === 0 && cfg.previewSize.height === 0,
|
||||
"Initial preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
|
||||
ok(cfg.recorderProfile === "default",
|
||||
"Initial recorder profile = '" + cfg.recorderProfile + "'");
|
||||
|
||||
// Apply our specific configuration
|
||||
camera.setConfiguration(config).then(setConfig_onSuccess, onError);
|
||||
}
|
||||
|
||||
var cfg = {
|
||||
mode: 'unspecified',
|
||||
};
|
||||
navigator.mozCameras.getCamera(whichCamera, cfg).then(getCamera_onSuccess, onError);
|
||||
// Check the default configuration
|
||||
var cfg = p.configuration;
|
||||
ok(cfg.mode === "unspecified", "Initial mode = " + cfg.mode);
|
||||
ok(cfg.previewSize.width === 0 && cfg.previewSize.height === 0,
|
||||
"Initial preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
|
||||
ok(cfg.recorderProfile === "default",
|
||||
"Initial recorder profile = '" + cfg.recorderProfile + "'");
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
if (Camera.cameraObj) {
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
function configure(p) {
|
||||
// Apply our specific configuration
|
||||
return suite.camera.setConfiguration(postConfig);
|
||||
}
|
||||
|
||||
function resolveConfigure(cfg) {
|
||||
// Check our specific configuration
|
||||
ok(cfg.mode === postConfig.mode, "Configured mode = " + cfg.mode);
|
||||
ok(cfg.previewSize.width === postConfig.previewSize.width &&
|
||||
cfg.previewSize.height === postConfig.previewSize.height,
|
||||
"Configured preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
|
||||
ok(cfg.recorderProfile === postConfig.recorderProfile,
|
||||
"Configured recorder profile = '" + cfg.recorderProfile + "'");
|
||||
}
|
||||
|
||||
return cameraManager.getCamera(whichCamera, {mode: 'unspecified'})
|
||||
.then(resolveGetCamera, suite.rejectGetCamera)
|
||||
.then(configure)
|
||||
.then(resolveConfigure, suite.rejectConfigure);
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -12,95 +12,42 @@
|
|||
<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 config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 352,
|
||||
height: 288
|
||||
}
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
suite.test('bug-1099390', function() {
|
||||
function release(p) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var gotCloseEvent = false;
|
||||
var gotReleasePromise = false;
|
||||
|
||||
var Camera = {
|
||||
_cameraObj: null,
|
||||
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
|
||||
release: function release() {
|
||||
viewfinder.mozSrcObject = null;
|
||||
if (Camera._cameraObj) {
|
||||
Camera._cameraObj.release();
|
||||
Camera._cameraObj = null;
|
||||
}
|
||||
},
|
||||
|
||||
test: function test(cam) {
|
||||
var gotCloseEvent = false;
|
||||
var gotReleasePromise = false;
|
||||
|
||||
function gotAll() {
|
||||
var all = gotCloseEvent && gotReleasePromise;
|
||||
if (all) {
|
||||
info("Got all expected notifications");
|
||||
}
|
||||
return all;
|
||||
};
|
||||
|
||||
var onClosed = function(e) {
|
||||
cam.removeEventListener('close', onClosed);
|
||||
ok(!gotCloseEvent, "gotCloseEvent was " + gotCloseEvent);
|
||||
ok(e.reason === "HardwareReleased", "'close' event reason is: " + e.reason);
|
||||
gotCloseEvent = true;
|
||||
if (gotAll()) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
cam.addEventListener('close', onClosed);
|
||||
|
||||
var onResolve = function() {
|
||||
ok(!gotReleasePromise, "gotReleasePromise was " + gotReleasePromise);
|
||||
gotReleasePromise = true;
|
||||
if (gotAll()) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
cam.release().then(onResolve, onError);
|
||||
}, // test()
|
||||
|
||||
start: function start() {
|
||||
function onSuccess(d) {
|
||||
Camera._cameraObj = d.camera;
|
||||
var cam = d.camera;
|
||||
|
||||
var onPreviewStateChange = function(e) {
|
||||
if (e.newState === 'started') {
|
||||
cam.removeEventListener('previewstatechange', onPreviewStateChange);
|
||||
Camera.test(cam);
|
||||
var onClosed = function(e) {
|
||||
suite.camera.removeEventListener('close', onClosed);
|
||||
ok(!gotCloseEvent, "gotCloseEvent was " + gotCloseEvent);
|
||||
ok(e.reason === "HardwareReleased", "'close' event reason is: " + e.reason);
|
||||
gotCloseEvent = true;
|
||||
if (gotReleasePromise) {
|
||||
resolve();
|
||||
}
|
||||
}; // onPreviewStateChange
|
||||
cam.addEventListener('previewstatechange', onPreviewStateChange);
|
||||
}; // onSuccess()
|
||||
};
|
||||
|
||||
navigator.mozCameras.getCamera(whichCamera, config).then(onSuccess, onError);
|
||||
}, // start()
|
||||
}
|
||||
suite.camera.addEventListener('close', onClosed);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
suite.camera.release().then(function(p) {
|
||||
ok(true, "released camera");
|
||||
gotReleasePromise = true;
|
||||
if (gotCloseEvent) {
|
||||
resolve();
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.release();
|
||||
return suite.getCamera()
|
||||
.then(release, suite.rejectGetCamera);
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -12,237 +12,170 @@
|
|||
<img src="#" alt="This image is going to load" id="testimage"/>
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
const Cr = Components.results;
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'high',
|
||||
previewSize: {
|
||||
width: 320,
|
||||
height: 240
|
||||
}
|
||||
};
|
||||
var options = {
|
||||
rotation: 0,
|
||||
position: {
|
||||
latitude: 43.645687,
|
||||
longitude: -79.393661
|
||||
},
|
||||
dateTime: Date.now()
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
function next() {
|
||||
Camera.nextTest();
|
||||
function cameraRelease(p) {
|
||||
return suite.camera.release();
|
||||
}
|
||||
|
||||
// The array of tests
|
||||
var tests = [
|
||||
{
|
||||
key: "release-after-release",
|
||||
func: function testAutoFocus(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(true, "release() succeeded");
|
||||
next();
|
||||
}
|
||||
function onError(error) {
|
||||
ok(false, "release() failed with: " + error);
|
||||
}
|
||||
camera.release().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-picture-size-after-release",
|
||||
func: function testSetPictureSize(camera) {
|
||||
try {
|
||||
camera.setPictureSize({ width: 0, height: 0 });
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setPictureSize() failed with: " + e.name);
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-thumbnail-size-after-release",
|
||||
func: function testSetThumbnailSize(camera) {
|
||||
try {
|
||||
camera.setThumbnailSize({ width: 0, height: 0 });
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setThumbnailSize() failed with: " + e.name);
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "get-sensor-angle-after-release",
|
||||
func: function testGetSensorAngle(camera) {
|
||||
ok(camera.sensorAngle == 0, "camera.sensorAngle = " + camera.sensorAngle);
|
||||
next();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "resume-preview-after-release",
|
||||
func: function testResumePreview(camera) {
|
||||
try {
|
||||
camera.resumePreview();
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"resumePreview() failed with: " + e.name);
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "auto-focus-after-release",
|
||||
func: function testAutoFocus(camera) {
|
||||
function onSuccess(success) {
|
||||
ok(false, "autoFocus() succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"autoFocus() failed with: " + error.name);
|
||||
next();
|
||||
}
|
||||
camera.autoFocus().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "take-picture-after-release",
|
||||
func: function testTakePicture(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "takePicture() succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"takePicture() failed with: " + error.name);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "start-recording-after-release",
|
||||
func: function testStartRecording(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "startRecording() process succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"startRecording() failed with: " + error.name);
|
||||
next();
|
||||
}
|
||||
var recordingOptions = {
|
||||
profile: 'high',
|
||||
rotation: 0
|
||||
};
|
||||
camera.startRecording(recordingOptions,
|
||||
navigator.getDeviceStorage('videos'),
|
||||
'bug975472.mp4').then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "stop-recording-after-release",
|
||||
func: function testStopRecording(camera) {
|
||||
try {
|
||||
camera.stopRecording();
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"stopRecording() failed with: " + e.name);
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "set-configuration-after-release",
|
||||
func: function testSetConfiguration(camera) {
|
||||
function onSuccess(picture) {
|
||||
ok(false, "setConfiguration() process succeeded incorrectly");
|
||||
}
|
||||
function onError(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"setConfiguration() failed with: " + error.name);
|
||||
next();
|
||||
}
|
||||
camera.setConfiguration(config).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var testGenerator = function() {
|
||||
for (var i = 0; i < tests.length; ++i ) {
|
||||
yield tests[i];
|
||||
}
|
||||
}();
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
_otherPictureSize: null,
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
onCameraReady: function () {
|
||||
Camera.nextTest = function() {
|
||||
try {
|
||||
var t = testGenerator.next();
|
||||
info("test: " + t.key);
|
||||
t.func(Camera.cameraObj);
|
||||
} catch(e) {
|
||||
if (e instanceof StopIteration) {
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Release the camera hardware, and call all of the asynchronous methods
|
||||
// to make sure they properly handle being in this state.
|
||||
Camera.cameraObj.release();
|
||||
next();
|
||||
},
|
||||
release: function release() {
|
||||
cameraObj = null;
|
||||
},
|
||||
start: function run_test() {
|
||||
function onSuccess(d) {
|
||||
var camera = d.camera;
|
||||
Camera.cameraObj = camera;
|
||||
var onPreviewStateChange = function(e) {
|
||||
if (e.newState === 'started') {
|
||||
info("viewfinder is ready and playing");
|
||||
Camera.cameraObj.removeEventListener('previewstatechange', onPreviewStateChange);
|
||||
Camera.onCameraReady();
|
||||
}
|
||||
};
|
||||
camera.addEventListener('previewstatechange', onPreviewStateChange);
|
||||
Camera.viewfinder.mozSrcObject = camera;
|
||||
Camera.viewfinder.play();
|
||||
ok(camera.capabilities.pictureSizes.length > 0,
|
||||
"capabilities.pictureSizes.length = " +
|
||||
camera.capabilities.pictureSizes.length);
|
||||
Camera._otherPictureSize = camera.capabilities.pictureSizes.slice(-1)[0];
|
||||
camera.setPictureSize(camera.capabilities.pictureSizes[0]);
|
||||
options.pictureSize = Camera._otherPictureSize;
|
||||
options.fileFormat = camera.capabilities.fileFormats[0];
|
||||
info("getCamera callback, setting pictureSize = " + options.pictureSize.toSource());
|
||||
};
|
||||
navigator.mozCameras.getCamera(whichCamera, config).then(onSuccess, onError);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
suite.test('release-after-release', function() {
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(cameraRelease, suite.rejectRelease)
|
||||
.catch(suite.rejectRelease);
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
suite.test('set-picture-size-after-release', function() {
|
||||
function setPictureSize(p) {
|
||||
try {
|
||||
suite.camera.setPictureSize({ width: 0, height: 0 });
|
||||
ok(false, "SetPictureSize() should have failed");
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setPictureSize() failed with: " + e.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(setPictureSize, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.test('set-thumbnail-size-after-release', function() {
|
||||
function setThumbnailSize(p) {
|
||||
try {
|
||||
suite.camera.setThumbnailSize({ width: 0, height: 0 });
|
||||
ok(false, "SetThumbnailSize() should have failed");
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"setThumbnailSize() failed with: " + e.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(setThumbnailSize, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.test('get-sensor-angle-after-release', function() {
|
||||
function getSensorAngle(p) {
|
||||
ok(suite.camera.sensorAngle == 0, "camera.sensorAngle = " + suite.camera.sensorAngle);
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(getSensorAngle, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.test('resume-preview-after-release', function() {
|
||||
function resumePreview(p) {
|
||||
try {
|
||||
suite.camera.resumePreview();
|
||||
ok(false, "resumePreview() should have failed");
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"resumePreview() failed with: " + e.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(resumePreview, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.test('auto-focus-after-release', function() {
|
||||
function autoFocus(p) {
|
||||
return suite.camera.autoFocus();
|
||||
}
|
||||
|
||||
function rejectAutoFocus(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"autoFocus() failed with: " + error.name);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(autoFocus, suite.rejectRelease)
|
||||
.then(suite.expectedRejectAutoFocus, rejectAutoFocus);
|
||||
});
|
||||
|
||||
suite.test('take-picture-after-release', function() {
|
||||
function takePicture(p) {
|
||||
return suite.camera.takePicture(null);
|
||||
}
|
||||
|
||||
function rejectTakePicture(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"takePicture() failed with: " + error.name);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(takePicture, suite.rejectRelease)
|
||||
.then(suite.expectedRejectTakePicture, rejectTakePicture);
|
||||
});
|
||||
|
||||
suite.test('start-recording-after-release', function() {
|
||||
function startRecording(p) {
|
||||
return suite.camera.startRecording(
|
||||
{
|
||||
profile: 'high',
|
||||
rotation: 0
|
||||
},
|
||||
navigator.getDeviceStorage('videos'),
|
||||
'bug975472.mp4'
|
||||
);
|
||||
}
|
||||
|
||||
function rejectStartRecording(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"takePicture() failed with: " + error.name);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(startRecording, suite.rejectRelease)
|
||||
.then(suite.expectedRejectStartRecording, rejectStartRecording);
|
||||
});
|
||||
|
||||
suite.test('stop-recording-after-release', function() {
|
||||
function stopRecording(p) {
|
||||
try {
|
||||
suite.camera.stopRecording();
|
||||
ok(false, "stopRecording() should have failed");
|
||||
} catch(e) {
|
||||
ok(e.result === SpecialPowers.Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"stopRecording() failed with: " + e.name);
|
||||
}
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(stopRecording, suite.rejectRelease);
|
||||
});
|
||||
|
||||
suite.test('set-configuration-after-release', function() {
|
||||
function configure(p) {
|
||||
return suite.camera.setConfiguration(null);
|
||||
}
|
||||
|
||||
function rejectConfigure(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"takePicture() failed with: " + error.name);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return suite.getCamera()
|
||||
.then(cameraRelease, suite.rejectGetCamera)
|
||||
.then(configure, suite.rejectRelease)
|
||||
.then(suite.expectedRejectConfigure, rejectConfigure);
|
||||
});
|
||||
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -12,45 +12,31 @@
|
|||
<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 config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'foobar',
|
||||
};
|
||||
var suite = new CameraTestSuite();
|
||||
|
||||
var Camera = {
|
||||
cameraObj: null,
|
||||
suite.test('bad-initial-config', function() {
|
||||
function getCamera() {
|
||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
||||
var config = {
|
||||
mode: 'picture',
|
||||
recorderProfile: 'foobar',
|
||||
};
|
||||
|
||||
get viewfinder() {
|
||||
return document.getElementById('viewfinder');
|
||||
},
|
||||
|
||||
start: function test_start() {
|
||||
function getCamera_onSuccess(d) {
|
||||
ok(false, "Get camera should have failed");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function getCamera_onError(e) {
|
||||
ok(true, "Get camera failed as expected: " + JSON.stringify(e));
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
navigator.mozCameras.getCamera(whichCamera, config).then(getCamera_onSuccess, getCamera_onError);
|
||||
return navigator.mozCameras.getCamera(whichCamera, config);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
Camera.viewfinder.mozSrcObject = null;
|
||||
if (Camera.cameraObj) {
|
||||
Camera.cameraObj.release();
|
||||
Camera.cameraObj = null;
|
||||
function rejectGetCamera(error) {
|
||||
ok(error.name === "NS_ERROR_NOT_AVAILABLE",
|
||||
"getCamera() failed with: " + error.name);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return getCamera()
|
||||
.then(suite.expectedRejectGetCamera, rejectGetCamera);
|
||||
});
|
||||
|
||||
Camera.start();
|
||||
suite.setup()
|
||||
.then(suite.run);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -391,7 +391,7 @@ MediaDevice::MediaDevice(MediaEngineSource* aSource)
|
|||
|
||||
VideoDevice::VideoDevice(MediaEngineVideoSource* aSource)
|
||||
: MediaDevice(aSource) {
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
if (mName.EqualsLiteral("back")) {
|
||||
mHasFacingMode = true;
|
||||
mFacingMode = dom::VideoFacingModeEnum::Environment;
|
||||
|
@ -1705,7 +1705,7 @@ MediaManager::GetUserMedia(
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
if (mCameraManager == nullptr) {
|
||||
mCameraManager = nsDOMCameraManager::CreateInstance(aWindow);
|
||||
}
|
||||
|
|
|
@ -630,7 +630,7 @@ private:
|
|||
|
||||
static StaticRefPtr<MediaManager> sSingleton;
|
||||
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
nsRefPtr<nsDOMCameraManager> mCameraManager;
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ GetUserMediaLog()
|
|||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
#include "ICameraControl.h"
|
||||
#include "MediaEngineGonkVideoSource.h"
|
||||
#endif
|
||||
|
@ -62,7 +62,9 @@ MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
|
|||
compMgr->IsContractIDRegistered(NS_TABSOURCESERVICE_CONTRACTID, &mHasTabVideoSource);
|
||||
}
|
||||
#else
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
AsyncLatencyLogger::Get()->AddRef();
|
||||
#endif
|
||||
#endif
|
||||
// XXX
|
||||
gFarendObserver = new AudioOutputObserver();
|
||||
|
@ -78,7 +80,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
|
|||
// We spawn threads to handle gUM runnables, so we must protect the member vars
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
if (aMediaSource != dom::MediaSourceEnum::Camera) {
|
||||
// only supports camera sources
|
||||
return;
|
||||
|
|
|
@ -255,7 +255,7 @@ public:
|
|||
private:
|
||||
~MediaEngineWebRTC() {
|
||||
Shutdown();
|
||||
#ifdef MOZ_B2G_CAMERA
|
||||
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
|
||||
AsyncLatencyLogger::Get()->Release();
|
||||
#endif
|
||||
gFarendObserver = nullptr;
|
||||
|
|
|
@ -36,7 +36,7 @@ if CONFIG['MOZ_WEBRTC']:
|
|||
'/media/webrtc/trunk',
|
||||
]
|
||||
# Gonk camera source.
|
||||
if CONFIG['MOZ_B2G_CAMERA']:
|
||||
if CONFIG['MOZ_B2G_CAMERA'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
EXPORTS += [
|
||||
'GonkCameraImage.h',
|
||||
'MediaEngineGonkVideoSource.h',
|
||||
|
|
|
@ -162,14 +162,15 @@ NfcContentHelper.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
writeNDEF: function writeNDEF(records, sessionToken, callback) {
|
||||
writeNDEF: function writeNDEF(records, isP2P, sessionToken, callback) {
|
||||
let requestId = callback.getCallbackId();
|
||||
this._requestMap[requestId] = callback;
|
||||
|
||||
cpmm.sendAsyncMessage("NFC:WriteNDEF", {
|
||||
requestId: requestId,
|
||||
sessionToken: sessionToken,
|
||||
records: records
|
||||
records: records,
|
||||
isP2P: isP2P
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -91,6 +91,14 @@ const NfcRequestType = {
|
|||
TRANSCEIVE: "transceive"
|
||||
};
|
||||
|
||||
const CommandMsgTable = {};
|
||||
CommandMsgTable["NFC:ChangeRFState"] = NfcRequestType.CHANGE_RF_STATE;
|
||||
CommandMsgTable["NFC:ReadNDEF"] = NfcRequestType.READ_NDEF;
|
||||
CommandMsgTable["NFC:WriteNDEF"] = NfcRequestType.WRITE_NDEF;
|
||||
CommandMsgTable["NFC:MakeReadOnly"] = NfcRequestType.MAKE_READ_ONLY;
|
||||
CommandMsgTable["NFC:Format"] = NfcRequestType.FORMAT;
|
||||
CommandMsgTable["NFC:Transceive"] = NfcRequestType.TRANSCEIVE;
|
||||
|
||||
// Should be consistent with NfcResponseType defined in NfcOptions.webidl.
|
||||
const NfcResponseType = {
|
||||
CHANGE_RF_STATE_RSP: "changeRFStateRsp",
|
||||
|
@ -398,6 +406,20 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
case "NFC:CallDefaultLostHandler":
|
||||
this.callDefaultLostHandler(message.data);
|
||||
return null;
|
||||
case "NFC:SendFile":
|
||||
// Chrome process is the arbitrator / mediator between
|
||||
// system app (content process) that issued nfc 'sendFile' operation
|
||||
// and system app that handles the system message :
|
||||
// 'nfc-manager-send-file'. System app subsequently handover's
|
||||
// the data to alternate carrier's (BT / WiFi) 'sendFile' interface.
|
||||
|
||||
// Notify system app to initiate BT send file operation
|
||||
let sysMsg = new NfcSendFileSysMsg(message.data.requestId,
|
||||
message.data.sessionToken,
|
||||
message.data.blob);
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-send-file",
|
||||
sysMsg);
|
||||
return null;
|
||||
default:
|
||||
return this.nfc.receiveMessage(message);
|
||||
}
|
||||
|
@ -671,52 +693,18 @@ Nfc.prototype = {
|
|||
break;
|
||||
}
|
||||
|
||||
if (["NFC:ChangeRFState",
|
||||
"NFC:SendFile"].indexOf(message.name) == -1) {
|
||||
if (message.name != "NFC:ChangeRFState") {
|
||||
// Update the current sessionId before sending to the NFC service.
|
||||
message.data.sessionId = SessionHelper.getId(message.data.sessionToken);
|
||||
}
|
||||
|
||||
switch (message.name) {
|
||||
case "NFC:ChangeRFState":
|
||||
this.sendToNfcService(NfcRequestType.CHANGE_RF_STATE, message.data);
|
||||
break;
|
||||
case "NFC:ReadNDEF":
|
||||
this.sendToNfcService(NfcRequestType.READ_NDEF, message.data);
|
||||
break;
|
||||
case "NFC:WriteNDEF":
|
||||
message.data.isP2P = SessionHelper.isP2PSession(message.data.sessionId);
|
||||
this.sendToNfcService(NfcRequestType.WRITE_NDEF, message.data);
|
||||
break;
|
||||
case "NFC:MakeReadOnly":
|
||||
this.sendToNfcService(NfcRequestType.MAKE_READ_ONLY, message.data);
|
||||
break;
|
||||
case "NFC:Format":
|
||||
this.sendToNfcService(NfcRequestType.FORMAT, message.data);
|
||||
break;
|
||||
case "NFC:Transceive":
|
||||
this.sendToNfcService(NfcRequestType.TRANSCEIVE, message.data);
|
||||
break;
|
||||
case "NFC:SendFile":
|
||||
// Chrome process is the arbitrator / mediator between
|
||||
// system app (content process) that issued nfc 'sendFile' operation
|
||||
// and system app that handles the system message :
|
||||
// 'nfc-manager-send-file'. System app subsequently handover's
|
||||
// the data to alternate carrier's (BT / WiFi) 'sendFile' interface.
|
||||
|
||||
// Notify system app to initiate BT send file operation
|
||||
let sysMsg = new NfcSendFileSysMsg(message.data.requestId,
|
||||
message.data.sessionToken,
|
||||
message.data.blob);
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-send-file",
|
||||
sysMsg);
|
||||
break;
|
||||
default:
|
||||
debug("UnSupported : Message Name " + message.name);
|
||||
return null;
|
||||
let command = CommandMsgTable[message.name];
|
||||
if (!command) {
|
||||
debug("Unknown message: " + message.name);
|
||||
return null;
|
||||
}
|
||||
this.targetsByRequestId[message.data.requestId] = message.target;
|
||||
|
||||
this.sendToNfcService(command, message.data);
|
||||
return null;
|
||||
},
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ interface nsINfcBrowserAPI : nsISupports
|
|||
in boolean isFocus);
|
||||
};
|
||||
|
||||
[scriptable, uuid(39e1b25b-5063-449e-b9e8-5514cdca9c3a)]
|
||||
[scriptable, uuid(9cf841c9-0347-4564-99e5-18c0f74eca4d)]
|
||||
interface nsINfcContentHelper : nsISupports
|
||||
{
|
||||
void init(in nsIDOMWindow window);
|
||||
|
@ -142,6 +142,8 @@ interface nsINfcContentHelper : nsISupports
|
|||
* @param records
|
||||
* NDEF records to be written
|
||||
*
|
||||
* @param isP2P
|
||||
* If this write is for P2P.
|
||||
* @param sessionToken
|
||||
* Current token
|
||||
*
|
||||
|
@ -149,6 +151,7 @@ interface nsINfcContentHelper : nsISupports
|
|||
* Called when request is finished
|
||||
*/
|
||||
void writeNDEF(in nsIVariant records,
|
||||
in boolean isP2P,
|
||||
in DOMString sessionToken,
|
||||
in nsINfcRequestCallback callback);
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ MozNFCTagImpl.prototype = {
|
|||
}
|
||||
|
||||
let callback = new NfcCallback(this._window);
|
||||
this._nfcContentHelper.writeNDEF(records, this.session, callback);
|
||||
this._nfcContentHelper.writeNDEF(records, false, this.session, callback);
|
||||
return callback.promise;
|
||||
},
|
||||
|
||||
|
@ -281,7 +281,7 @@ MozNFCPeerImpl.prototype = {
|
|||
|
||||
// Just forward sendNDEF to writeNDEF
|
||||
let callback = new NfcCallback(this._window);
|
||||
this._nfcContentHelper.writeNDEF(records, this.session, callback);
|
||||
this._nfcContentHelper.writeNDEF(records, true, this.session, callback);
|
||||
return callback.promise;
|
||||
},
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
/* global RIL */
|
||||
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
|
||||
let obj = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", obj);
|
||||
|
@ -59,14 +60,17 @@ const RIL_IPC_MSG_NAMES = [
|
|||
"RIL:GetServiceState"
|
||||
];
|
||||
|
||||
/* global cpmm */
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
/* global UUIDGenerator */
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
"nsIUUIDGenerator");
|
||||
|
||||
/* global gNumRadioInterfaces */
|
||||
XPCOMUtils.defineLazyGetter(this, "gNumRadioInterfaces", function() {
|
||||
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
|
||||
|
@ -77,7 +81,7 @@ XPCOMUtils.defineLazyGetter(this, "gNumRadioInterfaces", function() {
|
|||
try {
|
||||
ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
|
||||
} catch(e) {}
|
||||
return ril.numRadioInterfaces
|
||||
return ril.numRadioInterfaces;
|
||||
}
|
||||
|
||||
return Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
|
||||
|
|
|
@ -609,6 +609,11 @@ void
|
|||
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
int charge;
|
||||
static bool previousCharging = false;
|
||||
static double previousLevel = 0.0, remainingTime = 0.0;
|
||||
static struct timespec lastLevelChange;
|
||||
struct timespec now;
|
||||
double dtime, dlevel;
|
||||
|
||||
if (GetCurrentBatteryCharge(&charge)) {
|
||||
aBatteryInfo->level() = (double)charge / 100.0;
|
||||
|
@ -624,11 +629,50 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
|||
aBatteryInfo->charging() = true;
|
||||
}
|
||||
|
||||
if (!aBatteryInfo->charging() || (aBatteryInfo->level() < 1.0)) {
|
||||
if (aBatteryInfo->charging() != previousCharging){
|
||||
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
|
||||
} else {
|
||||
aBatteryInfo->remainingTime() = dom::battery::kDefaultRemainingTime;
|
||||
memset(&lastLevelChange, 0, sizeof(struct timespec));
|
||||
}
|
||||
|
||||
if (aBatteryInfo->charging()) {
|
||||
if (aBatteryInfo->level() == 1.0) {
|
||||
aBatteryInfo->remainingTime() = dom::battery::kDefaultRemainingTime;
|
||||
} else if (aBatteryInfo->level() != previousLevel){
|
||||
if (lastLevelChange.tv_sec != 0) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
dtime = now.tv_sec - lastLevelChange.tv_sec;
|
||||
dlevel = aBatteryInfo->level() - previousLevel;
|
||||
|
||||
if (dlevel <= 0.0) {
|
||||
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
|
||||
} else {
|
||||
remainingTime = (double) round(dtime / dlevel * (1.0 - aBatteryInfo->level()));
|
||||
aBatteryInfo->remainingTime() = remainingTime;
|
||||
}
|
||||
|
||||
lastLevelChange = now;
|
||||
} else { // lastLevelChange.tv_sec == 0
|
||||
clock_gettime(CLOCK_MONOTONIC, &lastLevelChange);
|
||||
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
|
||||
}
|
||||
|
||||
} else {
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
dtime = now.tv_sec - lastLevelChange.tv_sec;
|
||||
if (dtime < remainingTime) {
|
||||
aBatteryInfo->remainingTime() = round(remainingTime - dtime);
|
||||
} else {
|
||||
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
|
||||
}
|
||||
|
||||
previousCharging = aBatteryInfo->charging();
|
||||
previousLevel = aBatteryInfo->level();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -11,4 +11,4 @@ skip-if(B2G||Mulet) fails-if(Android) == radio-stretched.html radio-stretched-re
|
|||
!= indeterminate-native-checked.html indeterminate-native-checked-notref.html
|
||||
!= indeterminate-native-unchecked.html indeterminate-native-unchecked-notref.html
|
||||
== indeterminate-selector.html indeterminate-selector-ref.html
|
||||
skip-if(!gtk2Widget) == gtk-theme-width-height.html gtk-theme-width-height-ref.html
|
||||
skip-if(!gtk2Widget||Mulet) == gtk-theme-width-height.html gtk-theme-width-height-ref.html # bug 1141511: Disable some gtk2Widget-dependant reftests on Mulet
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
!= checked-notref.html about:blank
|
||||
!= checked-native.html about:blank
|
||||
!= checked-native-notref.html about:blank
|
||||
skip-if(!gtk2Widget) == gtk-theme-width-height.html gtk-theme-width-height-ref.html
|
||||
skip-if(!gtk2Widget||Mulet) == gtk-theme-width-height.html gtk-theme-width-height-ref.html # bug 1141511: Disable some gtk2Widget-dependant reftests on Mulet
|
||||
|
|
|
@ -6,4 +6,4 @@ fuzzy-if(d2d,16,96) == outline-and-3d-transform-2.html outline-and-3d-transform-
|
|||
== outline-overflow-block-float.html outline-overflow-block-ref.html
|
||||
== outline-overflow-inlineblock-abspos.html outline-overflow-inlineblock-ref.html
|
||||
== outline-overflow-inlineblock-float.html outline-overflow-inlineblock-ref.html
|
||||
pref(layout.css.outline-style-auto.enabled,true) skip-if(!gtk2Widget&&!winWidget&&!cocoaWidget) == outline-auto-001.html outline-auto-001-ref.html # only works on platforms that supports NS_THEME_FOCUS_OUTLINE
|
||||
pref(layout.css.outline-style-auto.enabled,true) skip-if((!gtk2Widget&&!winWidget&&!cocoaWidget)||Mulet) == outline-auto-001.html outline-auto-001-ref.html # only works on platforms that supports NS_THEME_FOCUS_OUTLINE # bug 1141511: Disable some gtk2Widget-dependant reftests on Mulet
|
||||
|
|
|
@ -201,7 +201,7 @@ if CONFIG['MOZ_B2G_BT_BLUEZ'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
|||
'dbus',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G_CAMERA']:
|
||||
if CONFIG['MOZ_B2G_CAMERA'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
OS_LIBS += [
|
||||
'stagefright',
|
||||
'stagefright_omx',
|
||||
|
|
Загрузка…
Ссылка в новой задаче