Merge latest green fx-team changeset and mozilla-central; a=merge

This commit is contained in:
Ed Morley 2014-08-20 15:14:31 +01:00
commit 9e018ab910
434 changed files with 10086 additions and 3547 deletions

View File

@ -9,9 +9,14 @@
display: none;
border-radius: 2px;
box-shadow: 1px 1px 1px #444;
display: none;
}
#virtual-cursor-inset {
#virtual-cursor-box.show {
display: block;
}
#virtual-cursor-box > div {
border-radius: 1px;
box-shadow: inset 1px 1px 1px #444;
display: block;

View File

@ -394,23 +394,19 @@ this.AccessFu = { // jshint ignore:line
_processedMessageManagers: [],
/**
* Adjusts the given bounds relative to the given browser. Converts from
* screen or device pixels to either device or CSS pixels.
* Adjusts the given bounds relative to the given browser.
* @param {Rect} aJsonBounds the bounds to adjust
* @param {browser} aBrowser the browser we want the bounds relative to
* @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
* device pixels)
* @param {bool} aFromDevicePixels whether to convert from device pixels (as
* opposed to screen pixels)
*/
adjustContentBounds:
function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) {
function(aJsonBounds, aBrowser, aToCSSPixels) {
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
aJsonBounds.right - aJsonBounds.left,
aJsonBounds.bottom - aJsonBounds.top);
let win = Utils.win;
let dpr = win.devicePixelRatio;
let vp = Utils.getViewport(win);
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
if (!aBrowser.contentWindow) {
@ -421,16 +417,6 @@ this.AccessFu = { // jshint ignore:line
offset.left += clientRect.left + win.mozInnerScreenX;
offset.top += clientRect.top + win.mozInnerScreenY;
}
// Here we scale from screen pixels to layout device pixels by dividing by
// the resolution (caused by pinch-zooming). The resolution is the
// viewport zoom divided by the devicePixelRatio. If there's no viewport,
// then we're on a platform without pinch-zooming and we can just ignore
// this.
if (!aFromDevicePixels && vp) {
bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr);
}
// Add the offset; the offset is in CSS pixels, so multiply the
// devicePixelRatio back in before adding to preserve unit consistency.
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
@ -545,11 +531,10 @@ var Output = {
highlightBox.id = 'virtual-cursor-box';
// Add highlight inset for inner shadow
let inset = Utils.win.document.
createElementNS('http://www.w3.org/1999/xhtml', 'div');
inset.id = 'virtual-cursor-inset';
highlightBox.appendChild(
Utils.win.document.createElementNS(
'http://www.w3.org/1999/xhtml', 'div'));
highlightBox.appendChild(inset);
this.highlightBox = Cu.getWeakReference(highlightBox);
} else {
highlightBox = this.highlightBox.get();
@ -559,12 +544,12 @@ var Output = {
let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
// First hide it to avoid flickering when changing the style.
highlightBox.style.display = 'none';
highlightBox.classList.remove('show');
highlightBox.style.top = (r.top - padding) + 'px';
highlightBox.style.left = (r.left - padding) + 'px';
highlightBox.style.width = (r.width + padding*2) + 'px';
highlightBox.style.height = (r.height + padding*2) + 'px';
highlightBox.style.display = 'block';
highlightBox.classList.add('show');
break;
}
@ -572,7 +557,7 @@ var Output = {
{
let highlightBox = this.highlightBox ? this.highlightBox.get() : null;
if (highlightBox) {
highlightBox.style.display = 'none';
highlightBox.classList.remove('show');
}
break;
}
@ -889,8 +874,7 @@ var Input = {
activateContextMenu: function activateContextMenu(aDetails) {
if (Utils.MozBuildApp === 'mobile/android') {
let p = AccessFu.adjustContentBounds(aDetails.bounds,
Utils.CurrentBrowser,
true, true).center();
Utils.CurrentBrowser, true).center();
Services.obs.notifyObservers(null, 'Gesture:LongPress',
JSON.stringify({x: p.x, y: p.y}));
}
@ -915,8 +899,8 @@ var Input = {
doScroll: function doScroll(aDetails) {
let horizontal = aDetails.horizontal;
let page = aDetails.page;
let p = AccessFu.adjustContentBounds(aDetails.bounds, Utils.CurrentBrowser,
true, true).center();
let p = AccessFu.adjustContentBounds(
aDetails.bounds, Utils.CurrentBrowser, true).center();
Utils.winUtils.sendWheelEvent(p.x, p.y,
horizontal ? page : 0, horizontal ? 0 : page, 0,
Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);

View File

@ -255,15 +255,6 @@ this.Utils = { // jshint ignore:line
}
},
getViewport: function getViewport(aWindow) {
switch (this.MozBuildApp) {
case 'mobile/android':
return aWindow.BrowserApp.selectedTab.getViewport();
default:
return null;
}
},
getState: function getState(aAccessibleOrEvent) {
if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) {
return new State(
@ -302,18 +293,37 @@ this.Utils = { // jshint ignore:line
return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor;
},
getBounds: function getBounds(aAccessible) {
let objX = {}, objY = {}, objW = {}, objH = {};
aAccessible.getBounds(objX, objY, objW, objH);
return new Rect(objX.value, objY.value, objW.value, objH.value);
getContentResolution: function _getContentResolution(aAccessible) {
let resX = { value: 1 }, resY = { value: 1 };
aAccessible.document.window.QueryInterface(
Ci.nsIInterfaceRequestor).getInterface(
Ci.nsIDOMWindowUtils).getResolution(resX, resY);
return [resX.value, resY.value];
},
getTextBounds: function getTextBounds(aAccessible, aStart, aEnd) {
let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
let objX = {}, objY = {}, objW = {}, objH = {};
accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
return new Rect(objX.value, objY.value, objW.value, objH.value);
getBounds: function getBounds(aAccessible, aPreserveContentScale) {
let objX = {}, objY = {}, objW = {}, objH = {};
aAccessible.getBounds(objX, objY, objW, objH);
let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] :
this.getContentResolution(aAccessible);
return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
scaleX, scaleY);
},
getTextBounds: function getTextBounds(aAccessible, aStart, aEnd,
aPreserveContentScale) {
let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
let objX = {}, objY = {}, objW = {}, objH = {};
accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] :
this.getContentResolution(aAccessible);
return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
scaleX, scaleY);
},
/**

View File

@ -65,14 +65,10 @@ function forwardToChild(aMessage, aListener, aVCPosition) {
}
function activateContextMenu(aMessage) {
function sendContextMenuCoordinates(aAccessible) {
let bounds = Utils.getBounds(aAccessible);
sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds});
}
let position = Utils.getVirtualCursor(content.document).position;
if (!forwardToChild(aMessage, activateContextMenu, position)) {
sendContextMenuCoordinates(position);
sendAsyncMessage('AccessFu:ActivateContextMenu',
{ bounds: Utils.getBounds(position, true) });
}
}
@ -85,16 +81,12 @@ function presentCaretChange(aText, aOldOffset, aNewOffset) {
}
function scroll(aMessage) {
function sendScrollCoordinates(aAccessible) {
let bounds = Utils.getBounds(aAccessible);
sendAsyncMessage('AccessFu:DoScroll',
{ bounds: bounds,
page: aMessage.json.page,
horizontal: aMessage.json.horizontal });
}
let position = Utils.getVirtualCursor(content.document).position;
if (!forwardToChild(aMessage, scroll, position)) {
sendAsyncMessage('AccessFu:DoScroll',
{ bounds: Utils.getBounds(position, true),
page: aMessage.json.page,
horizontal: aMessage.json.horizontal });
sendScrollCoordinates(position);
}
}

View File

@ -407,18 +407,18 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) {
let fullId = join(rootURI, id);
let resolvedPath;
if (resolvedPath = loadAsFile(fullId))
if ((resolvedPath = loadAsFile(fullId)))
return stripBase(rootURI, resolvedPath);
else if (resolvedPath = loadAsDirectory(fullId))
else if ((resolvedPath = loadAsDirectory(fullId)))
return stripBase(rootURI, resolvedPath);
// If manifest has dependencies, attempt to look up node modules
// in the `dependencies` list
else {
let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id));
for (let i = 0; i < dirs.length; i++) {
if (resolvedPath = loadAsFile(dirs[i]))
if ((resolvedPath = loadAsFile(dirs[i])))
return stripBase(rootURI, resolvedPath);
if (resolvedPath = loadAsDirectory(dirs[i]))
if ((resolvedPath = loadAsDirectory(dirs[i])))
return stripBase(rootURI, resolvedPath);
}
}
@ -459,7 +459,7 @@ function loadAsDirectory (path) {
let main = getManifestMain(JSON.parse(readURI(path + '/package.json')));
if (main != null) {
let tmpPath = join(path, main);
if (found = loadAsFile(tmpPath))
if ((found = loadAsFile(tmpPath)))
return found
}
try {

View File

@ -1201,8 +1201,7 @@ const kTransferContractId = "@mozilla.org/transfer;1";
// Override Toolkit's nsITransfer implementation with the one from the
// JavaScript API for downloads. This will eventually be removed when
// nsIDownloadManager will not be available anymore (bug 851471). The
// old code in this module will be removed in bug 899110.
// nsIDownloadManager will not be available anymore (bug 851471).
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
.registerFactory(kTransferCid, "",
kTransferContractId, null);

View File

@ -0,0 +1,38 @@
{
"config_version": 2,
"mock_target": "mozilla-centos6-x86_64",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "bc"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": ["kernelheader", ""],
"upload_files": [
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{objdir}/dist/b2g-*.tar.gz",
"{workdir}/sources.xml"
],
"public_upload_files": [
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{objdir}/dist/b2g-*.tar.gz",
"{workdir}/sources.xml"
],
"zip_files": [
["{workdir}/out/target/product/scx15_sp7715ga/*.img", "out/target/product/scx15_sp7715ga/"],
"{workdir}/flash.sh",
"{workdir}/load-config.sh",
"{workdir}/.config",
"{workdir}/sources.xml"
],
"env": {
"VARIANT": "user",
"MOZILLA_OFFICIAL": "1"
},
"b2g_manifest": "dolphin.xml",
"b2g_manifest_intree": true,
"additional_source_tarballs": [],
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"root": "https://hg.mozilla.org/gaia-l10n"
}
}
}

View File

@ -0,0 +1,143 @@
<?xml version="1.0" ?><manifest>
<!--original fetch url was https://android.googlesource.com/-->
<remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
<!--original fetch url was git://github.com/mozilla-b2g/-->
<remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
<!--original fetch url was git://github.com/mozilla/-->
<remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="1865c6639c51f0290d5778adef146147d5d6a5f0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0688d2e417602961fec3847db1d0788cd0bd49a4"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
<project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
<project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
<project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
<project name="device/sample" path="device/sample" revision="1a3d8efa0ad32ec8f145367a3cf0f54b97385c3c"/>
<project name="platform/abi/cpp" path="abi/cpp" revision="18f1b5e28734183ff8073fe86dc46bc4ebba8a59"/>
<project name="platform/bionic" path="bionic" revision="86b1f589c313422a7da1812512b9ec8d1cf9ba3c"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="1f68d4c6a5d2e72bc02fa837af94c0a51afa94de"/>
<project name="platform/external/aac" path="external/aac" revision="fa3eba16446cc8f2f5e2dfc20d86a49dbd37299e"/>
<project name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="c50830cae1b748024eec7e73ad98a4e427f663c7"/>
<project name="platform/external/bsdiff" path="external/bsdiff" revision="23e322ab19fb7d74c2c37e40ce364d9f709bdcee"/>
<project name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de"/>
<project name="platform/external/checkpolicy" path="external/checkpolicy" revision="0d73ef7049feee794f14cf1af88d05dae8139914"/>
<project name="platform/external/dhcpcd" path="external/dhcpcd" revision="84b7252b0a9d0edc9a1db1e0c518771d26b23058"/>
<project name="platform/external/dnsmasq" path="external/dnsmasq" revision="41d356427a632f5336384bfa45c8420ffc274f66"/>
<project name="platform/external/dropbear" path="external/dropbear" revision="a34ddbe3819bc465968f3676c734b405e655f8b7"/>
<project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="47478a2944a2a17c7fdebe9d92573db92013125c"/>
<project name="platform/external/elfutils" path="external/elfutils" revision="b23b2dfb354b3ccf5d1c5d39815f02e7048cf516"/>
<project name="platform/external/expat" path="external/expat" revision="0af0cb3bc7519e567bd9daff3dcd315ab0134a99"/>
<project name="platform/external/fdlibm" path="external/fdlibm" revision="0da5f683c9ddc9442af3b389b4220e91ccffb320"/>
<project name="platform/external/flac" path="external/flac" revision="ab37b6247df0e8c4ec0ccaa870e667f62c74975b"/>
<project name="platform/external/freetype" path="external/freetype" revision="899c67b6cfcd2010784fbf08c5415af16c526e0c"/>
<project name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9241386b62c353302c2f9eccda0672685b252b4d"/>
<project name="platform/external/genext2fs" path="external/genext2fs" revision="e11a9c7fe6f1cef99aad2f25afaea37b72fe9f93"/>
<project name="platform/external/giflib" path="external/giflib" revision="9aef3ea079a57c98a9207f8c3b95a5dc08ee74b5"/>
<project name="platform/external/gtest" path="external/gtest" revision="0f1ce3dd0b880b6ae0cf7f5413702b8ef542efb2"/>
<project name="platform/external/harfbuzz" path="external/harfbuzz" revision="858f2d28ac741ef139f74bdbdbcefa7560f17c91"/>
<project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="3309edccdbc2a92eb03a285abb27c1c1c4a88e43"/>
<project name="platform/external/iproute2" path="external/iproute2" revision="157d428913c3d738be481f12e8cbf9267b3b2862"/>
<project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="f4cb1ee4b00abbfb6f968dc25818c23b4b47e584"/>
<project name="platform/external/iptables" path="external/iptables" revision="93e814c9b08136846335ce463192d90ba59766bb"/>
<project name="platform/external/jack" path="external/jack" revision="5ceb2025ac5d25ed48183ac2d3dac4691fe761fb"/>
<project name="platform/external/jhead" path="external/jhead" revision="31b17e69a87e4caa50f9c6b1a47c84ef75f79d83"/>
<project name="platform/external/jpeg" path="external/jpeg" revision="68f6f73d3157cc0481826e03d0fae9586217a300"/>
<project name="platform/external/junit" path="external/junit" revision="3abf41974d8aae44b3bbd15d83487894253d287d"/>
<project name="platform/external/libgsm" path="external/libgsm" revision="50761abed8f4734970874165b386cfd4d9599db4"/>
<project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
<project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="9e987ccb716624d658f98abc7db2097e11e3d8ed"/>
<project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
<project name="platform/external/libogg" path="external/libogg" revision="ec0b24fb1468abe37be4164a6feb16568e036bde"/>
<project name="platform/external/libpcap" path="external/libpcap" revision="3a7bce5dda6a8db92c9248846d0255e68c3a5b2a"/>
<project name="platform/external/libpng" path="external/libpng" revision="b5e7fb4c103b3898cb78e9f7615cf7893626a5e9"/>
<project name="platform/external/libselinux" path="external/libselinux" revision="1e2cf2c4a2d15a9b1ca2d353b99fb6884413ffe1"/>
<project name="platform/external/libsepol" path="external/libsepol" revision="8fd7c65a336d45d5225f32363a9f26c1e3e60c3c"/>
<project name="platform/external/libvpx" path="external/libvpx" revision="5e563eddf3e143a4b670766b49f676ce39023322"/>
<project name="platform/external/mdnsresponder" path="external/mdnsresponder" revision="c46f53f5e072f23051c4eedef730386f7634dc11"/>
<project name="platform/external/mksh" path="external/mksh" revision="f8c396c4d446a038358106a301b329607a04633d"/>
<project name="platform/external/netcat" path="external/netcat" revision="444644cfa9a2f3002863caa168fb2d6b34dfd1e8"/>
<project name="platform/external/netperf" path="external/netperf" revision="58ecd3b7c76263900e38921360e334a416aec362"/>
<project name="platform/external/openssl" path="external/openssl" revision="bb8428f762b3632f493572c4f73957e1281ade79"/>
<project name="platform/external/protobuf" path="external/protobuf" revision="48ee66d295979372ed0234cefda42385daae8312"/>
<project name="platform/external/safe-iop" path="external/safe-iop" revision="aa0725fb1da35e47676b6da30009322eb5ed59be"/>
<project name="platform/external/scrypt" path="external/scrypt" revision="eb05b73c3bba21fff55529813109de4bad5ddbd1"/>
<project name="platform/external/sepolicy" path="external/sepolicy" revision="f3525622103090156a6bbd9a8609be8b009d223f"/>
<project name="platform/external/sfntly" path="external/sfntly" revision="30d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cd"/>
<project name="platform/external/skia" path="external/skia" revision="97c714a01e32e6aee7faf9c57fbbd4d95b41d353"/>
<project name="platform/external/sonivox" path="external/sonivox" revision="2dbbd3bac0f0e819d196a80cc7855054148ef8b6"/>
<project name="platform/external/speex" path="external/speex" revision="fb7db5853ffb841a4d32fea8b5c3a43e6b875cae"/>
<project name="platform/external/sqlite" path="external/sqlite" revision="ac0e0d5f866fbce0ebf00d0ddd615464849aa83b"/>
<project name="platform/external/stlport" path="external/stlport" revision="628e14d37c5b239839a466e81c74bf66255b770b"/>
<project name="platform/external/strace" path="external/strace" revision="1a4e05d53dec658a061acb9869cb1eb1342cd09d"/>
<project name="platform/external/svox" path="external/svox" revision="838228cc17b5798e51bc20d06e54dbd781e441db"/>
<project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
<project name="platform/external/tcpdump" path="external/tcpdump" revision="532b8f38c144da9a298260a5d8978ab9e8e3856c"/>
<project name="platform/external/tinyalsa" path="external/tinyalsa" revision="aa08b9c35638a32de0444a940cf47708e4ba0eda"/>
<project name="platform/external/tinycompress" path="external/tinycompress" revision="a85e245a09c028d36cbf04f233be10bc583691f5"/>
<project name="platform/external/tinyxml" path="external/tinyxml" revision="494e448824844d866e805831d1d5f5acb654065c"/>
<project name="platform/external/tinyxml2" path="external/tinyxml2" revision="c74b546f5af36968ffa56d7fd4529f4273b96f48"/>
<project name="platform/external/tremolo" path="external/tremolo" revision="0499204aa97d3e2978ee77d869dd033acb2196e2"/>
<project name="platform/external/webp" path="external/webp" revision="513e97bd307573e2adc776eb5368bd129aceaa4a"/>
<project name="platform/external/webrtc" path="external/webrtc" revision="446452f84e9cc4c75d8e80f6f05e24793397a19d"/>
<project name="platform/external/yaffs2" path="external/yaffs2" revision="a2cff2275e1b501ff478b03757d6e4f05fddc2db"/>
<project name="platform/external/zlib" path="external/zlib" revision="a5c7131da47c991585a6c6ac0c063b6d7d56e3fc"/>
<project name="platform/frameworks/base" path="frameworks/base" revision="2d12cb68a6c680e1ef50c6fbd19f782f67aec9de"/>
<project name="platform/frameworks/native" path="frameworks/native" revision="b6018ccb81af66e0523a4bfdc45f0bd2ab472b55"/>
<project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="dbbe673145107e99883f62bafd70c5f43f11065c"/>
<project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="aac6c4bb59a6577c97cbda68699829b507b7490d"/>
<project name="platform/hardware/libhardware" path="hardware/libhardware" revision="fbeca55f4695dd07c0291213403533b8fbca4885"/>
<project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="6e98e2d0762a8e6dc12df228261fd741db98531f"/>
<project name="platform/libcore" path="libcore" revision="e195beab082c09217318fc19250caeaf4c1bd800"/>
<project name="platform/libnativehelper" path="libnativehelper" revision="feeb36c2bd4adfe285f98f5de92e0f3771b2c115"/>
<project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
<project name="platform/prebuilts/misc" path="prebuilts/misc" revision="ee724654c72825f8d732ba45caf75ca59e06975d"/>
<project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
<project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
<project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
<project name="platform/system/netd" path="system/netd" revision="3ae56364946d4a5bf5a5f83f12f9a45a30398e33"/>
<project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
<project name="platform/system/vold" path="system/vold" revision="118dec582647895a863dbbce8ec26bc7af457bbe"/>
<!--original fetch url was http://sprdsource.spreadtrum.com:8085/b2g/android-->
<remote fetch="https://git.mozilla.org/external/sprd-aosp" name="sprd-aosp"/>
<default remote="sprd-aosp" revision="sprdb2g_gonk4.4" sync-j="4"/>
<!-- Stock Android things -->
<project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
<!-- dolphin specific things -->
<project name="device/sprd" path="device/sprd" revision="054d217fc6efdeff296742b58b5bda427d9d4384"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="cbd80d8c03fc639dd810b17c4b682c67abc06ee8"/>
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
<project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
<project name="kernel/common" path="kernel" revision="7cd1a292befc685e8be55996cedad1386037cbea"/>
<project name="platform/system/core" path="system/core" revision="b5de04ae22343b6bdaa3455aee291bdf9a872738"/>
<project name="u-boot" path="u-boot" revision="81522506a5ade829a18bcc8d1f1813129010b6fe"/>
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7feb3df0e150053e0143ef525f6e082bda320aea"/>
<project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="da06ca296bccf13e1f775ca5e7ba9b6d98069fc8"/>
<project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/>
<project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d994b716d979a5b57b11a61cc05d31fe7ca61d38"/>
</manifest>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0688d2e417602961fec3847db1d0788cd0bd49a4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="1865c6639c51f0290d5778adef146147d5d6a5f0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0688d2e417602961fec3847db1d0788cd0bd49a4"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "0aa0d2ae3f0ee2215c18808c88d9366666536e9b",
"revision": "03a4bc3b7d10bcc197511ac7accdb05346a0b9dd",
"repo_path": "/integration/gaia-central"
}

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0688d2e417602961fec3847db1d0788cd0bd49a4"/>

View File

@ -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="df39c463259d348396ef7f143c2c780eeb8f02d8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="33d4b999f464fbad1c23d488da4689c5de9967ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -980,7 +980,11 @@ pref("browser.safebrowsing.reportMalwareURL", "http://%LOCALE%.malware-report.mo
pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%");
pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
// Turn off remote lookups in beta and stable channel.
#ifndef RELEASE_BUILD
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
#endif
#ifdef MOZILLA_OFFICIAL
// Normally the "client ID" sent in updates is appinfo.name, but for

View File

@ -438,6 +438,13 @@ var gPopupBlockerObserver = {
// Hide the icon in the location bar (if the location bar exists)
if (gURLBar)
this._reportButton.hidden = true;
// Hide the notification box (if it's visible).
var notificationBox = gBrowser.getNotificationBox();
var notification = notificationBox.getNotificationWithValue("popup-blocked");
if (notification) {
notificationBox.removeNotification(notification, false);
}
return;
}

View File

@ -293,7 +293,14 @@ AppCacheUtils.prototype = {
},
clearAll: function ACU_clearAll() {
Services.cache.evictEntries(Ci.nsICache.STORE_OFFLINE);
if (!Services.prefs.getBoolPref("browser.cache.disk.enable")) {
throw new Error(l10n.GetStringFromName("cacheDisabled"));
}
let appCacheStorage = Services.cache2.appCacheStorage(LoadContextInfo.default, null);
appCacheStorage.asyncEvictStorage({
onCacheEntryDoomed: function(result) {}
});
},
_getManifestURI: function ACU__getManifestURI() {

View File

@ -15,7 +15,7 @@ let test = asyncTest(function*() {
info("Creating the test document");
content.document.body.innerHTML = '<style type="text/css"> ' +
'span { font-variant: small-caps; color: #000000; } ' +
'span { font-variant-caps: small-caps; color: #000000; } ' +
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
'<h1>Some header text</h1>\n' +
@ -58,7 +58,7 @@ function checkCopySelection(view) {
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
"font-size: 16px;[\\r\\n]+" +
"font-variant: small-caps;[\\r\\n]*";
"font-variant-caps: small-caps;[\\r\\n]*";
return waitForClipboard(() => {
fireCopyEvent(props[0]);
@ -80,7 +80,7 @@ function checkSelectAll(view) {
let expectedPattern = "color: #FF0;[\\r\\n]+" +
"font-family: helvetica,sans-serif;[\\r\\n]+" +
"font-size: 16px;[\\r\\n]+" +
"font-variant: small-caps;[\\r\\n]*";
"font-variant-caps: small-caps;[\\r\\n]*";
return waitForClipboard(() => {
fireCopyEvent(prop);

View File

@ -816,6 +816,7 @@ bin/libfreebl_32int64_3.so
@BINPATH@/webapprt/components/PaymentUIGlue.js
@BINPATH@/webapprt/components/components.manifest
@BINPATH@/webapprt/defaults/preferences/prefs.js
@BINPATH@/webapprt/modules/DownloadView.jsm
@BINPATH@/webapprt/modules/Startup.jsm
@BINPATH@/webapprt/modules/WebappRT.jsm
@BINPATH@/webapprt/modules/WebappManager.jsm

View File

@ -28,12 +28,43 @@ leak:GI___strdup
###
### Many leaks only affect some test suites. The suite annotations are not checked.
### Bug 979928 - WebRTC leaks. m2, m3.
###
# Bug 979928 - WebRTC is leaky. m2, m3
leak:/media/mtransport/
leak:/media/webrtc/signaling/
# WebRTC leaks added for Mochitest 2.
leak:NR_reg_init
leak:fsmdef_init
leak:r_log_register
leak:nr_reg_set
leak:ccsnap_device_init
leak:ccsnap_line_init
leak:media/webrtc/signaling/src/sipcc/core/common/init.c
leak:cprPostMessage
leak:mozilla::NrIceStunServer::Create
# Additional WebRTC leak suppressions added for Mochitest 3.
leak:mozilla::TransportLayerDtls::Setup
leak:mozilla::NrIceTurnServer::Create
# There are about 228KB of leaks from the call to |pmsg->sdp = cpr_malloc(sdp_size);|
# in send_message_helper.
leak:send_message_helper
leak:fsmdef_ev_createoffer
leak:fsmdef_ev_setremotedesc
leak:fsmdef_ev_setlocaldesc
leak:fsmdef_ev_createanswer
# About 70KB of leaks under this stack.
leak:vcmRxAllocICE_s
leak:vcmRxStartICE_m
# About 50KB of leaks under this stack.
leak:ccsnap_EscapeStrToLocaleStr
leak:gsmsdp_add_default_audio_formats_to_local_sdp
leak:gsmsdp_add_default_video_formats_to_local_sdp
leak:CCAPI_CallInfo_getMediaStreams
###
### Many leaks only affect some test suites. The suite annotations are not checked.
###
# Bug 981195 - Small leak in the parser. m4
leak:TypeCompartment::fixObjectType

View File

@ -728,7 +728,7 @@ public:
int32_t ScrollTop()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ? sf->GetScrollPositionCSSPixels().y : 0;
return sf ? sf->GetScrollPositionCSSPixels().y.value : 0;
}
void SetScrollTop(int32_t aScrollTop)
{
@ -741,7 +741,7 @@ public:
int32_t ScrollLeft()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ? sf->GetScrollPositionCSSPixels().x : 0;
return sf ? sf->GetScrollPositionCSSPixels().x.value : 0;
}
void SetScrollLeft(int32_t aScrollLeft)
{

View File

@ -405,15 +405,6 @@ public:
static bool CanCallerAccess(nsPIDOMWindow* aWindow);
/**
* Get the window through the JS context that's currently on the stack.
* If there's no JS context currently on the stack, returns null.
*/
static nsPIDOMWindow *GetWindowFromCaller();
/**
* The two GetDocumentFrom* functions below allow a caller to get at a
* document that is relevant to the currently executing script.
*
* GetDocumentFromCaller gets its document by looking at the last called
* function and finding the document that the function itself relates to.
* For example, consider two windows A and B in the same origin. B has a
@ -421,28 +412,10 @@ public:
* If a script in window A were to call B's function, GetDocumentFromCaller
* would find that function (in B) and return B's document.
*
* GetDocumentFromContext gets its document by looking at the currently
* executing context's global object and returning its document. Thus,
* given the example above, GetDocumentFromCaller would see that the
* currently executing script was in window A, and return A's document.
*/
/**
* Get the document from the currently executing function. This will return
* the document that the currently executing function is in/from.
*
* @return The document or null if no JS Context.
*/
static nsIDocument* GetDocumentFromCaller();
/**
* Get the document through the JS context that's currently on the stack.
* If there's no JS context currently on the stack it will return null.
* This will return the document of the calling script.
*
* @return The document or null if no JS context
*/
static nsIDocument* GetDocumentFromContext();
// Check if a node is in the document prolog, i.e. before the document
// element.
static bool InProlog(nsINode *aNode);
@ -2279,9 +2252,7 @@ private:
static bool sInitialized;
static uint32_t sScriptBlockerCount;
#ifdef DEBUG
static uint32_t sDOMNodeRemovedSuppressCount;
#endif
static uint32_t sMicroTaskLevel;
// Not an nsCOMArray because removing elements from those is slower
static nsTArray< nsCOMPtr<nsIRunnable> >* sBlockedScriptRunners;
@ -2338,14 +2309,10 @@ class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
public nsAutoScriptBlocker {
public:
nsAutoScriptBlockerSuppressNodeRemoved() {
#ifdef DEBUG
++nsContentUtils::sDOMNodeRemovedSuppressCount;
#endif
}
~nsAutoScriptBlockerSuppressNodeRemoved() {
#ifdef DEBUG
--nsContentUtils::sDOMNodeRemovedSuppressCount;
#endif
}
};

View File

@ -8,9 +8,7 @@
#include "nsIDOMNodeList.h"
#include "nsWrapperCache.h"
class nsIContent;
class nsINode;
#include "nsIContent.h"
// IID for the nsINodeList interface
#define NS_INODELIST_IID \

View File

@ -686,7 +686,7 @@ WebSocket::Init(JSContext* aCx,
// Confirmed we are opening plain ws:// and want to prevent this from a
// secure context (e.g. https). Check the principal's uri to determine if
// we were loaded from https.
nsCOMPtr<nsIGlobalObject> globalObject(BrokenGetEntryGlobal());
nsCOMPtr<nsIGlobalObject> globalObject(GetEntryGlobal());
if (globalObject) {
nsCOMPtr<nsIPrincipal> principal(globalObject->PrincipalOrNull());
if (principal) {

View File

@ -214,9 +214,7 @@ nsILineBreaker *nsContentUtils::sLineBreaker;
nsIWordBreaker *nsContentUtils::sWordBreaker;
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
uint32_t nsContentUtils::sScriptBlockerCount = 0;
#ifdef DEBUG
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
#endif
uint32_t nsContentUtils::sMicroTaskLevel = 0;
nsTArray< nsCOMPtr<nsIRunnable> >* nsContentUtils::sBlockedScriptRunners = nullptr;
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
@ -1953,19 +1951,6 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)
}
}
nsPIDOMWindow *
nsContentUtils::GetWindowFromCaller()
{
JSContext *cx = GetCurrentJSContext();
if (cx) {
nsCOMPtr<nsPIDOMWindow> win =
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
return win;
}
return nullptr;
}
nsIDocument*
nsContentUtils::GetDocumentFromCaller()
{
@ -1980,24 +1965,6 @@ nsContentUtils::GetDocumentFromCaller()
return win->GetExtantDoc();
}
nsIDocument*
nsContentUtils::GetDocumentFromContext()
{
JSContext *cx = GetCurrentJSContext();
if (cx) {
nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
if (sgo) {
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(sgo);
if (pwin) {
return pwin->GetExtantDoc();
}
}
}
return nullptr;
}
bool
nsContentUtils::IsCallerChrome()
{
@ -3920,30 +3887,27 @@ nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent");
NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
// This checks that IsSafeToRunScript is true since we don't want to fire
// events when that is false. We can't rely on EventDispatcher to assert
// this in this situation since most of the time there are no mutation
// event listeners, in which case we won't even attempt to dispatch events.
// However this also allows for two exceptions. First off, we don't assert
// if the mutation happens to native anonymous content since we never fire
// mutation events on such content anyway.
// Second, we don't assert if sDOMNodeRemovedSuppressCount is true since
// that is a know case when we'd normally fire a mutation event, but can't
// make that safe and so we suppress it at this time. Ideally this should
// go away eventually.
NS_ASSERTION((aChild->IsNodeOfType(nsINode::eCONTENT) &&
static_cast<nsIContent*>(aChild)->
IsInNativeAnonymousSubtree()) ||
IsSafeToRunScript() ||
sDOMNodeRemovedSuppressCount,
"Want to fire DOMNodeRemoved event, but it's not safe");
// Having an explicit check here since it's an easy mistake to fall into,
// and there might be existing code with problems. We'd rather be safe
// than fire DOMNodeRemoved in all corner cases. We also rely on it for
// nsAutoScriptBlockerSuppressNodeRemoved.
if (!IsSafeToRunScript()) {
WarnScriptWasIgnored(aOwnerDoc);
// This checks that IsSafeToRunScript is true since we don't want to fire
// events when that is false. We can't rely on EventDispatcher to assert
// this in this situation since most of the time there are no mutation
// event listeners, in which case we won't even attempt to dispatch events.
// However this also allows for two exceptions. First off, we don't assert
// if the mutation happens to native anonymous content since we never fire
// mutation events on such content anyway.
// Second, we don't assert if sDOMNodeRemovedSuppressCount is true since
// that is a know case when we'd normally fire a mutation event, but can't
// make that safe and so we suppress it at this time. Ideally this should
// go away eventually.
if (!(aChild->IsContent() && aChild->AsContent()->IsInNativeAnonymousSubtree()) &&
!sDOMNodeRemovedSuppressCount) {
NS_ERROR("Want to fire DOMNodeRemoved event, but it's not safe");
WarnScriptWasIgnored(aOwnerDoc);
}
return;
}

View File

@ -1429,10 +1429,10 @@ nsHTMLDocument::Open(JSContext* cx,
return ret.forget();
}
// Note: We want to use GetDocumentFromContext here because this document
// Note: We want to use GetEntryDocument here because this document
// should inherit the security information of the document that's opening us,
// (since if it's secure, then it's presumably trusted).
nsCOMPtr<nsIDocument> callerDoc = nsContentUtils::GetDocumentFromContext();
nsCOMPtr<nsIDocument> callerDoc = GetEntryDocument();
if (!callerDoc) {
// If we're called from C++ or in some other way without an originating
// document we can't do a document.open w/o changing the principal of the

View File

@ -128,14 +128,15 @@ GMPChild::Init(const std::string& aPluginPath,
return false;
}
#ifdef MOZ_CRASHREPORTER
SendPCrashReporterConstructor(CrashReporter::CurrentThreadId());
#endif
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
mPluginPath = aPluginPath;
return true;
#endif
#ifdef MOZ_CRASHREPORTER
SendPCrashReporterConstructor(CrashReporter::CurrentThreadId());
#endif
#if defined(XP_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#endif

View File

@ -75,6 +75,7 @@ private:
public:
ResourceQueue() :
nsDeque(new ResourceQueueDeallocator()),
mLogicalLength(0),
mOffset(0)
{
}
@ -87,12 +88,7 @@ private:
// Returns the length of all items in the queue plus the offset.
// This is the logical length of the resource.
inline uint64_t GetLength() {
uint64_t s = mOffset;
for (uint32_t i = 0; i < GetSize(); ++i) {
ResourceItem* item = ResourceAt(i);
s += item->mData.Length();
}
return s;
return mLogicalLength;
}
// Copies aCount bytes from aOffset in the queue into aDest.
@ -113,6 +109,7 @@ private:
}
inline void PushBack(ResourceItem* aItem) {
mLogicalLength += aItem->mData.Length();
nsDeque::Push(aItem);
}
@ -184,8 +181,10 @@ private:
return static_cast<ResourceItem*>(nsDeque::PopFront());
}
// Logical offset into the resource of the first element
// in the queue.
// Logical length of the resource.
uint64_t mLogicalLength;
// Logical offset into the resource of the first element in the queue.
uint64_t mOffset;
};

View File

@ -67,9 +67,6 @@ EXPORTS += [
'AudioCompactor.h',
'AudioEventTimeline.h',
'AudioMixer.h',
'AudioNodeEngine.h',
'AudioNodeExternalInputStream.h',
'AudioNodeStream.h',
'AudioSampleFormat.h',
'AudioSegment.h',
'AudioStream.h',
@ -130,9 +127,6 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'AudioChannelFormat.cpp',
'AudioCompactor.cpp',
'AudioNodeEngine.cpp',
'AudioNodeExternalInputStream.cpp',
'AudioNodeStream.cpp',
'AudioSegment.cpp',
'AudioSink.cpp',
'AudioStream.cpp',
@ -185,10 +179,6 @@ SOURCES += [
FAIL_ON_WARNINGS = True
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
SOURCES += ['AudioNodeEngineNEON.cpp']
SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
MSVC_ENABLE_PGO = True
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -19,6 +19,9 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
EXPORTS += [
'AudioContext.h',
'AudioNodeEngine.h',
'AudioNodeExternalInputStream.h',
'AudioNodeStream.h',
'AudioParamTimeline.h',
'MediaBufferDecoder.h',
'ThreeDPoint.h',
@ -65,6 +68,9 @@ UNIFIED_SOURCES += [
'AudioDestinationNode.cpp',
'AudioListener.cpp',
'AudioNode.cpp',
'AudioNodeEngine.cpp',
'AudioNodeExternalInputStream.cpp',
'AudioNodeStream.cpp',
'AudioParam.cpp',
'AudioProcessingEvent.cpp',
'BiquadFilterNode.cpp',
@ -90,8 +96,15 @@ UNIFIED_SOURCES += [
'WebAudioUtils.cpp',
]
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
SOURCES += ['AudioNodeEngineNEON.cpp']
SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
FAIL_ON_WARNINGS = True
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'..'
]

View File

@ -128,6 +128,7 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_periodicWave.html]
[test_scriptProcessorNode.html]
[test_scriptProcessorNodeChannelCount.html]
[test_scriptProcessorNodePassThrough.html]
[test_scriptProcessorNode_playbackTime1.html]
[test_scriptProcessorNodeZeroInputOutput.html]
[test_scriptProcessorNodeNotConnected.html]

View File

@ -26,7 +26,7 @@ addLoadEvent(function() {
for (var i = 0; i < 2048; ++i) {
// Make sure our first sample won't be zero
e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate);
e.outputBuffer.getChannelData(0)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
e.outputBuffer.getChannelData(1)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
}
// Remember our generated audio
buffer = e.outputBuffer;

View File

@ -0,0 +1,103 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test ScriptProcessorNode with passthrough</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="webaudio.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
// We do not use our generic graph test framework here because
// the testing logic here is sort of complicated, and would
// not be easy to map to OfflineAudioContext, as ScriptProcessorNodes
// can experience delays.
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var context = new AudioContext();
var buffer = null;
var sourceSP = context.createScriptProcessor(2048);
sourceSP.addEventListener("audioprocess", function(e) {
// generate the audio
for (var i = 0; i < 2048; ++i) {
// Make sure our first sample won't be zero
e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate);
e.outputBuffer.getChannelData(1)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
}
// Remember our generated audio
buffer = e.outputBuffer;
sourceSP.removeEventListener("audioprocess", arguments.callee);
}, false);
function findFirstNonZeroSample(buffer) {
for (var i = 0; i < buffer.length; ++i) {
if (buffer.getChannelData(0)[i] != 0) {
return i;
}
}
return buffer.length;
}
var sp = context.createScriptProcessor(2048);
sourceSP.connect(sp);
var spWrapped = SpecialPowers.wrap(sp);
ok("passThrough" in spWrapped, "ScriptProcessorNode should support the passThrough API");
spWrapped.passThrough = true;
sp.onaudioprocess = function() {
ok(false, "The audioprocess event must never be dispatched on the passthrough ScriptProcessorNode");
};
var sp2 = context.createScriptProcessor(2048);
sp.connect(sp2);
sp2.connect(context.destination);
var emptyBuffer = context.createBuffer(1, 2048, context.sampleRate);
sp2.onaudioprocess = function(e) {
// Because of the initial latency added by the second script processor node,
// we will never see any generated audio frames in the first callback.
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0));
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0));
sp2.onaudioprocess = function(e) {
var firstNonZero = findFirstNonZeroSample(e.inputBuffer);
ok(firstNonZero <= 2048, "First non-zero sample within range");
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0), firstNonZero);
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0), firstNonZero);
compareChannels(e.inputBuffer.getChannelData(0), buffer.getChannelData(0), 2048 - firstNonZero, firstNonZero, 0);
compareChannels(e.inputBuffer.getChannelData(1), buffer.getChannelData(1), 2048 - firstNonZero, firstNonZero, 0);
if (firstNonZero == 0) {
// If we did not experience any delays, the test is done!
sp2.onaudioprocess = null;
SimpleTest.finish();
} else if (firstNonZero != 2048) {
// In case we just saw a zero buffer this time, wait one more round
sp2.onaudioprocess = function(e) {
compareChannels(e.inputBuffer.getChannelData(0), buffer.getChannelData(0), firstNonZero, 0, 2048 - firstNonZero);
compareChannels(e.inputBuffer.getChannelData(1), buffer.getChannelData(1), firstNonZero, 0, 2048 - firstNonZero);
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0), undefined, firstNonZero);
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0), undefined, firstNonZero);
sp2.onaudioprocess = null;
SimpleTest.finish();
};
}
};
};
});
</script>
</pre>
</body>
</html>

