merge b2g-inbound to mozilla-central
This commit is contained in:
@@ -650,6 +650,9 @@ pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
|
||||
pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
|
||||
pref("hal.processPriorityManager.gonk.MASTER.Nice", 0);
|
||||
|
||||
pref("hal.processPriorityManager.gonk.PREALLOC.OomScoreAdjust", 67);
|
||||
pref("hal.processPriorityManager.gonk.PREALLOC.Nice", 18);
|
||||
|
||||
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.OomScoreAdjust", 67);
|
||||
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
|
||||
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.Nice", 0);
|
||||
|
||||
59
b2g/chrome/content/desktop.css
Normal file
59
b2g/chrome/content/desktop.css
Normal file
@@ -0,0 +1,59 @@
|
||||
#controls {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom:0;
|
||||
right: 0;
|
||||
height: 30px;
|
||||
background-color: -moz-dialog;
|
||||
}
|
||||
|
||||
#home-button {
|
||||
margin: auto;
|
||||
margin-top: 3px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: #eee url("images/desktop/home-black.png") center no-repeat;
|
||||
border: 1px solid #888;
|
||||
border-radius: 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#home-button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#home-button:hover {
|
||||
background-image: url("images/desktop/home-white.png");
|
||||
background-color: #ccc;
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
#home-button.active {
|
||||
background-image: url("images/desktop/home-white.png");
|
||||
background-color: #888;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
#rotate-button {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
bottom: 3px;
|
||||
right: 3px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: #eee url("images/desktop/rotate.png") center no-repeat;
|
||||
border: 1px solid #888;
|
||||
border-radius: 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#rotate-button:hover {
|
||||
background-color: #ccc;
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
#rotate-button.active {
|
||||
background-color: #888;
|
||||
border-color: black;
|
||||
}
|
||||
@@ -2,16 +2,51 @@
|
||||
* 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/. */
|
||||
|
||||
window.addEventListener("ContentStart", function(evt) {
|
||||
// Enable touch event shim on desktop that translates mouse events
|
||||
// into touch ones
|
||||
let require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {})
|
||||
// Enable touch event shim on desktop that translates mouse events
|
||||
// into touch ones
|
||||
function enableTouch() {
|
||||
let require = Cu.import('resource://gre/modules/devtools/Loader.jsm', {})
|
||||
.devtools.require;
|
||||
let { TouchEventHandler } = require("devtools/touch-events");
|
||||
let { TouchEventHandler } = require('devtools/touch-events');
|
||||
let chromeEventHandler = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler || window;
|
||||
let touchEventHandler = new TouchEventHandler(chromeEventHandler);
|
||||
touchEventHandler.start();
|
||||
}
|
||||
|
||||
function setupButtons() {
|
||||
let homeButton = document.getElementById('home-button');
|
||||
if (!homeButton) {
|
||||
// The toolbar only exists in b2g desktop build with
|
||||
// FXOS_SIMULATOR turned on.
|
||||
return;
|
||||
}
|
||||
// The touch event helper is enabled on shell.html document,
|
||||
// so that click events are delayed and it is better to
|
||||
// listen for touch events.
|
||||
homeButton.addEventListener('touchstart', function() {
|
||||
shell.sendChromeEvent({type: 'home-button-press'});
|
||||
homeButton.classList.add('active');
|
||||
});
|
||||
homeButton.addEventListener('touchend', function() {
|
||||
shell.sendChromeEvent({type: 'home-button-release'});
|
||||
homeButton.classList.remove('active');
|
||||
});
|
||||
|
||||
Cu.import("resource://gre/modules/GlobalSimulatorScreen.jsm");
|
||||
let rotateButton = document.getElementById('rotate-button');
|
||||
rotateButton.addEventListener('touchstart', function () {
|
||||
rotateButton.classList.add('active');
|
||||
});
|
||||
rotateButton.addEventListener('touchend', function() {
|
||||
GlobalSimulatorScreen.flipScreen();
|
||||
rotateButton.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('ContentStart', function() {
|
||||
enableTouch();
|
||||
setupButtons();
|
||||
});
|
||||
|
||||
BIN
b2g/chrome/content/images/desktop/home-black.png
Normal file
BIN
b2g/chrome/content/images/desktop/home-black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 331 B |
BIN
b2g/chrome/content/images/desktop/home-white.png
Normal file
BIN
b2g/chrome/content/images/desktop/home-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 B |
BIN
b2g/chrome/content/images/desktop/rotate.png
Normal file
BIN
b2g/chrome/content/images/desktop/rotate.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 657 B |
@@ -18,7 +18,7 @@ window.addEventListener('ContentStart', function() {
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
let hostDPI = windowUtils.displayDPI;
|
||||
|
||||
let DEFAULT_SCREEN = "320x480";
|
||||
let DEFAULT_SCREEN = '320x480';
|
||||
|
||||
// This is a somewhat random selection of named screens.
|
||||
// Add more to this list when we support more hardware.
|
||||
@@ -121,6 +121,11 @@ window.addEventListener('ContentStart', function() {
|
||||
usage();
|
||||
}
|
||||
|
||||
Cu.import("resource://gre/modules/GlobalSimulatorScreen.jsm");
|
||||
function resize(width, height, dpi, shouldFlip) {
|
||||
GlobalSimulatorScreen.width = width;
|
||||
GlobalSimulatorScreen.height = height;
|
||||
|
||||
// In order to do rescaling, we set the <browser> tag to the specified
|
||||
// width and height, and then use a CSS transform to scale it so that
|
||||
// it appears at the correct size on the host display. We also set
|
||||
@@ -128,28 +133,80 @@ window.addEventListener('ContentStart', function() {
|
||||
let scale = rescale ? hostDPI / dpi : 1;
|
||||
|
||||
// Set the window width and height to desired size plus chrome
|
||||
// Include the size of the toolbox displayed under the system app
|
||||
let controls = document.getElementById('controls');
|
||||
let controlsHeight = 0;
|
||||
if (controls) {
|
||||
controlsHeight = controls.getBoundingClientRect().height;
|
||||
}
|
||||
let chromewidth = window.outerWidth - window.innerWidth;
|
||||
let chromeheight = window.outerHeight - window.innerHeight;
|
||||
let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
|
||||
window.resizeTo(Math.round(width * scale) + chromewidth,
|
||||
Math.round(height * scale) + chromeheight);
|
||||
|
||||
let frameWidth = width, frameHeight = height;
|
||||
if (shouldFlip) {
|
||||
frameWidth = height;
|
||||
frameHeight = width;
|
||||
}
|
||||
|
||||
// Set the browser element to the full unscaled size of the screen
|
||||
browser.style.width = browser.style.minWidth = browser.style.maxWidth =
|
||||
width + 'px';
|
||||
browser.style.height = browser.style.minHeight = browser.style.maxHeight =
|
||||
height + 'px';
|
||||
let style = browser.style;
|
||||
style.width = style.minWidth = style.maxWidth =
|
||||
frameWidth + 'px';
|
||||
style.height = style.minHeight = style.maxHeight =
|
||||
frameHeight + 'px';
|
||||
browser.setAttribute('flex', '0'); // Don't let it stretch
|
||||
|
||||
style.transformOrigin = '';
|
||||
style.transform = '';
|
||||
|
||||
// Now scale the browser element as needed
|
||||
if (scale !== 1) {
|
||||
browser.style.transformOrigin = 'top left';
|
||||
browser.style.transform = 'scale(' + scale + ',' + scale + ')';
|
||||
style.transformOrigin = 'top left';
|
||||
style.transform += ' scale(' + scale + ',' + scale + ')';
|
||||
}
|
||||
|
||||
if (shouldFlip) {
|
||||
// Display the system app with a 90° clockwise rotation
|
||||
let shift = Math.floor(Math.abs(frameWidth-frameHeight) / 2);
|
||||
style.transform +=
|
||||
' rotate(0.25turn) translate(-' + shift + 'px, -' + shift + 'px)';
|
||||
}
|
||||
|
||||
// Set the pixel density that we want to simulate.
|
||||
// This doesn't change the on-screen size, but makes
|
||||
// CSS media queries and mozmm units work right.
|
||||
Services.prefs.setIntPref('layout.css.dpi', dpi);
|
||||
}
|
||||
|
||||
// Resize on startup
|
||||
resize(width, height, dpi, false);
|
||||
|
||||
let defaultOrientation = width < height ? 'portrait' : 'landscape';
|
||||
|
||||
// Then resize on each rotation button click,
|
||||
// or when the system app lock/unlock the orientation
|
||||
Services.obs.addObserver(function orientationChangeListener(subject) {
|
||||
let screen = subject.wrappedJSObject;
|
||||
let { mozOrientation, screenOrientation } = screen;
|
||||
|
||||
let newWidth = width;
|
||||
let newHeight = height;
|
||||
// If we have an orientation different than the startup one,
|
||||
// we switch the sizes
|
||||
if (screenOrientation != defaultOrientation) {
|
||||
newWidth = height;
|
||||
newHeight = width;
|
||||
}
|
||||
|
||||
// If the current app doesn't supports the current screen orientation
|
||||
// still resize the window, but rotate its frame so that
|
||||
// it is displayed rotated on the side
|
||||
let shouldFlip = mozOrientation != screenOrientation;
|
||||
|
||||
resize(newWidth, newHeight, dpi, shouldFlip);
|
||||
}, 'simulator-adjust-window-size', false);
|
||||
|
||||
// A utility function like console.log() for printing to the terminal window
|
||||
// Uses dump(), but enables it first, if necessary
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="shell.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="shell.css" type="text/css">
|
||||
#ifdef FXOS_SIMULATOR
|
||||
<link rel="stylesheet" href="desktop.css" type="text/css">
|
||||
#endif
|
||||
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://b2g/content/settings.js"> </script>
|
||||
<script type="application/javascript;version=1.8"
|
||||
@@ -31,7 +35,15 @@
|
||||
#endif
|
||||
</head>
|
||||
<body id="container">
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#ifdef FXOS_SIMULATOR
|
||||
<!--
|
||||
Some additional buttons are displayed on desktop to fake hardware buttons.
|
||||
-->
|
||||
<footer id="controls">
|
||||
<button id="home-button"></button>
|
||||
<button id="rotate-button"></button>
|
||||
</footer>
|
||||
#elifdef MOZ_WIDGET_COCOA
|
||||
<!--
|
||||
If the document is empty at startup, we don't display the window
|
||||
at all on Mac OS...
|
||||
|
||||
@@ -303,7 +303,11 @@ var shell = {
|
||||
systemAppFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
|
||||
let container = document.getElementById('container');
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
container.removeChild(document.getElementById('placeholder'));
|
||||
// See shell.html
|
||||
let hotfix = document.getElementById('placeholder');
|
||||
if (hotfix) {
|
||||
container.removeChild(hotfix);
|
||||
}
|
||||
#endif
|
||||
container.appendChild(systemAppFrame);
|
||||
|
||||
|
||||
@@ -14,7 +14,13 @@ chrome.jar:
|
||||
* content/shell.js (content/shell.js)
|
||||
content/shell.css (content/shell.css)
|
||||
content/devtools.js (content/devtools.js)
|
||||
#ifndef ANDROID
|
||||
#ifdef FXOS_SIMULATOR
|
||||
content/desktop.css (content/desktop.css)
|
||||
content/images/desktop/home-black.png (content/images/desktop/home-black.png)
|
||||
content/images/desktop/home-white.png (content/images/desktop/home-white.png)
|
||||
content/images/desktop/rotate.png (content/images/desktop/rotate.png)
|
||||
#endif
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
content/desktop.js (content/desktop.js)
|
||||
content/screen.js (content/screen.js)
|
||||
content/runapp.js (content/runapp.js)
|
||||
|
||||
@@ -81,3 +81,9 @@ contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3
|
||||
# HelperAppDialog.js
|
||||
component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js
|
||||
contract @mozilla.org/helperapplauncherdialog;1 {710322af-e6ae-4b0c-b2c9-1474a87b077e}
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js
|
||||
contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880}
|
||||
category profile-after-change SimulatorScreen @mozilla.org/simulator-screen;1
|
||||
#endif
|
||||
|
||||
90
b2g/components/GlobalSimulatorScreen.jsm
Normal file
90
b2g/components/GlobalSimulatorScreen.jsm
Normal file
@@ -0,0 +1,90 @@
|
||||
/* 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/. */
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ 'GlobalSimulatorScreen' ];
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
this.GlobalSimulatorScreen = {
|
||||
mozOrientationLocked: false,
|
||||
|
||||
// Actual orientation of apps
|
||||
mozOrientation: 'portrait',
|
||||
|
||||
// The restricted list of actual orientation that can be used
|
||||
// if mozOrientationLocked is true
|
||||
lockedOrientation: [],
|
||||
|
||||
// The faked screen orientation
|
||||
// if screenOrientation doesn't match mozOrientation due
|
||||
// to lockedOrientation restriction, the app will be displayed
|
||||
// on the side on desktop
|
||||
screenOrientation: 'portrait',
|
||||
|
||||
// Updated by screen.js
|
||||
width: 0, height: 0,
|
||||
|
||||
lock: function(orientation) {
|
||||
this.mozOrientationLocked = true;
|
||||
|
||||
// Normalize to portrait or landscape,
|
||||
// i.e. the possible values of screenOrientation
|
||||
function normalize(str) {
|
||||
if (str.match(/^portrait/)) {
|
||||
return 'portrait';
|
||||
} else if (str.match(/^landscape/)) {
|
||||
return 'landscape';
|
||||
} else {
|
||||
return 'portrait';
|
||||
}
|
||||
}
|
||||
this.lockedOrientation = orientation.map(normalize);
|
||||
|
||||
this.updateOrientation();
|
||||
},
|
||||
|
||||
unlock: function() {
|
||||
this.mozOrientationLocked = false;
|
||||
this.updateOrientation();
|
||||
},
|
||||
|
||||
updateOrientation: function () {
|
||||
let orientation = this.screenOrientation;
|
||||
|
||||
// If the orientation is locked, we have to ensure ending up with a value
|
||||
// of lockedOrientation. If none of lockedOrientation values matches
|
||||
// the screen orientation we just choose the first locked orientation.
|
||||
// This will be the precise scenario where the app is displayed on the
|
||||
// side on desktop!
|
||||
if (this.mozOrientationLocked &&
|
||||
this.lockedOrientation.indexOf(this.screenOrientation) == -1) {
|
||||
orientation = this.lockedOrientation[0];
|
||||
}
|
||||
|
||||
// If the actual orientation changed,
|
||||
// we have to fire mozorientation DOM events
|
||||
if (this.mozOrientation != orientation) {
|
||||
this.mozOrientation = orientation;
|
||||
|
||||
// Notify each app screen object to fire the event
|
||||
Services.obs.notifyObservers(null, 'simulator-orientation-change', null);
|
||||
}
|
||||
|
||||
// Finally, in any case, we update the window size and orientation
|
||||
// (Use wrappedJSObject trick to be able to pass a raw JS object)
|
||||
Services.obs.notifyObservers({wrappedJSObject:this}, 'simulator-adjust-window-size', null);
|
||||
},
|
||||
|
||||
flipScreen: function() {
|
||||
if (this.screenOrientation == 'portrait') {
|
||||
this.screenOrientation = 'landscape';
|
||||
} else if (this.screenOrientation == 'landscape') {
|
||||
this.screenOrientation = 'portrait';
|
||||
}
|
||||
this.updateOrientation();
|
||||
}
|
||||
}
|
||||
112
b2g/components/SimulatorScreen.js
Normal file
112
b2g/components/SimulatorScreen.js
Normal file
@@ -0,0 +1,112 @@
|
||||
/* 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/. */
|
||||
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen',
|
||||
'resource://gre/modules/GlobalSimulatorScreen.jsm');
|
||||
|
||||
let DEBUG_PREFIX = 'SimulatorScreen.js - ';
|
||||
function debug() {
|
||||
//dump(DEBUG_PREFIX + Array.slice(arguments) + '\n');
|
||||
}
|
||||
|
||||
function fireOrientationEvent(window) {
|
||||
let e = new window.Event('mozorientationchange');
|
||||
window.screen.dispatchEvent(e);
|
||||
}
|
||||
|
||||
function hookScreen(window) {
|
||||
let nodePrincipal = window.document.nodePrincipal;
|
||||
let origin = nodePrincipal.origin;
|
||||
if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
|
||||
Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed');
|
||||
return;
|
||||
}
|
||||
|
||||
let screen = window.wrappedJSObject.screen;
|
||||
|
||||
screen.mozLockOrientation = function (orientation) {
|
||||
debug('mozLockOrientation:', orientation, 'from', origin);
|
||||
|
||||
// Normalize and do some checks against orientation input
|
||||
if (typeof(orientation) == 'string') {
|
||||
orientation = [orientation];
|
||||
}
|
||||
|
||||
function isInvalidOrientationString(str) {
|
||||
return typeof(str) != 'string' ||
|
||||
!str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/);
|
||||
}
|
||||
if (!Array.isArray(orientation) ||
|
||||
orientation.some(isInvalidOrientationString)) {
|
||||
Cu.reportError('Invalid orientation "' + orientation + '"');
|
||||
return false;
|
||||
}
|
||||
|
||||
GlobalSimulatorScreen.lock(orientation);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
screen.mozUnlockOrientation = function() {
|
||||
debug('mozOrientationUnlock from', origin);
|
||||
GlobalSimulatorScreen.unlock();
|
||||
return true;
|
||||
};
|
||||
|
||||
Object.defineProperty(screen, 'width', {
|
||||
get: function () GlobalSimulatorScreen.width
|
||||
});
|
||||
Object.defineProperty(screen, 'height', {
|
||||
get: function () GlobalSimulatorScreen.height
|
||||
});
|
||||
Object.defineProperty(screen, 'mozOrientation', {
|
||||
get: function () GlobalSimulatorScreen.mozOrientation
|
||||
});
|
||||
}
|
||||
|
||||
function SimulatorScreen() {}
|
||||
SimulatorScreen.prototype = {
|
||||
classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
_windows: new Set(),
|
||||
|
||||
observe: function (subject, topic, data) {
|
||||
switch (topic) {
|
||||
case 'profile-after-change':
|
||||
Services.obs.addObserver(this, 'document-element-inserted', false);
|
||||
Services.obs.addObserver(this, 'simulator-orientation-change', false);
|
||||
break;
|
||||
|
||||
case 'document-element-inserted':
|
||||
let window = subject.defaultView;
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
hookScreen(window);
|
||||
|
||||
let windows = this._windows;
|
||||
window.addEventListener('unload', function unload() {
|
||||
window.removeEventListener('unload', unload);
|
||||
windows.delete(window);
|
||||
});
|
||||
windows.add(window);
|
||||
break;
|
||||
|
||||
case 'simulator-orientation-change':
|
||||
this._windows.forEach(fireOrientationEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);
|
||||
@@ -46,6 +46,21 @@ XPCOMUtils.defineLazyServiceGetter(Services, "settings",
|
||||
"@mozilla.org/settingsService;1",
|
||||
"nsISettingsService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, 'env',
|
||||
'@mozilla.org/process/environment;1',
|
||||
'nsIEnvironment');
|
||||
|
||||
function useSettings() {
|
||||
// When we're running in the real phone, then we can use settings.
|
||||
// But when we're running as part of xpcshell, there is no settings database
|
||||
// and trying to use settings in this scenario causes lots of weird
|
||||
// assertions at shutdown time.
|
||||
if (typeof useSettings.result === "undefined") {
|
||||
useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
|
||||
}
|
||||
return useSettings.result;
|
||||
}
|
||||
|
||||
function UpdateCheckListener(updatePrompt) {
|
||||
this._updatePrompt = updatePrompt;
|
||||
}
|
||||
@@ -183,8 +198,10 @@ UpdatePrompt.prototype = {
|
||||
|
||||
showUpdateHistory: function UP_showUpdateHistory(aParent) { },
|
||||
showUpdateInstalled: function UP_showUpdateInstalled() {
|
||||
if (useSettings()) {
|
||||
let lock = Services.settings.createLock();
|
||||
lock.set("deviceinfo.last_updated", Date.now(), null, null);
|
||||
}
|
||||
},
|
||||
|
||||
// Custom functions
|
||||
@@ -200,10 +217,12 @@ UpdatePrompt.prototype = {
|
||||
},
|
||||
|
||||
setUpdateStatus: function UP_setUpdateStatus(aStatus) {
|
||||
if (useSettings()) {
|
||||
log("Setting gecko.updateStatus: " + aStatus);
|
||||
|
||||
let lock = Services.settings.createLock();
|
||||
lock.set("gecko.updateStatus", aStatus, null);
|
||||
}
|
||||
},
|
||||
|
||||
showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
|
||||
@@ -379,6 +398,7 @@ UpdatePrompt.prototype = {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (useSettings()) {
|
||||
// Save current os version in deviceinfo.previous_os
|
||||
let lock = Services.settings.createLock({
|
||||
handle: callbackAfterSet,
|
||||
@@ -393,6 +413,7 @@ UpdatePrompt.prototype = {
|
||||
lock.set("deviceinfo.previous_os", value, null, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
forceUpdateCheck: function UP_forceUpdateCheck() {
|
||||
|
||||
@@ -23,6 +23,11 @@ EXTRA_COMPONENTS += [
|
||||
'YoutubeProtocolHandler.js',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
||||
EXTRA_COMPONENTS += [
|
||||
'SimulatorScreen.js'
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'B2GComponents.manifest',
|
||||
'DirectoryProvider.js',
|
||||
@@ -41,6 +46,11 @@ EXTRA_JS_MODULES += [
|
||||
'WebappsUpdater.jsm',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
||||
EXTRA_JS_MODULES += [
|
||||
'GlobalSimulatorScreen.jsm'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_SERVICES_FXACCOUNTS']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'FxAccountsUIGlue.js'
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"branch": "",
|
||||
"revision": ""
|
||||
},
|
||||
"revision": "91e5760ff948d3bef3959866c6a1744991560ef6",
|
||||
"revision": "6d2a2c5c58fce4b2263a7e5e654f6c4ccee5875a",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<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="db2ef2b61c70889533a0837fa3e053d24e95fdea"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="06d3242182370ba93db9acbe54cbe6cc8f7b239f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
||||
@@ -176,7 +176,11 @@ fi
|
||||
if test -n "$FXOS_SIMULATOR" -a -z "$GAIADIR" ; then
|
||||
AC_MSG_ERROR([FXOS_SIMULATOR=1 requires GAIADIR to be defined])
|
||||
fi
|
||||
AC_SUBST(FXOS_SIMULATOR)
|
||||
|
||||
if test -n "$FXOS_SIMULATOR" ; then
|
||||
AC_DEFINE(FXOS_SIMULATOR)
|
||||
AC_SUBST(FXOS_SIMULATOR)
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(gonk,
|
||||
[ --with-gonk=DIR
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "EncodedBufferCache.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "mozilla/dom/BlobEvent.h"
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsMimeTypes.h"
|
||||
|
||||
#include "mozilla/dom/AudioStreamTrack.h"
|
||||
#include "mozilla/dom/VideoStreamTrack.h"
|
||||
@@ -320,7 +321,19 @@ private:
|
||||
|
||||
// Allocate encoder and bind with union stream.
|
||||
// At this stage, the API doesn't allow UA to choose the output mimeType format.
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = mRecorder->GetOwner()->GetExtantDoc();
|
||||
uint16_t appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
if (doc) {
|
||||
doc->NodePrincipal()->GetAppStatus(&appStatus);
|
||||
}
|
||||
// Only allow certificated application can assign AUDIO_3GPP
|
||||
if (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
|
||||
mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP)) {
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP), aTrackTypes);
|
||||
} else {
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""), aTrackTypes);
|
||||
}
|
||||
|
||||
if (!mEncoder) {
|
||||
DoSessionEndTask(NS_ERROR_ABORT);
|
||||
@@ -579,7 +592,9 @@ MediaRecorder::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
|
||||
/* static */ already_AddRefed<MediaRecorder>
|
||||
MediaRecorder::Constructor(const GlobalObject& aGlobal,
|
||||
DOMMediaStream& aStream, ErrorResult& aRv)
|
||||
DOMMediaStream& aStream,
|
||||
const MediaRecorderOptions& aInitDict,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!sgo) {
|
||||
@@ -594,6 +609,7 @@ MediaRecorder::Constructor(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
nsRefPtr<MediaRecorder> object = new MediaRecorder(aStream, ownerWindow);
|
||||
object->SetMimeType(aInitDict.mMimeType);
|
||||
return object.forget();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ class EncodedBufferCache;
|
||||
class MediaEncoder;
|
||||
class ProcessedMediaStream;
|
||||
class MediaInputPort;
|
||||
struct MediaRecorderOptions;
|
||||
|
||||
namespace dom {
|
||||
|
||||
@@ -75,7 +76,9 @@ public:
|
||||
|
||||
static already_AddRefed<MediaRecorder>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
DOMMediaStream& aStream, ErrorResult& aRv);
|
||||
DOMMediaStream& aStream,
|
||||
const MediaRecorderOptions& aInitDict,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// EventHandler
|
||||
IMPL_EVENT_HANDLER(dataavailable)
|
||||
|
||||
@@ -115,7 +115,7 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint8_t aTrackTypes)
|
||||
(aMIMEType.EqualsLiteral(VIDEO_MP4) ||
|
||||
(aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK))) {
|
||||
if (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK) {
|
||||
audioEncoder = new OmxAudioTrackEncoder();
|
||||
audioEncoder = new OmxAACAudioTrackEncoder();
|
||||
NS_ENSURE_TRUE(audioEncoder, nullptr);
|
||||
}
|
||||
videoEncoder = new OmxVideoTrackEncoder();
|
||||
@@ -123,6 +123,14 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint8_t aTrackTypes)
|
||||
NS_ENSURE_TRUE(writer, nullptr);
|
||||
NS_ENSURE_TRUE(videoEncoder, nullptr);
|
||||
mimeType = NS_LITERAL_STRING(VIDEO_MP4);
|
||||
} else if (MediaEncoder::IsOMXEncoderEnabled() &&
|
||||
(aMIMEType.EqualsLiteral(AUDIO_3GPP))) {
|
||||
audioEncoder = new OmxAMRAudioTrackEncoder();
|
||||
NS_ENSURE_TRUE(audioEncoder, nullptr);
|
||||
|
||||
writer = new ISOMediaWriter(aTrackTypes, ISOMediaWriter::TYPE_FRAG_3GP);
|
||||
NS_ENSURE_TRUE(writer, nullptr);
|
||||
mimeType = NS_LITERAL_STRING(AUDIO_3GPP);
|
||||
}
|
||||
#endif // MOZ_OMX_ENCODER
|
||||
else if (MediaDecoder::IsOggEnabled() && MediaDecoder::IsOpusEnabled() &&
|
||||
|
||||
@@ -67,6 +67,8 @@ OmxVideoTrackEncoder::GetMetadata()
|
||||
nsRefPtr<AVCTrackMetadata> meta = new AVCTrackMetadata();
|
||||
meta->mWidth = mFrameWidth;
|
||||
meta->mHeight = mFrameHeight;
|
||||
meta->mDisplayWidth = mDisplayWidth;
|
||||
meta->mDisplayHeight = mDisplayHeight;
|
||||
meta->mFrameRate = ENCODER_CONFIG_FRAME_RATE;
|
||||
return meta.forget();
|
||||
}
|
||||
@@ -155,49 +157,6 @@ OmxVideoTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
OmxAudioTrackEncoder::Init(int aChannels, int aSamplingRate)
|
||||
{
|
||||
mChannels = aChannels;
|
||||
mSamplingRate = aSamplingRate;
|
||||
|
||||
mEncoder = OMXCodecWrapper::CreateAACEncoder();
|
||||
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = mEncoder->Configure(mChannels, mSamplingRate);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
mInitialized = (rv == NS_OK);
|
||||
|
||||
mReentrantMonitor.NotifyAll();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<TrackMetadataBase>
|
||||
OmxAudioTrackEncoder::GetMetadata()
|
||||
{
|
||||
{
|
||||
// Wait if mEncoder is not initialized nor is being canceled.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
while (!mCanceled && !mInitialized) {
|
||||
mReentrantMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (mCanceled || mEncodingComplete) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<AACTrackMetadata> meta = new AACTrackMetadata();
|
||||
meta->mChannels = mChannels;
|
||||
meta->mSampleRate = mSamplingRate;
|
||||
meta->mFrameSize = OMXCodecWrapper::kAACFrameSize;
|
||||
meta->mFrameDuration = OMXCodecWrapper::kAACFrameDuration;
|
||||
|
||||
return meta.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
OmxAudioTrackEncoder::AppendEncodedFrames(EncodedFrameContainer& aContainer)
|
||||
{
|
||||
@@ -218,8 +177,15 @@ OmxAudioTrackEncoder::AppendEncodedFrames(EncodedFrameContainer& aContainer)
|
||||
}
|
||||
|
||||
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
|
||||
if (mEncoder->GetCodecType() == OMXCodecWrapper::AAC_ENC) {
|
||||
audiodata->SetFrameType(isCSD ?
|
||||
EncodedFrame::AAC_CSD : EncodedFrame::AAC_AUDIO_FRAME);
|
||||
} else if (mEncoder->GetCodecType() == OMXCodecWrapper::AMR_NB_ENC){
|
||||
audiodata->SetFrameType(isCSD ?
|
||||
EncodedFrame::AMR_AUDIO_CSD : EncodedFrame::AMR_AUDIO_FRAME);
|
||||
} else {
|
||||
MOZ_ASSERT("audio codec not supported");
|
||||
}
|
||||
audiodata->SetTimeStamp(outTimeUs);
|
||||
rv = audiodata->SwapInFrameData(frameData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -277,4 +243,82 @@ OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
OmxAACAudioTrackEncoder::Init(int aChannels, int aSamplingRate)
|
||||
{
|
||||
mChannels = aChannels;
|
||||
mSamplingRate = aSamplingRate;
|
||||
|
||||
mEncoder = OMXCodecWrapper::CreateAACEncoder();
|
||||
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = mEncoder->Configure(mChannels, mSamplingRate, mSamplingRate);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
mInitialized = (rv == NS_OK);
|
||||
|
||||
mReentrantMonitor.NotifyAll();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<TrackMetadataBase>
|
||||
OmxAACAudioTrackEncoder::GetMetadata()
|
||||
{
|
||||
{
|
||||
// Wait if mEncoder is not initialized nor is being canceled.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
while (!mCanceled && !mInitialized) {
|
||||
mReentrantMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (mCanceled || mEncodingComplete) {
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<AACTrackMetadata> meta = new AACTrackMetadata();
|
||||
meta->mChannels = mChannels;
|
||||
meta->mSampleRate = mSamplingRate;
|
||||
meta->mFrameSize = OMXCodecWrapper::kAACFrameSize;
|
||||
meta->mFrameDuration = OMXCodecWrapper::kAACFrameDuration;
|
||||
return meta.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
OmxAMRAudioTrackEncoder::Init(int aChannels, int aSamplingRate)
|
||||
{
|
||||
mChannels = aChannels;
|
||||
mSamplingRate = aSamplingRate;
|
||||
|
||||
mEncoder = OMXCodecWrapper::CreateAMRNBEncoder();
|
||||
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = mEncoder->Configure(mChannels, mSamplingRate, AMR_NB_SAMPLERATE);
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
mInitialized = (rv == NS_OK);
|
||||
|
||||
mReentrantMonitor.NotifyAll();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<TrackMetadataBase>
|
||||
OmxAMRAudioTrackEncoder::GetMetadata()
|
||||
{
|
||||
{
|
||||
// Wait if mEncoder is not initialized nor is being canceled.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
while (!mCanceled && !mInitialized) {
|
||||
mReentrantMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (mCanceled || mEncodingComplete) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<AMRTrackMetadata> meta = new AMRTrackMetadata();
|
||||
return meta.forget();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,26 +43,54 @@ private:
|
||||
nsAutoPtr<android::OMXVideoEncoder> mEncoder;
|
||||
};
|
||||
|
||||
class OmxAudioTrackEncoder MOZ_FINAL : public AudioTrackEncoder
|
||||
class OmxAudioTrackEncoder : public AudioTrackEncoder
|
||||
{
|
||||
public:
|
||||
OmxAudioTrackEncoder()
|
||||
: AudioTrackEncoder()
|
||||
{}
|
||||
|
||||
already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
|
||||
already_AddRefed<TrackMetadataBase> GetMetadata() = 0;
|
||||
|
||||
nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsresult Init(int aChannels, int aSamplingRate) MOZ_OVERRIDE;
|
||||
nsresult Init(int aChannels, int aSamplingRate) = 0;
|
||||
|
||||
private:
|
||||
// Append encoded frames to aContainer.
|
||||
nsresult AppendEncodedFrames(EncodedFrameContainer& aContainer);
|
||||
|
||||
nsAutoPtr<android::OMXAudioEncoder> mEncoder;
|
||||
};
|
||||
|
||||
class OmxAACAudioTrackEncoder MOZ_FINAL : public OmxAudioTrackEncoder
|
||||
{
|
||||
public:
|
||||
OmxAACAudioTrackEncoder()
|
||||
: OmxAudioTrackEncoder()
|
||||
{}
|
||||
|
||||
already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsresult Init(int aChannels, int aSamplingRate) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
class OmxAMRAudioTrackEncoder MOZ_FINAL : public OmxAudioTrackEncoder
|
||||
{
|
||||
public:
|
||||
OmxAMRAudioTrackEncoder()
|
||||
: OmxAudioTrackEncoder()
|
||||
{}
|
||||
|
||||
enum {
|
||||
AMR_NB_SAMPLERATE = 8000,
|
||||
};
|
||||
already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsresult Init(int aChannels, int aSamplingRate) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -49,10 +49,14 @@ public:
|
||||
// The base class for video metadata.
|
||||
class VideoTrackMetadata : public TrackMetadataBase {
|
||||
public:
|
||||
// VideoHeight and VideoWidth are the frame size of the elementary stream.
|
||||
virtual uint32_t GetVideoHeight() = 0;
|
||||
|
||||
virtual uint32_t GetVideoWidth() = 0;
|
||||
|
||||
// VideoDisplayHeight and VideoDisplayWidth are the display frame size.
|
||||
virtual uint32_t GetVideoDisplayHeight() = 0;
|
||||
virtual uint32_t GetVideoDisplayWidth() = 0;
|
||||
|
||||
// VideoClockRate is the number of samples per second in video frame's
|
||||
// timestamp.
|
||||
// For example, if VideoClockRate is 90k Hz and VideoFrameRate is
|
||||
|
||||
@@ -167,6 +167,7 @@ nsresult
|
||||
ISOControl::SetMetadata(TrackMetadataBase* aTrackMeta)
|
||||
{
|
||||
if (aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AAC ||
|
||||
aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AMR ||
|
||||
aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AVC) {
|
||||
mMetaArray.AppendElement(aTrackMeta);
|
||||
return NS_OK;
|
||||
@@ -178,7 +179,8 @@ nsresult
|
||||
ISOControl::GetAudioMetadata(nsRefPtr<AudioTrackMetadata>& aAudMeta)
|
||||
{
|
||||
for (uint32_t i = 0; i < mMetaArray.Length() ; i++) {
|
||||
if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AAC) {
|
||||
if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AAC ||
|
||||
mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AMR) {
|
||||
aAudMeta = static_cast<AudioTrackMetadata*>(mMetaArray[i].get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1179,9 +1179,14 @@ TrackHeaderBox::Generate(uint32_t* aBoxSize)
|
||||
volume = (mTrackType == Audio_Track ? 0x0100 : 0);
|
||||
|
||||
if (mTrackType == Video_Track) {
|
||||
width = mVideoMeta->GetVideoDisplayWidth() << 16;
|
||||
height = mVideoMeta->GetVideoDisplayHeight() << 16;
|
||||
// Check display size, using the pixel size if any of them is invalid.
|
||||
if (!width || !height) {
|
||||
width = mVideoMeta->GetVideoWidth() << 16;
|
||||
height = mVideoMeta->GetVideoHeight() << 16;
|
||||
}
|
||||
}
|
||||
|
||||
size += sizeof(creation_time) +
|
||||
sizeof(modification_time) +
|
||||
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
// VideoTrackMetadata members
|
||||
uint32_t GetVideoHeight() MOZ_OVERRIDE { return mHeight; }
|
||||
uint32_t GetVideoWidth() MOZ_OVERRIDE {return mWidth; }
|
||||
uint32_t GetVideoDisplayHeight() MOZ_OVERRIDE { return mDisplayHeight; }
|
||||
uint32_t GetVideoDisplayWidth() MOZ_OVERRIDE { return mDisplayWidth; }
|
||||
uint32_t GetVideoClockRate() MOZ_OVERRIDE { return AVC_CLOCK_RATE; }
|
||||
uint32_t GetVideoFrameRate() MOZ_OVERRIDE { return mFrameRate; }
|
||||
|
||||
@@ -55,6 +57,8 @@ public:
|
||||
AVCTrackMetadata()
|
||||
: mHeight(0)
|
||||
, mWidth(0)
|
||||
, mDisplayHeight(0)
|
||||
, mDisplayWidth(0)
|
||||
, mFrameRate(0) {
|
||||
MOZ_COUNT_CTOR(AVCTrackMetadata);
|
||||
}
|
||||
@@ -62,6 +66,8 @@ public:
|
||||
|
||||
uint32_t mHeight;
|
||||
uint32_t mWidth;
|
||||
uint32_t mDisplayHeight;
|
||||
uint32_t mDisplayWidth;
|
||||
uint32_t mFrameRate; // frames per second
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ using namespace mozilla::layers;
|
||||
#define ENCODER_CONFIG_I_FRAME_INTERVAL 1
|
||||
// Wait up to 5ms for input buffers.
|
||||
#define INPUT_BUFFER_TIMEOUT_US (5 * 1000ll)
|
||||
// AMR NB kbps
|
||||
#define AMRNB_BITRATE 12200
|
||||
|
||||
#define CODEC_ERROR(args...) \
|
||||
do { \
|
||||
@@ -45,6 +47,16 @@ OMXCodecWrapper::CreateAACEncoder()
|
||||
return aac.forget();
|
||||
}
|
||||
|
||||
OMXAudioEncoder*
|
||||
OMXCodecWrapper::CreateAMRNBEncoder()
|
||||
{
|
||||
nsAutoPtr<OMXAudioEncoder> amr(new OMXAudioEncoder(CodecType::AMR_NB_ENC));
|
||||
// Return the object only when media codec is valid.
|
||||
NS_ENSURE_TRUE(amr->IsValid(), nullptr);
|
||||
|
||||
return amr.forget();
|
||||
}
|
||||
|
||||
OMXVideoEncoder*
|
||||
OMXCodecWrapper::CreateAVCEncoder()
|
||||
{
|
||||
@@ -56,7 +68,9 @@ OMXCodecWrapper::CreateAVCEncoder()
|
||||
}
|
||||
|
||||
OMXCodecWrapper::OMXCodecWrapper(CodecType aCodecType)
|
||||
: mStarted(false)
|
||||
: mCodecType(aCodecType)
|
||||
, mStarted(false)
|
||||
, mAMRCSDProvided(false)
|
||||
{
|
||||
ProcessState::self()->startThreadPool();
|
||||
|
||||
@@ -65,6 +79,8 @@ OMXCodecWrapper::OMXCodecWrapper(CodecType aCodecType)
|
||||
|
||||
if (aCodecType == CodecType::AVC_ENC) {
|
||||
mCodec = MediaCodec::CreateByType(mLooper, MEDIA_MIMETYPE_VIDEO_AVC, true);
|
||||
} else if (aCodecType == CodecType::AMR_NB_ENC) {
|
||||
mCodec = MediaCodec::CreateByType(mLooper, MEDIA_MIMETYPE_AUDIO_AMR_NB, true);
|
||||
} else if (aCodecType == CodecType::AAC_ENC) {
|
||||
mCodec = MediaCodec::CreateByType(mLooper, MEDIA_MIMETYPE_AUDIO_AAC, true);
|
||||
} else {
|
||||
@@ -380,28 +396,53 @@ void OMXVideoEncoder::AppendFrame(nsTArray<uint8_t>* aOutputBuf,
|
||||
}
|
||||
|
||||
nsresult
|
||||
OMXAudioEncoder::Configure(int aChannels, int aSamplingRate)
|
||||
OMXAudioEncoder::Configure(int aChannels, int aInputSampleRate,
|
||||
int aEncodedSampleRate)
|
||||
{
|
||||
MOZ_ASSERT(!mStarted);
|
||||
|
||||
NS_ENSURE_TRUE(aChannels > 0 && aSamplingRate > 0, NS_ERROR_INVALID_ARG);
|
||||
NS_ENSURE_TRUE(aChannels > 0 && aInputSampleRate > 0 && aEncodedSampleRate >= 0,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (aInputSampleRate != aEncodedSampleRate) {
|
||||
int error;
|
||||
mResampler = speex_resampler_init(aChannels,
|
||||
aInputSampleRate,
|
||||
aEncodedSampleRate,
|
||||
SPEEX_RESAMPLER_QUALITY_DEFAULT,
|
||||
&error);
|
||||
|
||||
if (error != RESAMPLER_ERR_SUCCESS) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
speex_resampler_skip_zeros(mResampler);
|
||||
}
|
||||
// Set up configuration parameters for AAC encoder.
|
||||
sp<AMessage> format = new AMessage;
|
||||
// Fixed values.
|
||||
if (mCodecType == AAC_ENC) {
|
||||
format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
|
||||
format->setInt32("bitrate", kAACBitrate);
|
||||
format->setInt32("aac-profile", OMX_AUDIO_AACObjectLC);
|
||||
format->setInt32("bitrate", kAACBitrate);
|
||||
format->setInt32("sample-rate", aInputSampleRate);
|
||||
} else if (mCodecType == AMR_NB_ENC) {
|
||||
format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
|
||||
format->setInt32("bitrate", AMRNB_BITRATE);
|
||||
format->setInt32("sample-rate", aEncodedSampleRate);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Can't support this codec type!!");
|
||||
}
|
||||
// Input values.
|
||||
format->setInt32("channel-count", aChannels);
|
||||
format->setInt32("sample-rate", aSamplingRate);
|
||||
|
||||
status_t result = mCodec->configure(format, nullptr, nullptr,
|
||||
MediaCodec::CONFIGURE_FLAG_ENCODE);
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
mChannels = aChannels;
|
||||
mSampleDuration = 1000000 / aSamplingRate;
|
||||
mSampleDuration = 1000000 / aInputSampleRate;
|
||||
mResamplingRatio = aEncodedSampleRate > 0 ? 1.0 *
|
||||
aEncodedSampleRate / aInputSampleRate : 1.0;
|
||||
result = Start();
|
||||
|
||||
return result == OK ? NS_OK : NS_ERROR_FAILURE;
|
||||
@@ -474,6 +515,14 @@ private:
|
||||
size_t mOffset;
|
||||
};
|
||||
|
||||
OMXAudioEncoder::~OMXAudioEncoder()
|
||||
{
|
||||
if (mResampler) {
|
||||
speex_resampler_destroy(mResampler);
|
||||
mResampler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
{
|
||||
@@ -495,16 +544,16 @@ OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
}
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
size_t samplesCopied = 0; // Number of copied samples.
|
||||
size_t sourceSamplesCopied = 0; // Number of copied samples.
|
||||
|
||||
if (numSamples > 0) {
|
||||
// Copy input PCM data to input buffer until queue is empty.
|
||||
AudioSegment::ChunkIterator iter(const_cast<AudioSegment&>(aSegment));
|
||||
while (!iter.IsEnded()) {
|
||||
AudioChunk chunk = *iter;
|
||||
size_t samplesToCopy = chunk.GetDuration(); // Number of samples to copy.
|
||||
size_t bytesToCopy = samplesToCopy * mChannels * sizeof(AudioDataValue);
|
||||
|
||||
size_t sourceSamplesToCopy = chunk.GetDuration(); // Number of samples to copy.
|
||||
size_t bytesToCopy = sourceSamplesToCopy * mChannels *
|
||||
sizeof(AudioDataValue) * mResamplingRatio;
|
||||
if (bytesToCopy > buffer.AvailableSize()) {
|
||||
// Not enough space left in input buffer. Send it to encoder and get a
|
||||
// new one.
|
||||
@@ -515,32 +564,47 @@ OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
if (result == -EAGAIN) {
|
||||
// All input buffers are full. Caller can try again later after
|
||||
// consuming some output buffers.
|
||||
aSegment.RemoveLeading(samplesCopied);
|
||||
aSegment.RemoveLeading(sourceSamplesCopied);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mTimestamp += samplesCopied * mSampleDuration;
|
||||
samplesCopied = 0;
|
||||
mTimestamp += sourceSamplesCopied * mSampleDuration;
|
||||
sourceSamplesCopied = 0;
|
||||
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
AudioDataValue* dst = reinterpret_cast<AudioDataValue*>(buffer.GetPointer());
|
||||
uint32_t dstSamplesCopied = sourceSamplesToCopy;
|
||||
if (!chunk.IsNull()) {
|
||||
if (mResampler) {
|
||||
nsAutoTArray<AudioDataValue, 9600> pcm;
|
||||
pcm.SetLength(bytesToCopy);
|
||||
// Append the interleaved data to input buffer.
|
||||
AudioTrackEncoder::InterleaveTrackData(chunk, samplesToCopy, mChannels,
|
||||
AudioTrackEncoder::InterleaveTrackData(chunk, sourceSamplesToCopy,
|
||||
mChannels,
|
||||
pcm.Elements());
|
||||
uint32_t inframes = sourceSamplesToCopy;
|
||||
short* in = reinterpret_cast<short*>(pcm.Elements());
|
||||
speex_resampler_process_interleaved_int(mResampler, in, &inframes,
|
||||
dst, &dstSamplesCopied);
|
||||
} else {
|
||||
AudioTrackEncoder::InterleaveTrackData(chunk, sourceSamplesToCopy,
|
||||
mChannels,
|
||||
dst);
|
||||
dstSamplesCopied = sourceSamplesToCopy * mChannels;
|
||||
}
|
||||
} else {
|
||||
// Silence.
|
||||
memset(dst, 0, bytesToCopy);
|
||||
memset(dst, 0, mResamplingRatio * sourceSamplesToCopy * sizeof(AudioDataValue));
|
||||
}
|
||||
|
||||
samplesCopied += samplesToCopy;
|
||||
buffer.IncreaseOffset(bytesToCopy);
|
||||
sourceSamplesCopied += sourceSamplesToCopy;
|
||||
buffer.IncreaseOffset(dstSamplesCopied * sizeof(AudioDataValue));
|
||||
iter.Next();
|
||||
}
|
||||
if (samplesCopied > 0) {
|
||||
aSegment.RemoveLeading(samplesCopied);
|
||||
if (sourceSamplesCopied > 0) {
|
||||
aSegment.RemoveLeading(sourceSamplesCopied);
|
||||
}
|
||||
} else if (aInputFlags & BUFFER_EOS) {
|
||||
// No audio data left in segment but we still have to feed something to
|
||||
@@ -548,10 +612,10 @@ OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
size_t bytesToCopy = mChannels * sizeof(AudioDataValue);
|
||||
memset(buffer.GetPointer(), 0, bytesToCopy);
|
||||
buffer.IncreaseOffset(bytesToCopy);
|
||||
samplesCopied = 1;
|
||||
sourceSamplesCopied = 1;
|
||||
}
|
||||
|
||||
if (samplesCopied > 0) {
|
||||
if (sourceSamplesCopied > 0) {
|
||||
int flags = aInputFlags;
|
||||
if (aSegment.GetDuration() > 0) {
|
||||
// Don't signal EOS until source segment is empty.
|
||||
@@ -560,7 +624,7 @@ OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
result = buffer.Enqueue(mTimestamp, flags);
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
mTimestamp += samplesCopied * mSampleDuration;
|
||||
mTimestamp += sourceSamplesCopied * mSampleDuration;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -663,6 +727,20 @@ OMXCodecWrapper::GetNextEncodedFrame(nsTArray<uint8_t>* aOutputBuf,
|
||||
mCodec->releaseOutputBuffer(index);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else if ((mCodecType == AMR_NB_ENC) && !mAMRCSDProvided){
|
||||
// OMX AMR codec won't provide csd data, need to generate a fake one.
|
||||
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
|
||||
// Decoder config descriptor
|
||||
const uint8_t decConfig[] = {
|
||||
0x0, 0x0, 0x0, 0x0, // vendor: 4 bytes
|
||||
0x0, // decoder version
|
||||
0x83, 0xFF, // mode set: all enabled
|
||||
0x00, // mode change period
|
||||
0x01, // frames per sample
|
||||
};
|
||||
aOutputBuf->AppendElements(decConfig, sizeof(decConfig));
|
||||
outFlags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
|
||||
mAMRCSDProvided = true;
|
||||
} else {
|
||||
AppendFrame(aOutputBuf, omxBuf->data(), omxBuf->size());
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "GonkNativeWindow.h"
|
||||
#include "GonkNativeWindowClient.h"
|
||||
|
||||
#include <speex/speex_resampler.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class OMXAudioEncoder;
|
||||
@@ -53,6 +55,7 @@ public:
|
||||
// Codec types.
|
||||
enum CodecType {
|
||||
AAC_ENC, // AAC encoder.
|
||||
AMR_NB_ENC, // AMR_NB encoder.
|
||||
AVC_ENC, // AVC/H.264 encoder.
|
||||
TYPE_COUNT
|
||||
};
|
||||
@@ -83,6 +86,9 @@ public:
|
||||
/** Create a AAC audio encoder. Returns nullptr when failed. */
|
||||
static OMXAudioEncoder* CreateAACEncoder();
|
||||
|
||||
/** Create a AMR audio encoder. Returns nullptr when failed. */
|
||||
static OMXAudioEncoder* CreateAMRNBEncoder();
|
||||
|
||||
/** Create a AVC/H.264 video encoder. Returns nullptr when failed. */
|
||||
static OMXVideoEncoder* CreateAVCEncoder();
|
||||
|
||||
@@ -97,7 +103,10 @@ public:
|
||||
nsresult GetNextEncodedFrame(nsTArray<uint8_t>* aOutputBuf,
|
||||
int64_t* aOutputTimestamp, int* aOutputFlags,
|
||||
int64_t aTimeOut);
|
||||
|
||||
/*
|
||||
* Get the codec type
|
||||
*/
|
||||
int GetCodecType() { return mCodecType; }
|
||||
protected:
|
||||
/**
|
||||
* See whether the object has been initialized successfully and is ready to
|
||||
@@ -160,7 +169,9 @@ private:
|
||||
Vector<sp<ABuffer> > mInputBufs; // MediaCodec buffers to hold input data.
|
||||
Vector<sp<ABuffer> > mOutputBufs; // MediaCodec buffers to hold output data.
|
||||
|
||||
int mCodecType;
|
||||
bool mStarted; // Has MediaCodec been started?
|
||||
bool mAMRCSDProvided;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -172,8 +183,9 @@ public:
|
||||
/**
|
||||
* Configure audio codec parameters and start media codec. It must be called
|
||||
* before calling Encode() and GetNextEncodedFrame().
|
||||
* aReSamplingRate = 0 means no resampler required
|
||||
*/
|
||||
nsresult Configure(int aChannelCount, int aSampleRate);
|
||||
nsresult Configure(int aChannelCount, int aInputSampleRate, int aEncodedSampleRate);
|
||||
|
||||
/**
|
||||
* Encode 16-bit PCM audio samples stored in aSegment. To notify end of
|
||||
@@ -183,10 +195,10 @@ public:
|
||||
*/
|
||||
nsresult Encode(mozilla::AudioSegment& aSegment, int aInputFlags = 0);
|
||||
|
||||
~OMXAudioEncoder();
|
||||
protected:
|
||||
virtual status_t AppendDecoderConfig(nsTArray<uint8_t>* aOutputBuf,
|
||||
ABuffer* aData) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// Hide these. User should always use creator functions to get a media codec.
|
||||
OMXAudioEncoder() MOZ_DELETE;
|
||||
@@ -199,15 +211,24 @@ private:
|
||||
*/
|
||||
OMXAudioEncoder(CodecType aCodecType)
|
||||
: OMXCodecWrapper(aCodecType)
|
||||
, mResampler(nullptr)
|
||||
, mChannels(0)
|
||||
, mTimestamp(0)
|
||||
, mSampleDuration(0) {}
|
||||
, mSampleDuration(0)
|
||||
, mResamplingRatio(0) {}
|
||||
|
||||
// For creator function to access hidden constructor.
|
||||
friend class OMXCodecWrapper;
|
||||
|
||||
/**
|
||||
* If the input sample rate does not divide 48kHz evenly, the input data are
|
||||
* resampled.
|
||||
*/
|
||||
SpeexResamplerState* mResampler;
|
||||
// Number of audio channels.
|
||||
size_t mChannels;
|
||||
|
||||
float mResamplingRatio;
|
||||
// The total duration of audio samples that have been encoded in microseconds.
|
||||
int64_t mTimestamp;
|
||||
// Time per audio sample in microseconds.
|
||||
|
||||
@@ -30,12 +30,10 @@ function startTest(test, token) {
|
||||
}
|
||||
manager.started(token);
|
||||
var a = new Audio(test.name);
|
||||
a.addEventListener("canplaythrough",
|
||||
function(e){ e.target.play(); },
|
||||
false);
|
||||
a.autoplay = true;
|
||||
a.addEventListener("ended",
|
||||
function(e){
|
||||
ok(true, "We should get to the end. Oh look we did.");
|
||||
ok(true, "[" + a.src + "]We should get to the end. Oh look we did.");
|
||||
manager.finished(token);
|
||||
},
|
||||
false);
|
||||
|
||||
@@ -61,7 +61,7 @@ function runTest()
|
||||
// Ensure that the preallocated process initially gets BACKGROUND priority.
|
||||
// That's it.
|
||||
expectProcessCreated().then(function(childID) {
|
||||
return expectPriorityChange(childID, 'BACKGROUND');
|
||||
return expectPriorityChange(childID, 'PREALLOC');
|
||||
}).then(function() {
|
||||
cleanUp();
|
||||
SimpleTest.finish();
|
||||
|
||||
@@ -448,7 +448,7 @@ ContentParent::PreallocateAppProcess()
|
||||
new ContentParent(/* app = */ nullptr,
|
||||
/* isForBrowserElement = */ false,
|
||||
/* isForPreallocated = */ true,
|
||||
PROCESS_PRIORITY_BACKGROUND);
|
||||
PROCESS_PRIORITY_PREALLOC);
|
||||
process->Init();
|
||||
return process.forget();
|
||||
}
|
||||
@@ -1453,7 +1453,7 @@ ContentParent::ContentParent(ContentParent* aTemplate,
|
||||
// memory priority, which it has inherited from this process.
|
||||
ProcessPriority priority;
|
||||
if (IsPreallocated()) {
|
||||
priority = PROCESS_PRIORITY_BACKGROUND;
|
||||
priority = PROCESS_PRIORITY_PREALLOC;
|
||||
} else {
|
||||
priority = PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
@@ -945,6 +945,10 @@ ParticularProcessPriorityManager::ComputePriority()
|
||||
ProcessCPUPriority
|
||||
ParticularProcessPriorityManager::ComputeCPUPriority()
|
||||
{
|
||||
if (mPriority == PROCESS_PRIORITY_PREALLOC) {
|
||||
return PROCESS_CPU_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
if (mPriority >= PROCESS_PRIORITY_FOREGROUND_HIGH) {
|
||||
return PROCESS_CPU_PRIORITY_NORMAL;
|
||||
}
|
||||
|
||||
@@ -336,7 +336,9 @@ function isNetworkReady() {
|
||||
.getService(SpecialPowers.Ci.nsINetworkInterfaceListService);
|
||||
var itfList = listService.getDataInterfaceList(
|
||||
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_MMS_INTERFACES |
|
||||
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_SUPL_INTERFACES);
|
||||
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_SUPL_INTERFACES |
|
||||
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_IMS_INTERFACES |
|
||||
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_DUN_INTERFACES);
|
||||
var num = itfList.getNumberOfInterface();
|
||||
for (var i = 0; i < num; i++) {
|
||||
if (itfList.getInterface(i).ip) {
|
||||
|
||||
@@ -14,7 +14,7 @@ interface nsIDOMMozSmsSegmentInfo;
|
||||
#define MOBILE_MESSAGE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/mobilemessageservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, builtinclass, uuid(67d038b2-0039-11e3-9fd3-83de190730f7)]
|
||||
[scriptable, builtinclass, uuid(17fce9e4-af56-11e3-83d9-b71055e95493)]
|
||||
interface nsIMobileMessageService : nsISupports
|
||||
{
|
||||
[implicit_jscontext]
|
||||
@@ -27,9 +27,9 @@ interface nsIMobileMessageService : nsISupports
|
||||
in DOMString receiver,
|
||||
in DOMString body,
|
||||
in DOMString messageClass,
|
||||
in jsval timestamp,
|
||||
in jsval sentTimestamp,
|
||||
in jsval deliveryTimestamp,
|
||||
in unsigned long long timestamp,
|
||||
in unsigned long long sentTimestamp,
|
||||
in unsigned long long deliveryTimestamp,
|
||||
in bool read);
|
||||
|
||||
[implicit_jscontext]
|
||||
@@ -40,13 +40,13 @@ interface nsIMobileMessageService : nsISupports
|
||||
in jsval deliveryInfo,
|
||||
in DOMString sender,
|
||||
in jsval receivers,
|
||||
in jsval timestamp,
|
||||
in jsval sentTimestamp,
|
||||
in unsigned long long timestamp,
|
||||
in unsigned long long sentTimestamp,
|
||||
in boolean read,
|
||||
in DOMString subject,
|
||||
in DOMString smil,
|
||||
in jsval attachments,
|
||||
in jsval expiryDate,
|
||||
in unsigned long long expiryDate,
|
||||
in boolean readReportRequested);
|
||||
|
||||
nsIDOMMozSmsSegmentInfo createSmsSegmentInfo(in long segments,
|
||||
@@ -56,7 +56,7 @@ interface nsIMobileMessageService : nsISupports
|
||||
[implicit_jscontext]
|
||||
nsIDOMMozMobileMessageThread createThread(in unsigned long long id,
|
||||
in jsval participants,
|
||||
in jsval timestamp,
|
||||
in unsigned long long timestamp,
|
||||
in DOMString lastMessageSubject,
|
||||
in DOMString body,
|
||||
in unsigned long long unreadCount,
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef MessageUtils_h
|
||||
#define MessageUtils_h
|
||||
|
||||
/**
|
||||
* A helper function to convert the JS value to an integer value for time.
|
||||
*
|
||||
* @params aCx
|
||||
* The JS context.
|
||||
* @params aTime
|
||||
* Can be an object or a number.
|
||||
* @params aReturn
|
||||
* The integer value to return.
|
||||
* @return NS_OK if the convertion succeeds.
|
||||
*/
|
||||
static nsresult
|
||||
convertTimeToInt(JSContext* aCx, const JS::Value& aTime, uint64_t& aReturn)
|
||||
{
|
||||
if (aTime.isObject()) {
|
||||
JS::Rooted<JSObject*> timestampObj(aCx, &aTime.toObject());
|
||||
if (!JS_ObjectIsDate(aCx, timestampObj)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
aReturn = js_DateGetMsecSinceEpoch(timestampObj);
|
||||
} else {
|
||||
if (!aTime.isNumber()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
double number = aTime.toNumber();
|
||||
if (static_cast<uint64_t>(number) != number) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
aReturn = static_cast<uint64_t>(number);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "mozilla/dom/mobilemessage/SmsTypes.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "MessageUtils.h"
|
||||
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
|
||||
@@ -174,13 +173,13 @@ MmsMessage::Create(int32_t aId,
|
||||
const JS::Value& aDeliveryInfo,
|
||||
const nsAString& aSender,
|
||||
const JS::Value& aReceivers,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
const JS::Value& aAttachments,
|
||||
const JS::Value& aExpiryDate,
|
||||
uint64_t aExpiryDate,
|
||||
bool aIsReadReportRequested,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozMmsMessage** aMessage)
|
||||
@@ -255,16 +254,6 @@ MmsMessage::Create(int32_t aId,
|
||||
receivers.AppendElement(receiverStr);
|
||||
}
|
||||
|
||||
// Set |timestamp|.
|
||||
uint64_t timestamp;
|
||||
nsresult rv = convertTimeToInt(aCx, aTimestamp, timestamp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |sentTimestamp|.
|
||||
uint64_t sentTimestamp;
|
||||
rv = convertTimeToInt(aCx, aSentTimestamp, sentTimestamp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set |attachments|.
|
||||
if (!aAttachments.isObject()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
@@ -291,11 +280,6 @@ MmsMessage::Create(int32_t aId,
|
||||
attachments.AppendElement(attachment);
|
||||
}
|
||||
|
||||
// Set |expiryDate|.
|
||||
uint64_t expiryDate;
|
||||
rv = convertTimeToInt(aCx, aExpiryDate, expiryDate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMMozMmsMessage> message = new MmsMessage(aId,
|
||||
aThreadId,
|
||||
aIccId,
|
||||
@@ -303,13 +287,13 @@ MmsMessage::Create(int32_t aId,
|
||||
deliveryInfo,
|
||||
aSender,
|
||||
receivers,
|
||||
timestamp,
|
||||
sentTimestamp,
|
||||
aTimestamp,
|
||||
aSentTimestamp,
|
||||
aRead,
|
||||
aSubject,
|
||||
aSmil,
|
||||
attachments,
|
||||
expiryDate,
|
||||
aExpiryDate,
|
||||
aIsReadReportRequested);
|
||||
message.forget(aMessage);
|
||||
return NS_OK;
|
||||
|
||||
@@ -66,13 +66,13 @@ public:
|
||||
const JS::Value& aDeliveryInfo,
|
||||
const nsAString& aSender,
|
||||
const JS::Value& aReceivers,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
const JS::Value& aAttachments,
|
||||
const JS::Value& aExpiryDate,
|
||||
uint64_t aExpiryDate,
|
||||
bool aReadReportRequested,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozMmsMessage** aMessage);
|
||||
|
||||
@@ -38,10 +38,10 @@ MobileMessageService::CreateSmsMessage(int32_t aId,
|
||||
const nsAString& aReceiver,
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
JS::Handle<JS::Value> aTimestamp,
|
||||
JS::Handle<JS::Value> aSentTimestamp,
|
||||
JS::Handle<JS::Value> aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozSmsMessage** aMessage)
|
||||
{
|
||||
@@ -70,13 +70,13 @@ MobileMessageService::CreateMmsMessage(int32_t aId,
|
||||
JS::Handle<JS::Value> aDeliveryInfo,
|
||||
const nsAString& aSender,
|
||||
JS::Handle<JS::Value> aReceivers,
|
||||
JS::Handle<JS::Value> aTimestamp,
|
||||
JS::Handle<JS::Value> aSentTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
bool aRead,
|
||||
const nsAString& aSubject,
|
||||
const nsAString& aSmil,
|
||||
JS::Handle<JS::Value> aAttachments,
|
||||
JS::Handle<JS::Value> aExpiryDate,
|
||||
uint64_t aExpiryDate,
|
||||
bool aReadReportRequested,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozMmsMessage** aMessage)
|
||||
@@ -115,7 +115,7 @@ MobileMessageService::CreateSmsSegmentInfo(int32_t aSegments,
|
||||
NS_IMETHODIMP
|
||||
MobileMessageService::CreateThread(uint64_t aId,
|
||||
JS::Handle<JS::Value> aParticipants,
|
||||
JS::Handle<JS::Value> aTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
const nsAString& aLastMessageSubject,
|
||||
const nsAString& aBody,
|
||||
uint64_t aUnreadCount,
|
||||
|
||||
@@ -28,12 +28,12 @@ NS_IMPL_ADDREF(MobileMessageThread)
|
||||
NS_IMPL_RELEASE(MobileMessageThread)
|
||||
|
||||
/* static */ nsresult
|
||||
MobileMessageThread::Create(const uint64_t aId,
|
||||
MobileMessageThread::Create(uint64_t aId,
|
||||
const JS::Value& aParticipants,
|
||||
const JS::Value& aTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
const nsAString& aLastMessageSubject,
|
||||
const nsAString& aBody,
|
||||
const uint64_t aUnreadCount,
|
||||
uint64_t aUnreadCount,
|
||||
const nsAString& aLastMessageType,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozMobileMessageThread** aThread)
|
||||
@@ -76,25 +76,10 @@ MobileMessageThread::Create(const uint64_t aId,
|
||||
}
|
||||
}
|
||||
|
||||
// We support both a Date object and a millisecond timestamp as a number.
|
||||
if (aTimestamp.isObject()) {
|
||||
JS::Rooted<JSObject*> obj(aCx, &aTimestamp.toObject());
|
||||
if (!JS_ObjectIsDate(aCx, obj)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
data.timestamp() = js_DateGetMsecSinceEpoch(obj);
|
||||
} else {
|
||||
if (!aTimestamp.isNumber()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
double number = aTimestamp.toNumber();
|
||||
if (static_cast<uint64_t>(number) != number) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
data.timestamp() = static_cast<uint64_t>(number);
|
||||
}
|
||||
// Set |timestamp|;
|
||||
data.timestamp() = aTimestamp;
|
||||
|
||||
// Set |aLastMessageType|.
|
||||
// Set |lastMessageType|.
|
||||
{
|
||||
MessageType lastMessageType;
|
||||
if (aLastMessageType.Equals(MESSAGE_TYPE_SMS)) {
|
||||
@@ -112,12 +97,12 @@ MobileMessageThread::Create(const uint64_t aId,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MobileMessageThread::MobileMessageThread(const uint64_t aId,
|
||||
MobileMessageThread::MobileMessageThread(uint64_t aId,
|
||||
const nsTArray<nsString>& aParticipants,
|
||||
const uint64_t aTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
const nsString& aLastMessageSubject,
|
||||
const nsString& aBody,
|
||||
const uint64_t aUnreadCount,
|
||||
uint64_t aUnreadCount,
|
||||
MessageType aLastMessageType)
|
||||
: mData(aId, aParticipants, aTimestamp, aLastMessageSubject, aBody,
|
||||
aUnreadCount, aLastMessageType)
|
||||
|
||||
@@ -23,22 +23,22 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMMOZMOBILEMESSAGETHREAD
|
||||
|
||||
MobileMessageThread(const uint64_t aId,
|
||||
MobileMessageThread(uint64_t aId,
|
||||
const nsTArray<nsString>& aParticipants,
|
||||
const uint64_t aTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
const nsString& aLastMessageSubject,
|
||||
const nsString& aBody,
|
||||
const uint64_t aUnreadCount,
|
||||
uint64_t aUnreadCount,
|
||||
mobilemessage::MessageType aLastMessageType);
|
||||
|
||||
MobileMessageThread(const ThreadData& aData);
|
||||
|
||||
static nsresult Create(const uint64_t aId,
|
||||
static nsresult Create(uint64_t aId,
|
||||
const JS::Value& aParticipants,
|
||||
const JS::Value& aTimestamp,
|
||||
uint64_t aTimestamp,
|
||||
const nsAString& aLastMessageSubject,
|
||||
const nsAString& aBody,
|
||||
const uint64_t aUnreadCount,
|
||||
uint64_t aUnreadCount,
|
||||
const nsAString& aLastMessageType,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozMobileMessageThread** aThread);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "jsapi.h" // For OBJECT_TO_JSVAL and JS_NewDateObjectMsec
|
||||
#include "jsfriendapi.h" // For js_DateGetMsecSinceEpoch
|
||||
#include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
|
||||
#include "MessageUtils.h"
|
||||
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
|
||||
@@ -60,10 +59,10 @@ SmsMessage::Create(int32_t aId,
|
||||
const nsAString& aReceiver,
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
const JS::Value& aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozSmsMessage** aMessage)
|
||||
{
|
||||
@@ -119,16 +118,13 @@ SmsMessage::Create(int32_t aId,
|
||||
}
|
||||
|
||||
// Set |timestamp|.
|
||||
nsresult rv = convertTimeToInt(aCx, aTimestamp, data.timestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
data.timestamp() = aTimestamp;
|
||||
|
||||
// Set |sentTimestamp|.
|
||||
rv = convertTimeToInt(aCx, aSentTimestamp, data.sentTimestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
data.sentTimestamp() = aSentTimestamp;
|
||||
|
||||
// Set |deliveryTimestamp|.
|
||||
rv = convertTimeToInt(aCx, aDeliveryTimestamp, data.deliveryTimestamp());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
data.deliveryTimestamp() = aDeliveryTimestamp;
|
||||
|
||||
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(data);
|
||||
message.swap(*aMessage);
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead);
|
||||
|
||||
SmsMessage(const mobilemessage::SmsMessageData& aData);
|
||||
|
||||
static nsresult Create(int32_t aId,
|
||||
@@ -45,10 +46,10 @@ public:
|
||||
const nsAString& aReceiver,
|
||||
const nsAString& aBody,
|
||||
const nsAString& aMessageClass,
|
||||
const JS::Value& aTimestamp,
|
||||
const JS::Value& aSentTimestamp,
|
||||
const JS::Value& aDeliveryTimestamp,
|
||||
const bool aRead,
|
||||
uint64_t aTimestamp,
|
||||
uint64_t aSentTimestamp,
|
||||
uint64_t aDeliveryTimestamp,
|
||||
bool aRead,
|
||||
JSContext* aCx,
|
||||
nsIDOMMozSmsMessage** aMessage);
|
||||
const mobilemessage::SmsMessageData& GetData() const;
|
||||
|
||||
@@ -40,7 +40,7 @@ NS_IMETHODIMP
|
||||
SmsService::Send(uint32_t aServiceId,
|
||||
const nsAString& aNumber,
|
||||
const nsAString& aMessage,
|
||||
const bool aSilent,
|
||||
bool aSilent,
|
||||
nsIMobileMessageCallback* aRequest)
|
||||
{
|
||||
if (!AndroidBridge::Bridge()) {
|
||||
|
||||
@@ -100,7 +100,7 @@ NS_IMETHODIMP
|
||||
SmsService::Send(uint32_t aServiceId,
|
||||
const nsAString& aNumber,
|
||||
const nsAString& aMessage,
|
||||
const bool aSilent,
|
||||
bool aSilent,
|
||||
nsIMobileMessageCallback* aRequest)
|
||||
{
|
||||
nsCOMPtr<nsIRadioInterface> radioInterface;
|
||||
|
||||
@@ -165,7 +165,7 @@ NS_IMETHODIMP
|
||||
SmsIPCService::Send(uint32_t aServiceId,
|
||||
const nsAString& aNumber,
|
||||
const nsAString& aMessage,
|
||||
const bool aSilent,
|
||||
bool aSilent,
|
||||
nsIMobileMessageCallback* aRequest)
|
||||
{
|
||||
return SendRequest(SendMessageRequest(SendSmsMessageRequest(aServiceId,
|
||||
|
||||
@@ -33,7 +33,7 @@ function run_test() {
|
||||
*/
|
||||
add_test(function test_interface() {
|
||||
let sms = newMessage(null, null, ICC_ID, "sent", "success", null, null, null,
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
"normal", Date.now(), Date.now(), Date.now(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
@@ -53,7 +53,7 @@ add_test(function test_interface() {
|
||||
*/
|
||||
add_test(function test_icc_id_not_available() {
|
||||
let sms = newMessage(null, null, null, "sent", "success", null, null, null,
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
"normal", Date.now(), Date.now(), Date.now(), true);
|
||||
do_check_true(sms instanceof Ci.nsIDOMMozSmsMessage);
|
||||
do_check_eq(sms.id, 0);
|
||||
do_check_eq(sms.threadId, 0);
|
||||
@@ -73,7 +73,7 @@ add_test(function test_icc_id_not_available() {
|
||||
*/
|
||||
add_test(function test_readonly_attributes() {
|
||||
let sms = newMessage(null, null, ICC_ID, "sent", "success", null, null, null,
|
||||
"normal", new Date(), new Date(), new Date(), true);
|
||||
"normal", Date.now(), Date.now(), Date.now(), true);
|
||||
|
||||
sms.id = 1;
|
||||
do_check_eq(sms.id, 0);
|
||||
@@ -144,7 +144,8 @@ add_test(function test_timestamp_number() {
|
||||
});
|
||||
|
||||
/**
|
||||
* Test supplying the timestamp as a Date object.
|
||||
* Test supplying the timestamp as a Date object, which will be automatically
|
||||
* casted to unsigned long long.
|
||||
*/
|
||||
add_test(function test_timestamp_date() {
|
||||
let date = new Date();
|
||||
@@ -166,113 +167,13 @@ add_test(function test_timestamp_date() {
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that a floating point number for the timestamp is not allowed.
|
||||
*/
|
||||
add_test(function test_invalid_timestamp_float() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", 3.1415, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), 3.1415, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), new Date(), 3.1415, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that a null value for the timestamp is not allowed.
|
||||
*/
|
||||
add_test(function test_invalid_timestamp_null() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", null, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), null, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), new Date(), null, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that undefined for the timestamp is not allowed.
|
||||
*/
|
||||
add_test(function test_invalid_timestamp_undefined() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", undefined, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), undefined, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), new Date(), undefined, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that a random object for the timestamp is not allowed.
|
||||
*/
|
||||
add_test(function test_invalid_timestamp_object() {
|
||||
// Test timestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", {}, new Date(), new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test sentTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), {}, new Date(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Test deliveryTimestamp.
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), new Date(), {}, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that an invalid delivery string is not accepted.
|
||||
*/
|
||||
add_test(function test_invalid_delivery_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "this is invalid", "pending", "the sender",
|
||||
"the receiver", "the body", "normal", new Date(), 0, 0, true);
|
||||
"the receiver", "the body", "normal", Date.now(), 0, 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -283,7 +184,7 @@ add_test(function test_invalid_delivery_string() {
|
||||
add_test(function test_invalid_delivery_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, 1, "pending", "the sender", "the receiver", "the body",
|
||||
"normal", new Date(), 0, 0, true);
|
||||
"normal", Date.now(), 0, 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -294,7 +195,7 @@ add_test(function test_invalid_delivery_string() {
|
||||
add_test(function test_invalid_delivery_status_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "this is invalid", "the sender", "the receiver",
|
||||
"the body", "normal", new Date(), new Date(), 0, true);
|
||||
"the body", "normal", Date.now(), Date.now(), 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -305,7 +206,7 @@ add_test(function test_invalid_delivery_status_string() {
|
||||
add_test(function test_invalid_delivery_status_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", 1, "the sender", "the receiver", "the body",
|
||||
"normal", new Date(), new Date(), 0, true);
|
||||
"normal", Date.now(), Date.now(), 0, true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -316,7 +217,7 @@ add_test(function test_invalid_delivery_status_string() {
|
||||
add_test(function test_invalid_message_class_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", "this is invalid", new Date(), new Date(), new Date(), true);
|
||||
"the body", "this is invalid", Date.now(), Date.now(), Date.now(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
@@ -327,7 +228,7 @@ add_test(function test_invalid_message_class_string() {
|
||||
add_test(function test_invalid_message_class_string() {
|
||||
do_check_throws(function() {
|
||||
newMessage(42, 1, ICC_ID, "sent", "success", "the sender", "the receiver",
|
||||
"the body", 1, new Date(), new Date(), new Date(), true);
|
||||
"the body", 1, Date.now(), Date.now(), Date.now(), true);
|
||||
}, Cr.NS_ERROR_INVALID_ARG);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ var gData = [
|
||||
perm: ["wifi-manage"],
|
||||
needParentPerm: true,
|
||||
obj: "mozWifiManager",
|
||||
idl: "nsIDOMWifiManager",
|
||||
webidl: "MozWifiManager",
|
||||
verifier: verifier.toSource(),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -38,7 +38,10 @@ NetworkInterfaceListService.prototype = {
|
||||
LIST_NOT_INCLUDE_MMS_INTERFACES) != 0,
|
||||
excludeIms: (aConditions &
|
||||
Ci.nsINetworkInterfaceListService.
|
||||
LIST_NOT_INCLUDE_IMS_INTERFACES) != 0
|
||||
LIST_NOT_INCLUDE_IMS_INTERFACES) != 0,
|
||||
excludeDun: (aConditions &
|
||||
Ci.nsINetworkInterfaceListService.
|
||||
LIST_NOT_INCLUDE_DUN_INTERFACES) != 0
|
||||
}
|
||||
)[0]);
|
||||
}
|
||||
|
||||
@@ -452,7 +452,8 @@ NetworkManager.prototype = {
|
||||
isNetworkTypeSecondaryMobile: function(type) {
|
||||
return (type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
|
||||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL ||
|
||||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS);
|
||||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS ||
|
||||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
|
||||
},
|
||||
|
||||
isNetworkTypeMobile: function(type) {
|
||||
|
||||
@@ -64,11 +64,11 @@ EXTRA_COMPONENTS += [
|
||||
'NetworkInterfaceListService.js',
|
||||
'NetworkInterfaceListService.manifest',
|
||||
'NetworkManager.manifest',
|
||||
'NetworkService.js',
|
||||
'NetworkService.manifest',
|
||||
]
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'NetworkManager.js',
|
||||
'NetworkService.js',
|
||||
]
|
||||
EXTRA_JS_MODULES += [
|
||||
'systemlibs.js',
|
||||
|
||||
@@ -59,7 +59,7 @@ function setEmulatorAPN() {
|
||||
[{"carrier":"T-Mobile US",
|
||||
"apn":"epc.tmobile.com",
|
||||
"mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
|
||||
"types":["default","supl","mms","ims"]}]
|
||||
"types":["default","supl","mms","ims","dun"]}]
|
||||
];
|
||||
|
||||
return setSetting(APN_KEY, apn);
|
||||
@@ -155,7 +155,8 @@ function testNonDefaultDataConnection() {
|
||||
let typeMapping = {
|
||||
"mms": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
|
||||
"supl": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL,
|
||||
"ims": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS
|
||||
"ims": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS,
|
||||
"dun": Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN
|
||||
};
|
||||
let networkType = typeMapping[type];
|
||||
|
||||
@@ -176,6 +177,7 @@ function testNonDefaultDataConnection() {
|
||||
.then(() => doTestNonDefaultDataConnection("mms"))
|
||||
.then(() => doTestNonDefaultDataConnection("supl"))
|
||||
.then(() => doTestNonDefaultDataConnection("ims"))
|
||||
.then(() => doTestNonDefaultDataConnection("dun"))
|
||||
// Restore APN settings
|
||||
.then(() => setSetting(APN_KEY, currentApn))
|
||||
.then(null, () => {
|
||||
|
||||
@@ -677,8 +677,16 @@ var interfaceNamesInGlobalScope =
|
||||
{name: "MozVoicemailEvent", b2g: true, pref: "dom.voicemail.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWakeLock", b2g: true, pref: "dom.wakelock.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiConnection", b2g: true, permission: "wifi-manage"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiConnectionInfo", b2g: true, permission: "wifi-manage"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiConnectionInfoEvent", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiManager", b2g: true, permission: "wifi-manage"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiNetwork", b2g: true, permission: "wifi-manage"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MozWifiStatusChangeEvent", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
enum RecordingState { "inactive", "recording", "paused" };
|
||||
|
||||
[Constructor(MediaStream stream)]
|
||||
[Constructor(MediaStream stream, optional MediaRecorderOptions options)]
|
||||
interface MediaRecorder : EventTarget {
|
||||
|
||||
readonly attribute MediaStream stream;
|
||||
@@ -45,3 +45,6 @@ interface MediaRecorder : EventTarget {
|
||||
void requestData();
|
||||
};
|
||||
|
||||
dictionary MediaRecorderOptions {
|
||||
DOMString mimeType = ""; // Default encoding mimeType.
|
||||
};
|
||||
|
||||
237
dom/webidl/MozWifiManager.webidl
Normal file
237
dom/webidl/MozWifiManager.webidl
Normal file
@@ -0,0 +1,237 @@
|
||||
/* 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/. */
|
||||
|
||||
enum WifiWPSMethod {
|
||||
"pbc",
|
||||
"pin",
|
||||
"cancel"
|
||||
};
|
||||
|
||||
enum ConnectionStatus {
|
||||
"connecting",
|
||||
"associated",
|
||||
"connected",
|
||||
"disconnected"
|
||||
};
|
||||
|
||||
dictionary WifiWPSInfo {
|
||||
WifiWPSMethod method;
|
||||
DOMString? pin;
|
||||
DOMString? bssid;
|
||||
};
|
||||
|
||||
dictionary NetworkProperties {
|
||||
DOMString ssid;
|
||||
sequence<DOMString>? security;
|
||||
sequence<DOMString>? capabilities;
|
||||
boolean known;
|
||||
boolean connected;
|
||||
boolean hidden;
|
||||
};
|
||||
|
||||
[Constructor(optional NetworkProperties properties),
|
||||
JSImplementation="@mozilla.org/mozwifinetwork;1"]
|
||||
interface MozWifiNetwork {
|
||||
readonly attribute DOMString ssid;
|
||||
readonly attribute any security;
|
||||
readonly attribute any capabilities;
|
||||
readonly attribute boolean known;
|
||||
readonly attribute boolean connected;
|
||||
readonly attribute boolean hidden;
|
||||
|
||||
attribute DOMString? bssid;
|
||||
attribute DOMString? signalStrength;
|
||||
attribute long? relSignalStrength;
|
||||
attribute DOMString? psk;
|
||||
attribute DOMString? keyManagement;
|
||||
attribute DOMString? identity;
|
||||
attribute DOMString? password;
|
||||
attribute DOMString? phase1;
|
||||
attribute DOMString? phase2;
|
||||
attribute DOMString? eap;
|
||||
attribute DOMString? pin;
|
||||
};
|
||||
|
||||
[JSImplementation="@mozilla.org/mozwificonnection;1"]
|
||||
interface MozWifiConnection {
|
||||
readonly attribute ConnectionStatus status;
|
||||
readonly attribute MozWifiNetwork? network;
|
||||
};
|
||||
|
||||
[JSImplementation="@mozilla.org/mozwificonnectioninfo;1"]
|
||||
interface MozWifiConnectionInfo {
|
||||
readonly attribute short signalStrength;
|
||||
readonly attribute short relSignalStrength;
|
||||
readonly attribute long linkSpeed;
|
||||
readonly attribute DOMString? ipAddress;
|
||||
};
|
||||
|
||||
dictionary IPConfiguration {
|
||||
boolean enabled;
|
||||
DOMString ipaddr;
|
||||
DOMString proxy;
|
||||
short maskLength;
|
||||
DOMString gateway;
|
||||
DOMString dns1;
|
||||
DOMString dns2;
|
||||
};
|
||||
|
||||
[JSImplementation="@mozilla.org/wifimanager;1",
|
||||
NavigatorProperty="mozWifiManager",
|
||||
Func="Navigator::HasWifiManagerSupport"]
|
||||
interface MozWifiManager : EventTarget {
|
||||
/**
|
||||
* Returns the list of currently available networks.
|
||||
* onsuccess: We have obtained the current list of networks. request.value
|
||||
* is an object whose property names are SSIDs and values are
|
||||
* network objects.
|
||||
* onerror: We were unable to obtain a list of property names.
|
||||
*/
|
||||
DOMRequest getNetworks();
|
||||
|
||||
/**
|
||||
* Returns the list of networks known to the system that will be
|
||||
* automatically connected to if they're in range.
|
||||
* onsuccess: request.value is an object whose property names are
|
||||
* SSIDs and values are network objects.
|
||||
* onerror: We were unable to obtain a list of known networks.
|
||||
*/
|
||||
DOMRequest getKnownNetworks();
|
||||
|
||||
/**
|
||||
* Takes one of the networks returned from getNetworks and tries to
|
||||
* connect to it.
|
||||
* @param network A network object with information about the network,
|
||||
* such as the SSID, key management desired, etc.
|
||||
* onsuccess: We have started attempting to associate with the network.
|
||||
* request.value is true.
|
||||
* onerror: We were unable to select the network. This most likely means a
|
||||
* configuration error.
|
||||
*/
|
||||
DOMRequest associate(MozWifiNetwork network);
|
||||
|
||||
/**
|
||||
* Given a network, removes it from the list of networks that we'll
|
||||
* automatically connect to. In order to re-connect to the network, it is
|
||||
* necessary to call associate on it.
|
||||
* @param network A network object with the SSID of the network to remove.
|
||||
* onsuccess: We have removed this network. If we were previously
|
||||
* connected to it, we have started reconnecting to the next
|
||||
* network in the list.
|
||||
* onerror: We were unable to remove the network.
|
||||
*/
|
||||
DOMRequest forget(MozWifiNetwork network);
|
||||
|
||||
/**
|
||||
* Wi-Fi Protected Setup functionality.
|
||||
* @param detail WPS detail which has 'method' and 'pin' field.
|
||||
* The possible method field values are:
|
||||
* - pbc: The Push Button Configuration.
|
||||
* - pin: The PIN configuration.
|
||||
* - cancel: Request to cancel WPS in progress.
|
||||
* If method field is 'pin', 'pin' field can exist and has
|
||||
* a PIN number.
|
||||
* If method field is 'pin', 'bssid' field can exist and has
|
||||
* a opposite BSSID.
|
||||
* onsuccess: We have successfully started/canceled wps.
|
||||
* onerror: We have failed to start/cancel wps.
|
||||
*/
|
||||
DOMRequest wps(optional WifiWPSInfo detail);
|
||||
|
||||
/**
|
||||
* Turn on/off wifi power saving mode.
|
||||
* @param enabled true or false.
|
||||
* onsuccess: We have successfully turn on/off wifi power saving mode.
|
||||
* onerror: We have failed to turn on/off wifi power saving mode.
|
||||
*/
|
||||
DOMRequest setPowerSavingMode(boolean enabled);
|
||||
|
||||
/**
|
||||
* Given a network, configure using static IP instead of running DHCP
|
||||
* @param network A network object with the SSID of the network to set static ip.
|
||||
* @param info info should have following field:
|
||||
* - enabled True to enable static IP, false to use DHCP
|
||||
* - ipaddr configured static IP address
|
||||
* - proxy configured proxy server address
|
||||
* - maskLength configured mask length
|
||||
* - gateway configured gateway address
|
||||
* - dns1 configured first DNS server address
|
||||
* - dns2 configured seconf DNS server address
|
||||
* onsuccess: We have successfully configure the static ip mode.
|
||||
* onerror: We have failed to configure the static ip mode.
|
||||
*/
|
||||
DOMRequest setStaticIpMode(MozWifiNetwork network, optional IPConfiguration info);
|
||||
|
||||
/**
|
||||
* Given a network, configure http proxy when using wifi.
|
||||
* @param network A network object with the SSID of the network to set http proxy.
|
||||
* @param info info should have following field:
|
||||
* - httpProxyHost ip address of http proxy.
|
||||
* - httpProxyPort port of http proxy, set 0 to use default port 8080.
|
||||
* set info to null to clear http proxy.
|
||||
* onsuccess: We have successfully configure http proxy.
|
||||
* onerror: We have failed to configure http proxy.
|
||||
*/
|
||||
DOMRequest setHttpProxy(MozWifiNetwork network, any info);
|
||||
|
||||
/**
|
||||
* Returns whether or not wifi is currently enabled.
|
||||
*/
|
||||
readonly attribute boolean enabled;
|
||||
|
||||
/**
|
||||
* Returns the MAC address of the wifi adapter.
|
||||
*/
|
||||
readonly attribute DOMString macAddress;
|
||||
|
||||
/**
|
||||
* An non-null object containing the following information:
|
||||
* - status ("disconnected", "connecting", "associated", "connected")
|
||||
* - network
|
||||
*
|
||||
* Note that the object returned is read only. Any changes required must
|
||||
* be done by calling other APIs.
|
||||
*/
|
||||
readonly attribute MozWifiConnection? connection;
|
||||
|
||||
/**
|
||||
* A connectionInformation object with the same information found in an
|
||||
* nsIDOMMozWifiConnectionInfoEvent (but without the network).
|
||||
* If we are not currently connected to a network, this will be null.
|
||||
*/
|
||||
readonly attribute MozWifiConnectionInfo? connectionInformation;
|
||||
|
||||
/**
|
||||
* State notification listeners. These all take an
|
||||
* nsIDOMMozWifiStatusChangeEvent with the new status and a network (which
|
||||
* may be null).
|
||||
*
|
||||
* The possible statuses are:
|
||||
* - connecting: Fires when we start the process of connecting to a
|
||||
* network.
|
||||
* - associated: Fires when we have connected to an access point but do
|
||||
* not yet have an IP address.
|
||||
* - connected: Fires once we are fully connected to an access point and
|
||||
* can access the internet.
|
||||
* - disconnected: Fires when we either fail to connect to an access
|
||||
* point (transition: associated -> disconnected) or
|
||||
* when we were connected to a network but have
|
||||
* disconnected for any reason (transition: connected ->
|
||||
* disconnected).
|
||||
*/
|
||||
attribute EventHandler onstatuschange;
|
||||
|
||||
/**
|
||||
* An event listener that is called with information about the signal
|
||||
* strength and link speed every 5 seconds.
|
||||
*/
|
||||
attribute EventHandler onconnectionInfoUpdate;
|
||||
|
||||
/**
|
||||
* These two events fire when the wifi system is brought online or taken
|
||||
* offline.
|
||||
*/
|
||||
attribute EventHandler onenabled;
|
||||
attribute EventHandler ondisabled;
|
||||
};
|
||||
@@ -553,6 +553,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
WEBIDL_FILES += [
|
||||
'MozSpeakerManager.webidl',
|
||||
'MozWifiConnectionInfoEvent.webidl',
|
||||
'MozWifiManager.webidl',
|
||||
'MozWifiP2pManager.webidl',
|
||||
'MozWifiP2pStatusChangeEvent.webidl',
|
||||
'MozWifiStatusChangeEvent.webidl',
|
||||
|
||||
@@ -15,67 +15,74 @@ Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
const DEBUG = false; // set to false to suppress debug messages
|
||||
|
||||
const DOMWIFIMANAGER_CONTRACTID = "@mozilla.org/wifimanager;1";
|
||||
const DOMWIFIMANAGER_CID = Components.ID("{2cf775a7-1837-410c-9e26-323c42e076da}");
|
||||
const DOMWIFIMANAGER_CID = Components.ID("{c9b5f09e-25d2-40ca-aef4-c4d13d93c706}");
|
||||
|
||||
function DOMWifiManager() {
|
||||
function MozWifiNetwork() {
|
||||
}
|
||||
|
||||
function exposeCurrentNetwork(currentNetwork) {
|
||||
currentNetwork.__exposedProps__ = exposeCurrentNetwork.currentNetworkApi;
|
||||
}
|
||||
MozWifiNetwork.prototype = {
|
||||
|
||||
exposeCurrentNetwork.currentNetworkApi = {
|
||||
ssid: "r",
|
||||
security: "r",
|
||||
capabilities: "r",
|
||||
known: "r"
|
||||
init: function(aWindow) {
|
||||
this._window = aWindow;
|
||||
},
|
||||
|
||||
__init: function(obj) {
|
||||
this.ssid = obj.ssid;
|
||||
this.security = obj.security;
|
||||
this.capabilities = obj.capabilities;
|
||||
this.known = obj.known;
|
||||
this.connected = obj.connected;
|
||||
this.hidden = obj.hidden;
|
||||
},
|
||||
|
||||
classID: Components.ID("{c01fd751-43c0-460a-8b64-abf652ec7220}"),
|
||||
contractID: "@mozilla.org/mozwifinetwork;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIDOMGlobalPropertyInitializer])
|
||||
};
|
||||
|
||||
// For smaller, read-only APIs, we expose any property that doesn't begin with
|
||||
// an underscore.
|
||||
function exposeReadOnly(obj) {
|
||||
var exposedProps = {};
|
||||
for (let i in obj) {
|
||||
if (i[0] === "_")
|
||||
continue;
|
||||
exposedProps[i] = "r";
|
||||
}
|
||||
function MozWifiConnection(obj) {
|
||||
this.status = obj.status;
|
||||
this.network = obj.network;
|
||||
}
|
||||
|
||||
obj.__exposedProps__ = exposedProps;
|
||||
return obj;
|
||||
MozWifiConnection.prototype = {
|
||||
classID: Components.ID("{23579da4-201b-4319-bd42-9b7f337343ac}"),
|
||||
contractID: "@mozilla.org/mozwificonnection;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
|
||||
};
|
||||
|
||||
function MozWifiConnectionInfo(obj) {
|
||||
this.signalStrength = obj.signalStrength;
|
||||
this.relSignalStrength = obj.relSignalStrength;
|
||||
this.linkSpeed = obj.linkSpeed;
|
||||
this.ipAddress = obj.ipAddress;
|
||||
}
|
||||
|
||||
MozWifiConnectionInfo.prototype = {
|
||||
classID: Components.ID("{83670352-6ed4-4c35-8de9-402296a1959c}"),
|
||||
contractID: "@mozilla.org/mozwificonnectioninfo;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
|
||||
}
|
||||
|
||||
function DOMWifiManager() {
|
||||
this.defineEventHandlerGetterSetter("onstatuschange");
|
||||
this.defineEventHandlerGetterSetter("onconnectionInfoUpdate");
|
||||
this.defineEventHandlerGetterSetter("onenabled");
|
||||
this.defineEventHandlerGetterSetter("ondisabled");
|
||||
}
|
||||
|
||||
DOMWifiManager.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
classID: DOMWIFIMANAGER_CID,
|
||||
classInfo: XPCOMUtils.generateCI({classID: DOMWIFIMANAGER_CID,
|
||||
contractID: DOMWIFIMANAGER_CONTRACTID,
|
||||
classDescription: "DOMWifiManager",
|
||||
interfaces: [Ci.nsIDOMWifiManager],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMWifiManager,
|
||||
Ci.nsIDOMGlobalPropertyInitializer,
|
||||
classID: DOMWIFIMANAGER_CID,
|
||||
contractID: DOMWIFIMANAGER_CONTRACTID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIObserver]),
|
||||
|
||||
// nsIDOMGlobalPropertyInitializer implementation
|
||||
init: function(aWindow) {
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
|
||||
let perm = principal == secMan.getSystemPrincipal()
|
||||
? Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
: Services.perms.testExactPermissionFromPrincipal(principal, "wifi-manage");
|
||||
|
||||
// Only pages with perm set can use the wifi manager.
|
||||
this._hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
|
||||
if (!this._hasPrivileges) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Maintain this state for synchronous APIs.
|
||||
this._currentNetwork = null;
|
||||
this._connectionStatus = "disconnected";
|
||||
@@ -101,10 +108,8 @@ DOMWifiManager.prototype = {
|
||||
|
||||
var state = this._mm.sendSyncMessage("WifiManager:getState")[0];
|
||||
if (state) {
|
||||
this._currentNetwork = state.network;
|
||||
if (this._currentNetwork)
|
||||
exposeCurrentNetwork(this._currentNetwork);
|
||||
this._lastConnectionInfo = state.connectionInfo;
|
||||
this._currentNetwork = this._convertWifiNetwork(state.network);
|
||||
this._lastConnectionInfo = this._convertConnectionInfo(state.connectionInfo);
|
||||
this._enabled = state.enabled;
|
||||
this._connectionStatus = state.status;
|
||||
this._macAddress = state.macAddress;
|
||||
@@ -117,11 +122,40 @@ DOMWifiManager.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._onStatusChange = null;
|
||||
this._onConnectionInfoUpdate = null;
|
||||
this._onEnabled = null;
|
||||
this._onDisabled = null;
|
||||
_convertWifiNetworkToJSON: function(aNetwork) {
|
||||
let json = {};
|
||||
|
||||
for (let key in aNetwork) {
|
||||
// In WifiWorker.js there are lots of check using "key in network".
|
||||
// So if the value of any property of WifiNetwork is undefined, do not clone it.
|
||||
if (aNetwork[key] != undefined) {
|
||||
json[key] = aNetwork[key];
|
||||
}
|
||||
}
|
||||
return json;
|
||||
},
|
||||
|
||||
_convertWifiNetwork: function(aNetwork) {
|
||||
let network = aNetwork ? new this._window.MozWifiNetwork(aNetwork) : null;
|
||||
return network;
|
||||
},
|
||||
|
||||
_convertWifiNetworks: function(aNetworks) {
|
||||
let networks = [];
|
||||
for (let i in aNetworks) {
|
||||
networks.push(this._convertWifiNetwork(aNetworks[i]));
|
||||
}
|
||||
return networks;
|
||||
},
|
||||
|
||||
_convertConnection: function(aConn) {
|
||||
let conn = aConn ? new MozWifiConnection(aConn) : null;
|
||||
return conn;
|
||||
},
|
||||
|
||||
_convertConnectionInfo: function(aInfo) {
|
||||
let info = aInfo ? new MozWifiConnectionInfo(aInfo) : null;
|
||||
return info;
|
||||
},
|
||||
|
||||
_sendMessageForRequest: function(name, data, request) {
|
||||
@@ -144,7 +178,7 @@ DOMWifiManager.prototype = {
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "WifiManager:getNetworks:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data));
|
||||
break;
|
||||
|
||||
case "WifiManager:getNetworks:Return:NO":
|
||||
@@ -152,7 +186,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:getKnownNetworks:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data));
|
||||
break;
|
||||
|
||||
case "WifiManager:getKnownNetworks:Return:NO":
|
||||
@@ -176,7 +210,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:wps:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, msg.data);
|
||||
break;
|
||||
|
||||
case "WifiManager:wps:Return:NO":
|
||||
@@ -184,7 +218,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:setPowerSavingMode:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, msg.data);
|
||||
break;
|
||||
|
||||
case "WifiManager:setPowerSavingMode:Return:NO":
|
||||
@@ -192,7 +226,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:setHttpProxy:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, msg.data);
|
||||
break;
|
||||
|
||||
case "WifiManager:setHttpProxy:Return:NO":
|
||||
@@ -200,7 +234,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:setStaticIpMode:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
|
||||
Services.DOMRequest.fireSuccess(request, msg.data);
|
||||
break;
|
||||
|
||||
case "WifiManager:setStaticIpMode:Return:NO":
|
||||
@@ -220,22 +254,19 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:onconnecting":
|
||||
this._currentNetwork = msg.network;
|
||||
exposeCurrentNetwork(this._currentNetwork);
|
||||
this._currentNetwork = this._convertWifiNetwork(msg.network);
|
||||
this._connectionStatus = "connecting";
|
||||
this._fireStatusChangeEvent();
|
||||
break;
|
||||
|
||||
case "WifiManager:onassociate":
|
||||
this._currentNetwork = msg.network;
|
||||
exposeCurrentNetwork(this._currentNetwork);
|
||||
this._currentNetwork = this._convertWifiNetwork(msg.network);
|
||||
this._connectionStatus = "associated";
|
||||
this._fireStatusChangeEvent();
|
||||
break;
|
||||
|
||||
case "WifiManager:onconnect":
|
||||
this._currentNetwork = msg.network;
|
||||
exposeCurrentNetwork(this._currentNetwork);
|
||||
this._currentNetwork = this._convertWifiNetwork(msg.network);
|
||||
this._connectionStatus = "connected";
|
||||
this._fireStatusChangeEvent();
|
||||
break;
|
||||
@@ -269,7 +300,7 @@ DOMWifiManager.prototype = {
|
||||
break;
|
||||
|
||||
case "WifiManager:connectionInfoUpdate":
|
||||
this._lastConnectionInfo = msg;
|
||||
this._lastConnectionInfo = this._convertConnectionInfo(msg);
|
||||
this._fireConnectionInfoUpdate(msg);
|
||||
break;
|
||||
case "WifiManager:onconnectingfailed":
|
||||
@@ -282,156 +313,115 @@ DOMWifiManager.prototype = {
|
||||
},
|
||||
|
||||
_fireStatusChangeEvent: function StatusChangeEvent() {
|
||||
if (this._onStatusChange) {
|
||||
debug("StatusChangeEvent");
|
||||
var event = new this._window.MozWifiStatusChangeEvent("statusChangeEvent",
|
||||
var event = new this._window.MozWifiStatusChangeEvent("statuschange",
|
||||
{ network: this._currentNetwork,
|
||||
status: this._connectionStatus
|
||||
});
|
||||
this._onStatusChange.handleEvent(event);
|
||||
}
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
},
|
||||
|
||||
_fireConnectionInfoUpdate: function connectionInfoUpdate(info) {
|
||||
if (this._onConnectionInfoUpdate) {
|
||||
debug("ConnectionInfoEvent");
|
||||
var evt = new this._window.MozWifiConnectionInfoEvent("connectionInfoEvent",
|
||||
_fireConnectionInfoUpdate: function onConnectionInfoUpdate(info) {
|
||||
var evt = new this._window.MozWifiConnectionInfoEvent("connectioninfoupdate",
|
||||
{ network: this._currentNetwork,
|
||||
signalStrength: info.signalStrength,
|
||||
relSignalStrength: info.relSignalStrength,
|
||||
linkSpeed: info.linkSpeed,
|
||||
ipAddress: info.ipAddress,
|
||||
});
|
||||
this._onConnectionInfoUpdate.handleEvent(evt);
|
||||
}
|
||||
this.__DOM_IMPL__.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_fireEnabledOrDisabled: function enabledDisabled(enabled) {
|
||||
var handler = enabled ? this._onEnabled : this._onDisabled;
|
||||
if (handler) {
|
||||
var evt = new this._window.Event("WifiEnabled");
|
||||
handler.handleEvent(evt);
|
||||
}
|
||||
var evt = new this._window.Event(enabled ? "enabled" : "disabled");
|
||||
this.__DOM_IMPL__.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
// nsIDOMWifiManager
|
||||
getNetworks: function nsIDOMWifiManager_getNetworks() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
getNetworks: function getNetworks() {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:getNetworks", null, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
getKnownNetworks: function nsIDOMWifiManager_getKnownNetworks() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
getKnownNetworks: function getKnownNetworks() {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:getKnownNetworks", null, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
associate: function nsIDOMWifiManager_associate(network) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
associate: function associate(network) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:associate", network, request);
|
||||
this._sendMessageForRequest("WifiManager:associate",
|
||||
this._convertWifiNetworkToJSON(network), request);
|
||||
return request;
|
||||
},
|
||||
|
||||
forget: function nsIDOMWifiManager_forget(network) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
forget: function forget(network) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:forget", network, request);
|
||||
this._sendMessageForRequest("WifiManager:forget",
|
||||
this._convertWifiNetworkToJSON(network), request);
|
||||
return request;
|
||||
},
|
||||
|
||||
wps: function nsIDOMWifiManager_wps(detail) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
wps: function wps(detail) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:wps", detail, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
setPowerSavingMode: function nsIDOMWifiManager_setPowerSavingMode(enabled) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
setPowerSavingMode: function setPowerSavingMode(enabled) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:setPowerSavingMode", enabled, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
setHttpProxy: function nsIDOMWifiManager_setHttpProxy(network, info) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
setHttpProxy: function setHttpProxy(network, info) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:setHttpProxy", {network:network, info:info}, request);
|
||||
this._sendMessageForRequest("WifiManager:setHttpProxy",
|
||||
{ network: this._convertWifiNetworkToJSON(network), info:info}, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
setStaticIpMode: function nsIDOMWifiManager_setStaticIpMode(network, info) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
setStaticIpMode: function setStaticIpMode(network, info) {
|
||||
var request = this.createRequest();
|
||||
this._sendMessageForRequest("WifiManager:setStaticIpMode", {network: network,info: info}, request);
|
||||
this._sendMessageForRequest("WifiManager:setStaticIpMode",
|
||||
{ network: this._convertWifiNetworkToJSON(network), info: info}, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
return this._enabled;
|
||||
},
|
||||
|
||||
get macAddress() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
return this._macAddress;
|
||||
},
|
||||
|
||||
get connection() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
return exposeReadOnly({ status: this._connectionStatus,
|
||||
network: this._currentNetwork });
|
||||
let _connection = this._convertConnection({ status: this._connectionStatus,
|
||||
network: this._currentNetwork,
|
||||
});
|
||||
return _connection;
|
||||
},
|
||||
|
||||
get connectionInformation() {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
return this._lastConnectionInfo
|
||||
? exposeReadOnly(this._lastConnectionInfo)
|
||||
: null;
|
||||
return this._lastConnectionInfo;
|
||||
},
|
||||
|
||||
set onstatuschange(callback) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
this._onStatusChange = callback;
|
||||
defineEventHandlerGetterSetter: function(name) {
|
||||
Object.defineProperty(this, name, {
|
||||
get: function() {
|
||||
return this.__DOM_IMPL__.getEventHandler(name);
|
||||
},
|
||||
|
||||
set connectionInfoUpdate(callback) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
this._onConnectionInfoUpdate = callback;
|
||||
},
|
||||
|
||||
set onenabled(callback) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
this._onEnabled = callback;
|
||||
},
|
||||
|
||||
set ondisabled(callback) {
|
||||
if (!this._hasPrivileges)
|
||||
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
this._onDisabled = callback;
|
||||
set: function(handler) {
|
||||
this.__DOM_IMPL__.setEventHandler(name, handler);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DOMWifiManager]);
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
DOMWifiManager, MozWifiNetwork, MozWifiConnection, MozWifiConnectionInfo
|
||||
]);
|
||||
|
||||
let debug;
|
||||
if (DEBUG) {
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
# DOMWifiManager.js
|
||||
component {2cf775a7-1837-410c-9e26-323c42e076da} DOMWifiManager.js
|
||||
contract @mozilla.org/wifimanager;1 {2cf775a7-1837-410c-9e26-323c42e076da}
|
||||
category JavaScript-navigator-property mozWifiManager @mozilla.org/wifimanager;1
|
||||
component {c9b5f09e-25d2-40ca-aef4-c4d13d93c706} DOMWifiManager.js
|
||||
contract @mozilla.org/wifimanager;1 {c9b5f09e-25d2-40ca-aef4-c4d13d93c706}
|
||||
|
||||
component {c01fd751-43c0-460a-8b64-abf652ec7220} DOMWifiManager.js
|
||||
contract @mozilla.org/mozwifinetwork;1 {c01fd751-43c0-460a-8b64-abf652ec7220}
|
||||
|
||||
component {23579da4-201b-4319-bd42-9b7f337343ac} DOMWifiManager.js
|
||||
contract @mozilla.org/mozwificonnection;1 {23579da4-201b-4319-bd42-9b7f337343ac}
|
||||
|
||||
component {83670352-6ed4-4c35-8de9-402296a1959c} DOMWifiManager.js
|
||||
contract @mozilla.org/mozwificonnectioninfo;1 {83670352-6ed4-4c35-8de9-402296a1959c}
|
||||
|
||||
@@ -58,163 +58,3 @@ interface nsIWifi : nsISupports
|
||||
*/
|
||||
void getWifiScanResults(in nsIWifiScanResultsReady callback);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e5a72295-1c5f-4848-9cbb-f1d3785c16c1)]
|
||||
interface nsIDOMWifiManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Returns the list of currently available networks.
|
||||
* onsuccess: We have obtained the current list of networks. request.value
|
||||
* is an object whose property names are SSIDs and values are
|
||||
* network objects.
|
||||
* onerror: We were unable to obtain a list of property names.
|
||||
*/
|
||||
nsIDOMDOMRequest getNetworks();
|
||||
|
||||
/**
|
||||
* Returns the list of networks known to the system that will be
|
||||
* automatically connected to if they're in range.
|
||||
* onsuccess: request.value is an object whose property names are
|
||||
* SSIDs and values are network objects.
|
||||
* onerror: We were unable to obtain a list of known networks.
|
||||
*/
|
||||
nsIDOMDOMRequest getKnownNetworks();
|
||||
|
||||
/**
|
||||
* Takes one of the networks returned from getNetworks and tries to
|
||||
* connect to it.
|
||||
* @param network A network object with information about the network,
|
||||
* such as the SSID, key management desired, etc.
|
||||
* onsuccess: We have started attempting to associate with the network.
|
||||
* request.value is true.
|
||||
* onerror: We were unable to select the network. This most likely means a
|
||||
* configuration error.
|
||||
*/
|
||||
nsIDOMDOMRequest associate(in jsval network);
|
||||
|
||||
/**
|
||||
* Given a network, removes it from the list of networks that we'll
|
||||
* automatically connect to. In order to re-connect to the network, it is
|
||||
* necessary to call associate on it.
|
||||
* @param network A network object with the SSID of the network to remove.
|
||||
* onsuccess: We have removed this network. If we were previously
|
||||
* connected to it, we have started reconnecting to the next
|
||||
* network in the list.
|
||||
* onerror: We were unable to remove the network.
|
||||
*/
|
||||
nsIDOMDOMRequest forget(in jsval network);
|
||||
|
||||
/**
|
||||
* Wi-Fi Protected Setup functionality.
|
||||
* @param detail WPS detail which has 'method' and 'pin' field.
|
||||
* The possible method field values are:
|
||||
* - pbc: The Push Button Configuration.
|
||||
* - pin: The PIN configuration.
|
||||
* - cancel: Request to cancel WPS in progress.
|
||||
* If method field is 'pin', 'pin' field can exist and has
|
||||
* a PIN number.
|
||||
* If method field is 'pin', 'bssid' field can exist and has
|
||||
* a opposite BSSID.
|
||||
* onsuccess: We have successfully started/canceled wps.
|
||||
* onerror: We have failed to start/cancel wps.
|
||||
*/
|
||||
nsIDOMDOMRequest wps(in jsval detail);
|
||||
|
||||
/**
|
||||
* Turn on/off wifi power saving mode.
|
||||
* @param enabled true or false.
|
||||
* onsuccess: We have successfully turn on/off wifi power saving mode.
|
||||
* onerror: We have failed to turn on/off wifi power saving mode.
|
||||
*/
|
||||
nsIDOMDOMRequest setPowerSavingMode(in boolean enabled);
|
||||
|
||||
/**
|
||||
* Given a network, configure using static IP instead of running DHCP
|
||||
* @param network A network object with the SSID of the network to set static ip.
|
||||
* @param info info should have following field:
|
||||
* - enabled True to enable static IP, false to use DHCP
|
||||
* - ipaddr configured static IP address
|
||||
* - proxy configured proxy server address
|
||||
* - maskLength configured mask length
|
||||
* - gateway configured gateway address
|
||||
* - dns1 configured first DNS server address
|
||||
* - dns2 configured seconf DNS server address
|
||||
* onsuccess: We have successfully configure the static ip mode.
|
||||
* onerror: We have failed to configure the static ip mode.
|
||||
*/
|
||||
nsIDOMDOMRequest setStaticIpMode(in jsval network,
|
||||
in jsval info);
|
||||
|
||||
/**
|
||||
* Given a network, configure http proxy when using wifi.
|
||||
* @param network A network object with the SSID of the network to set http proxy.
|
||||
* @param info info should have following field:
|
||||
* - httpProxyHost ip address of http proxy.
|
||||
* - httpProxyPort port of http proxy, set 0 to use default port 8080.
|
||||
* set info to null to clear http proxy.
|
||||
* onsuccess: We have successfully configure http proxy.
|
||||
* onerror: We have failed to configure http proxy.
|
||||
*/
|
||||
nsIDOMDOMRequest setHttpProxy(in jsval network,
|
||||
in jsval info);
|
||||
|
||||
/**
|
||||
* Returns whether or not wifi is currently enabled.
|
||||
*/
|
||||
readonly attribute boolean enabled;
|
||||
|
||||
/**
|
||||
* Returns the MAC address of the wifi adapter.
|
||||
*/
|
||||
readonly attribute DOMString macAddress;
|
||||
|
||||
/**
|
||||
* An non-null object containing the following information:
|
||||
* - status ("disconnected", "connecting", "associated", "connected")
|
||||
* - network
|
||||
*
|
||||
* Note that the object returned is read only. Any changes required must
|
||||
* be done by calling other APIs.
|
||||
*/
|
||||
readonly attribute jsval connection;
|
||||
|
||||
/**
|
||||
* A connectionInformation object with the same information found in an
|
||||
* nsIDOMMozWifiConnectionInfoEvent (but without the network).
|
||||
* If we are not currently connected to a network, this will be null.
|
||||
*/
|
||||
readonly attribute jsval connectionInformation;
|
||||
|
||||
/**
|
||||
* State notification listeners. These all take an
|
||||
* nsIDOMMozWifiStatusChangeEvent with the new status and a network (which
|
||||
* may be null).
|
||||
*
|
||||
* The possible statuses are:
|
||||
* - connecting: Fires when we start the process of connecting to a
|
||||
* network.
|
||||
* - associated: Fires when we have connected to an access point but do
|
||||
* not yet have an IP address.
|
||||
* - connected: Fires once we are fully connected to an access point and
|
||||
* can access the internet.
|
||||
* - disconnected: Fires when we either fail to connect to an access
|
||||
* point (transition: associated -> disconnected) or
|
||||
* when we were connected to a network but have
|
||||
* disconnected for any reason (transition: connected ->
|
||||
* disconnected).
|
||||
*/
|
||||
attribute nsIDOMEventListener onstatuschange;
|
||||
|
||||
/**
|
||||
* An event listener that is called with information about the signal
|
||||
* strength and link speed every 5 seconds.
|
||||
*/
|
||||
attribute nsIDOMEventListener connectionInfoUpdate;
|
||||
|
||||
/**
|
||||
* These two events fire when the wifi system is brought online or taken
|
||||
* offline.
|
||||
*/
|
||||
attribute nsIDOMEventListener onenabled;
|
||||
attribute nsIDOMEventListener ondisabled;
|
||||
};
|
||||
|
||||
@@ -878,6 +878,8 @@ ProcessPriorityToString(ProcessPriority aPriority)
|
||||
switch (aPriority) {
|
||||
case PROCESS_PRIORITY_MASTER:
|
||||
return "MASTER";
|
||||
case PROCESS_PRIORITY_PREALLOC:
|
||||
return "PREALLOC";
|
||||
case PROCESS_PRIORITY_FOREGROUND_HIGH:
|
||||
return "FOREGROUND_HIGH";
|
||||
case PROCESS_PRIORITY_FOREGROUND:
|
||||
@@ -916,6 +918,13 @@ ProcessPriorityToString(ProcessPriority aPriority,
|
||||
if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
|
||||
return "MASTER:CPU_LOW";
|
||||
}
|
||||
case PROCESS_PRIORITY_PREALLOC:
|
||||
if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
|
||||
return "PREALLOC:CPU_NORMAL";
|
||||
}
|
||||
if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
|
||||
return "PREALLOC:CPU_LOW";
|
||||
}
|
||||
case PROCESS_PRIORITY_FOREGROUND_HIGH:
|
||||
if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
|
||||
return "FOREGROUND_HIGH:CPU_NORMAL";
|
||||
|
||||
@@ -84,6 +84,9 @@ enum ProcessPriority {
|
||||
PROCESS_PRIORITY_BACKGROUND_HOMESCREEN,
|
||||
PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE,
|
||||
PROCESS_PRIORITY_FOREGROUND_KEYBOARD,
|
||||
// The special class for the preallocated process, high memory priority but
|
||||
// low CPU priority.
|
||||
PROCESS_PRIORITY_PREALLOC,
|
||||
// Any priority greater than or equal to FOREGROUND is considered
|
||||
// "foreground" for the purposes of priority testing, for example
|
||||
// CurrentProcessIsForeground().
|
||||
|
||||
@@ -1256,6 +1256,9 @@ EnsureKernelLowMemKillerParamsSet()
|
||||
nsPrintfCString("hal.processPriorityManager.gonk.%s.KillUnderKB",
|
||||
ProcessPriorityToString(priority)).get(),
|
||||
&killUnderKB))) {
|
||||
// ProcessPriority values like PROCESS_PRIORITY_FOREGROUND_KEYBOARD,
|
||||
// which has only OomScoreAdjust but lacks KillUnderMB value, will not
|
||||
// create new LMK parameters.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
||||
|
||||
int32_t flags =
|
||||
nsINetworkInterfaceListService::LIST_NOT_INCLUDE_SUPL_INTERFACES |
|
||||
nsINetworkInterfaceListService::LIST_NOT_INCLUDE_MMS_INTERFACES;
|
||||
nsINetworkInterfaceListService::LIST_NOT_INCLUDE_MMS_INTERFACES |
|
||||
nsINetworkInterfaceListService::LIST_NOT_INCLUDE_IMS_INTERFACES |
|
||||
nsINetworkInterfaceListService::LIST_NOT_INCLUDE_DUN_INTERFACES;
|
||||
nsCOMPtr<nsINetworkInterfaceList> networkList;
|
||||
NS_ENSURE_SUCCESS(listService->GetDataInterfaceList(flags,
|
||||
getter_AddRefs(networkList)),
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#define AUDIO_MP3 "audio/mpeg"
|
||||
#define AUDIO_MP4 "audio/mp4"
|
||||
#define AUDIO_AMR "audio/amr"
|
||||
#define AUDIO_3GPP "audio/3gpp"
|
||||
#define AUDIO_MIDI "audio/x-midi"
|
||||
|
||||
#define BINARY_OCTET_STREAM "binary/octet-stream"
|
||||
|
||||
@@ -225,6 +225,10 @@ class Emulator(object):
|
||||
self._get_telnet_response()
|
||||
return self._get_telnet_response(command)
|
||||
|
||||
def _run_shell(self, args):
|
||||
args.insert(0, 'shell')
|
||||
return self._run_adb(args).split('\r\n')
|
||||
|
||||
def close(self):
|
||||
if self.is_running and self._emulator_launched:
|
||||
self.proc.kill()
|
||||
|
||||
@@ -608,8 +608,16 @@ class Marionette(object):
|
||||
|
||||
# Process any emulator commands that are sent from a script
|
||||
# while it's executing.
|
||||
while response.get("emulator_cmd"):
|
||||
while True:
|
||||
if response.get("emulator_cmd"):
|
||||
response = self._handle_emulator_cmd(response)
|
||||
continue;
|
||||
|
||||
if response.get("emulator_shell"):
|
||||
response = self._handle_emulator_shell(response)
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
if response_key in response:
|
||||
return response[response_key]
|
||||
@@ -626,6 +634,16 @@ class Marionette(object):
|
||||
"id": response.get("id"),
|
||||
"result": result})
|
||||
|
||||
def _handle_emulator_shell(self, response):
|
||||
args = response.get("emulator_shell")
|
||||
if not isinstance(args, list) or not self.emulator:
|
||||
raise MarionetteException(
|
||||
"No emulator in this test to run shell command against")
|
||||
result = self.emulator._run_shell(args)
|
||||
return self.client.send({"name": "emulatorCmdResult",
|
||||
"id": response.get("id"),
|
||||
"result": result})
|
||||
|
||||
def _handle_error(self, response):
|
||||
if 'error' in response and isinstance(response['error'], dict):
|
||||
status = response['error'].get('status', 500)
|
||||
|
||||
@@ -17,6 +17,14 @@ class TestEmulatorContent(MarionetteTestCase):
|
||||
""");
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_emulator_shell(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
expected = ["Hello World!", ""]
|
||||
result = self.marionette.execute_async_script("""
|
||||
runEmulatorShell(["echo", "Hello World!"], marionetteScriptFinished)
|
||||
""");
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_emulator_order(self):
|
||||
self.marionette.set_script_timeout(10000)
|
||||
self.assertRaises(MarionetteException,
|
||||
|
||||
@@ -163,6 +163,7 @@ FrameManager.prototype = {
|
||||
messageManager.addWeakMessageListener("Marionette:shareData", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:register", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:runEmulatorCmd", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:runEmulatorShell", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:switchToModalOrigin", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:switchToFrame", this.server);
|
||||
messageManager.addWeakMessageListener("Marionette:switchedToFrame", this.server);
|
||||
@@ -190,6 +191,7 @@ FrameManager.prototype = {
|
||||
messageManager.removeWeakMessageListener("Marionette:shareData", this.server);
|
||||
messageManager.removeWeakMessageListener("Marionette:register", this.server);
|
||||
messageManager.removeWeakMessageListener("Marionette:runEmulatorCmd", this.server);
|
||||
messageManager.removeWeakMessageListener("Marionette:runEmulatorShell", this.server);
|
||||
messageManager.removeWeakMessageListener("Marionette:switchToFrame", this.server);
|
||||
messageManager.removeWeakMessageListener("Marionette:switchedToFrame", this.server);
|
||||
messageManager.removeWeakMessageListener("MarionetteFrame:handleModal", this);
|
||||
|
||||
@@ -2019,6 +2019,14 @@ function runEmulatorCmd(cmd, callback) {
|
||||
_emu_cb_id += 1;
|
||||
}
|
||||
|
||||
function runEmulatorShell(args, callback) {
|
||||
if (callback) {
|
||||
_emu_cbs[_emu_cb_id] = callback;
|
||||
}
|
||||
sendAsyncMessage("Marionette:runEmulatorShell", {emulator_shell: args, id: _emu_cb_id});
|
||||
_emu_cb_id += 1;
|
||||
}
|
||||
|
||||
function emulatorCmdResult(msg) {
|
||||
let message = msg.json;
|
||||
if (!sandbox) {
|
||||
|
||||
@@ -2128,6 +2128,17 @@ MarionetteServerConnection.prototype = {
|
||||
this._emu_cb_id += 1;
|
||||
},
|
||||
|
||||
runEmulatorShell: function runEmulatorShell(args, callback) {
|
||||
if (callback) {
|
||||
if (!this._emu_cbs) {
|
||||
this._emu_cbs = {};
|
||||
}
|
||||
this._emu_cbs[this._emu_cb_id] = callback;
|
||||
}
|
||||
this.sendToClient({emulator_shell: args, id: this._emu_cb_id}, -1);
|
||||
this._emu_cb_id += 1;
|
||||
},
|
||||
|
||||
emulatorCmdResult: function emulatorCmdResult(message) {
|
||||
if (this.context != "chrome") {
|
||||
this.sendAsync("emulatorCmdResult", message, -1);
|
||||
@@ -2325,6 +2336,7 @@ MarionetteServerConnection.prototype = {
|
||||
}
|
||||
break;
|
||||
case "Marionette:runEmulatorCmd":
|
||||
case "Marionette:runEmulatorShell":
|
||||
this.sendToClient(message.json, -1);
|
||||
break;
|
||||
case "Marionette:switchToFrame":
|
||||
|
||||
@@ -22,7 +22,7 @@ this.Marionette = function Marionette(scope, window, context, logObj, timeout,
|
||||
|
||||
Marionette.prototype = {
|
||||
exports: ['ok', 'is', 'isnot', 'log', 'getLogs', 'generate_results', 'waitFor',
|
||||
'runEmulatorCmd', 'TEST_PASS', 'TEST_KNOWN_FAIL',
|
||||
'runEmulatorCmd', 'runEmulatorShell', 'TEST_PASS', 'TEST_KNOWN_FAIL',
|
||||
'TEST_UNEXPECTED_FAIL'],
|
||||
|
||||
ok: function Marionette__ok(condition, name, passString, failString, diag) {
|
||||
@@ -163,5 +163,10 @@ Marionette.prototype = {
|
||||
this.scope.runEmulatorCmd(cmd, callback);
|
||||
},
|
||||
|
||||
runEmulatorShell: function runEmulatorShell(args, callback) {
|
||||
this.heartbeatCallback();
|
||||
this.scope.runEmulatorShell(args, callback);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -44,9 +44,6 @@ SERV_FILES = \
|
||||
android.json \
|
||||
androidx86.json \
|
||||
android23.json \
|
||||
b2g.json \
|
||||
b2g-desktop.json \
|
||||
b2g-debug.json \
|
||||
gl.json \
|
||||
b2g_start_script.js \
|
||||
$(NULL)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"runtests": {
|
||||
},
|
||||
"excludetests": {
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"runtests": {
|
||||
},
|
||||
"excludetests": {
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"runtests": {
|
||||
},
|
||||
"excludetests": {
|
||||
}
|
||||
}
|
||||
@@ -143,13 +143,6 @@ class MochitestRunner(MozbuildObject):
|
||||
test_path_dir = True;
|
||||
options.testPath = test_path
|
||||
|
||||
# filter test directiories or all tests according to the manifest
|
||||
if not test_path or test_path_dir:
|
||||
if conditions.is_b2g_desktop(self):
|
||||
options.testManifest = 'b2g-desktop.json'
|
||||
else:
|
||||
options.testManifest = 'b2g.json'
|
||||
|
||||
for k, v in kwargs.iteritems():
|
||||
setattr(options, k, v)
|
||||
options.noWindow = no_window
|
||||
|
||||
@@ -47,6 +47,23 @@ typedef hwc_layer_list_t HwcList;
|
||||
typedef hwc_layer_t HwcLayer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* HwcComposer2D provides a way for gecko to render frames
|
||||
* using hwcomposer.h in the AOSP HAL.
|
||||
*
|
||||
* hwcomposer.h defines an interface for display composition
|
||||
* using dedicated hardware. This hardware is usually faster
|
||||
* or more power efficient than the GPU. However, in exchange
|
||||
* for better performance, generality has to be sacrificed:
|
||||
* no 3d transforms, no intermediate surfaces, no special shader effects,
|
||||
* and loss of other goodies depending on the platform.
|
||||
*
|
||||
* In general, when hwc is enabled gecko tries to compose
|
||||
* its frames using HwcComposer2D first. Then if HwcComposer2D is
|
||||
* unable to compose a frame then it falls back to compose it
|
||||
* using the GPU with OpenGL.
|
||||
*
|
||||
*/
|
||||
class HwcComposer2D : public mozilla::layers::Composer2D {
|
||||
public:
|
||||
HwcComposer2D();
|
||||
|
||||
Reference in New Issue
Block a user