mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-06 22:53:08 +00:00
Bug 1009809 - Use ManifestHelper::biggestIconURL in the desktop app installer. r=myk,jmaher
--HG-- rename : toolkit/webapps/tests/test_hosted.xul => toolkit/webapps/tests/test_hosted_icons.xul rename : toolkit/webapps/tests/test_packaged.xul => toolkit/webapps/tests/test_packaged_icons.xul
This commit is contained in:
parent
f8d0d8a07d
commit
433a7a0683
@ -249,7 +249,7 @@ SimpleTest.is = function (a, b, name) {
|
||||
};
|
||||
|
||||
SimpleTest.isfuzzy = function (a, b, epsilon, name) {
|
||||
var pass = (a > b - epsilon) && (a < b + epsilon);
|
||||
var pass = (a >= b - epsilon) && (a <= b + epsilon);
|
||||
var diag = pass ? "" : "got " + repr(a) + ", expected " + repr(b) + " epsilon: +/- " + repr(epsilon)
|
||||
SimpleTest.ok(pass, name, diag);
|
||||
};
|
||||
|
@ -291,12 +291,23 @@ NativeApp.prototype = {
|
||||
_processIcon: function(aMimeType, aIcon, aDir) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let tmpIconPath = OS.Path.join(aDir, this.iconFile);
|
||||
|
||||
function conversionDone(aSubject, aTopic) {
|
||||
if (aTopic == "process-finished") {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
if (aTopic != "process-finished") {
|
||||
deferred.reject("Failure converting icon, exit code: " + aSubject.exitValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// SIPS silently fails to convert the icon, so we need to verify if the
|
||||
// icon was successfully converted.
|
||||
OS.File.exists(tmpIconPath).then((aExists) => {
|
||||
if (aExists) {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
deferred.reject("Failure converting icon, unrecognized image format");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let process = Cc["@mozilla.org/process/util;1"].
|
||||
@ -306,7 +317,7 @@ NativeApp.prototype = {
|
||||
process.init(sipsFile);
|
||||
process.runAsync(["-s", "format", "icns",
|
||||
aIcon.path,
|
||||
"--out", OS.Path.join(aDir, this.iconFile),
|
||||
"--out", tmpIconPath,
|
||||
"-z", "128", "128"],
|
||||
9, conversionDone);
|
||||
|
||||
|
@ -18,6 +18,8 @@ Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
const DEFAULT_ICON_URL = "chrome://global/skin/icons/webapps-64.png";
|
||||
|
||||
const ERR_NOT_INSTALLED = "The application isn't installed";
|
||||
const ERR_UPDATES_UNSUPPORTED_OLD_NAMING_SCHEME =
|
||||
"Updates for apps installed with the old naming scheme unsupported";
|
||||
@ -100,20 +102,8 @@ CommonNativeApp.prototype = {
|
||||
let manifest = new ManifestHelper(aManifest, this.app.origin);
|
||||
let origin = Services.io.newURI(this.app.origin, null, null);
|
||||
|
||||
let biggestIcon = getBiggestIconURL(manifest.icons);
|
||||
try {
|
||||
let iconURI = Services.io.newURI(biggestIcon, null, null);
|
||||
if (iconURI.scheme == "data") {
|
||||
this.iconURI = iconURI;
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
if (!this.iconURI) {
|
||||
try {
|
||||
this.iconURI = Services.io.newURI(origin.resolve(biggestIcon), null, null);
|
||||
}
|
||||
catch (ex) {}
|
||||
}
|
||||
this.iconURI = Services.io.newURI(manifest.biggestIconURL || DEFAULT_ICON_URL,
|
||||
null, null);
|
||||
|
||||
if (manifest.developer) {
|
||||
if (manifest.developer.name) {
|
||||
@ -406,5 +396,72 @@ function getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/* More helpers for handling the app icon */
|
||||
#include WebappsIconHelpers.js
|
||||
// Download an icon using either a temp file or a pipe.
|
||||
function downloadIcon(aIconURI) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
let mimeType;
|
||||
try {
|
||||
let tIndex = aIconURI.path.indexOf(";");
|
||||
if("data" == aIconURI.scheme && tIndex != -1) {
|
||||
mimeType = aIconURI.path.substring(0, tIndex);
|
||||
} else {
|
||||
mimeType = mimeService.getTypeFromURI(aIconURI);
|
||||
}
|
||||
} catch(e) {
|
||||
deferred.reject("Failed to determine icon MIME type: " + e);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onIconDownloaded(aStatusCode, aIcon) {
|
||||
if (Components.isSuccessCode(aStatusCode)) {
|
||||
deferred.resolve([ mimeType, aIcon ]);
|
||||
} else {
|
||||
deferred.reject("Failure downloading icon: " + aStatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
#ifdef XP_MACOSX
|
||||
let downloadObserver = {
|
||||
onDownloadComplete: function(downloader, request, cx, aStatus, file) {
|
||||
onIconDownloaded(aStatus, file);
|
||||
}
|
||||
};
|
||||
|
||||
let tmpIcon = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
tmpIcon.append("tmpicon." + mimeService.getPrimaryExtension(mimeType, ""));
|
||||
tmpIcon.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
|
||||
let listener = Cc["@mozilla.org/network/downloader;1"]
|
||||
.createInstance(Ci.nsIDownloader);
|
||||
listener.init(downloadObserver, tmpIcon);
|
||||
#else
|
||||
let pipe = Cc["@mozilla.org/pipe;1"]
|
||||
.createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, 0xffffffff, null);
|
||||
|
||||
let listener = Cc["@mozilla.org/network/simple-stream-listener;1"]
|
||||
.createInstance(Ci.nsISimpleStreamListener);
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest: function() {},
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
pipe.outputStream.close();
|
||||
onIconDownloaded(aStatusCode, pipe.inputStream);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
let channel = NetUtil.newChannel(aIconURI);
|
||||
let { BadCertHandler } = Cu.import("resource://gre/modules/CertUtils.jsm", {});
|
||||
// Pass true to avoid optional redirect-cert-checking behavior.
|
||||
channel.notificationCallbacks = new BadCertHandler(true);
|
||||
|
||||
channel.asyncOpen(listener, null);
|
||||
} catch(e) {
|
||||
deferred.reject("Failure initiating download of icon: " + e);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
const DEFAULT_ICON_URL = "chrome://global/skin/icons/webapps-64.png";
|
||||
|
||||
/**
|
||||
* This function receives a list of icon sizes
|
||||
* and URLs and returns the url string for the biggest icon.
|
||||
*
|
||||
* @param aIcons An object where the keys are the icon sizes
|
||||
* and the values are URL strings. E.g.:
|
||||
* aIcons = {
|
||||
* "16": "http://www.example.org/icon16.png",
|
||||
* "32": "http://www.example.org/icon32.png"
|
||||
* };
|
||||
*
|
||||
* @returns the URL string for the largest specified icon
|
||||
*/
|
||||
function getBiggestIconURL(aIcons) {
|
||||
if (!aIcons) {
|
||||
return DEFAULT_ICON_URL;
|
||||
}
|
||||
|
||||
let iconSizes = Object.keys(aIcons);
|
||||
if (iconSizes.length == 0) {
|
||||
return DEFAULT_ICON_URL;
|
||||
}
|
||||
iconSizes.sort(function(a, b) a - b);
|
||||
return aIcons[iconSizes.pop()];
|
||||
}
|
||||
|
||||
// Download an icon using either a temp file or a pipe.
|
||||
function downloadIcon(aIconURI) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
let mimeType;
|
||||
try {
|
||||
let tIndex = aIconURI.path.indexOf(";");
|
||||
if("data" == aIconURI.scheme && tIndex != -1) {
|
||||
mimeType = aIconURI.path.substring(0, tIndex);
|
||||
} else {
|
||||
mimeType = mimeService.getTypeFromURI(aIconURI);
|
||||
}
|
||||
} catch(e) {
|
||||
deferred.reject("Failed to determine icon MIME type: " + e);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onIconDownloaded(aStatusCode, aIcon) {
|
||||
if (Components.isSuccessCode(aStatusCode)) {
|
||||
deferred.resolve([ mimeType, aIcon ]);
|
||||
} else {
|
||||
deferred.reject("Failure downloading icon: " + aStatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
#ifdef XP_MACOSX
|
||||
let downloadObserver = {
|
||||
onDownloadComplete: function(downloader, request, cx, aStatus, file) {
|
||||
onIconDownloaded(aStatus, file);
|
||||
}
|
||||
};
|
||||
|
||||
let tmpIcon = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
tmpIcon.append("tmpicon." + mimeService.getPrimaryExtension(mimeType, ""));
|
||||
tmpIcon.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
|
||||
let listener = Cc["@mozilla.org/network/downloader;1"]
|
||||
.createInstance(Ci.nsIDownloader);
|
||||
listener.init(downloadObserver, tmpIcon);
|
||||
#else
|
||||
let pipe = Cc["@mozilla.org/pipe;1"]
|
||||
.createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, 0xffffffff, null);
|
||||
|
||||
let listener = Cc["@mozilla.org/network/simple-stream-listener;1"]
|
||||
.createInstance(Ci.nsISimpleStreamListener);
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest: function() {},
|
||||
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||
pipe.outputStream.close();
|
||||
onIconDownloaded(aStatusCode, pipe.inputStream);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
let channel = NetUtil.newChannel(aIconURI);
|
||||
let { BadCertHandler } = Cu.import("resource://gre/modules/CertUtils.jsm", {});
|
||||
// Pass true to avoid optional redirect-cert-checking behavior.
|
||||
channel.notificationCallbacks = new BadCertHandler(true);
|
||||
|
||||
channel.asyncOpen(listener, null);
|
||||
} catch(e) {
|
||||
deferred.reject("Failure initiating download of icon: " + e);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
@ -3,6 +3,7 @@ support-files =
|
||||
head.js
|
||||
app.sjs
|
||||
data/app/index.html
|
||||
data/icon.png
|
||||
|
||||
[test_hosted.xul]
|
||||
[test_packaged.xul]
|
||||
@ -18,3 +19,5 @@ skip-if = asan
|
||||
skip-if = asan
|
||||
[test_packaged_update_from_webapp_runtime.xul]
|
||||
skip-if = asan
|
||||
[test_hosted_icons.xul]
|
||||
[test_packaged_icons.xul]
|
||||
|
BIN
toolkit/webapps/tests/data/icon.png
Normal file
BIN
toolkit/webapps/tests/data/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
@ -13,6 +13,10 @@ const MAC = navigator.platform.startsWith("Mac");
|
||||
const WIN = navigator.platform.startsWith("Win");
|
||||
const MAC_106 = navigator.userAgent.contains("Mac OS X 10.6");
|
||||
|
||||
const PR_RDWR = 0x04;
|
||||
const PR_CREATE_FILE = 0x08;
|
||||
const PR_TRUNCATE = 0x20;
|
||||
|
||||
function checkFiles(files) {
|
||||
return Task.spawn(function*() {
|
||||
for (let file of files) {
|
||||
@ -90,6 +94,8 @@ function TestAppInfo(aApp) {
|
||||
"." + WebappOSUtils.getUniqueName(aApp));
|
||||
this.exePath = OS.Path.join(this.installPath, "webapprt-stub");
|
||||
|
||||
this.iconFile = OS.Path.join(this.installPath, "icon.png");
|
||||
|
||||
let xdg_data_home = Cc["@mozilla.org/process/environment;1"].
|
||||
getService(Ci.nsIEnvironment).
|
||||
get("XDG_DATA_HOME");
|
||||
@ -101,9 +107,9 @@ function TestAppInfo(aApp) {
|
||||
"owa-" + WebappOSUtils.getUniqueName(aApp) + ".desktop");
|
||||
|
||||
this.installedFiles = [
|
||||
OS.Path.join(this.installPath, "icon.png"),
|
||||
OS.Path.join(this.installPath, "webapp.json"),
|
||||
OS.Path.join(this.installPath, "webapp.ini"),
|
||||
this.iconFile,
|
||||
this.exePath,
|
||||
desktopINI,
|
||||
];
|
||||
@ -113,9 +119,9 @@ function TestAppInfo(aApp) {
|
||||
OS.Path.join(this.installPath, "update", "webapp.ini"),
|
||||
];
|
||||
this.updatedFiles = [
|
||||
OS.Path.join(this.installPath, "icon.png"),
|
||||
OS.Path.join(this.installPath, "webapp.json"),
|
||||
OS.Path.join(this.installPath, "webapp.ini"),
|
||||
this.iconFile,
|
||||
desktopINI,
|
||||
];
|
||||
|
||||
@ -146,18 +152,20 @@ function TestAppInfo(aApp) {
|
||||
WebappOSUtils.getUniqueName(aApp));
|
||||
this.exePath = OS.Path.join(this.installPath, aApp.name + ".exe");
|
||||
|
||||
this.iconFile = OS.Path.join(this.installPath, "chrome", "icons", "default", "default.ico");
|
||||
|
||||
let desktopShortcut = OS.Path.join(OS.Constants.Path.desktopDir,
|
||||
aApp.name + ".lnk");
|
||||
let startMenuShortcut = OS.Path.join(OS.Constants.Path.winStartMenuProgsDir,
|
||||
aApp.name + ".lnk");
|
||||
|
||||
this.installedFiles = [
|
||||
OS.Path.join(this.installPath, "chrome", "icons", "default", "default.ico"),
|
||||
OS.Path.join(this.installPath, "webapp.json"),
|
||||
OS.Path.join(this.installPath, "webapp.ini"),
|
||||
OS.Path.join(this.installPath, "uninstall", "shortcuts_log.ini"),
|
||||
OS.Path.join(this.installPath, "uninstall", "uninstall.log"),
|
||||
OS.Path.join(this.installPath, "uninstall", "webapp-uninstaller.exe"),
|
||||
this.iconFile,
|
||||
this.exePath,
|
||||
desktopShortcut,
|
||||
startMenuShortcut,
|
||||
@ -171,11 +179,11 @@ function TestAppInfo(aApp) {
|
||||
OS.Path.join(this.installPath, "update", "uninstall", "webapp-uninstaller.exe"),
|
||||
];
|
||||
this.updatedFiles = [
|
||||
OS.Path.join(this.installPath, "chrome", "icons", "default", "default.ico"),
|
||||
OS.Path.join(this.installPath, "webapp.json"),
|
||||
OS.Path.join(this.installPath, "webapp.ini"),
|
||||
OS.Path.join(this.installPath, "uninstall", "shortcuts_log.ini"),
|
||||
OS.Path.join(this.installPath, "uninstall", "uninstall.log"),
|
||||
this.iconFile,
|
||||
desktopShortcut,
|
||||
startMenuShortcut,
|
||||
];
|
||||
@ -238,6 +246,8 @@ function TestAppInfo(aApp) {
|
||||
aApp.name + ".app");
|
||||
this.exePath = OS.Path.join(this.installPath, "Contents", "MacOS", "webapprt");
|
||||
|
||||
this.iconFile = OS.Path.join(this.installPath, "Contents", "Resources", "appicon.icns");
|
||||
|
||||
let appProfileDir = OS.Path.join(OS.Constants.Path.macUserLibDir,
|
||||
"Application Support",
|
||||
WebappOSUtils.getUniqueName(aApp));
|
||||
@ -245,8 +255,8 @@ function TestAppInfo(aApp) {
|
||||
this.installedFiles = [
|
||||
OS.Path.join(this.installPath, "Contents", "Info.plist"),
|
||||
OS.Path.join(this.installPath, "Contents", "MacOS", "webapp.ini"),
|
||||
OS.Path.join(this.installPath, "Contents", "Resources", "appicon.icns"),
|
||||
OS.Path.join(appProfileDir, "webapp.json"),
|
||||
this.iconFile,
|
||||
this.exePath,
|
||||
];
|
||||
this.tempUpdatedFiles = [
|
||||
@ -258,8 +268,8 @@ function TestAppInfo(aApp) {
|
||||
this.updatedFiles = [
|
||||
OS.Path.join(this.installPath, "Contents", "Info.plist"),
|
||||
OS.Path.join(this.installPath, "Contents", "MacOS", "webapp.ini"),
|
||||
OS.Path.join(this.installPath, "Contents", "Resources", "appicon.icns"),
|
||||
OS.Path.join(appProfileDir, "webapp.json"),
|
||||
this.iconFile,
|
||||
];
|
||||
|
||||
if (this.isPackaged) {
|
||||
@ -287,7 +297,7 @@ function TestAppInfo(aApp) {
|
||||
}
|
||||
}
|
||||
|
||||
function buildAppPackage(aManifest) {
|
||||
function buildAppPackage(aManifest, aIconFile) {
|
||||
let zipFile = getFile(OS.Constants.Path.profileDir, "sample.zip");
|
||||
|
||||
let zipWriter = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
|
||||
@ -303,6 +313,14 @@ function buildAppPackage(aManifest) {
|
||||
zipWriter.addEntryStream("manifest.webapp", Date.now(),
|
||||
Ci.nsIZipWriter.COMPRESSION_NONE,
|
||||
manStream, false);
|
||||
|
||||
if (aIconFile) {
|
||||
zipWriter.addEntryFile(aIconFile.leafName,
|
||||
Ci.nsIZipWriter.COMPRESSION_NONE,
|
||||
aIconFile,
|
||||
false);
|
||||
}
|
||||
|
||||
zipWriter.close();
|
||||
|
||||
return zipFile.path;
|
||||
@ -326,3 +344,20 @@ function wasAppSJSAccessed() {
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function generateDataURI(aFile) {
|
||||
var contentType = Cc["@mozilla.org/mime;1"].
|
||||
getService(Ci.nsIMIMEService).
|
||||
getTypeFromFile(aFile);
|
||||
|
||||
var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
inputStream.init(aFile, -1, -1, Ci.nsIFileInputStream.CLOSE_ON_EOF);
|
||||
|
||||
var stream = Cc["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Ci.nsIBinaryInputStream);
|
||||
stream.setInputStream(inputStream);
|
||||
|
||||
return "data:" + contentType + ";base64," +
|
||||
btoa(stream.readBytes(stream.available()));
|
||||
}
|
||||
|
159
toolkit/webapps/tests/test_hosted_icons.xul
Normal file
159
toolkit/webapps/tests/test_hosted_icons.xul
Normal file
@ -0,0 +1,159 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=898647
|
||||
-->
|
||||
<window title="Mozilla Bug 898647"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript" src="head.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=898647"
|
||||
target="_blank">Mozilla Bug 898647</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 898647 **/
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/NativeApp.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
|
||||
let manifest = {
|
||||
name: "Sample hosted app",
|
||||
};
|
||||
|
||||
let app = {
|
||||
name: "Sample hosted app",
|
||||
manifestURL: "http://example.com/sample.manifest",
|
||||
manifest: manifest,
|
||||
origin: "http://example.com/",
|
||||
categories: [],
|
||||
installOrigin: "http://example.com/",
|
||||
receipts: [],
|
||||
installTime: Date.now(),
|
||||
};
|
||||
|
||||
let iconTests = [
|
||||
// No icon specified
|
||||
{},
|
||||
// Absolute URI
|
||||
{"32": "http://example.com/chrome/toolkit/webapps/tests/data/icon.png"},
|
||||
// Relative URI
|
||||
{"32": "/chrome/toolkit/webapps/tests/data/icon.png"},
|
||||
// Data URI icon
|
||||
{"32": generateDataURI(getFile(getTestFilePath("data/icon.png"))) },
|
||||
// URI to a file that isn't an image
|
||||
{"32": "/chrome/toolkit/webapps/tests/data/app/index.html"},
|
||||
];
|
||||
|
||||
// This is an array of the icon sizes associated with the elements of
|
||||
// iconTests. Each element in the iconSizes array is an array of two values:
|
||||
// - The expected size of the icon
|
||||
// - An epsilon value that defines an accepted range around the icon size.
|
||||
// On each platform the size is different (because the format of the file is
|
||||
// different: ICO on Windows, PNG on Linux, ICNS on Mac).
|
||||
// The epsilon value is 0 on Windows and Linux, where the size of the file
|
||||
// is precise (because we convert the icons with our own code). It is ~0 on
|
||||
// Mac because we use SIPS to convert the icon, and its output isn't
|
||||
// the same across Mac versions.
|
||||
|
||||
let iconSizes;
|
||||
|
||||
if (LINUX) {
|
||||
iconSizes = [
|
||||
[4009, 0],
|
||||
[2787, 0],
|
||||
[2787, 0],
|
||||
[2787, 0],
|
||||
[4009, 0],
|
||||
];
|
||||
} else if (WIN) {
|
||||
iconSizes = [
|
||||
[16958, 0],
|
||||
[4286, 0],
|
||||
[4286, 0],
|
||||
[4286, 0],
|
||||
[16958, 0],
|
||||
];
|
||||
} else if (MAC) {
|
||||
iconSizes = [
|
||||
[14000, 2000],
|
||||
[27000, 2000],
|
||||
[27000, 2000],
|
||||
[27000, 2000],
|
||||
[14000, 2000],
|
||||
];
|
||||
}
|
||||
|
||||
let testAppInfo = new TestAppInfo(app);
|
||||
|
||||
let runTest = Task.async(function*() {
|
||||
SimpleTest.registerCleanupFunction(() => testAppInfo.cleanup());
|
||||
|
||||
setDryRunPref();
|
||||
|
||||
for (let curTest = 0; curTest < iconTests.length; curTest++) {
|
||||
// Get to a clean state before the test
|
||||
yield testAppInfo.cleanup();
|
||||
|
||||
manifest.icons = iconTests[curTest];
|
||||
info("Test icon: " + JSON.stringify(manifest.icons));
|
||||
|
||||
let nativeApp = new NativeApp(app, manifest, app.categories);
|
||||
ok(nativeApp, "NativeApp object created");
|
||||
|
||||
testAppInfo.profileDir = nativeApp.createProfile();
|
||||
ok(testAppInfo.profileDir && testAppInfo.profileDir.exists(), "Profile directory created");
|
||||
ok((yield OS.File.exists(testAppInfo.profilesIni)), "profiles.ini file created");
|
||||
|
||||
// On Mac build servers, we don't have enough privileges to write to /Applications,
|
||||
// so we install apps in a user-owned directory.
|
||||
if (MAC) {
|
||||
nativeApp._rootInstallDir = OS.Path.join(OS.Constants.Path.homeDir, "Applications");
|
||||
yield OS.File.makeDir(nativeApp._rootInstallDir, { ignoreExisting: true });
|
||||
}
|
||||
|
||||
// Install application
|
||||
info("Test installation");
|
||||
yield nativeApp.install(manifest);
|
||||
while (!WebappOSUtils.isLaunchable(app)) {
|
||||
yield wait(1000);
|
||||
}
|
||||
ok(true, "App launchable");
|
||||
|
||||
let stat = yield OS.File.stat(testAppInfo.iconFile);
|
||||
isfuzzy(stat.size, iconSizes[curTest][0], iconSizes[curTest][1],
|
||||
"Icon size correct");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
// The test doesn't work yet on Mac OS X 10.6 machines.
|
||||
// See bug 993690.
|
||||
if (MAC_106) {
|
||||
todo(false, "The test doesn't work on Mac OS X 10.6 machines");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
runTest().then(null, function(e) {
|
||||
ok(false, "Error during test: " + e);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
172
toolkit/webapps/tests/test_packaged_icons.xul
Normal file
172
toolkit/webapps/tests/test_packaged_icons.xul
Normal file
@ -0,0 +1,172 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=898647
|
||||
-->
|
||||
<window title="Mozilla Bug 898647"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript" src="head.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=898647"
|
||||
target="_blank">Mozilla Bug 898647</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 898647 **/
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/NativeApp.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
|
||||
let zipPath = OS.Path.join(OS.Constants.Path.profileDir, "sample.zip");
|
||||
|
||||
let manifest = {
|
||||
name: "Sample packaged app",
|
||||
version: "0.1a",
|
||||
size: 777,
|
||||
package_path: "/sample.zip",
|
||||
};
|
||||
|
||||
let app = {
|
||||
name: "Sample packaged app",
|
||||
manifestURL: "http://example.com/sample.manifest",
|
||||
manifest: manifest,
|
||||
updateManifest: manifest,
|
||||
origin: "app://test_desktop_packaged_launch/",
|
||||
categories: [],
|
||||
installOrigin: "http://example.com/",
|
||||
receipts: [],
|
||||
installTime: Date.now(),
|
||||
};
|
||||
|
||||
let testIconFile = getFile(getTestFilePath("data/icon.png"));
|
||||
|
||||
let iconTests = [
|
||||
// No icon specified
|
||||
{},
|
||||
// Absolute URI
|
||||
{"32": "http://example.com/chrome/toolkit/webapps/tests/data/icon.png"},
|
||||
// Relative URI
|
||||
{"32": "/icon.png"},
|
||||
// Data URI icon
|
||||
{"32": generateDataURI(testIconFile) },
|
||||
// URI to a file that isn't an image
|
||||
{"32": "/index.html"},
|
||||
];
|
||||
|
||||
// This is an array of the icon sizes associated with the elements of
|
||||
// iconTests. Each element in the iconSizes array is an array of two values:
|
||||
// - The expected size of the icon
|
||||
// - An epsilon value that defines an accepted range around the icon size.
|
||||
// On each platform the size is different (because the format of the file is
|
||||
// different: ICO on Windows, PNG on Linux, ICNS on Mac).
|
||||
// The epsilon value is 0 on Windows and Linux, where the size of the file
|
||||
// is precise (because we convert the icons with our own code). It is ~0 on
|
||||
// Mac because we use SIPS to convert the icon, and its output isn't
|
||||
// the same across Mac versions.
|
||||
|
||||
let iconSizes;
|
||||
|
||||
if (LINUX) {
|
||||
iconSizes = [
|
||||
[4009, 0],
|
||||
[2787, 0],
|
||||
[2787, 0],
|
||||
[2787, 0],
|
||||
[4009, 0],
|
||||
];
|
||||
} else if (WIN) {
|
||||
iconSizes = [
|
||||
[16958, 0],
|
||||
[4286, 0],
|
||||
[4286, 0],
|
||||
[4286, 0],
|
||||
[16958, 0],
|
||||
];
|
||||
} else if (MAC) {
|
||||
iconSizes = [
|
||||
[14000, 2000],
|
||||
[27000, 2000],
|
||||
[27000, 2000],
|
||||
[27000, 2000],
|
||||
[14000, 2000],
|
||||
];
|
||||
}
|
||||
|
||||
let testAppInfo = new TestAppInfo(app);
|
||||
|
||||
let runTest = Task.async(function*() {
|
||||
SimpleTest.registerCleanupFunction(() => testAppInfo.cleanup());
|
||||
|
||||
setDryRunPref();
|
||||
|
||||
for (let curTest = 0; curTest < iconTests.length; curTest++) {
|
||||
// Get to a clean state before the test
|
||||
yield testAppInfo.cleanup();
|
||||
|
||||
manifest.icons = iconTests[curTest];
|
||||
info("Test icon: " + JSON.stringify(manifest.icons));
|
||||
|
||||
let zipPath = buildAppPackage(manifest, testIconFile);
|
||||
|
||||
let nativeApp = new NativeApp(app, manifest, app.categories);
|
||||
ok(nativeApp, "NativeApp object created");
|
||||
|
||||
testAppInfo.profileDir = nativeApp.createProfile();
|
||||
ok(testAppInfo.profileDir && testAppInfo.profileDir.exists(), "Profile directory created");
|
||||
ok((yield OS.File.exists(testAppInfo.profilesIni)), "profiles.ini file created");
|
||||
|
||||
// On Mac build servers, we don't have enough privileges to write to /Applications,
|
||||
// so we install apps in a user-owned directory.
|
||||
if (MAC) {
|
||||
nativeApp._rootInstallDir = OS.Path.join(OS.Constants.Path.homeDir, "Applications");
|
||||
yield OS.File.makeDir(nativeApp._rootInstallDir, { ignoreExisting: true });
|
||||
}
|
||||
|
||||
// Install application
|
||||
info("Test installation");
|
||||
yield nativeApp.install(manifest, zipPath);
|
||||
while (!WebappOSUtils.isLaunchable(app)) {
|
||||
yield wait(1000);
|
||||
}
|
||||
ok(true, "App launchable");
|
||||
|
||||
let stat = yield OS.File.stat(testAppInfo.iconFile);
|
||||
isfuzzy(stat.size, iconSizes[curTest][0], iconSizes[curTest][1],
|
||||
"Icon size correct");
|
||||
|
||||
// Flush the ZipReaderCache (so that the application.zip file gets closed)
|
||||
Services.obs.notifyObservers(null, "chrome-flush-caches", null);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
// The test doesn't work yet on Mac OS X 10.6 machines.
|
||||
// See bug 993690.
|
||||
if (MAC_106) {
|
||||
todo(false, "The test doesn't work on Mac OS X 10.6 machines");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
runTest().then(null, function(e) {
|
||||
ok(false, "Error during test: " + e);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -32,10 +32,6 @@ Cu.import("resource://gre/modules/NativeApp.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
const PR_RDWR = 0x04;
|
||||
const PR_CREATE_FILE = 0x08;
|
||||
const PR_TRUNCATE = 0x20;
|
||||
|
||||
let manifest = {
|
||||
name: "test_desktop_packaged_launch",
|
||||
version: "0.1a",
|
||||
|
@ -32,10 +32,6 @@ Cu.import("resource://gre/modules/NativeApp.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
const PR_RDWR = 0x04;
|
||||
const PR_CREATE_FILE = 0x08;
|
||||
const PR_TRUNCATE = 0x20;
|
||||
|
||||
let manifest = {
|
||||
name: "test_desktop_packaged_launch_no_registry",
|
||||
version: "0.1a",
|
||||
|
@ -32,10 +32,6 @@ Cu.import("resource://gre/modules/NativeApp.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
const PR_RDWR = 0x04;
|
||||
const PR_CREATE_FILE = 0x08;
|
||||
const PR_TRUNCATE = 0x20;
|
||||
|
||||
let manifest = {
|
||||
name: "test_desktop_packaged_launch",
|
||||
version: "0.1a",
|
||||
|
Loading…
x
Reference in New Issue
Block a user