View File

@ -60,7 +60,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
// and return to CLUSTER_SYNC.
if (mClusterIDPos == sizeof(CLUSTER_ID)) {
mClusterIDPos = 0;
mClusterOffset = mCurrentOffset + (p - aBuffer) - 1;
mClusterOffset = mCurrentOffset + (p - aBuffer) - sizeof(CLUSTER_ID);
mState = READ_VINT;
mNextState = TIMECODE_SYNC;
}

View File

@ -1965,16 +1965,16 @@ Navigator::GetMozCameras(ErrorResult& aRv)
return mCameraManager;
}
already_AddRefed<workers::ServiceWorkerContainer>
already_AddRefed<ServiceWorkerContainer>
Navigator::ServiceWorker()
{
MOZ_ASSERT(mWindow);
if (!mServiceWorkerContainer) {
mServiceWorkerContainer = new workers::ServiceWorkerContainer(mWindow);
mServiceWorkerContainer = new ServiceWorkerContainer(mWindow);
}
nsRefPtr<workers::ServiceWorkerContainer> ref = mServiceWorkerContainer;
nsRefPtr<ServiceWorkerContainer> ref = mServiceWorkerContainer;
return ref.forget();
}

View File

@ -36,6 +36,7 @@ struct MediaStreamConstraints;
class WakeLock;
class ArrayBufferViewOrBlobOrStringOrFormData;
struct MobileIdOptions;
class ServiceWorkerContainer;
}
}
@ -104,10 +105,6 @@ class AudioChannelManager;
#endif
} // namespace system
namespace workers {
class ServiceWorkerContainer;
} // namespace workers
class Navigator : public nsIDOMNavigator
, public nsIMozNavigatorNetwork
, public nsWrapperCache
@ -262,7 +259,7 @@ public:
ErrorResult& aRv);
#endif // MOZ_MEDIA_NAVIGATOR
already_AddRefed<workers::ServiceWorkerContainer> ServiceWorker();
already_AddRefed<ServiceWorkerContainer> ServiceWorker();
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
@ -340,7 +337,7 @@ private:
nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
nsRefPtr<time::TimeManager> mTimeManager;
nsRefPtr<workers::ServiceWorkerContainer> mServiceWorkerContainer;
nsRefPtr<ServiceWorkerContainer> mServiceWorkerContainer;
nsCOMPtr<nsPIDOMWindow> mWindow;
// Hashtable for saving cached objects newresolve created, so we don't create

View File

@ -122,27 +122,18 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
ScriptSettingsStack::Pop(this);
}
// This mostly gets the entry global, but doesn't entirely match the spec in
// certain edge cases. It's good enough for some purposes, but not others. If
// you want to call this function, ping bholley and describe your use-case.
nsIGlobalObject*
BrokenGetEntryGlobal()
GetEntryGlobal()
{
// We need the current JSContext in order to check the JS for
// scripted frames that may have appeared since anyone last
// manipulated the stack. If it's null, that means that there
// must be no entry global on the stack.
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr);
return nullptr;
}
return nsJSUtils::GetDynamicScriptGlobal(cx);
return ScriptSettingsStack::EntryGlobal();
}
// Note: When we're ready to expose it, GetEntryGlobal will look similar to
// GetIncumbentGlobal below.
nsIDocument*
GetEntryDocument()
{
nsCOMPtr<nsPIDOMWindow> entryWin = do_QueryInterface(GetEntryGlobal());
return entryWin ? entryWin->GetExtantDoc() : nullptr;
}
nsIGlobalObject*
GetIncumbentGlobal()
@ -171,6 +162,22 @@ GetIncumbentGlobal()
return ScriptSettingsStack::IncumbentGlobal();
}
nsIGlobalObject*
GetCurrentGlobal()
{
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
return nullptr;
}
JSObject *global = JS::CurrentGlobalOrNull(cx);
if (!global) {
return nullptr;
}
return xpc::GetNativeForGlobal(global);
}
nsIPrincipal*
GetWebIDLCallerPrincipal()
{

View File

@ -20,6 +20,7 @@
class nsPIDOMWindow;
class nsGlobalWindow;
class nsIScriptContext;
class nsIDocument;
namespace mozilla {
namespace dom {
@ -63,17 +64,57 @@ private:
void InitScriptSettings();
void DestroyScriptSettings();
// This mostly gets the entry global, but doesn't entirely match the spec in
// certain edge cases. It's good enough for some purposes, but not others. If
// you want to call this function, ping bholley and describe your use-case.
nsIGlobalObject* BrokenGetEntryGlobal();
// To implement a web-compatible browser, it is often necessary to obtain the
// global object that is "associated" with the currently-running code. This
// process is made more complicated by the fact that, historically, different
// algorithms have operated with different definitions of the "associated"
// global.
//
// HTML5 formalizes this into two concepts: the "incumbent global" and the
// "entry global". The incumbent global corresponds to the global of the
// current script being executed, whereas the entry global corresponds to the
// global of the script where the current JS execution began.
//
// There is also a potentially-distinct third global that is determined by the
// current compartment. This roughly corresponds with the notion of Realms in
// ECMAScript.
//
// Suppose some event triggers an event listener in window |A|, which invokes a
// scripted function in window |B|, which invokes the |window.location.href|
// setter in window |C|. The entry global would be |A|, the incumbent global
// would be |B|, and the current compartment would be that of |C|.
//
// In general, it's best to use to use the most-closely-associated global
// unless the spec says to do otherwise. In 95% of the cases, the global of
// the current compartment (GetCurrentGlobal()) is the right thing. For
// example, WebIDL constructors (new C.XMLHttpRequest()) are initialized with
// the global of the current compartment (i.e. |C|).
//
// The incumbent global is very similar, but differs in a few edge cases. For
// example, if window |B| does |C.location.href = "..."|, the incumbent global
// used for the navigation algorithm is B, because no script from |C| was ever run.
//
// The entry global is used for various things like computing base URIs, mostly
// for historical reasons.
//
// Note that all of these functions return bonafide global objects. This means
// that, for Windows, they always return the inner.
// Note: We don't yet expose GetEntryGlobal, because in order for it to be
// correct, we first need to replace a bunch of explicit cx pushing in the
// browser with AutoEntryScript. But GetIncumbentGlobal is simpler, because it
// can mostly be inferred from the JS stack.
// Returns the global associated with the top-most Candidate Entry Point on
// the Script Settings Stack. See the HTML spec. This may be null.
nsIGlobalObject* GetEntryGlobal();
// If the entry global is a window, returns its extant document. Otherwise,
// returns null.
nsIDocument* GetEntryDocument();
// Returns the global associated with the top-most entry of the the Script
// Settings Stack. See the HTML spec. This may be null.
nsIGlobalObject* GetIncumbentGlobal();
// Returns the global associated with the current compartment. This may be null.
nsIGlobalObject* GetCurrentGlobal();
// JS-implemented WebIDL presents an interesting situation with respect to the
// subject principal. A regular C++-implemented API can simply examine the
// compartment of the most-recently-executed script, and use that to infer the

View File

@ -2501,11 +2501,6 @@ OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct,
}
}
// Don't expose CSSFontFeatureValuesRule unless the pref is enabled
if (aStruct->mDOMClassInfoID == eDOMClassInfo_CSSFontFeatureValuesRule_id) {
return nsCSSFontFeatureValuesRule::PrefEnabled();
}
return true;
}

View File

@ -420,7 +420,7 @@ nsFocusManager::GetLastFocusMethod(nsIDOMWindow* aWindow, uint32_t* aLastFocusMe
{
// the focus method is stored on the inner window
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
if (window)
if (window && window->IsOuterWindow())
window = window->GetCurrentInnerWindow();
if (!window)
window = mFocusedWindow;

View File

@ -1482,10 +1482,11 @@ nsGlobalWindow::CleanUp()
mChromeEventHandler = nullptr; // Forces Release
mParentTarget = nullptr;
nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
if (inner) {
inner->CleanUp();
if (IsOuterWindow()) {
nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
if (inner) {
inner->CleanUp();
}
}
if (IsInnerWindow()) {
@ -5915,15 +5916,8 @@ nsGlobalWindow::RefreshCompartmentPrincipal()
static already_AddRefed<nsIDocShellTreeItem>
GetCallerDocShellTreeItem()
{
JSContext *cx = nsContentUtils::GetCurrentJSContext();
nsCOMPtr<nsIDocShellTreeItem> callerItem;
if (cx) {
nsCOMPtr<nsIWebNavigation> callerWebNav =
do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
callerItem = do_QueryInterface(callerWebNav);
}
nsCOMPtr<nsIWebNavigation> callerWebNav = do_GetInterface(GetEntryGlobal());
nsCOMPtr<nsIDocShellTreeItem> callerItem = do_QueryInterface(callerWebNav);
return callerItem.forget();
}
@ -6557,7 +6551,7 @@ nsGlobalWindow::Focus(ErrorResult& aError)
return;
}
nsIDOMWindow *caller = nsContentUtils::GetWindowFromCaller();
nsCOMPtr<nsIDOMWindow> caller = do_QueryInterface(GetEntryGlobal());
nsCOMPtr<nsIDOMWindow> opener;
GetOpener(getter_AddRefs(opener));
@ -7535,20 +7529,7 @@ nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
nsIURI *baseURL = nullptr;
JSContext *cx = nsContentUtils::GetCurrentJSContext();
nsCOMPtr<nsPIDOMWindow> contextWindow;
if (cx) {
nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx);
if (currentCX) {
contextWindow = do_QueryInterface(currentCX->GetGlobalObject());
}
}
if (!contextWindow) {
contextWindow = this;
}
nsCOMPtr<nsIDocument> doc = contextWindow->GetDoc();
nsCOMPtr<nsIDocument> doc = GetEntryDocument();
if (doc)
baseURL = doc->GetDocBaseURI();
@ -8253,7 +8234,7 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
nsCOMPtr<nsIPrincipal> providedPrincipal;
if (aTargetOrigin.EqualsASCII("/")) {
providedPrincipal = BrokenGetEntryGlobal()->PrincipalOrNull();
providedPrincipal = GetEntryGlobal()->PrincipalOrNull();
if (NS_WARN_IF(!providedPrincipal))
return;
}
@ -12803,11 +12784,7 @@ nsGlobalWindow::GetScrollFrame()
nsresult
nsGlobalWindow::SecurityCheckURL(const char *aURL)
{
nsCOMPtr<nsPIDOMWindow> sourceWindow;
JSContext* topCx = nsContentUtils::GetCurrentJSContext();
if (topCx) {
sourceWindow = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx));
}
nsCOMPtr<nsPIDOMWindow> sourceWindow = do_QueryInterface(GetEntryGlobal());
if (!sourceWindow) {
sourceWindow = this;
}

View File

@ -599,6 +599,7 @@ public:
nsGlobalWindow *GetCurrentInnerWindowInternal() const
{
MOZ_ASSERT(IsOuterWindow());
return static_cast<nsGlobalWindow *>(mInnerWindow);
}

View File

@ -557,46 +557,38 @@ NS_ScriptErrorReporter(JSContext *cx,
}
}
// XXX this means we are not going to get error reports on non DOM contexts
nsIScriptContext *context = nsJSUtils::GetDynamicScriptContext(cx);
JS::Rooted<JS::Value> exception(cx);
::JS_GetPendingException(cx, &exception);
// Note: we must do this before running any more code on cx (if cx is the
// dynamic script context).
// Note: we must do this before running any more code on cx.
::JS_ClearPendingException(cx);
if (context) {
nsIScriptGlobalObject *globalObject = context->GetGlobalObject();
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsCOMPtr<nsIGlobalObject> globalObject = GetEntryGlobal();
if (globalObject) {
if (globalObject) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
if (win) {
win = win->GetCurrentInnerWindow();
}
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
do_QueryInterface(globalObject);
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
"nsIScriptObjectPrincipal");
nsContentUtils::AddScriptRunner(
new ScriptErrorEvent(JS_GetRuntime(cx),
report,
message,
nsJSPrincipals::get(report->originPrincipals),
scriptPrincipal->GetPrincipal(),
win,
exception,
/* We do not try to report Out Of Memory via a dom
* event because the dom event handler would
* encounter an OOM exception trying to process the
* event, and then we'd need to generate a new OOM
* event for that new OOM instance -- this isn't
* pretty.
*/
report->errorNumber != JSMSG_OUT_OF_MEMORY));
}
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
MOZ_ASSERT_IF(win, win->IsInnerWindow());
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
do_QueryInterface(globalObject);
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
"nsIScriptObjectPrincipal");
nsContentUtils::AddScriptRunner(
new ScriptErrorEvent(JS_GetRuntime(cx),
report,
message,
nsJSPrincipals::get(report->originPrincipals),
scriptPrincipal->GetPrincipal(),
win,
exception,
/* We do not try to report Out Of Memory via a dom
* event because the dom event handler would
* encounter an OOM exception trying to process the
* event, and then we'd need to generate a new OOM
* event for that new OOM instance -- this isn't
* pretty.
*/
report->errorNumber != JSMSG_OUT_OF_MEMORY));
}
if (nsContentUtils::DOMWindowDumpEnabled()) {

View File

@ -63,21 +63,6 @@ nsJSUtils::GetStaticScriptContext(JSObject* aObj)
return nativeGlobal->GetScriptContext();
}
nsIScriptGlobalObject *
nsJSUtils::GetDynamicScriptGlobal(JSContext* aContext)
{
nsIScriptContext *scriptCX = GetDynamicScriptContext(aContext);
if (!scriptCX)
return nullptr;
return scriptCX->GetGlobalObject();
}
nsIScriptContext *
nsJSUtils::GetDynamicScriptContext(JSContext *aContext)
{
return GetScriptContextFromJSContext(aContext);
}
uint64_t
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
{

View File

@ -32,10 +32,6 @@ public:
static nsIScriptContext *GetStaticScriptContext(JSObject* aObj);
static nsIScriptGlobalObject *GetDynamicScriptGlobal(JSContext *aContext);
static nsIScriptContext *GetDynamicScriptContext(JSContext *aContext);
/**
* Retrieve the inner window ID based on the given JSContext.
*

View File

@ -28,6 +28,7 @@
#include "nsITextToSubURI.h"
#include "nsJSUtils.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "mozilla/Likely.h"
#include "nsCycleCollectionParticipant.h"
#include "nsNullPrincipal.h"
@ -42,15 +43,8 @@ GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset)
{
aCharset.Truncate();
JSContext *cx = nsContentUtils::GetCurrentJSContext();
if (cx) {
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
if (nsIDocument* doc = window->GetDoc()) {
aCharset = doc->GetDocumentCharacterSet();
}
if (nsIDocument* doc = GetEntryDocument()) {
aCharset = doc->GetDocumentCharacterSet();
}
return NS_OK;
@ -545,23 +539,23 @@ nsLocation::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
* anywhere else. This is part of solution for bug # 39938, 72197
*
*/
bool inScriptTag=false;
JSContext *cx = nsContentUtils::GetCurrentJSContext();
if (cx) {
nsIScriptContext *scriptContext =
nsJSUtils::GetDynamicScriptContext(cx);
bool inScriptTag = false;
nsIScriptContext* scriptContext = nullptr;
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(GetEntryGlobal());
if (win) {
scriptContext = static_cast<nsGlobalWindow*>(win.get())->GetContextInternal();
}
if (scriptContext) {
if (scriptContext->GetProcessingScriptTag()) {
// Now check to make sure that the script is running in our window,
// since we only want to replace if the location is set by a
// <script> tag in the same window. See bug 178729.
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
docShell ? docShell->GetScriptGlobalObject() : nullptr;
inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
}
}
} //cx
if (scriptContext) {
if (scriptContext->GetProcessingScriptTag()) {
// Now check to make sure that the script is running in our window,
// since we only want to replace if the location is set by a
// <script> tag in the same window. See bug 178729.
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
docShell ? docShell->GetScriptGlobalObject() : nullptr;
inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
}
}
return SetURI(newUri, aReplace || inScriptTag);
}
@ -1020,22 +1014,20 @@ nsLocation::ValueOf(nsIDOMLocation** aReturn)
nsresult
nsLocation::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
{
*sourceURL = nullptr;
nsCOMPtr<nsIScriptGlobalObject> sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
// If this JS context doesn't have an associated DOM window, we effectively
// have no script entry point stack. This doesn't generally happen with the DOM,
nsIDocument* doc = GetEntryDocument();
// If there's no entry document, we either have no Script Entry Point or one
// that isn't a DOM Window. This doesn't generally happen with the DOM,
// but can sometimes happen with extension code in certain IPC configurations.
// If this happens, try falling back on the current document associated with
// the docshell. If that fails, just return null and hope that the caller passed
// an absolute URI.
if (!sgo && GetDocShell()) {
sgo = GetDocShell()->GetScriptGlobalObject();
if (!doc && GetDocShell()) {
nsCOMPtr<nsPIDOMWindow> docShellWin = do_QueryInterface(GetDocShell()->GetScriptGlobalObject());
if (docShellWin) {
doc = docShellWin->GetDoc();
}
}
NS_ENSURE_TRUE(sgo, NS_OK);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(sgo);
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
nsIDocument* doc = window->GetDoc();
NS_ENSURE_TRUE(doc, NS_OK);
*sourceURL = doc->GetBaseURI().take();
return NS_OK;

View File

@ -192,12 +192,7 @@ public:
bool IsLoadingOrRunningTimeout() const
{
const nsPIDOMWindow *win = GetCurrentInnerWindow();
if (!win) {
win = this;
}
const nsPIDOMWindow* win = IsInnerWindow() ? this : GetCurrentInnerWindow();
return !win->mIsDocumentLoaded || win->mRunningTimeout;
}
@ -299,6 +294,7 @@ public:
nsPIDOMWindow *GetCurrentInnerWindow() const
{
MOZ_ASSERT(IsOuterWindow());
return mInnerWindow;
}

View File

@ -56,7 +56,8 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow,
// Measure the inner window, if there is one.
nsWindowSizes innerWindowSizes(moz_malloc_size_of);
nsGlobalWindow* inner = aWindow->GetCurrentInnerWindowInternal();
nsGlobalWindow* inner = aWindow->IsOuterWindow() ? aWindow->GetCurrentInnerWindowInternal()
: nullptr;
if (inner) {
inner->AddSizeOfIncludingThis(&innerWindowSizes);
innerWindowSizes.addToTabSizes(aSizes);

View File

@ -2645,5 +2645,12 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
}
#endif
bool
CallerSubsumes(JSObject *aObject)
{
nsIPrincipal* objPrin = nsContentUtils::ObjectPrincipal(js::UncheckedUnwrap(aObject));
return nsContentUtils::SubjectPrincipal()->Subsumes(objPrin);
}
} // namespace dom
} // namespace mozilla

View File

@ -2937,6 +2937,18 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
bool
CheckPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
bool
CallerSubsumes(JSObject* aObject);
MOZ_ALWAYS_INLINE bool
CallerSubsumes(JS::Handle<JS::Value> aValue)
{
if (!aValue.isObject()) {
return true;
}
return CallerSubsumes(&aValue.toObject());
}
} // namespace dom
} // namespace mozilla

View File

@ -1053,11 +1053,6 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h',
},
'ServiceWorkerContainer': {
'nativeType': 'mozilla::dom::workers::ServiceWorkerContainer',
'headerFile': 'mozilla/dom/ServiceWorkerContainer.h',
},
'ServiceWorkerGlobalScope': {
'headerFile': 'mozilla/dom/WorkerScope.h',
'workers': True,

View File

@ -3572,6 +3572,9 @@ class JSToNativeConversionInfo():
for whether we have a JS::Value. Only used when
defaultValue is not None or when True is passed for
checkForValue to instantiateJSToNativeConversion.
${passedToJSImpl} replaced by an expression that evaluates to a boolean
for whether this value is being passed to a JS-
implemented interface.
declType: A CGThing representing the native C++ type we're converting
to. This is allowed to be None if the conversion code is
@ -3827,7 +3830,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
return templateBody
# A helper function for converting things that look like a JSObject*.
def handleJSObjectType(type, isMember, failureCode):
def handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription):
if not isMember:
if isOptional:
# We have a specialization of Optional that will use a
@ -3843,6 +3846,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
declType = CGGeneric("JSObject*")
declArgs = None
templateBody = "${declName} = &${val}.toObject();\n"
# For JS-implemented APIs, we refuse to allow passing objects that the
# API consumer does not subsume.
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
templateBody = fill("""
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
$*{exceptionCode}
}
""",
sourceDescription=sourceDescription,
exceptionCode=exceptionCode) + templateBody
setToNullCode = "${declName} = nullptr;\n"
template = wrapObjectTemplate(templateBody, type, setToNullCode,
failureCode)
@ -3917,7 +3933,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# We only need holderName here to handle isExternal()
# interfaces, which use an internal holder for the
# conversion even when forceOwningType ends up true.
"holderName": "tempHolder"
"holderName": "tempHolder",
"passedToJSImpl": "${passedToJSImpl}"
})
# NOTE: Keep this in sync with variadic conversions as needed
@ -4021,7 +4038,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# We only need holderName here to handle isExternal()
# interfaces, which use an internal holder for the
# conversion even when forceOwningType ends up true.
"holderName": "tempHolder"
"holderName": "tempHolder",
"passedToJSImpl": "${passedToJSImpl}"
})
templateBody = fill(
@ -4114,7 +4132,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
for memberType in interfaceMemberTypes:
name = getUnionMemberName(memberType)
interfaceObject.append(
CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext" %
CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext" %
(unionArgumentObj, name)))
names.append(name)
interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"),
@ -4127,7 +4145,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert len(arrayObjectMemberTypes) == 1
name = getUnionMemberName(arrayObjectMemberTypes[0])
arrayObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
@ -4151,7 +4169,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
memberType = callbackMemberTypes[0]
name = getUnionMemberName(memberType)
callbackObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
@ -4162,7 +4180,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert len(dictionaryMemberTypes) == 1
name = getUnionMemberName(dictionaryMemberTypes[0])
setDictionary = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
@ -4173,7 +4191,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert len(mozMapMemberTypes) == 1
name = getUnionMemberName(mozMapMemberTypes[0])
mozMapObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
@ -4185,8 +4203,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# Very important to NOT construct a temporary Rooted here, since the
# SetToObject call can call a Rooted constructor and we need to keep
# stack discipline for Rooted.
object = CGGeneric("%s.SetToObject(cx, &${val}.toObject());\n"
"done = true;\n" % unionArgumentObj)
object = CGGeneric("if (!%s.SetToObject(cx, &${val}.toObject(), ${passedToJSImpl})) {\n"
"%s"
"}\n"
"done = true;\n" % (unionArgumentObj, indent(exceptionCode)))
names.append(objectMemberTypes[0].name)
else:
object = None
@ -4425,7 +4445,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if descriptor.nativeType == 'JSObject':
# XXXbz Workers code does this sometimes
assert descriptor.workers
return handleJSObjectType(type, isMember, failureCode)
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
if descriptor.interface.isCallback():
name = descriptor.interface.identifier.name
@ -4507,7 +4527,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
isCallbackReturnValue,
firstCap(sourceDescription)))
elif descriptor.workers:
return handleJSObjectType(type, isMember, failureCode)
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
else:
# Either external, or new-binding non-castable. We always have a
# holder for these, because we don't actually know whether we have
@ -4826,6 +4846,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not isOptional
templateBody = "${declName} = ${val};\n"
# For JS-implemented APIs, we refuse to allow passing objects that the
# API consumer does not subsume.
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
templateBody = fill("""
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
$*{exceptionCode}
}
""",
sourceDescription=sourceDescription,
exceptionCode=exceptionCode) + templateBody
# We may not have a default value if we're being converted for
# a setter, say.
if defaultValue:
@ -4841,7 +4874,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.isObject():
assert not isEnforceRange and not isClamp
return handleJSObjectType(type, isMember, failureCode)
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
if type.isDictionary():
# There are no nullable dictionaries
@ -4891,7 +4924,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.nullable():
dictLoc += ".SetValue()"
template += ('if (!%s.Init(cx, %s, "%s")) {\n'
template += ('if (!%s.Init(cx, %s, "%s", ${passedToJSImpl})) {\n'
"%s"
"}\n" % (dictLoc, val, firstCap(sourceDescription),
exceptionCodeIndented.define()))
@ -5167,7 +5200,8 @@ class CGArgumentConverter(CGThing):
self.replacementVariables = {
"declName": "arg%d" % index,
"holderName": ("arg%d" % index) + "_holder",
"obj": "obj"
"obj": "obj",
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(descriptorProvider))
}
self.replacementVariables["val"] = string.Template(
"args[${index}]").substitute(replacer)
@ -5245,7 +5279,8 @@ class CGArgumentConverter(CGThing):
# conversion even when forceOwningType ends up true.
"holderName": "tempHolder",
# Use the same ${obj} as for the variadic arg itself
"obj": replacer["obj"]
"obj": replacer["obj"],
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(self.descriptorProvider))
}), 4)
variadicConversion += (" }\n"
@ -6741,7 +6776,8 @@ class CGMethodCall(CGThing):
"holderName": ("arg%d" % distinguishingIndex) + "_holder",
"val": distinguishingArg,
"obj": "obj",
"haveValue": "args.hasDefined(%d)" % distinguishingIndex
"haveValue": "args.hasDefined(%d)" % distinguishingIndex,
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(descriptor))
},
checkForValue=argIsOptional)
caseBody.append(CGIndenter(testCode, indent))
@ -8316,9 +8352,22 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
mUnion.mValue.mObject.SetValue(cx, obj);
mUnion.mType = mUnion.eObject;
""")
setter = ClassMethod("SetToObject", "void",
# It's a bit sketchy to do the security check after setting the value,
# but it keeps the code cleaner and lets us avoid rooting |obj| over the
# call to CallerSubsumes().
body = body + dedent("""
if (passedToJSImpl && !CallerSubsumes(obj)) {
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "%s");
return false;
}
return true;
""")
setter = ClassMethod("SetToObject", "bool",
[Argument("JSContext*", "cx"),
Argument("JSObject*", "obj")],
Argument("JSObject*", "obj"),
Argument("bool", "passedToJSImpl", default="false")],
inline=True, bodyInHeader=True,
body=body)
@ -8338,7 +8387,8 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
val="value",
declName="memberSlot",
holderName=(holderName if ownsMembers else "%s.ref()" % holderName),
destroyHolder=destroyHolder)
destroyHolder=destroyHolder,
passedToJSImpl="passedToJSImpl")
jsConversion = fill(
"""
@ -8357,7 +8407,8 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
setter = ClassMethod("TrySetTo" + name, "bool",
[Argument("JSContext*", "cx"),
Argument("JS::Handle<JS::Value>", "value"),
Argument("bool&", "tryNext")],
Argument("bool&", "tryNext"),
Argument("bool", "passedToJSImpl", default="false")],
inline=not ownsMembers,
bodyInHeader=not ownsMembers,
body=jsConversion)
@ -9463,7 +9514,8 @@ class CGProxySpecialOperation(CGPerSignatureCall):
"declName": argument.identifier.name,
"holderName": argument.identifier.name + "_holder",
"val": argumentMutableValue,
"obj": "obj"
"obj": "obj",
"passedToJSImpl": "false"
}
self.cgRoot.prepend(instantiateJSToNativeConversion(info, templateValues))
elif operation.isGetter() or operation.isDeleter():
@ -11087,7 +11139,8 @@ class CGDictionary(CGThing):
return ClassMethod("Init", "bool", [
Argument('JSContext*', 'cx'),
Argument('JS::Handle<JS::Value>', 'val'),
Argument('const char*', 'sourceDescription', default='"Value"')
Argument('const char*', 'sourceDescription', default='"Value"'),
Argument('bool', 'passedToJSImpl', default='false')
], body=body)
def initFromJSONMethod(self):
@ -11322,7 +11375,8 @@ class CGDictionary(CGThing):
# We need a holder name for external interfaces, but
# it's scoped down to the conversion so we can just use
# anything we want.
"holderName": "holder"
"holderName": "holder",
"passedToJSImpl": "passedToJSImpl"
}
# We can't handle having a holderType here
assert conversionInfo.holderType is None
@ -11458,6 +11512,11 @@ class CGDictionary(CGThing):
trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
if type.nullable():
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
elif type.isMozMap():
# If you implement this, add a MozMap<object> to
# TestInterfaceJSDictionary and test it in test_bug1036214.html
# to make sure we end up with the correct security properties.
assert False
else:
assert False # unknown type
@ -13389,7 +13448,8 @@ class CallbackMember(CGNativeMember):
# We actually want to pass in a null scope object here, because
# wrapping things into our current compartment (that of mCallback)
# is what we want.
"obj": "nullptr"
"obj": "nullptr",
"passedToJSImpl": "false"
}
if isJSImplementedDescriptor(self.descriptorProvider):

View File

@ -58,3 +58,4 @@ MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, "Headers are immutable and cannot be modified.
MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, "Permission denied to pass cross-origin object as {0}.")

View File

@ -9,17 +9,6 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
var gGlobal = this;
function checkGlobal(obj) {
if (Object(obj) === obj && Cu.getGlobalForObject(obj) != gGlobal) {
// This message may not make it to the caller in a useful form, so dump
// as well.
var msg = "TestInterfaceJS received an object from a different scope!";
dump(msg + "\n");
throw new Error(msg);
}
}
function TestInterfaceJS(anyArg, objectArg) {}
TestInterfaceJS.prototype = {
@ -27,23 +16,32 @@ TestInterfaceJS.prototype = {
contractID: "@mozilla.org/dom/test-interface-js;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
__init: function (anyArg, objectArg) {
__init: function (anyArg, objectArg, dictionaryArg) {
this._anyAttr = undefined;
this._objectAttr = null;
this._anyArg = anyArg;
this._objectArg = objectArg;
checkGlobal(anyArg);
checkGlobal(objectArg);
this._dictionaryArg = dictionaryArg;
},
get anyArg() { return this._anyArg; },
get objectArg() { return this._objectArg; },
get dictionaryArg() { return this._dictionaryArg; },
get anyAttr() { return this._anyAttr; },
set anyAttr(val) { checkGlobal(val); this._anyAttr = val; },
set anyAttr(val) { this._anyAttr = val; },
get objectAttr() { return this._objectAttr; },
set objectAttr(val) { checkGlobal(val); this._objectAttr = val; },
pingPongAny: function(any) { checkGlobal(any); return any; },
pingPongObject: function(obj) { checkGlobal(obj); return obj; },
set objectAttr(val) { this._objectAttr = val; },
get dictionaryAttr() { return this._dictionaryAttr; },
set dictionaryAttr(val) { this._dictionaryAttr = val; },
pingPongAny: function(any) { return any; },
pingPongObject: function(obj) { return obj; },
pingPongObjectOrString: function(objectOrString) { return objectOrString; },
pingPongDictionary: function(dict) { return dict; },
pingPongDictionaryOrLong: function(dictOrLong) { return dictOrLong.anyMember || dictOrLong; },
pingPongMap: function(map) { return JSON.stringify(map); },
objectSequenceLength: function(seq) { return seq.length; },
anySequenceLength: function(seq) { return seq.length; },
getCallerPrincipal: function() { return Cu.getWebIDLCallerPrincipal().origin; },

View File

@ -17,10 +17,8 @@ support-files =
[test_bug788369.html]
[test_bug852846.html]
[test_bug862092.html]
# When bug 923904 lands, this test can be turned on, but only for debug builds
# where we have our test component. So this should become skip-if = debug == false.
[test_bug923904.html]
skip-if = true
[test_bug1036214.html]
skip-if = debug == false
[test_bug1041646.html]
[test_barewordGetsWindow.html]
[test_callback_default_thisval.html]

View File

@ -0,0 +1,123 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1036214</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for subsumes-checking |any| and |object| for js-implemented WebIDL. **/
SimpleTest.waitForExplicitFinish();
var xoObjects = [];
function setup() {
xoObjects.push(window[0]);
xoObjects.push(window[0].location);
xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap(window[0]).document));
xoObjects.push(SpecialPowers);
xoObjects.push(SpecialPowers.wrap);
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
}
function checkThrows(f, msg) {
try {
f();
ok(false, "Should have thrown: " + msg);
} catch (e) {
ok(true, "Threw correctly: " + msg);
ok(/denied|insecure/.test(e), "Threw security exception: " + e);
}
}
function go() {
//
// Test the basics of the test interface.
//
var any = { a: 11 };
var obj = { b: 22, c: "str" };
var obj2 = { foo: "baz" };
var myDict = { anyMember: 42, objectMember: { answer: 42 }, objectOrStringMember: { answer: "anobject" },
anySequenceMember: [{}, 1, "thirdinsequence"],
innerDictionary: { innerObject: { answer: "rabbithole" } } };
var t = new TestInterfaceJS(any, obj, myDict);
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
is(t.anyArg, any, "anyArg is correct");
is(t.objectArg, obj, "objectArg is correct");
is(t.dictionaryArg.anyMember, 42, "dictionaryArg looks correct");
is(t.dictionaryArg.objectMember.answer, 42, "dictionaryArg looks correct");
t.anyAttr = 2;
is(t.anyAttr, 2, "ping-pong any attribute works");
t.objAttr = obj2;
is(t.objAttr, obj2, "ping-pong object attribute works");
t.dictionaryAttr = myDict;
is(t.dictionaryAttr.anyMember, 42, "ping-pong dictionary attribute works");
is(t.dictionaryAttr.objectMember.answer, 42, "ping-pong dictionary attribute works");
is(any, t.pingPongAny(any), "ping-pong works with any");
is(obj, t.pingPongObject(obj), "ping-pong works with obj");
is(obj, t.pingPongObjectOrString(obj), "ping-pong works with obj or string");
is("foo", t.pingPongObjectOrString("foo"), "ping-pong works with obj or string");
is(t.pingPongDictionary(myDict).anyMember, 42, "ping pong works with dict");
is(t.pingPongDictionary(myDict).objectMember.answer, 42, "ping pong works with dict");
is(t.pingPongDictionary(myDict).objectOrStringMember.answer, "anobject", "ping pong works with dict");
is(t.pingPongDictionary(myDict).anySequenceMember[2], "thirdinsequence", "ping pong works with dict");
is(t.pingPongDictionary(myDict).innerDictionary.innerObject.answer, "rabbithole", "ping pong works with layered dicts");
is(t.pingPongDictionaryOrLong({anyMember: 42}), 42, "ping pong (dict or long) works with dict");
is(t.pingPongDictionaryOrLong(42), 42, "ping pong (dict or long) works with long");
ok(/canary/.test(t.pingPongMap({ someVal: 42, someOtherVal: "canary" })), "ping pong works with mozmap");
is(t.objectSequenceLength([{}, {}, {}]), 3, "ping pong works with object sequence");
is(t.anySequenceLength([42, 'string', {}, undefined]), 4, "ping pong works with any sequence");
//
// Test that we throw in the cross-origin cases.
//
xoObjects.forEach(function(xoObj) {
var blank = new TestInterfaceJS();
checkThrows(() => new TestInterfaceJS(xoObj, undefined), "any param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, xoObj), "obj param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, undefined, { anyMember: xoObj }), "any dict param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectMember: xoObj }), "object dict param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectOrStringMember: xoObj }), "union dict param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, undefined, { anySequenceMember: [0, xoObj, 'hi' ] }), "sequence dict param for constructor");
checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
checkThrows(() => t.anyAttr = xoObj, "anyAttr");
checkThrows(() => t.objectAttr = xoObj, "objAttr");
checkThrows(() => t.dictionaryAttr = { anyMember: xoObj }, "dictionaryAttr any");
checkThrows(() => t.dictionaryAttr = { objectMember: xoObj }, "dictionaryAttr object");
checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");
checkThrows(() => t.pingPongDictionary({ anyMember: xoObj }), "dictionary pingpong any");
checkThrows(() => t.pingPongDictionary({ objectMember: xoObj }), "dictionary pingpong object");
checkThrows(() => t.pingPongDictionary({ anyMember: xoObj, objectMember: xoObj }), "dictionary pingpong both");
checkThrows(() => t.pingPongDictionary({ objectOrStringMember: xoObj }), "dictionary pingpong objectorstring");
checkThrows(() => t.pingPongDictionaryOrLong({ objectMember: xoObj }), "unionable dictionary");
checkThrows(() => t.pingPongDictionaryOrLong({ anyMember: xoObj }), "unionable dictionary");
checkThrows(() => t.pingPongMap({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "mozmap");
checkThrows(() => t.objectSequenceLength([{}, {}, xoObj, {}]), "object sequence");
checkThrows(() => t.anySequenceLength([42, 'someString', xoObj, {}]), "any sequence");
});
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1036214">Mozilla Bug 1036214</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<iframe id="ifr" onload="setup();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
</body>
</html>

View File

@ -1,66 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=923904
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 923904</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for cloning of |any| and |object| for JS-Implemented WebIDL. **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
function go() {
var someAny = { a: 11 };
var someObj = { b: 22, c: "str" };
var t = new TestInterfaceJS(someAny, someObj);
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
is(t.anyArg.toSource(), someAny.toSource(), "anyArg comes back looking like what we sent");
is(t.objectArg.toSource(), someObj.toSource(), "objectArg comes back looking like what we sent");
isnot(t.anyArg, t.anyArg, "get a new anyArg each time");
isnot(t.objectArg, t.objectArg, "get a new objectArg each time");
t.anyAttr = 2;
is(t.anyAttr, 2, "ping-pong works");
testObjectCloned(t, 'anyAttr');
testObjectCloned(t, 'objectAttr');
is(someAny.toSource(), t.pingPongAny(someAny).toSource(), "ping-pong works with any");
is(someObj.toSource(), t.pingPongObject(someObj).toSource(), "ping-pong works with obj");
isnot(someAny, t.pingPongAny(someAny), "Clone works for ping-pong any");
isnot(someObj, t.pingPongObject(someObj), "Clone works for ping-pong obj");
SimpleTest.finish();
}
function testObjectCloned(iface, propname) {
var obj = { prop: 42 };
iface[propname] = obj;
is(iface[propname].prop, 42, "objects come back as well");
is(iface[propname].__proto__, Object.prototype, "vanilla object");
isnot(iface[propname], obj, "Should not be the original object");
isnot(iface[propname], iface[propname], "Should get cloned each time");
try {
iface[propname] = { stringProp: "hi", reflectorProp: document };
ok(false, "Should throw when trying to clone reflector");
} catch (e) {
ok(/cloned/.test(e), "Should throw clone error: " + e);
}
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=923904">Mozilla Bug 923904</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -1985,7 +1985,7 @@ CanvasRenderingContext2D::ArcTo(double x1, double y1, double x2,
}
// Check for colinearity
dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value;
if (dir == 0) {
LineTo(p1.x, p1.y);
return;
@ -4500,7 +4500,7 @@ CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
}
// Check for colinearity
dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value;
if (dir == 0) {
LineTo(p1.x, p1.y);
return;

View File

@ -790,7 +790,7 @@ protected:
// The spec says we should not draw shadows if the operator is OVER.
// If it's over and the alpha value is zero, nothing needs to be drawn.
return NS_GET_A(state.shadowColor) != 0 &&
(state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
(state.shadowBlur != 0.f || state.shadowOffset.x != 0.f || state.shadowOffset.y != 0.f);
}
mozilla::gfx::CompositionOp UsedOperation()

View File

@ -88,6 +88,8 @@ CellBroadcast::~CellBroadcast()
mProvider->UnregisterCellBroadcastMsg(mListener);
}
NS_IMPL_ISUPPORTS_INHERITED0(CellBroadcast, DOMEventTargetHelper)
JSObject*
CellBroadcast::WrapObject(JSContext* aCx)
{

View File

@ -17,10 +17,11 @@ class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class CellBroadcast MOZ_FINAL : public DOMEventTargetHelper
class CellBroadcast MOZ_FINAL : public DOMEventTargetHelper,
private nsICellBroadcastListener
{
/**
* Class CellBroadcast doesn't actually inherit nsICellBroadcastListener.
* Class CellBroadcast doesn't actually expose nsICellBroadcastListener.
* Instead, it owns an nsICellBroadcastListener derived instance mListener
* and passes it to nsICellBroadcastProvider. The onreceived events are first
* delivered to mListener and then forwarded to its owner, CellBroadcast. See
@ -28,7 +29,11 @@ class CellBroadcast MOZ_FINAL : public DOMEventTargetHelper
*/
class Listener;
// MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
~CellBroadcast();
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSICELLBROADCASTLISTENER
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
@ -39,8 +44,6 @@ public:
CellBroadcast() MOZ_DELETE;
CellBroadcast(nsPIDOMWindow *aWindow,
nsICellBroadcastProvider* aProvider);
// MOZ_FINAL suppresses -Werror,-Wdelete-non-virtual-dtor
~CellBroadcast();
nsPIDOMWindow*
GetParentObject() const { return GetOwner(); }

View File

@ -1595,8 +1595,9 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
// fire drag gesture if mouse has moved enough
LayoutDeviceIntPoint pt = aEvent->refPoint +
LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset());
if (DeprecatedAbs(pt.x - mGestureDownPoint.x) > pixelThresholdX ||
DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) {
LayoutDeviceIntPoint distance = pt - mGestureDownPoint;
if (Abs(distance.x.value) > SafeCast<uint32_t>(pixelThresholdX) ||
Abs(distance.y.value) > SafeCast<uint32_t>(pixelThresholdY)) {
if (Prefs::ClickHoldContextMenu()) {
// stop the click-hold before we fire off the drag gesture, in case
// it takes a long time

View File

@ -8,7 +8,7 @@
interface nsIDocument;
interface nsIURI;
[uuid(cc539f1e-1ce6-4af5-bf94-195b30bde010)]
[uuid(9b5acea4-2601-4ac7-8836-4352ceb88178)]
interface nsIServiceWorkerManager : nsISupports
{
// Returns a Promise
@ -17,9 +17,9 @@ interface nsIServiceWorkerManager : nsISupports
// Returns a Promise
nsISupports unregister(in nsIDOMWindow aWindow, in DOMString aScope);
// aTarget MUST be a ServiceWorkerContainer.
[noscript] void AddContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
[noscript] void RemoveContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
// aTarget MUST be a ServiceWorkerRegistration.
[noscript] void AddRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
[noscript] void RemoveRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
/**
* Call this to request that document `aDoc` be controlled by a ServiceWorker

View File

@ -2102,12 +2102,12 @@ MediaManager::MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVide
// results.
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
if (piWin) {
if (piWin->GetCurrentInnerWindow() || piWin->IsInnerWindow()) {
if (piWin->IsInnerWindow() || piWin->GetCurrentInnerWindow()) {
uint64_t windowID;
if (piWin->GetCurrentInnerWindow()) {
windowID = piWin->GetCurrentInnerWindow()->WindowID();
} else {
if (piWin->IsInnerWindow()) {
windowID = piWin->WindowID();
} else {
windowID = piWin->GetCurrentInnerWindow()->WindowID();
}
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
if (listeners) {

View File

@ -91,6 +91,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
// MobileConnection does not expose nsIMobileConnectionListener. mListener is
// the exposed nsIMobileConnectionListener and forwards the calls it receives
// to us.
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(MobileConnection, DOMEventTargetHelper)

View File

@ -17,10 +17,11 @@
namespace mozilla {
namespace dom {
class MobileConnection MOZ_FINAL : public DOMEventTargetHelper
class MobileConnection MOZ_FINAL : public DOMEventTargetHelper,
private nsIMobileConnectionListener
{
/**
* Class MobileConnection doesn't actually inherit
* Class MobileConnection doesn't actually expose
* nsIMobileConnectionListener. Instead, it owns an
* nsIMobileConnectionListener derived instance mListener and passes it to
* nsIMobileConnectionProvider. The onreceived events are first delivered to

View File

@ -55,14 +55,14 @@ var SMILUtil =
},
// Smart wrapper for getComputedStyle, which will generate a "fake" computed
// style for recognized shorthand properties (font, overflow, marker)
// style for recognized shorthand properties (font, font-variant, overflow, marker)
getComputedStyleWrapper : function(elem, propName)
{
// Special cases for shorthand properties (which aren't directly queriable
// via getComputedStyle)
var computedStyle;
if (propName == "font") {
var subProps = ["font-style", "font-variant", "font-weight",
var subProps = ["font-style", "font-variant-caps", "font-weight",
"font-size", "line-height", "font-family"];
for (var i in subProps) {
var subPropStyle = SMILUtil.getComputedStyleSimple(elem, subProps[i]);
@ -78,6 +78,10 @@ var SMILUtil =
}
}
}
} else if (propName == "font-variant") {
// xxx - this isn't completely correct but it's sufficient for what's
// being tested here
computedStyle = SMILUtil.getComputedStyleSimple(elem, "font-variant-caps");
} else if (propName == "marker") {
var subProps = ["marker-end", "marker-mid", "marker-start"];
for (var i in subProps) {

View File

@ -16,7 +16,6 @@
#include <netinet/in.h>
#include <sys/socket.h>
#include <android/log.h>
#include <cutils/properties.h>
#include "AutoMounter.h"
#include "nsVolumeService.h"
@ -27,9 +26,7 @@
#include "mozilla/Hal.h"
#include "mozilla/StaticPtr.h"
#include "MozMtpServer.h"
#include "MozMtpStorage.h"
#include "nsAutoPtr.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsMemory.h"
#include "nsString.h"
#include "nsThreadUtils.h"
@ -93,13 +90,6 @@ USING_MTP_NAMESPACE
namespace mozilla {
namespace system {
#define SYS_USB_CONFIG "sys.usb.config"
#define PERSIST_SYS_USB_CONFIG "persist.sys.usb.config"
#define USB_FUNC_ADB "adb"
#define USB_FUNC_MTP "mtp"
#define USB_FUNC_UMS "mass_storage"
class AutoMounter;
static void SetAutoMounterStatus(int32_t aStatus);
@ -125,29 +115,6 @@ IsUsbCablePluggedIn()
if (access(ICS_SYS_USB_STATE, F_OK) == 0) {
char usbState[20];
if (ReadSysFile(ICS_SYS_USB_STATE, usbState, sizeof(usbState))) {
DBG("IsUsbCablePluggedIn: state = '%s'", usbState);
return strcmp(usbState, "CONFIGURED") == 0 ||
strcmp(usbState, "CONNECTED") == 0;
}
ERR("Error reading file '%s': %s", ICS_SYS_USB_STATE, strerror(errno));
return false;
}
bool configured;
if (ReadSysFile(GB_SYS_USB_CONFIGURED, &configured)) {
return configured;
}
ERR("Error reading file '%s': %s", GB_SYS_USB_CONFIGURED, strerror(errno));
return false;
#endif
}
static bool
IsUsbConfigured()
{
if (access(ICS_SYS_USB_STATE, F_OK) == 0) {
char usbState[20];
if (ReadSysFile(ICS_SYS_USB_STATE, usbState, sizeof(usbState))) {
DBG("IsUsbConfigured: state = '%s'", usbState);
return strcmp(usbState, "CONFIGURED") == 0;
}
ERR("Error reading file '%s': %s", ICS_SYS_USB_STATE, strerror(errno));
@ -159,6 +126,7 @@ IsUsbConfigured()
}
ERR("Error reading file '%s': %s", GB_SYS_USB_CONFIGURED, strerror(errno));
return false;
#endif
}
/***************************************************************************/
@ -176,7 +144,7 @@ public:
class AutoVolumeEventObserver : public Volume::EventObserver
{
public:
virtual void Notify(Volume* const& aEvent);
virtual void Notify(Volume * const & aEvent);
};
class AutoMounterResponseCallback : public VolumeResponseCallback
@ -206,8 +174,7 @@ public:
typedef nsTArray<RefPtr<Volume>> VolumeArray;
AutoMounter()
: mState(STATE_IDLE),
mResponseCallback(new AutoMounterResponseCallback),
: mResponseCallback(new AutoMounterResponseCallback),
mMode(AUTOMOUNTER_DISABLE)
{
VolumeManager::RegisterStateObserver(&mVolumeManagerStateObserver);
@ -265,34 +232,21 @@ public:
}
}
void UpdateState();
void ConfigureUsbFunction(const char* aUsbFunc);
void StartMtpServer();
void StopMtpServer();
void StartUmsSharing();
void StopUmsSharing();
void UpdateState();
const char* ModeStr(int32_t aMode)
{
switch (aMode) {
case AUTOMOUNTER_DISABLE: return "Disable";
case AUTOMOUNTER_ENABLE_UMS: return "Enable-UMS";
case AUTOMOUNTER_ENABLE: return "Enable";
case AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED: return "DisableWhenUnplugged";
case AUTOMOUNTER_ENABLE_MTP: return "Enable-MTP";
}
return "??? Unknown ???";
}
bool IsModeEnabled(int32_t aMode)
{
return aMode == AUTOMOUNTER_ENABLE_MTP ||
aMode == AUTOMOUNTER_ENABLE_UMS;
}
void SetMode(int32_t aMode)
{
if ((aMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) &&
@ -302,8 +256,8 @@ public:
aMode = AUTOMOUNTER_DISABLE;
}
if (aMode == AUTOMOUNTER_DISABLE &&
mMode == AUTOMOUNTER_ENABLE_UMS && IsUsbCablePluggedIn()) {
if ((aMode == AUTOMOUNTER_DISABLE) &&
(mMode == AUTOMOUNTER_ENABLE) && IsUsbCablePluggedIn()) {
// On many devices (esp non-Samsung), we can't force the disable, so we
// need to defer until the USB cable is actually unplugged.
// See bug 777043.
@ -392,64 +346,10 @@ public:
private:
enum STATE
{
// IDLE - Nothing is being shared
STATE_IDLE,
// We've detected that conditions are right to enable mtp. So we've
// set sys.usb.config to include mtp, and we're waiting for the USB
// subsystem to be "configured". Once mtp shows up in
// then we know
// that its been configured and we can open /dev/mtp_usb
STATE_MTP_CONFIGURING,
// mtp has been configured (i.e. mtp now shows up in
// /sys/devices/virtual/android_usb/android0/functions so we can start
// the mtp server.
STATE_MTP_STARTED,
// The mtp server has reported sessionStarted. We'll leave this state
// when we receive sessionEnded.
STATE_MTP_CONNECTED,
// We've added mass_storage (aka UMS) to sys.usb.config and we're waiting for
// mass_storage to appear in /sys/devices/virtual/android_usb/android0/functions
STATE_UMS_CONFIGURING,
// mass_storage has been configured and we can start sharing once the user
// enables it.
STATE_UMS_CONFIGURED,
};
const char *StateStr(STATE aState)
{
switch (aState) {
case STATE_IDLE: return "IDLE";
case STATE_MTP_CONFIGURING: return "MTP_CONFIGURING";
case STATE_MTP_CONNECTED: return "MTP_CONNECTED";
case STATE_MTP_STARTED: return "MTP_STARTED";
case STATE_UMS_CONFIGURING: return "UMS_CONFIGURING";
case STATE_UMS_CONFIGURED: return "UMS_CONFIGURED";
}
return "STATE_???";
}
void SetState(STATE aState)
{
const char *oldStateStr = StateStr(mState);
mState = aState;
const char *newStateStr = StateStr(mState);
LOG("AutoMounter state changed from %s to %s", oldStateStr, newStateStr);
}
STATE mState;
AutoVolumeEventObserver mVolumeEventObserver;
AutoVolumeManagerStateObserver mVolumeManagerStateObserver;
RefPtr<VolumeResponseCallback> mResponseCallback;
int32_t mMode;
MozMtpStorage::Array mMozMtpStorage;
};
static StaticRefPtr<AutoMounter> sAutoMounter;
@ -505,78 +405,6 @@ AutoMounterResponseCallback::ResponseReceived(const VolumeCommand* aCommand)
}
}
static bool
IsUsbFunctionEnabled(const char* aConfig, const char* aUsbFunc)
{
nsAutoCString config(aConfig);
nsCCharSeparatedTokenizer tokenizer(config, ',');
while (tokenizer.hasMoreTokens()) {
nsAutoCString token(tokenizer.nextToken());
if (token.Equals(aUsbFunc)) {
DBG("IsUsbFunctionEnabled('%s', '%s'): returning true", aConfig, aUsbFunc);
return true;
}
}
DBG("IsUsbFunctionEnabled('%s', '%s'): returning false", aConfig, aUsbFunc);
return false;
}
static void
SetUsbFunction(const char* aUsbFunc)
{
char oldSysUsbConfig[PROPERTY_VALUE_MAX];
property_get(SYS_USB_CONFIG, oldSysUsbConfig, "");
if (IsUsbFunctionEnabled(oldSysUsbConfig, aUsbFunc)) {
// The function is already configured. Nothing else to do.
DBG("SetUsbFunction('%s') - already set - nothing to do", aUsbFunc);
return;
}
char newSysUsbConfig[PROPERTY_VALUE_MAX];
if (strcmp(aUsbFunc, USB_FUNC_MTP) == 0) {
// We're enabling MTP. For this we'll wind up using mtp, or mtp,adb
strlcpy(newSysUsbConfig, USB_FUNC_MTP, sizeof(newSysUsbConfig));
} else if (strcmp(aUsbFunc, USB_FUNC_UMS) == 0) {
// We're enabling UMS. For this we make the assumption that the persisted
// property has mass_storage enabled.
property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
} else {
printf_stderr("AutoMounter::SetUsbFunction Unrecognized aUsbFunc '%s'\n", aUsbFunc);
MOZ_ASSERT(0);
return;
}
// Make sure the new value that we write into sys.usb.config keeps the adb
// (or non-adb) of the current string.
if (IsUsbFunctionEnabled(oldSysUsbConfig, USB_FUNC_ADB)) {
// ADB was turned on - keep it on.
if (!IsUsbFunctionEnabled(newSysUsbConfig, USB_FUNC_ADB)) {
// Add adb to the new string
strlcat(newSysUsbConfig, ",", sizeof(newSysUsbConfig));
strlcat(newSysUsbConfig, USB_FUNC_ADB, sizeof(newSysUsbConfig));
}
} else {
// ADB was turned off - keep it off
if (IsUsbFunctionEnabled(newSysUsbConfig, USB_FUNC_ADB)) {
// Remove ADB from the new string.
if (strcmp(newSysUsbConfig, USB_FUNC_ADB) == 0) {
newSysUsbConfig[0] = '\0';
} else {
nsAutoCString withoutAdb(newSysUsbConfig);
withoutAdb.ReplaceSubstring( "," USB_FUNC_ADB, "");
strlcpy(newSysUsbConfig, withoutAdb.get(), sizeof(newSysUsbConfig));
}
}
}
LOG("SetUsbFunction(%s) %s to '%s'", aUsbFunc, SYS_USB_CONFIG, newSysUsbConfig);
property_set(SYS_USB_CONFIG, newSysUsbConfig);
}
void
AutoMounter::StartMtpServer()
{
@ -587,22 +415,12 @@ AutoMounter::StartMtpServer()
LOG("Starting MtpServer");
sMozMtpServer = new MozMtpServer();
sMozMtpServer->Run();
VolumeArray::index_type volIndex;
VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
nsRefPtr<MozMtpStorage> storage = new MozMtpStorage(vol, sMozMtpServer);
mMozMtpStorage.AppendElement(storage);
}
}
void
AutoMounter::StopMtpServer()
{
LOG("Stopping MtpServer");
mMozMtpStorage.Clear();
sMozMtpServer = nullptr;
}
@ -647,20 +465,10 @@ AutoMounter::UpdateState()
return;
}
// Calling setprop sys.usb.config mtp,adb (or adding mass_storage) will
// cause /sys/devices/virtual/android_usb/android0/state to go:
// CONFIGURED -> DISCONNECTED -> CONNECTED -> CONFIGURED
//
// Since IsUsbCablePluggedIn returns state == CONFIGURED, it will look
// like a cable pull and replugin.
bool umsAvail = false;
bool umsConfigured = false;
bool umsEnabled = false;
bool mtpAvail = false;
bool mtpConfigured = false;
bool mtpEnabled = false;
bool usbCablePluggedIn = IsUsbCablePluggedIn();
bool umsAvail = false;
bool umsEnabled = false;
bool mtpAvail = false;
bool mtpEnabled = false;
if (access(ICS_SYS_USB_FUNCTIONS, F_OK) == 0) {
char functionsStr[60];
@ -668,149 +476,40 @@ AutoMounter::UpdateState()
ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno));
functionsStr[0] = '\0';
}
DBG("UpdateState: USB functions: '%s'", functionsStr);
bool usbConfigured = IsUsbConfigured();
umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0);
if (umsAvail) {
umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr;
umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) ||
(mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured;
} else {
umsConfigured = false;
umsEnabled = false;
umsEnabled = strstr(functionsStr, "mass_storage") != nullptr;
}
mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0);
if (mtpAvail) {
mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr;
mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) ||
(mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured;
} else {
mtpConfigured = false;
mtpEnabled = false;
mtpEnabled = strstr(functionsStr, "mtp") != nullptr;
}
}
bool enabled = mtpEnabled || umsEnabled;
bool usbCablePluggedIn = IsUsbCablePluggedIn();
bool enabled = (mMode == AUTOMOUNTER_ENABLE);
if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) {
// DISABLE_WHEN_UNPLUGGED implies already enabled.
enabled = usbCablePluggedIn;
if (!usbCablePluggedIn) {
mMode = AUTOMOUNTER_DISABLE;
mtpEnabled = false;
umsEnabled = false;
}
}
DBG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d mode:%d usb:%d mState:%s",
umsAvail, umsConfigured, umsEnabled,
mtpAvail, mtpConfigured, mtpEnabled,
mMode, usbCablePluggedIn, StateStr(mState));
bool tryToShare = (((umsAvail && umsEnabled) || (mtpAvail && mtpEnabled))
&& enabled && usbCablePluggedIn);
LOG("UpdateState: ums:%d%d mtp:%d%d mode:%d usbCablePluggedIn:%d tryToShare:%d",
umsAvail, umsEnabled, mtpAvail, mtpEnabled, mMode, usbCablePluggedIn, tryToShare);
switch (mState) {
case STATE_IDLE:
if (!usbCablePluggedIn) {
// Stay in the IDLE state. We'll get a CONNECTED or CONFIGURED
// UEvent when the usb cable is plugged in.
break;
}
if (mtpEnabled) {
if (mtpConfigured) {
// The USB layer has already been configured. Now we can go ahead
// and start the MTP server. This particular codepath will not
// normally be taken, but it could happen if you stop and restart
// b2g while sys.usb.config is set to enable mtp.
StartMtpServer();
SetState(STATE_MTP_STARTED);
} else {
// The MTP USB layer is configuring. Wait for it to finish
// before we start the MTP server.
SetUsbFunction(USB_FUNC_MTP);
SetState(STATE_MTP_CONFIGURING);
}
} else if (umsConfigured) {
// UMS is already configured.
SetState(STATE_UMS_CONFIGURED);
} else if (umsAvail) {
// We do this whether or not UMS is enabled. With UMS, it's the
// sharing of the volume which is significant. What is important
// is that we don't leave it in MTP mode when MTP isn't enabled.
SetUsbFunction(USB_FUNC_UMS);
SetState(STATE_UMS_CONFIGURING);
}
break;
case STATE_MTP_CONFIGURING:
// While configuring, the USB configuration state will change from
// CONFIGURED -> CONNECTED -> DISCONNECTED -> CONNECTED -> CONFIGURED
// so we don't check for cable unplugged here.
if (mtpEnabled && mtpConfigured) {
// The USB layer has been configured. Now we can go ahead and start
// the MTP server.
StartMtpServer();
SetState(STATE_MTP_STARTED);
}
break;
case STATE_MTP_STARTED:
if (usbCablePluggedIn) {
if (mtpConfigured && mtpEnabled) {
// Everything is still good. Leave the MTP server running
break;
}
DBG("STATE_MTP_STARTED: About to StopMtpServer "
"mtpConfigured = %d mtpEnabled = %d usbCablePluggedIn: %d",
mtpConfigured, mtpEnabled, usbCablePluggedIn);
StopMtpServer();
if (umsAvail) {
// Switch back to UMS
SetUsbFunction(USB_FUNC_UMS);
SetState(STATE_UMS_CONFIGURING);
break;
}
}
SetState(STATE_IDLE);
break;
case STATE_UMS_CONFIGURING:
// While configuring, the USB configuration state will change from
// CONFIGURED -> CONNECTED -> DISCONNECTED -> CONNECTED -> CONFIGURED
// so we don't check for cable unplugged here.
if (umsConfigured) {
SetState(STATE_UMS_CONFIGURED);
}
break;
case STATE_UMS_CONFIGURED:
if (usbCablePluggedIn) {
if (mtpEnabled) {
// MTP was enabled. Start reconfiguring.
SetState(STATE_MTP_CONFIGURING);
SetUsbFunction(USB_FUNC_MTP);
break;
}
if (umsConfigured && umsEnabled) {
// This is the normal state when UMS is enabled.
break;
}
}
SetState(STATE_IDLE);
break;
default:
SetState(STATE_IDLE);
break;
if (mtpAvail && mtpEnabled) {
if (enabled && usbCablePluggedIn) {
StartMtpServer();
} else {
StopMtpServer();
}
return;
}
bool tryToShare = umsEnabled && usbCablePluggedIn;
LOG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d mode:%d usb:%d tryToShare:%d state:%s",
umsAvail, umsConfigured, umsEnabled,
mtpAvail, mtpConfigured, mtpEnabled,
mMode, usbCablePluggedIn, tryToShare, StateStr(mState));
bool filesOpen = false;
static unsigned filesOpenDelayCount = 0;
VolumeArray::index_type volIndex;
@ -825,8 +524,7 @@ AutoMounter::UpdateState()
vol->MediaPresent() ? "inserted" : "missing",
vol->MountPoint().get(), vol->MountGeneration(),
(int)vol->IsMountLocked(),
vol->CanBeShared() ? (vol->IsSharingEnabled() ?
(vol->IsSharing() ? "en-y" : "en-n") : "dis") : "x");
vol->CanBeShared() ? (vol->IsSharingEnabled() ? (vol->IsSharing() ? "en-y" : "en-n") : "dis") : "x");
if (vol->IsSharing() && !usbCablePluggedIn) {
// We call SetIsSharing(true) below to indicate intent to share. This
// causes a state change which notifys apps, and they'll close any
@ -1242,7 +940,6 @@ void
ShutdownAutoMounter()
{
if (sAutoMounter) {
DBG("ShutdownAutoMounter: About to StopMtpServer");
sAutoMounter->StopMtpServer();
}
sAutoMounterSetting = nullptr;

View File

@ -14,9 +14,8 @@ namespace system {
// AutoMounter modes
#define AUTOMOUNTER_DISABLE 0
#define AUTOMOUNTER_ENABLE_UMS 1
#define AUTOMOUNTER_ENABLE 1
#define AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED 2
#define AUTOMOUNTER_ENABLE_MTP 3
// Automounter statuses
#define AUTOMOUNTER_STATUS_DISABLED 0

View File

@ -40,9 +40,9 @@ ObjectPropertyAsStr(MtpObjectProperty aProperty)
return "MTP_PROPERTY_???";
}
MozMtpDatabase::MozMtpDatabase()
MozMtpDatabase::MozMtpDatabase(const char *aDir)
{
MTP_LOG("constructed");
MTP_LOG("");
// We use the index into the array as the handle. Since zero isn't a valid
// index, we stick a dummy entry there.
@ -50,12 +50,14 @@ MozMtpDatabase::MozMtpDatabase()
RefPtr<DbEntry> dummy;
mDb.AppendElement(dummy);
ReadVolume("sdcard", aDir);
}
//virtual
MozMtpDatabase::~MozMtpDatabase()
{
MTP_LOG("destructed");
MTP_LOG("");
}
void
@ -65,7 +67,7 @@ MozMtpDatabase::AddEntry(DbEntry *entry)
MOZ_ASSERT(mDb.Length() == entry->mHandle);
mDb.AppendElement(entry);
MTP_LOG("Handle: 0x%08x Parent: 0x%08x Path:'%s'",
MTP_LOG("AddEntry: Handle: 0x%08x Parent: 0x%08x Path:'%s'",
entry->mHandle, entry->mParent, entry->mPath.get());
}
@ -118,20 +120,18 @@ GetPathWithoutFileName(const nsCString& aFullPath)
}
void
MozMtpDatabase::AddDirectory(MtpStorageID aStorageID,
const char* aPath,
MtpObjectHandle aParent)
MozMtpDatabase::ParseDirectory(const char *aDir, MtpObjectHandle aParent)
{
ScopedCloseDir dir;
if (!(dir = PR_OpenDir(aPath))) {
MTP_ERR("Unable to open directory '%s'", aPath);
if (!(dir = PR_OpenDir(aDir))) {
MTP_ERR("Unable to open directory '%s'", aDir);
return;
}
PRDirEntry* dirEntry;
while ((dirEntry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
nsPrintfCString filename("%s/%s", aPath, dirEntry->name);
nsPrintfCString filename("%s/%s", aDir, dirEntry->name);
PRFileInfo64 fileInfo;
if (PR_GetFileInfo64(filename.get(), &fileInfo) != PR_SUCCESS) {
MTP_ERR("Unable to retrieve file information for '%s'", filename.get());
@ -140,7 +140,7 @@ MozMtpDatabase::AddDirectory(MtpStorageID aStorageID,
RefPtr<DbEntry> entry = new DbEntry;
entry->mStorageID = aStorageID;
entry->mStorageID = MTP_STORAGE_FIXED_RAM;
entry->mParent = aParent;
entry->mObjectName = dirEntry->name;
entry->mDisplayName = dirEntry->name;
@ -157,59 +157,40 @@ MozMtpDatabase::AddDirectory(MtpStorageID aStorageID,
entry->mObjectFormat = MTP_FORMAT_ASSOCIATION;
entry->mObjectSize = 0;
AddEntry(entry);
AddDirectory(aStorageID, filename.get(), entry->mHandle);
ParseDirectory(filename.get(), entry->mHandle);
}
}
}
void
MozMtpDatabase::AddStorage(MtpStorageID aStorageID,
const char* aPath,
const char* aName)
MozMtpDatabase::ReadVolume(const char *volumeName, const char *aDir)
{
//TODO: Add an assert re thread being run on
PRFileInfo fileInfo;
if (PR_GetFileInfo(aPath, &fileInfo) != PR_SUCCESS) {
MTP_ERR("'%s' doesn't exist", aPath);
if (PR_GetFileInfo(aDir, &fileInfo) != PR_SUCCESS) {
MTP_ERR("'%s' doesn't exist", aDir);
return;
}
if (fileInfo.type != PR_FILE_DIRECTORY) {
MTP_ERR("'%s' isn't a directory", aPath);
MTP_ERR("'%s' isn't a directory", aDir);
return;
}
#if 0
RefPtr<DbEntry> entry = new DbEntry;
entry->mStorageID = aStorageID;
entry->mStorageID = MTP_STORAGE_FIXED_RAM;
entry->mParent = MTP_PARENT_ROOT;
entry->mObjectName = aName;
entry->mDisplayName = aName;
entry->mPath = aPath;
entry->mObjectName = volumeName;
entry->mDisplayName = volumeName;
entry->mPath = aDir;
entry->mObjectFormat = MTP_FORMAT_ASSOCIATION;
entry->mObjectSize = 0;
AddEntry(entry);
AddDirectory(aStorageID, aPath, entry->mHandle);
#else
AddDirectory(aStorageID, aPath, MTP_PARENT_ROOT);
#endif
}
void
MozMtpDatabase::RemoveStorage(MtpStorageID aStorageID)
{
DbArray::size_type numEntries = mDb.Length();
DbArray::index_type entryIndex;
for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
RefPtr<DbEntry> entry = mDb[entryIndex];
if (entry && entry->mStorageID == aStorageID) {
mDb[entryIndex] = nullptr;
}
}
ParseDirectory(aDir, entry->mHandle);
}
// called from SendObjectInfo to reserve a database entry for the incoming file
@ -251,12 +232,12 @@ MozMtpDatabase::beginSendObject(const char* aPath,
//virtual
void
MozMtpDatabase::endSendObject(const char* aPath,
MtpObjectHandle aHandle,
MtpObjectFormat aFormat,
bool aSucceeded)
MtpObjectHandle aHandle,
MtpObjectFormat aFormat,
bool succeeded)
{
MTP_LOG("Handle: 0x%08x Path: '%s'", aHandle, aPath);
if (!aSucceeded) {
if (!succeeded) {
RemoveEntry(aHandle);
}
}
@ -264,8 +245,8 @@ MozMtpDatabase::endSendObject(const char* aPath,
//virtual
MtpObjectHandleList*
MozMtpDatabase::getObjectList(MtpStorageID aStorageID,
MtpObjectFormat aFormat,
MtpObjectHandle aParent)
MtpObjectFormat aFormat,
MtpObjectHandle aParent)
{
MTP_LOG("StorageID: 0x%08x Format: 0x%04x Parent: 0x%08x",
aStorageID, aFormat, aParent);
@ -276,14 +257,11 @@ MozMtpDatabase::getObjectList(MtpStorageID aStorageID,
list = new MtpObjectHandleList();
// Note: objects in the topmost directory of each storage area have a parent
// of MTP_PARENT_ROOT. So we need to filter on storage ID as well.
DbArray::size_type numEntries = mDb.Length();
DbArray::index_type entryIndex;
for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
RefPtr<DbEntry> entry = mDb[entryIndex];
if (entry && entry->mStorageID == aStorageID && entry->mParent == aParent) {
if (entry && entry->mParent == aParent) {
list->push(entry->mHandle);
}
}
@ -293,23 +271,12 @@ MozMtpDatabase::getObjectList(MtpStorageID aStorageID,
//virtual
int
MozMtpDatabase::getNumObjects(MtpStorageID aStorageID,
MtpObjectFormat aFormat,
MtpObjectHandle aParent)
MtpObjectFormat aFormat,
MtpObjectHandle aParent)
{
MTP_LOG("");
int count = 0;
DbArray::size_type numEntries = mDb.Length();
DbArray::index_type entryIndex;
for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
RefPtr<DbEntry> entry = mDb[entryIndex];
if (entry && entry->mStorageID == aStorageID) {
count++;
}
}
return count;
return mDb.Length() - 1;
}
//virtual
@ -377,8 +344,8 @@ MozMtpDatabase::getSupportedDeviceProperties()
//virtual
MtpResponseCode
MozMtpDatabase::getObjectPropertyValue(MtpObjectHandle aHandle,
MtpObjectProperty aProperty,
MtpDataPacket& aPacket)
MtpObjectProperty aProperty,
MtpDataPacket& aPacket)
{
RefPtr<DbEntry> entry = GetEntry(aHandle);
if (!entry) {
@ -450,8 +417,8 @@ GetTypeOfObjectProp(MtpObjectProperty aProperty)
//virtual
MtpResponseCode
MozMtpDatabase::setObjectPropertyValue(MtpObjectHandle aHandle,
MtpObjectProperty aProperty,
MtpDataPacket& aPacket)
MtpObjectProperty aProperty,
MtpDataPacket& aPacket)
{
MTP_LOG("Handle: 0x%08x Property: 0x%08x", aHandle, aProperty);
@ -496,7 +463,7 @@ MozMtpDatabase::setObjectPropertyValue(MtpObjectHandle aHandle,
//virtual
MtpResponseCode
MozMtpDatabase::getDevicePropertyValue(MtpDeviceProperty aProperty,
MtpDataPacket& aPacket)
MtpDataPacket& aPacket)
{
MTP_LOG("(GENERAL ERROR)");
return MTP_RESPONSE_GENERAL_ERROR;
@ -505,7 +472,7 @@ MozMtpDatabase::getDevicePropertyValue(MtpDeviceProperty aProperty,
//virtual
MtpResponseCode
MozMtpDatabase::setDevicePropertyValue(MtpDeviceProperty aProperty,
MtpDataPacket& aPacket)
MtpDataPacket& aPacket)
{
MTP_LOG("(NOT SUPPORTED)");
return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
@ -600,13 +567,13 @@ MozMtpDatabase::QueryEntries(MozMtpDatabase::MatchType aMatchType,
//virtual
MtpResponseCode
MozMtpDatabase::getObjectPropertyList(MtpObjectHandle aHandle,
uint32_t aFormat,
uint32_t aProperty,
int aGroupCode,
int aDepth,
MtpDataPacket& aPacket)
uint32_t aFormat,
uint32_t aProperty,
int aGroupCode,
int aDepth,
MtpDataPacket& aPacket)
{
MTP_LOG("Handle: 0x%08x Format: 0x%08x aProperty: 0x%08x aGroupCode: %d aDepth %d",
MTP_LOG("Handle: 0x%08x Format: 0x%08x aProperty: 0x%08x aGroupCode: %d aDepth %d (NOT SUPPORTED)",
aHandle, aFormat, aProperty, aGroupCode, aDepth);
if (aDepth > 1) {
@ -759,7 +726,7 @@ MozMtpDatabase::getObjectPropertyList(MtpObjectHandle aHandle,
//virtual
MtpResponseCode
MozMtpDatabase::getObjectInfo(MtpObjectHandle aHandle,
MtpObjectInfo& aInfo)
MtpObjectInfo& aInfo)
{
RefPtr<DbEntry> entry = GetEntry(aHandle);
if (!entry) {
@ -813,9 +780,9 @@ MozMtpDatabase::getThumbnail(MtpObjectHandle aHandle, size_t& aOutThumbSize)
//virtual
MtpResponseCode
MozMtpDatabase::getObjectFilePath(MtpObjectHandle aHandle,
MtpString& aOutFilePath,
int64_t& aOutFileLength,
MtpObjectFormat& aOutFormat)
MtpString& aOutFilePath,
int64_t& aOutFileLength,
MtpObjectFormat& aOutFormat)
{
RefPtr<DbEntry> entry = GetEntry(aHandle);
if (!entry) {
@ -844,10 +811,6 @@ MozMtpDatabase::deleteFile(MtpObjectHandle aHandle)
MTP_LOG("Handle: 0x%08x '%s'", aHandle, entry->mPath.get());
//TODO: MtpServer::doDeleteObject calls us, and then calls a private
// method (deletePath) which recursively deletes the path.
// We need to tell device storage that these files are gone
// File deletion will happen in lower level implementation.
// The only thing we need to do is removing the entry from the db.
RemoveEntry(aHandle);
@ -891,7 +854,7 @@ MozMtpDatabase::getObjectReferences(MtpObjectHandle aHandle)
//virtual
MtpResponseCode
MozMtpDatabase::setObjectReferences(MtpObjectHandle aHandle,
MtpObjectHandleList* aReferences)
MtpObjectHandleList* aReferences)
{
MTP_LOG("Handle: 0x%08x (NOT SUPPORTED)", aHandle);
return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;

View File

@ -22,9 +22,7 @@ using namespace android;
class MozMtpDatabase : public MtpDatabase
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpDatabase)
MozMtpDatabase();
MozMtpDatabase(const char *aDir);
virtual ~MozMtpDatabase();
// called from SendObjectInfo to reserve a database entry for the incoming file
@ -108,14 +106,11 @@ public:
virtual void sessionEnded();
void AddStorage(MtpStorageID aStorageID, const char* aPath, const char *aName);
void RemoveStorage(MtpStorageID aStorageID);
private:
struct DbEntry
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DbEntry)
NS_INLINE_DECL_REFCOUNTING(DbEntry)
MtpObjectHandle mHandle; // uint32_t
MtpStorageID mStorageID; // uint32_t
@ -157,7 +152,8 @@ private:
return mDb.Length();
}
void AddDirectory(MtpStorageID aStorageID, const char *aPath, MtpObjectHandle aParent);
void ParseDirectory(const char *aDir, MtpObjectHandle aParent);
void ReadVolume(const char *aVolumeName, const char *aDir);
};
END_MTP_NAMESPACE

View File

@ -16,34 +16,46 @@
#include <unistd.h>
#include <cutils/properties.h>
#include <private/android_filesystem_config.h>
#include "base/message_loop.h"
#include "mozilla/FileUtils.h"
#include "mozilla/Scoped.h"
#include "mozilla/StaticPtr.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "Volume.h"
using namespace android;
using namespace mozilla;
BEGIN_MTP_NAMESPACE
USING_MTP_NAMESPACE
class MtpServerRunnable : public nsRunnable
{
public:
MtpServerRunnable(int aMtpUsbFd, MozMtpServer* aMozMtpServer)
: mMozMtpServer(aMozMtpServer),
mMtpUsbFd(aMtpUsbFd)
{
}
nsresult Run()
{
nsRefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
const char *mtpUsbFilename = "/dev/mtp_usb";
const char *productName = "FirefoxOS";
const char *storageDir = "/storage/sdcard";
mFd = open(mtpUsbFilename, O_RDWR);
if (mFd.get() < 0) {
MTP_LOG("open of '%s' failed", mtpUsbFilename);
return NS_OK;
}
MTP_LOG("MozMtpServer open done, fd: %d. Start reading.", mFd.get());
ScopedDeletePtr<MozMtpDatabase> database;
ScopedDeletePtr<MtpServer> server;
ScopedDeletePtr<MtpStorage> storage;
database = new MozMtpDatabase(storageDir);
server = new MtpServer(mFd.get(), database, false, 1023, 0664, 0775);
storage = new MtpStorage(MTP_STORAGE_FIXED_RAM, // id
storageDir, // filePath
productName, // description
100uLL * 1024uLL * 1024uLL, // reserveSpace
false, // removable
2uLL * 1024uLL * 1024uLL * 1024uLL); // maxFileSize
server->addStorage(storage);
MTP_LOG("MozMtpServer started");
server->run();
@ -53,51 +65,16 @@ public:
}
private:
nsRefPtr<MozMtpServer> mMozMtpServer;
ScopedClose mMtpUsbFd; // We want to hold this open while the server runs
ScopedClose mFd;
};
already_AddRefed<RefCountedMtpServer>
MozMtpServer::GetMtpServer()
{
nsRefPtr<RefCountedMtpServer> server = mMtpServer;
return server.forget();
}
already_AddRefed<MozMtpDatabase>
MozMtpServer::GetMozMtpDatabase()
{
nsRefPtr<MozMtpDatabase> db = mMozMtpDatabase;
return db.forget();
}
void
MozMtpServer::Run()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
const char *mtpUsbFilename = "/dev/mtp_usb";
ScopedClose mtpUsbFd(open(mtpUsbFilename, O_RDWR));
if (mtpUsbFd.get() < 0) {
MTP_ERR("open of '%s' failed", mtpUsbFilename);
return;
}
MTP_LOG("Opened '%s' fd %d", mtpUsbFilename, mtpUsbFd.get());
mMozMtpDatabase = new MozMtpDatabase();
mMtpServer = new RefCountedMtpServer(mtpUsbFd.get(), // fd
mMozMtpDatabase.get(), // MtpDatabase
false, // ptp?
AID_MEDIA_RW, // file group
0664, // file permissions
0775); // dir permissions
nsresult rv = NS_NewNamedThread("MtpServer", getter_AddRefs(mServerThread));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
MOZ_ASSERT(mServerThread);
mServerThread->Dispatch(new MtpServerRunnable(mtpUsbFd.forget(), this), NS_DISPATCH_NORMAL);
mServerThread->Dispatch(new MtpServerRunnable(), 0);
}
END_MTP_NAMESPACE

View File

@ -8,48 +8,20 @@
#define mozilla_system_mozmtpserver_h__
#include "MozMtpCommon.h"
#include "MozMtpDatabase.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsIThread.h"
namespace mozilla {
namespace system {
class Volume;
}
}
BEGIN_MTP_NAMESPACE
using namespace android;
class RefCountedMtpServer : public MtpServer
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMtpServer)
RefCountedMtpServer(int aFd, MtpDatabase* aDatabase, bool aPtp,
int aFileGroup, int aFilePerm, int aDirectoryPerm)
: MtpServer(aFd, aDatabase, aPtp, aFileGroup, aFilePerm, aDirectoryPerm)
{
}
};
class MozMtpServer
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpServer)
NS_INLINE_DECL_REFCOUNTING(MozMtpServer)
void Run();
// void UpdateStorage(android::MtpStorageID id, Volume *vol);
already_AddRefed<RefCountedMtpServer> GetMtpServer();
already_AddRefed<MozMtpDatabase> GetMozMtpDatabase();
private:
nsRefPtr<RefCountedMtpServer> mMtpServer;
nsRefPtr<MozMtpDatabase> mMozMtpDatabase;
nsCOMPtr<nsIThread> mServerThread;
};

View File

@ -1,133 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#include "MozMtpStorage.h"
#include "MozMtpDatabase.h"
#include "MozMtpServer.h"
#include "base/message_loop.h"
#include "nsXULAppAPI.h"
BEGIN_MTP_NAMESPACE
using namespace android;
MozMtpStorage::MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer)
: mMozMtpServer(aMozMtpServer),
mVolume(aVolume)
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
// The MtpStorageID has the physical volume in the top 16 bits, and the
// logical volumein the lower 16 bits. We treat each volume as a separate
// phsyical storage;
mStorageID = mVolume->Id() << 16 | 1;
MTP_LOG("Storage constructed for Volume %s mStorageID 0x%08x",
aVolume->NameStr(), mStorageID);
Volume::RegisterObserver(this);
// Get things in sync
Notify(mVolume);
}
MozMtpStorage::~MozMtpStorage()
{
MTP_LOG("Storage destructed for Volume %s mStorageID 0x%08x",
mVolume->NameStr(), mStorageID);
Volume::UnregisterObserver(this);
if (mMtpStorage) {
StorageUnavailable();
}
}
// virtual
void
MozMtpStorage::Notify(Volume* const& aVolume)
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
if (aVolume != mVolume) {
// Not our volume
return;
}
Volume::STATE volState = aVolume->State();
MTP_LOG("Volume %s mStorageID 0x%08x state changed to %s SharingEnabled: %d",
aVolume->NameStr(), mStorageID, aVolume->StateStr(),
aVolume->IsSharingEnabled());
if (mMtpStorage) {
if (volState != nsIVolume::STATE_MOUNTED || !aVolume->IsSharingEnabled()) {
// The volume is no longer accessible. We need to remove this storage
// from the MTP server
StorageUnavailable();
}
} else {
if (volState == nsIVolume::STATE_MOUNTED && aVolume->IsSharingEnabled()) {
// The volume is accessible. Tell the MTP server.
StorageAvailable();
}
}
}
void
MozMtpStorage::StorageAvailable()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
nsCString mountPoint = mVolume->MountPoint();
MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MozMtpDatabase",
mVolume->NameStr(), mStorageID, mountPoint.get());
nsRefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
db->AddStorage(mStorageID, mountPoint.get(), mVolume->NameStr());
MOZ_ASSERT(!mMtpStorage);
//TODO: For now we assume that the storage removable unless we're sure it's
// not. Bug 1033952 will add an isRemovable attribute to the Volume
// and then we'll know properly.
//TODO: Figure out what to do about maxFileSize.
mMtpStorage.reset(new MtpStorage(mStorageID, // id
mountPoint.get(), // filePath
mVolume->NameStr(), // description
1024uLL * 1024uLL, // reserveSpace
true, // removable
2uLL * 1024uLL * 1024uLL * 1024uLL)); // maxFileSize
nsRefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MtpServer",
mVolume->NameStr(), mStorageID, mountPoint.get());
server->addStorage(mMtpStorage.get());
}
void
MozMtpStorage::StorageUnavailable()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
MOZ_ASSERT(mMtpStorage);
MTP_LOG("Removing mStorageID 0x%08x from MtpServer", mStorageID);
nsRefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
server->removeStorage(mMtpStorage.get());
MTP_LOG("Removing mStorageID 0x%08x from MozMtpDatabse", mStorageID);
nsRefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
db->RemoveStorage(mStorageID);
mMtpStorage = nullptr;
}
END_MTP_NAMESPACE

View File

@ -1,48 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 mozilla_system_mozmtpstorage_h__
#define mozilla_system_mozmtpstorage_h__
#include "MozMtpCommon.h"
#include "nsAutoPtr.h"
#include "mozilla/UniquePtr.h"
#include "Volume.h"
BEGIN_MTP_NAMESPACE
using namespace android;
class MozMtpServer;
class MozMtpStorage : public Volume::EventObserver
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpStorage)
MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer);
typedef nsTArray<nsRefPtr<MozMtpStorage> > Array;
private:
virtual ~MozMtpStorage();
virtual void Notify(Volume* const& aEvent);
void StorageAvailable();
void StorageUnavailable();
nsRefPtr<MozMtpServer> mMozMtpServer;
UniquePtr<MtpStorage> mMtpStorage;
RefPtr<Volume> mVolume;
MtpStorageID mStorageID;
};
END_MTP_NAMESPACE
#endif // mozilla_system_mozmtpstorage_h__

View File

@ -50,8 +50,6 @@ Volume::EventObserverList Volume::mEventObserverList;
// be locked until we get our first update from nsVolume (MainThread).
static int32_t sMountGeneration = 0;
static uint32_t sNextId = 1;
// We don't get media inserted/removed events at startup. So we
// assume it's present, and we'll be told that it's missing.
Volume::Volume(const nsCSubstring& aName)
@ -66,8 +64,7 @@ Volume::Volume(const nsCSubstring& aName)
mUnmountRequested(false),
mCanBeShared(true),
mIsSharing(false),
mIsFormatting(false),
mId(sNextId++)
mIsFormatting(false)
{
DBG("Volume %s: created", NameStr());
}
@ -143,7 +140,6 @@ Volume::SetSharingEnabled(bool aSharingEnabled)
LOG("SetSharingMode for volume %s to %d canBeShared = %d",
NameStr(), (int)mSharingEnabled, (int)mCanBeShared);
mEventObserverList.Broadcast(this);
}
void
@ -183,14 +179,14 @@ Volume::SetState(Volume::STATE aNewState)
}
if (aNewState == nsIVolume::STATE_MOUNTED) {
mMountGeneration = ++sMountGeneration;
LOG("Volume %s (%u): changing state from %s to %s @ '%s' (%d observers) "
LOG("Volume %s: changing state from %s to %s @ '%s' (%d observers) "
"mountGeneration = %d, locked = %d",
NameStr(), mId, StateStr(mState),
NameStr(), StateStr(mState),
StateStr(aNewState), mMountPoint.get(), mEventObserverList.Length(),
mMountGeneration, (int)mMountLocked);
} else {
LOG("Volume %s (%u): changing state from %s to %s (%d observers)",
NameStr(), mId, StateStr(mState),
LOG("Volume %s: changing state from %s to %s (%d observers)",
NameStr(), StateStr(mState),
StateStr(aNewState), mEventObserverList.Length());
}

View File

@ -44,8 +44,6 @@ public:
// (i.e. path that leads to the files stored on the volume).
const nsCString& MountPoint() const { return mMountPoint; }
uint32_t Id() const { return mId; }
int32_t MountGeneration() const { return mMountGeneration; }
bool IsMountLocked() const { return mMountLocked; }
bool MediaPresent() const { return mMediaPresent; }
@ -112,7 +110,6 @@ private:
bool mCanBeShared;
bool mIsSharing;
bool mIsFormatting;
uint32_t mId; // Unique ID (used by MTP)
static EventObserverList mEventObserverList;
};

View File

@ -43,7 +43,6 @@ SOURCES += [
'GonkGPSGeolocationProvider.cpp',
'MozMtpDatabase.cpp',
'MozMtpServer.cpp',
'MozMtpStorage.cpp',
'NetworkUtils.cpp',
'NetworkWorker.cpp',
'nsVolume.cpp',

View File

@ -596,6 +596,7 @@ this.GET_RESPONSE_EF_SIZE_BYTES = 15;
// EF path
this.EF_PATH_MF_SIM = "3f00";
this.EF_PATH_DF_PHONEBOOK = "5f3a";
this.EF_PATH_GRAPHICS = "5f50";
this.EF_PATH_DF_TELECOM = "7f10";
this.EF_PATH_DF_GSM = "7f20";
this.EF_PATH_DF_CDMA = "7f25";
@ -672,6 +673,19 @@ this.ICC_USIM_EFUID_TAG = 0xc9;
this.ICC_USIM_EFEMAIL_TAG = 0xca;
this.ICC_USIM_EFCCP1_TAG = 0xcb;
// ICC image coding scheme
// TS 31.102, sub-clause 4.6.1.1
this.ICC_IMG_CODING_SCHEME_BASIC = 0x11;
this.ICC_IMG_CODING_SCHEME_COLOR = 0x21;
this.ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY = 0x22;
// ICC image header size per coding scheme
// TS 31.102, Annex B
this.ICC_IMG_HEADER_SIZE_BASIC = 2;
this.ICC_IMG_HEADER_SIZE_COLOR = 6;
this.ICC_CLUT_ENTRY_SIZE = 3;
this.USIM_PBR_ANR = "anr";
this.USIM_PBR_ANR0 = "anr0";
this.USIM_PBR_EMAIL = "email";
@ -1246,6 +1260,7 @@ this.GECKO_ICC_SERVICES = {
DATA_DOWNLOAD_SMS_PP: 26,
CBMIR: 30,
BDN: 31,
IMG: 39,
PNN: 51,
OPL: 52,
MDN: 53,
@ -1261,6 +1276,7 @@ this.GECKO_ICC_SERVICES = {
GID1: 17,
SPN: 19,
MSISDN: 21,
IMG: 22,
DATA_DOWNLOAD_SMS_PP: 28,
DATA_DOWNLOAD_SMS_CB: 29,
PNN: 45,

View File

@ -5434,7 +5434,10 @@ RilObject.prototype = {
cmdDetails.rilMessageType = "stkcommand";
cmdDetails.options =
this.context.StkCommandParamsFactory.createParam(cmdDetails, ctlvs);
this.sendChromeMessage(cmdDetails);
if (!cmdDetails.options || !cmdDetails.options.pending) {
this.sendChromeMessage(cmdDetails);
}
},
/**
@ -10825,6 +10828,47 @@ StkCommandParamsFactoryObject.prototype = {
menu.nextActionList = ctlv.value;
}
let iconId;
let ids = [];
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (ctlv) {
iconId = ctlv.value;
menu.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
ids[0] = iconId.identifier;
}
let iconIdList;
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID_LIST, ctlvs);
if (ctlv) {
iconIdList = ctlv.value;
menu.itemIconSelfExplanatory = iconIdList.qualifier == 0 ? true : false;
ids = ids.concat(iconIdList.identifiers);
}
if (!ids.length ||
!this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return menu;
}
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
if (iconId) {
menu.icons = result.shift();
}
for (let i = 0; i < result.length; i++) {
menu.items[i].icons = result[i];
}
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
menu.pending = true;
this.context.IconLoader.loadIcons(ids, onsuccess, onerror);
return menu;
},
@ -10861,14 +10905,35 @@ StkCommandParamsFactoryObject.prototype = {
textMsg.userClear = true;
}
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return textMsg;
}
let iconId = ctlv.value;
textMsg.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
textMsg.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
textMsg.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return textMsg;
},
processSetUpIdleModeText: function(cmdDetails, ctlvs) {
let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
let textMsg = {};
let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
let ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
if (!ctlv) {
this.context.RIL.sendStkTerminalResponse({
command: cmdDetails,
@ -10877,6 +10942,26 @@ StkCommandParamsFactoryObject.prototype = {
}
textMsg.text = ctlv.value.textString;
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return textMsg;
}
let iconId = ctlv.value;
textMsg.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
textMsg.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
textMsg.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return textMsg;
},
@ -10924,6 +11009,26 @@ StkCommandParamsFactoryObject.prototype = {
input.isHelpAvailable = true;
}
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return input;
}
let iconId = ctlv.value;
input.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
input.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
input.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return input;
},
@ -10976,18 +11081,60 @@ StkCommandParamsFactoryObject.prototype = {
input.isHelpAvailable = true;
}
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return input;
}
let iconId = ctlv.value;
input.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
input.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
input.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return input;
},
processEventNotify: function(cmdDetails, ctlvs) {
let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
let textMsg = {};
let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
let ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
if (ctlv) {
textMsg.text = ctlv.value.identifier;
}
ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return textMsg;
}
let iconId = ctlv.value;
textMsg.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
textMsg.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
textMsg.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return textMsg;
},
@ -11021,6 +11168,26 @@ StkCommandParamsFactoryObject.prototype = {
call.duration = ctlv.value;
}
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return call;
}
let iconId = ctlv.value;
call.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
call.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
call.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return call;
},
@ -11044,6 +11211,26 @@ StkCommandParamsFactoryObject.prototype = {
browser.mode = cmdDetails.commandQualifier & 0x03;
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return browser;
}
let iconId = ctlv.value;
browser.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
browser.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
browser.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return browser;
},
@ -11052,7 +11239,7 @@ StkCommandParamsFactoryObject.prototype = {
let playTone = {};
let ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
if (ctlv) {
playTone.text = ctlv.value.identifier;
}
@ -11071,6 +11258,27 @@ StkCommandParamsFactoryObject.prototype = {
// vibrate is only defined in TS 102.223
playTone.isVibrate = (cmdDetails.commandQualifier & 0x01) !== 0x00;
ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return playTone;
}
let iconId = ctlv.value;
playTone.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
playTone.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
playTone.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return playTone;
},
@ -11119,14 +11327,35 @@ StkCommandParamsFactoryObject.prototype = {
* The all TLVs in this proactive command.
*/
processBipMessage: function(cmdDetails, ctlvs) {
let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
let bipMsg = {};
let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
let ctlv = StkProactiveCmdHelper.searchForTag(
COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
if (ctlv) {
bipMsg.text = ctlv.value.identifier;
}
ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
if (!ctlv || !this.context.ICCUtilsHelper.isICCServiceAvailable("IMG")) {
return bipMsg;
}
let iconId = ctlv.value;
bipMsg.iconSelfExplanatory = iconId.qualifier == 0 ? true : false;
let onerror = (function() {
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
let onsuccess = (function(result) {
bipMsg.icons = result[0];
this.context.RIL.sendChromeMessage(cmdDetails);
}).bind(this);
bipMsg.pending = true;
this.context.IconLoader.loadIcons([iconId.identifier], onsuccess, onerror);
return bipMsg;
}
};
@ -11471,6 +11700,52 @@ StkProactiveCmdHelperObject.prototype = {
};
},
/**
* Icon Id.
*
* | Byte | Description | Length |
* | 1 | Icon Identifier Tag | 1 |
* | 2 | Length = 02 | 1 |
* | 3 | Icon qualifier | 1 |
* | 4 | Icon identifier | 1 |
*/
retrieveIconId: function(length) {
if (!length) {
return null;
}
let iconId = {
qualifier: this.context.GsmPDUHelper.readHexOctet(),
identifier: this.context.GsmPDUHelper.readHexOctet()
};
return iconId;
},
/**
* Icon Id List.
*
* | Byte | Description | Length |
* | 1 | Icon Identifier Tag | 1 |
* | 2 | Length = X | 1 |
* | 3 | Icon qualifier | 1 |
* | 4~ | Icon identifier | X-1 |
* | 4+X-2 | | |
*/
retrieveIconIdList: function(length) {
if (!length) {
return null;
}
let iconIdList = {
qualifier: this.context.GsmPDUHelper.readHexOctet(),
identifiers: []
};
for (let i = 0; i < length - 1; i++) {
iconIdList.identifiers.push(this.context.GsmPDUHelper.readHexOctet());
}
return iconIdList;
},
/**
* Timer Identifier.
*
@ -11606,6 +11881,12 @@ StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_DEFAULT_TEXT] = funct
StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_EVENT_LIST] = function COMPREHENSIONTLV_TAG_EVENT_LIST(length) {
return this.retrieveEventList(length);
};
StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ICON_ID] = function COMPREHENSIONTLV_TAG_ICON_ID(length) {
return this.retrieveIconId(length);
};
StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_ICON_ID_LIST] = function COMPREHENSIONTLV_TAG_ICON_ID_LIST(length) {
return this.retrieveIconIdList(length);
};
StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER] = function COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER(length) {
return this.retrieveTimerId(length);
};
@ -12140,6 +12421,8 @@ ICCFileHelperObject.prototype = {
return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
case ICC_EF_PBR:
return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
case ICC_EF_IMG:
return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_GRAPHICS;
}
return null;
},
@ -13264,6 +13547,155 @@ SimRecordHelperObject.prototype = {
});
},
readIMG: function(recordNumber, onsuccess, onerror) {
function callback(options) {
let RIL = this.context.RIL;
let Buf = this.context.Buf;
let GsmPDUHelper = this.context.GsmPDUHelper;
let strLen = Buf.readInt32();
// Each octet is encoded into two chars.
let octetLen = strLen / 2;
let numInstances = GsmPDUHelper.readHexOctet();
// Correct data length should be 9n+1 or 9n+2. See TS 31.102, sub-clause
// 4.6.1.1.
if (octetLen != (9 * numInstances + 1) ||
octetLen != (9 * numInstances + 2)) {
if (onerror) {
onerror();
}
return;
}
let imgDescriptors = [];
for (let i = 0; i < numInstances; i++) {
imgDescriptors[i] = {
width: GsmPDUHelper.readHexOctet(),
height: GsmPDUHelper.readHexOctet(),
codingScheme: GsmPDUHelper.readHexOctet(),
fileId: (GsmPDUHelper.readHexOctet() << 8) |
GsmPDUHelper.readHexOctet(),
offset: (GsmPDUHelper.readHexOctet() << 8) |
GsmPDUHelper.readHexOctet(),
dataLen: (GsmPDUHelper.readHexOctet() << 8) |
GsmPDUHelper.readHexOctet()
};
}
Buf.readStringDelimiter(strLen);
let instances = [];
let currentInstance = 0;
let readNextInstance = (function(img) {
instances[currentInstance] = img;
currentInstance++;
if (currentInstance < numInstances) {
let imgDescriptor = imgDescriptors[currentInstance];
this.readIIDF(imgDescriptor.fileId,
imgDescriptor.offset,
imgDescriptor.dataLen,
imgDescriptor.codingScheme,
readNextInstance,
onerror);
} else {
if (onsuccess) {
onsuccess(instances);
}
}
}).bind(this);
this.readIIDF(imgDescriptors[0].fileId,
imgDescriptors[0].offset,
imgDescriptors[0].dataLen,
imgDescriptors[0].codingScheme,
readNextInstance,
onerror);
}
this.context.ICCIOHelper.loadLinearFixedEF({
fileId: ICC_EF_IMG,
recordNumber: recordNumber,
callback: callback.bind(this),
onerror: onerror
});
},
readIIDF: function(fileId, offset, dataLen, codingScheme, onsuccess, onerror) {
// Valid fileId is '4FXX', see TS 31.102, clause 4.6.1.2.
if ((fileId >> 8) != 0x4F) {
if (onerror) {
onerror();
}
return;
}
function callback() {
let Buf = this.context.Buf;
let RIL = this.context.RIL;
let GsmPDUHelper = this.context.GsmPDUHelper;
let strLen = Buf.readInt32();
// Each octet is encoded into two chars.
let octetLen = strLen / 2;
if (octetLen < offset + dataLen) {
// Data length is not enough. See TS 31.102, clause 4.6.1.1, the
// paragraph "Bytes 8 and 9: Length of Image Instance Data."
if (onerror) {
onerror();
}
return;
}
Buf.seekIncoming(offset * Buf.PDU_HEX_OCTET_SIZE);
let rawData = {
width: GsmPDUHelper.readHexOctet(),
height: GsmPDUHelper.readHexOctet(),
codingScheme: codingScheme
};
switch (codingScheme) {
case ICC_IMG_CODING_SCHEME_BASIC:
rawData.body = GsmPDUHelper.readHexOctetArray(
dataLen - ICC_IMG_HEADER_SIZE_BASIC);
Buf.seekIncoming((octetLen - offset - dataLen) * Buf.PDU_HEX_OCTET_SIZE);
break;
case ICC_IMG_CODING_SCHEME_COLOR:
case ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY:
rawData.bitsPerImgPoint = GsmPDUHelper.readHexOctet();
let num = GsmPDUHelper.readHexOctet();
// The value 0 shall be interpreted as 256. See TS 31.102, Annex B.2.
rawData.numOfClutEntries = (num === 0) ? 0x100 : num;
rawData.clutOffset = (GsmPDUHelper.readHexOctet() << 8) |
GsmPDUHelper.readHexOctet();
rawData.body = GsmPDUHelper.readHexOctetArray(
dataLen - ICC_IMG_HEADER_SIZE_COLOR);
Buf.seekIncoming((rawData.clutOffset - offset - dataLen) *
Buf.PDU_HEX_OCTET_SIZE);
let clut = GsmPDUHelper.readHexOctetArray(rawData.numOfClutEntries *
ICC_CLUT_ENTRY_SIZE);
rawData.clut = clut;
}
Buf.readStringDelimiter(strLen);
if (onsuccess) {
onsuccess(rawData);
}
}
this.context.ICCIOHelper.loadTransparentEF({
fileId: fileId,
pathId: this.context.ICCFileHelper.getEFPath(ICC_EF_IMG),
callback: callback.bind(this),
onerror: onerror
});
},
/**
* Read the (U)SIM Service Table from the (U)SIM.
*/
@ -15297,6 +15729,110 @@ ICCContactHelperObject.prototype = {
},
};
function IconLoaderObject(aContext) {
this.context = aContext;
}
IconLoaderObject.prototype = {
context: null,
/**
* Load icons.
*
* @param recordNumbers Array of the record identifiers of EF_IMG.
* @param onsuccess Callback to be called when success.
* @param onerror Callback to be called when error.
*/
loadIcons: function(recordNumbers, onsuccess, onerror) {
if (!recordNumbers || !recordNumbers.length) {
if (onerror) {
onerror();
}
return;
}
this._start({
recordNumbers: recordNumbers,
onsuccess: onsuccess,
onerror: onerror});
},
_start: function(options) {
let callback = (function(icons) {
if (!options.icons) {
options.icons = [];
}
for (let i = 0; i < icons.length; i++) {
icons[i] = this._parseRawData(icons[i]);
}
options.icons[options.currentRecordIndex] = icons;
options.currentRecordIndex++;
let recordNumbers = options.recordNumbers;
if (options.currentRecordIndex < recordNumbers.length) {
let recordNumber = recordNumbers[options.currentRecordIndex];
this.context.SimRecordHelper.readIMG(recordNumber,
callback,
options.onerror);
} else {
if (options.onsuccess) {
options.onsuccess(options.icons);
}
}
}).bind(this);
options.currentRecordIndex = 0;
this.context.SimRecordHelper.readIMG(options.recordNumbers[0],
callback,
options.onerror);
},
_parseRawData: function(rawData) {
let codingScheme = rawData.codingScheme;
switch (codingScheme) {
case ICC_IMG_CODING_SCHEME_BASIC:
return {pixels: rawData.body,
width: rawData.width,
height: rawData.height};
case ICC_IMG_CODING_SCHEME_COLOR:
case ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY:
let bitsPerImgPoint = rawData.bitsPerImgPoint;
let mask = 0xff >> (8 - bitsPerImgPoint);
let bitsStartOffset = 8 - bitsPerImgPoint;
let bitIndex = bitsStartOffset;
let numOfClutEntries = rawData.numOfClutEntries;
let clut = rawData.clut;
let body = rawData.body;
let numOfPixels = rawData.width * rawData.height;
let pixelIndex = 0;
let currentByteIndex = 0;
let currentByte = body[currentByteIndex++];
let pixels = [];
while (pixelIndex < numOfPixels) {
// Reassign data and index for every byte (8 bits).
if (bitIndex < 0) {
currentByte = body[currentByteIndex++];
bitIndex = bitsStartOffset;
}
let clutEntry = ((currentByte >> bitIndex) & mask);
let clutIndex = clutEntry * ICC_CLUT_ENTRY_SIZE;
let alpha = codingScheme == ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY &&
clutEntry == numOfClutEntries - 1;
pixels[pixelIndex++] = {red: clut[clutIndex],
green: clut[clutIndex + 1],
blue: clut[clutIndex + 2],
alpha: alpha ? 0x00 : 0xff};
bitIndex -= bitsPerImgPoint;
}
return {pixels: pixels,
width: rawData.width,
height: rawData.height};
}
},
};
/**
* Global stuff.
*/
@ -15326,7 +15862,7 @@ Context.prototype = {
"ComprehensionTlvHelper", "GsmPDUHelper", "ICCContactHelper",
"ICCFileHelper", "ICCIOHelper", "ICCPDUHelper", "ICCRecordHelper",
"ICCUtilsHelper", "RuimRecordHelper", "SimRecordHelper",
"StkCommandParamsFactory", "StkProactiveCmdHelper",
"StkCommandParamsFactory", "StkProactiveCmdHelper", "IconLoader",
];
for (let i = 0; i < lazySymbols.length; i++) {

View File

@ -0,0 +1,869 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
function run_test() {
run_next_test();
}
/**
* Verify IconLoader.loadIcons with recordNumbers array length being 1.
* Query images of one record at a time.
*/
add_test(function test_load_icon_basic() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let ril = context.RIL;
let iconLoader = context.IconLoader;
let simRecordHelper = context.SimRecordHelper;
let test_data = [
{rawData: [
{codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
width: 0x10,
height: 0x10,
body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
expected: [
{width: 0x10,
height: 0x10,
pixels: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}]},
{rawData: [
{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
width: 0x10,
height: 0x10,
bitsPerImgPoint: 0x04,
numOfClutEntries: 0x10,
body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc,
0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf,
0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc,
0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc,
0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf,
0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99],
clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80,
0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80,
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff]}],
expected: [
{width: 0x10,
height: 0x10,
pixels: [
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff}]}]},
{rawData: [
{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
width: 0x03,
height: 0x03,
bitsPerImgPoint: 0x05,
numOfClutEntries: 0x20,
body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]},
{codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
width: 0x10,
height: 0x10,
body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
expected: [
{width: 0x03,
height: 0x03,
pixels: [
{red: 0x00, green: 0x01, blue: 0x02, alpha: 0xff},
{red: 0x06, green: 0x07, blue: 0x08, alpha: 0xff},
{red: 0x0c, green: 0x0d, blue: 0x0e, alpha: 0xff},
{red: 0x12, green: 0x13, blue: 0x14, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x33, green: 0x34, blue: 0x35, alpha: 0xff}]},
{width: 0x10,
height: 0x10,
pixels: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}]},
{rawData: [
{codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
width: 0x04,
height: 0x04,
bitsPerImgPoint: 0x04,
numOfClutEntries: 0x10,
body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88],
clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2d, 0x2e, 0x2f]}],
expected: [
{width: 0x04,
height: 0x04,
pixels: [
{red: 0x2d, green: 0x2e, blue: 0x2f, alpha: 0x00},
{red: 0x2d, green: 0x2e, blue: 0x2f, alpha: 0x00},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x27, green: 0x28, blue: 0x29, alpha: 0xff},
{red: 0x27, green: 0x28, blue: 0x29, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x21, green: 0x22, blue: 0x23, alpha: 0xff},
{red: 0x21, green: 0x22, blue: 0x23, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x1b, green: 0x1c, blue: 0x1d, alpha: 0xff},
{red: 0x1b, green: 0x1c, blue: 0x1d, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff}]}]}];
function do_test(test_data, expected) {
simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) {
onsuccess(test_data);
};
let onsuccess = function(icons) {
// Query one record at a time.
do_check_eq(icons.length, 1);
do_check_eq(icons[0].length, expected.length);
for (let i = 0; i < icons[0].length; i++) {
// Read the i_th image of the record.
let icon = icons[0][i];
let exp = expected[i];
do_check_eq(icon.width, exp.width);
do_check_eq(icon.height, exp.height);
do_check_eq(icon.pixels.length, exp.pixels.length);
for (let j = 0; j < icon.pixels.length; j++) {
if (typeof icon.pixels[j] === "object") {
do_check_eq(icon.pixels[j].red, exp.pixels[j].red);
do_check_eq(icon.pixels[j].green, exp.pixels[j].green);
do_check_eq(icon.pixels[j].blue, exp.pixels[j].blue);
do_check_eq(icon.pixels[j].alpha, exp.pixels[j].alpha);
} else {
do_check_eq(icon.pixels[j], exp.pixels[j]);
}
}
}
};
iconLoader.loadIcons([0], onsuccess);
}
for (let i = 0; i < test_data.length; i++) {
do_test(test_data[i].rawData, test_data[i].expected);
}
run_next_test();
});
/**
* Verify IconLoader.loadIcons.
*/
add_test(function test_load_icons() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let ril = context.RIL;
let iconLoader = context.IconLoader;
let simRecordHelper = context.SimRecordHelper;
let test_data = {
rawData: [
// Record 1.
[{codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
width: 0x10,
height: 0x10,
body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
// Record 2.
[{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
width: 0x10,
height: 0x10,
bitsPerImgPoint: 0x04,
numOfClutEntries: 0x10,
body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc,
0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf,
0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc,
0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc,
0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf,
0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99],
clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80,
0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80,
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff]}],
// Record 3.
[{codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
width: 0x03,
height: 0x03,
bitsPerImgPoint: 0x05,
numOfClutEntries: 0x20,
body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]},
{codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
width: 0x10,
height: 0x10,
body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
// Record 4.
[{codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
width: 0x04,
height: 0x04,
bitsPerImgPoint: 0x04,
numOfClutEntries: 0x10,
body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88],
clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2d, 0x2e, 0x2f]}]],
expected: [
// Record 1.
[{width: 0x10,
height: 0x10,
pixels: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
// Record 2.
[{width: 0x10,
height: 0x10,
pixels: [
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0x00, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0x00, green: 0xff, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0xff, blue: 0xff, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff},
{red: 0xff, green: 0x00, blue: 0x00, alpha: 0xff}]}],
// Record 3.
[{width: 0x03,
height: 0x03,
pixels: [
{red: 0x00, green: 0x01, blue: 0x02, alpha: 0xff},
{red: 0x06, green: 0x07, blue: 0x08, alpha: 0xff},
{red: 0x0c, green: 0x0d, blue: 0x0e, alpha: 0xff},
{red: 0x12, green: 0x13, blue: 0x14, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x33, green: 0x34, blue: 0x35, alpha: 0xff}]},
{width: 0x10,
height: 0x10,
pixels: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b,
0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff]}],
// Record 4.
[{width: 0x04,
height: 0x04,
pixels: [
{red: 0x2d, green: 0x2e, blue: 0x2f, alpha: 0x00},
{red: 0x2d, green: 0x2e, blue: 0x2f, alpha: 0x00},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x2a, green: 0x2b, blue: 0x2c, alpha: 0xff},
{red: 0x27, green: 0x28, blue: 0x29, alpha: 0xff},
{red: 0x27, green: 0x28, blue: 0x29, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x24, green: 0x25, blue: 0x26, alpha: 0xff},
{red: 0x21, green: 0x22, blue: 0x23, alpha: 0xff},
{red: 0x21, green: 0x22, blue: 0x23, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x1e, green: 0x1f, blue: 0x20, alpha: 0xff},
{red: 0x1b, green: 0x1c, blue: 0x1d, alpha: 0xff},
{red: 0x1b, green: 0x1c, blue: 0x1d, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff},
{red: 0x18, green: 0x19, blue: 0x1a, alpha: 0xff}]}]]};
function do_test() {
simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) {
onsuccess(test_data.rawData[recordNumber]);
};
let onsuccess = function(icons) {
do_check_eq(icons.length, test_data.expected.length);
for (let i = 0; i < icons.length; i++) {
for (let j = 0; j < icons[i].length; j++) {
// Read the j_th image from the i_th record.
let icon = icons[i][j];
let expected = test_data.expected[i][j];
do_check_eq(icon.width, expected.width);
do_check_eq(icon.height, expected.height);
do_check_eq(icon.pixels.length, expected.pixels.length);
for (let k = 0; k < icon.pixels.length; k++) {
if (typeof icon.pixels[k] === "object") {
do_check_eq(icon.pixels[k].red, expected.pixels[k].red);
do_check_eq(icon.pixels[k].green, expected.pixels[k].green);
do_check_eq(icon.pixels[k].blue, expected.pixels[k].blue);
do_check_eq(icon.pixels[k].alpha, expected.pixels[k].alpha);
} else {
do_check_eq(icon.pixels[k], expected.pixels[k]);
}
}
}
}
};
let recordNumbers = [0, 1, 2, 3];
iconLoader.loadIcons(recordNumbers, onsuccess);
}
do_test();
run_next_test();
});

View File

@ -602,3 +602,672 @@ add_test(function test_update_display_condition() {
run_next_test();
});
/**
* Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_BASIC
*/
add_test(function test_reading_img_basic() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
let test_data = [
{img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
iidf: [
[/* Header */
0x05, 0x05,
/* Image body */
0x11, 0x33, 0x55, 0xfe]],
expected: [
{width: 0x05,
height: 0x05,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x11, 0x33, 0x55, 0xfe]}]},
{img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10,
0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04],
iidf: [
[/* Data offset */
0xff, 0xff, 0xff, 0xff, 0xff,
/* Header */
0x10, 0x01,
/* Image body */
0x11, 0x99,
/* Trailing data */
0xff, 0xff, 0xff],
[/* Data offset */
0xff, 0xff, 0xff, 0xff, 0xff,
/* Header */
0x10, 0x01,
/* Image body */
0x99, 0x11]],
expected: [
{width: 0x10,
height: 0x01,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x11, 0x99]},
{width: 0x10,
height: 0x01,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x99, 0x11]}]},
{img: [0x01, 0x28, 0x20, 0x11, 0x4f, 0xac, 0x00, 0x0b, 0x00, 0xa2],
iidf: [
[/* Data offset */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Header */
0x28, 0x20,
/* Image body */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02,
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]],
expected: [
{width: 0x28,
height: 0x20,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]}]}];
function do_test(img, iidf, expected) {
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img.length * 2);
// Write data
for (let i = 0; i < img.length; i++) {
helper.writeHexOctet(img[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img.length * 2);
if (options.callback) {
options.callback(options);
}
};
let instanceIndex = 0;
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf[instanceIndex].length * 2);
// Write data
for (let i = 0; i < iidf[instanceIndex].length; i++) {
helper.writeHexOctet(iidf[instanceIndex][i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
instanceIndex++;
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function(icons) {
do_check_eq(icons.length, expected.length);
for (let i = 0; i < icons.length; i++) {
let icon = icons[i];
let exp = expected[i];
do_check_eq(icon.width, exp.width);
do_check_eq(icon.height, exp.height);
do_check_eq(icon.codingScheme, exp.codingScheme);
do_check_eq(icon.body.length, exp.body.length);
for (let j = 0; j < icon.body.length; j++) {
do_check_eq(icon.body[j], exp.body[j]);
}
}
};
record.readIMG(0, onsuccess);
}
for (let i = 0; i< test_data.length; i++) {
do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
}
run_next_test();
});
/**
* Verify reading EF_IMG and EF_IIDF with the case data length is not enough
*/
add_test(function test_reading_img_length_error() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
// Offset is 0x0004.
let img_test = [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06];
let iidf_test = [0xff, 0xff, 0xff, // Offset length not enough.
0x05, 0x05, 0x11, 0x22, 0x33, 0xfe];
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img_test.length * 2);
// Write data
for (let i = 0; i < img_test.length; i++) {
helper.writeHexOctet(img_test[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img_test.length * 2);
if (options.callback) {
options.callback(options);
}
};
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf_test.length * 2);
// Write data
for (let i = 0; i < iidf_test.length; i++) {
helper.writeHexOctet(iidf_test[i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf_test.length * 2);
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function() {
do_print("onsuccess shouldn't be called.");
do_check_true(false);
};
let onerror = function() {
do_print("onerror called as expected.");
do_check_true(true);
};
record.readIMG(0, onsuccess, onerror);
run_next_test();
});
/**
* Verify reading EF_IMG and EF_IIDF with an invalid fileId
*/
add_test(function test_reading_img_invalid_fileId() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
// Test invalid fileId: 0x5f00.
let img_test = [0x01, 0x05, 0x05, 0x11, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x06];
let iidf_test = [0x05, 0x05, 0x11, 0x22, 0x33, 0xfe];
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img_test.length * 2);
// Write data
for (let i = 0; i < img_test.length; i++) {
helper.writeHexOctet(img_test[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img_test.length * 2);
if (options.callback) {
options.callback(options);
}
};
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf_test.length * 2);
// Write data
for (let i = 0; i < iidf_test.length; i++) {
helper.writeHexOctet(iidf_test[i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf_test.length * 2);
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function() {
do_print("onsuccess shouldn't be called.");
do_check_true(false);
};
let onerror = function() {
do_print("onerror called as expected.");
do_check_true(true);
};
record.readIMG(0, onsuccess, onerror);
run_next_test();
});
/**
* Verify reading EF_IMG with a wrong record length
*/
add_test(function test_reading_img_wrong_record_length() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
let test_data = [
[0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06,
0xff, 0xff],
[0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]];
function do_test(img) {
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img.length * 2);
// Write data
for (let i = 0; i < img.length; i++) {
helper.writeHexOctet(img[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img.length * 2);
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function() {
do_print("onsuccess shouldn't be called.");
do_check_true(false);
};
let onerror = function() {
do_print("onerror called as expected.");
do_check_true(true);
};
record.readIMG(0, onsuccess, onerror);
}
for (let i = 0; i < test_data.length; i++) {
do_test(test_data[i]);
}
run_next_test();
});
/**
* Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_COLOR
*/
add_test(function test_reading_img_color() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
let test_data = [
{img: [0x01, 0x05, 0x05, 0x21, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
iidf: [
[/* Header */
0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
/* Image body */
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
0xb0, 0xc0, 0xd0,
/* Clut entries */
0x00, 0x01, 0x02,
0x10, 0x11, 0x12,
0x20, 0x21, 0x22,
0x30, 0x31, 0x32,
0x40, 0x41, 0x42,
0x50, 0x51, 0x52,
0x60, 0x61, 0x62,
0x70, 0x71, 0x72]],
expected: [
{width: 0x05,
height: 0x05,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
bitsPerImgPoint: 0x03,
numOfClutEntries: 0x08,
body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0,
0xc0, 0xd0],
clut: [0x00, 0x01, 0x02,
0x10, 0x11, 0x12,
0x20, 0x21, 0x22,
0x30, 0x31, 0x32,
0x40, 0x41, 0x42,
0x50, 0x51, 0x52,
0x60, 0x61, 0x62,
0x70, 0x71, 0x72]}]},
{img: [0x02, 0x01, 0x06, 0x21, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
0x06, 0x21, 0x4f, 0x44, 0x00, 0x02, 0x00, 0x08],
iidf: [
[/* Data offset */
0xff, 0xff,
/* Header */
0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
/* Image body */
0x40, 0x50,
/* Clut offset */
0xaa, 0xbb, 0xcc,
/* Clut entries */
0x01, 0x03, 0x05,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65],
[/* Data offset */
0xff, 0xff,
/* Header */
0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
/* Image body */
0x4f, 0x5f,
/* Clut offset */
0xaa, 0xbb, 0xcc,
/* Clut entries */
0x11, 0x13, 0x15,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]],
expected: [
{width: 0x01,
height: 0x06,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
bitsPerImgPoint: 0x02,
numOfClutEntries: 0x04,
body: [0x40, 0x50],
clut: [0x01, 0x03, 0x05,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]},
{width: 0x01,
height: 0x06,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR,
bitsPerImgPoint: 0x02,
numOfClutEntries: 0x04,
body: [0x4f, 0x5f],
clut: [0x11, 0x13, 0x15,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]}]}];
function do_test(img, iidf, expected) {
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img.length * 2);
// Write data
for (let i = 0; i < img.length; i++) {
helper.writeHexOctet(img[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img.length * 2);
if (options.callback) {
options.callback(options);
}
};
let instanceIndex = 0;
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf[instanceIndex].length * 2);
// Write data
for (let i = 0; i < iidf[instanceIndex].length; i++) {
helper.writeHexOctet(iidf[instanceIndex][i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
instanceIndex++;
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function(icons) {
do_check_eq(icons.length, expected.length);
for (let i = 0; i < icons.length; i++) {
let icon = icons[i];
let exp = expected[i];
do_check_eq(icon.width, exp.width);
do_check_eq(icon.height, exp.height);
do_check_eq(icon.codingScheme, exp.codingScheme);
do_check_eq(icon.body.length, exp.body.length);
for (let j = 0; j < icon.body.length; j++) {
do_check_eq(icon.body[j], exp.body[j]);
}
do_check_eq(icon.clut.length, exp.clut.length);
for (let j = 0; j < icon.clut.length; j++) {
do_check_eq(icon.clut[j], exp.clut[j]);
}
}
};
record.readIMG(0, onsuccess);
}
for (let i = 0; i< test_data.length; i++) {
do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
}
run_next_test();
});
/**
* Verify reading EF_IMG and EF_IIDF with
* ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY
*/
add_test(function test_reading_img_color() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let record = context.SimRecordHelper;
let helper = context.GsmPDUHelper;
let ril = context.RIL;
let buf = context.Buf;
let io = context.ICCIOHelper;
let test_data = [
{img: [0x01, 0x05, 0x05, 0x22, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13],
iidf: [
[/* Header */
0x05, 0x05, 0x03, 0x08, 0x00, 0x13,
/* Image body */
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0,
0xb0, 0xc0, 0xd0,
/* Clut entries */
0x00, 0x01, 0x02,
0x10, 0x11, 0x12,
0x20, 0x21, 0x22,
0x30, 0x31, 0x32,
0x40, 0x41, 0x42,
0x50, 0x51, 0x52,
0x60, 0x61, 0x62,
0x70, 0x71, 0x72]],
expected: [
{width: 0x05,
height: 0x05,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
bitsPerImgPoint: 0x03,
numOfClutEntries: 0x08,
body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,
0xa0, 0xb0, 0xc0, 0xd0],
clut: [0x00, 0x01, 0x02,
0x10, 0x11, 0x12,
0x20, 0x21, 0x22,
0x30, 0x31, 0x32,
0x40, 0x41, 0x42,
0x50, 0x51, 0x52,
0x60, 0x61, 0x62,
0x70, 0x71, 0x72]}]},
{img: [0x02, 0x01, 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01,
0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08],
iidf: [
[/* Data offset */
0xff, 0xff,
/* Header */
0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
/* Image body */
0x40, 0x50,
/* Clut offset */
0x0a, 0x0b, 0x0c,
/* Clut entries */
0x01, 0x03, 0x05,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65],
[/* Data offset */
0xff, 0xff,
/* Header */
0x01, 0x06, 0x02, 0x04, 0x00, 0x0d,
/* Image body */
0x4f, 0x5f,
/* Clut offset */
0x0a, 0x0b, 0x0c,
/* Clut entries */
0x11, 0x13, 0x15,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]],
expected: [
{width: 0x01,
height: 0x06,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
bitsPerImgPoint: 0x02,
numOfClutEntries: 0x04,
body: [0x40, 0x50],
clut: [0x01, 0x03, 0x05,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]},
{width: 0x01,
height: 0x06,
codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY,
bitsPerImgPoint: 0x02,
numOfClutEntries: 0x04,
body: [0x4f, 0x5f],
clut: [0x11, 0x13, 0x15,
0x21, 0x23, 0x25,
0x41, 0x43, 0x45,
0x61, 0x63, 0x65]}]}];
function do_test(img, iidf, expected) {
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img.length * 2);
// Write data
for (let i = 0; i < img.length; i++) {
helper.writeHexOctet(img[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img.length * 2);
if (options.callback) {
options.callback(options);
}
};
let instanceIndex = 0;
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf[instanceIndex].length * 2);
// Write data
for (let i = 0; i < iidf[instanceIndex].length; i++) {
helper.writeHexOctet(iidf[instanceIndex][i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf[instanceIndex].length * 2);
instanceIndex++;
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function(icons) {
do_check_eq(icons.length, expected.length);
for (let i = 0; i < icons.length; i++) {
let icon = icons[i];
let exp = expected[i];
do_check_eq(icon.width, exp.width);
do_check_eq(icon.height, exp.height);
do_check_eq(icon.codingScheme, exp.codingScheme);
do_check_eq(icon.body.length, exp.body.length);
for (let j = 0; j < icon.body.length; j++) {
do_check_eq(icon.body[j], exp.body[j]);
}
do_check_eq(icon.clut.length, exp.clut.length);
for (let j = 0; j < icon.clut.length; j++) {
do_check_eq(icon.clut[j], exp.clut[j]);
}
}
};
record.readIMG(0, onsuccess);
}
for (let i = 0; i< test_data.length; i++) {
do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected);
}
run_next_test();
});

View File

@ -414,15 +414,20 @@ add_test(function test_stk_proactive_command_play_tone() {
let pduHelper = context.GsmPDUHelper;
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let tone_1 = [
0xD0,
0x1B,
0x1F,
0x81, 0x03, 0x01, 0x20, 0x00,
0x82, 0x02, 0x81, 0x03,
0x85, 0x09, 0x44, 0x69, 0x61, 0x6C, 0x20, 0x54, 0x6F, 0x6E, 0x65,
0x8E, 0x01, 0x01,
0x84, 0x02, 0x01, 0x05];
0x84, 0x02, 0x01, 0x05,
0x9E, 0x02, 0x00, 0x01];
for (let i = 0; i < tone_1.length; i++) {
pduHelper.writeHexOctet(tone_1[i]);
@ -445,6 +450,10 @@ add_test(function test_stk_proactive_command_play_tone() {
do_check_eq(tlv.value.timeUnit, STK_TIME_UNIT_SECOND);
do_check_eq(tlv.value.timeInterval, 5);
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
run_next_test();
});
@ -492,15 +501,20 @@ add_test(function test_read_septets_to_string() {
let pduHelper = context.GsmPDUHelper;
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let display_text_1 = [
0xd0,
0x28,
0x2c,
0x81, 0x03, 0x01, 0x21, 0x80,
0x82, 0x02, 0x81, 0x02,
0x0d, 0x1d, 0x00, 0xd3, 0x30, 0x9b, 0xfc, 0x06, 0xc9, 0x5c, 0x30, 0x1a,
0xa8, 0xe8, 0x02, 0x59, 0xc3, 0xec, 0x34, 0xb9, 0xac, 0x07, 0xc9, 0x60,
0x2f, 0x58, 0xed, 0x15, 0x9b, 0xb9, 0x40,
0x9e, 0x02, 0x00, 0x01
];
for (let i = 0; i < display_text_1.length; i++) {
@ -512,6 +526,10 @@ add_test(function test_read_septets_to_string() {
let tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
do_check_eq(tlv.value.textString, "Saldo 2.04 E. Validez 20/05/13. ");
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
run_next_test();
});
@ -562,15 +580,20 @@ add_test(function test_stk_proactive_command_get_input() {
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let stkCmdHelper = context.StkCommandParamsFactory;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let get_input_1 = [
0xD0,
0x1E,
0x22,
0x81, 0x03, 0x01, 0x23, 0x8F,
0x82, 0x02, 0x81, 0x82,
0x8D, 0x05, 0x04, 0x54, 0x65, 0x78, 0x74,
0x91, 0x02, 0x01, 0x10,
0x17, 0x08, 0x04, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74];
0x17, 0x08, 0x04, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74,
0x9E, 0x02, 0x00, 0x01];
for (let i = 0; i < get_input_1.length; i++) {
pduHelper.writeHexOctet(get_input_1[i]);
@ -593,6 +616,10 @@ add_test(function test_stk_proactive_command_get_input() {
do_check_eq(input.maxLength, 0x10);
do_check_eq(input.defaultText, "Default");
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
let get_input_2 = [
0xD0,
0x11,
@ -661,10 +688,14 @@ add_test(function test_stk_proactive_command_select_item() {
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let stkFactory = context.StkCommandParamsFactory;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let select_item_1 = [
0xD0,
0x33,
0x3C,
0x81, 0x03, 0x01, 0x24, 0x00,
0x82, 0x02, 0x81, 0x82,
0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
@ -672,7 +703,9 @@ add_test(function test_stk_proactive_command_select_item() {
0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
0x18, 0x03, 0x10, 0x15, 0x20,
0x90, 0x01, 0x01
0x90, 0x01, 0x01,
0x9E, 0x02, 0x00, 0x01,
0x9F, 0x03, 0x00, 0x01, 0x02
];
for(let i = 0 ; i < select_item_1.length; i++) {
@ -699,6 +732,15 @@ add_test(function test_stk_proactive_command_select_item() {
do_check_eq(menu.nextActionList[2], STK_CMD_PLAY_TONE);
do_check_eq(menu.defaultItem, 0x00);
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID_LIST, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifiers[0], 0x01);
do_check_eq(tlv.value.identifiers[1], 0x02);
let select_item_2 = [
0xD0,
0x33,
@ -749,17 +791,23 @@ add_test(function test_stk_proactive_command_set_up_menu() {
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let stkFactory = context.StkCommandParamsFactory;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let set_up_menu_1 = [
0xD0,
0x30,
0x39,
0x81, 0x03, 0x01, 0x25, 0x00,
0x82, 0x02, 0x81, 0x82,
0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65,
0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31,
0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32,
0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33,
0x18, 0x03, 0x10, 0x15, 0x20
0x18, 0x03, 0x10, 0x15, 0x20,
0x9E, 0x02, 0x00, 0x01,
0x9F, 0x03, 0x00, 0x01, 0x02
];
for(let i = 0 ; i < set_up_menu_1.length; i++) {
@ -785,6 +833,15 @@ add_test(function test_stk_proactive_command_set_up_menu() {
do_check_eq(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER);
do_check_eq(menu.nextActionList[2], STK_CMD_PLAY_TONE);
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID_LIST, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifiers[0], 0x01);
do_check_eq(tlv.value.identifiers[1], 0x02);
let set_up_menu_2 = [
0xD0,
0x30,
@ -833,15 +890,20 @@ add_test(function test_stk_proactive_command_set_up_call() {
let berHelper = context.BerTlvHelper;
let stkHelper = context.StkProactiveCmdHelper;
let cmdFactory = context.StkCommandParamsFactory;
let ril = context.RIL;
ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10];
ril.appType = CARD_APPTYPE_SIM;
let set_up_call_1 = [
0xD0,
0x29,
0x2d,
0x81, 0x03, 0x01, 0x10, 0x04,
0x82, 0x02, 0x81, 0x82,
0x05, 0x0A, 0x44, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74,
0x86, 0x09, 0x81, 0x10, 0x32, 0x04, 0x21, 0x43, 0x65, 0x1C, 0x2C,
0x05, 0x07, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65];
0x05, 0x07, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x9E, 0x02, 0x00, 0x01];
for (let i = 0 ; i < set_up_call_1.length; i++) {
pduHelper.writeHexOctet(set_up_call_1[i]);
@ -858,6 +920,10 @@ add_test(function test_stk_proactive_command_set_up_call() {
do_check_eq(setupCall.confirmMessage, "Disconnect");
do_check_eq(setupCall.callMessage, "Message");
tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_ICON_ID, ctlvs);
do_check_eq(tlv.value.qualifier, 0x00);
do_check_eq(tlv.value.identifier, 0x01);
run_next_test();
});

View File

@ -10,6 +10,7 @@ tail =
[test_ril_worker_icc_ICCIOHelper.js]
[test_ril_worker_icc_ICCPDUHelper.js]
[test_ril_worker_icc_ICCRecordHelper.js]
[test_ril_worker_icc_IconLoader.js]
[test_ril_worker_icc_ICCUtilsHelper.js]
[test_ril_worker_icc_SimRecordHelper.js]
[test_ril_worker_sms.js]

View File

@ -366,6 +366,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Telephony)
// Telephony does not expose nsITelephonyListener. mListener is the exposed
// nsITelephonyListener and forwards the calls it receives to us.
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(Telephony, DOMEventTargetHelper)

View File

@ -24,10 +24,11 @@ namespace dom {
class OwningTelephonyCallOrTelephonyCallGroup;
class Telephony MOZ_FINAL : public DOMEventTargetHelper
class Telephony MOZ_FINAL : public DOMEventTargetHelper,
private nsITelephonyListener
{
/**
* Class Telephony doesn't actually inherit nsITelephonyListener.
* Class Telephony doesn't actually expose nsITelephonyListener.
* Instead, it owns an nsITelephonyListener derived instance mListener
* and passes it to nsITelephonyService. The onreceived events are first
* delivered to mListener and then forwarded to its owner, Telephony. See

View File

@ -69,6 +69,8 @@ Voicemail::~Voicemail()
mProvider->UnregisterVoicemailMsg(mListener);
}
NS_IMPL_ISUPPORTS_INHERITED0(Voicemail, DOMEventTargetHelper)
JSObject*
Voicemail::WrapObject(JSContext* aCx)
{

View File

@ -22,10 +22,11 @@ namespace dom {
class MozVoicemailStatus;
class Voicemail MOZ_FINAL : public DOMEventTargetHelper
class Voicemail MOZ_FINAL : public DOMEventTargetHelper,
private nsIVoicemailListener
{
/**
* Class Voicemail doesn't actually inherit nsIVoicemailListener. Instead, it
* Class Voicemail doesn't actually expose nsIVoicemailListener. Instead, it
* owns an nsIVoicemailListener derived instance mListener and passes it to
* nsIVoicemailProvider. The onreceived events are first delivered to
* mListener and then forwarded to its owner, Voicemail. See also bug 775997
@ -33,15 +34,16 @@ class Voicemail MOZ_FINAL : public DOMEventTargetHelper
*/
class Listener;
virtual ~Voicemail();
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIVOICEMAILLISTENER
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
Voicemail(nsPIDOMWindow* aWindow, nsIVoicemailProvider* aProvider);
virtual ~Voicemail();
nsPIDOMWindow*
GetParentObject() const
{

Some files were not shown because too many files have changed in this diff Show More