This commit is contained in:
Ryan VanderMeulen 2013-05-06 11:20:45 -04:00
Родитель 1f865993c0 a99c4571dd
Коммит 765b164af0
25 изменённых файлов: 578 добавлений и 128 удалений

Просмотреть файл

@ -156,9 +156,13 @@ endif # SKIP_COPY_XULRUNNER
$(NSINSTALL) -D $(DIST)/bin/chrome/icons/default
# Copy the app icon for b2g-desktop
ifeq ($(OS_ARCH),WINNT)
cp $(srcdir)/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/$(APP_ICON).ico
$(REDIT_PATH)/redit$(HOST_BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY) $(srcdir)/$(APP_ICON).ico
cp $(srcdir)/$(APP_ICON).ico $(DIST)/bin/chrome/icons/default/default.ico
else ifneq (gonk,$(MOZ_WIDGET_TOOLKIT))
cp $(srcdir)/default.png $(DIST)/bin/chrome/icons/default/default.png
endif
endif

Двоичные данные
b2g/app/b2g.ico

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.2 KiB

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Просмотреть файл

@ -381,7 +381,6 @@ pref("dom.ipc.browser_frames.oop_by_default", false);
// Temporary permission hack for WebSMS
pref("dom.sms.enabled", true);
pref("dom.sms.strict7BitEncoding", false); // Disabled by default.
pref("dom.sms.requestStatusReport", false); // Disabled by default.
// Temporary permission hack for WebContacts
pref("dom.mozContacts.enabled", true);

Двоичные данные
b2g/app/default.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Просмотреть файл

@ -8,6 +8,12 @@ let Cu = Components.utils;
let Cc = Components.classes;
let Ci = Components.interfaces;
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
function debug(aMsg) {
/*
Cc["@mozilla.org/consoleservice;1"]
@ -32,6 +38,7 @@ WebappsActor.prototype = {
actorPrefix: "webapps",
_registerApp: function wa_actorRegisterApp(aApp, aId, aDir) {
debug("registerApp");
let reg = DOMApplicationRegistry;
let self = this;
@ -49,8 +56,12 @@ WebappsActor.prototype = {
reg._readManifests([{ id: aId }], function(aResult) {
let manifest = aResult[0].manifest;
aApp.name = manifest.name;
reg._registerSystemMessages(manifest, aApp);
reg._registerActivities(manifest, aApp, true);
if ("_registerSystemMessages" in reg) {
reg._registerSystemMessages(manifest, aApp);
}
if ("_registerActivities" in reg) {
reg._registerActivities(manifest, aApp, true);
}
reg._saveApps(function() {
aApp.manifest = manifest;
reg.broadcastMessage("Webapps:AddApp", { id: aId, app: aApp });
@ -237,10 +248,6 @@ WebappsActor.prototype = {
install: function wa_actorInstall(aRequest) {
debug("install");
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
let appId = aRequest.appId;
if (!appId) {
return { error: "missingParameter",
@ -289,6 +296,87 @@ WebappsActor.prototype = {
}
return { appId: appId, path: appDir.path }
},
getAll: function wa_actorGetAll(aRequest) {
debug("getAll");
let defer = Promise.defer();
let reg = DOMApplicationRegistry;
reg.getAll(function onsuccess(apps) {
defer.resolve({ apps: apps });
});
return defer.promise;
},
uninstall: function wa_actorUninstall(aRequest) {
debug("uninstall");
let manifestURL = aRequest.manifestURL;
if (!manifestURL) {
return { error: "missingParameter",
message: "missing parameter manifestURL" };
}
let defer = Promise.defer();
let reg = DOMApplicationRegistry;
reg.uninstall(
manifestURL,
function onsuccess() {
defer.resolve({});
},
function onfailure(reason) {
defer.resolve({ error: reason });
}
);
return defer.promise;
},
launch: function wa_actorLaunch(aRequest) {
debug("launch");
let manifestURL = aRequest.manifestURL;
if (!manifestURL) {
return { error: "missingParameter",
message: "missing parameter manifestURL" };
}
let defer = Promise.defer();
let reg = DOMApplicationRegistry;
reg.launch(
aRequest.manifestURL,
aRequest.startPoint || "",
function onsuccess() {
defer.resolve({});
},
function onfailure(reason) {
defer.resolve({ error: reason });
});
return defer.promise;
},
close: function wa_actorLaunch(aRequest) {
debug("close");
let manifestURL = aRequest.manifestURL;
if (!manifestURL) {
return { error: "missingParameter",
message: "missing parameter manifestURL" };
}
let reg = DOMApplicationRegistry;
let app = reg.getAppByManifestURL(manifestURL);
if (!app) {
return { error: "missingParameter",
message: "No application for " + manifestURL };
}
reg.close(app);
return {};
}
};
@ -296,7 +384,12 @@ WebappsActor.prototype = {
* The request types this actor can handle.
*/
WebappsActor.prototype.requestTypes = {
"install": WebappsActor.prototype.install
"install": WebappsActor.prototype.install,
"getAll": WebappsActor.prototype.getAll,
"launch": WebappsActor.prototype.launch,
"close": WebappsActor.prototype.close,
"uninstall": WebappsActor.prototype.uninstall
};
DebuggerServer.addGlobalActor(WebappsActor, "webappsActor");

Просмотреть файл

@ -164,11 +164,6 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
function(value) {
Services.prefs.setBoolPref('dom.sms.strict7BitEncoding', value);
});
SettingsListener.observe('ril.sms.requestStatusReport.enabled', false,
function(value) {
Services.prefs.setBoolPref('dom.sms.requestStatusReport', value);
});
})();
//=================== DeviceInfo ====================

Просмотреть файл

@ -876,6 +876,7 @@ var WebappsHelper = {
init: function webapps_init() {
Services.obs.addObserver(this, "webapps-launch", false);
Services.obs.addObserver(this, "webapps-ask-install", false);
Services.obs.addObserver(this, "webapps-close", false);
},
registerInstaller: function webapps_registerInstaller(data) {
@ -927,6 +928,12 @@ var WebappsHelper = {
app: json.app
});
break;
case "webapps-close":
shell.sendChromeEvent({
"type": "webapps-close",
"manifestURL": json.manifestURL
});
break;
}
}
}

Просмотреть файл

@ -84,6 +84,18 @@ XPCOMUtils.defineLazyModuleGetter(this, "IdentityService",
XPCOMUtils.defineLazyModuleGetter(this, "Logger",
"resource://gre/modules/identity/LogUtils.jsm");
// The default persona uri; can be overwritten with toolkit.identity.uri pref.
// Do this if you want to repoint to a different service for testing.
// There's no point in setting up an observer to monitor the pref, as b2g prefs
// can only be overwritten when the profie is recreated. So just get the value
// on start-up.
let kPersonaUri = "https://firefoxos.persona.org";
try {
kPersonaUri = Services.prefs.getCharPref("toolkit.identity.uri");
} catch(noSuchPref) {
// stick with the default value
}
// JS shim that contains the callback functions that
// live within the identity UI provisioning frame.
const kIdentityShimFile = "chrome://browser/content/identity.js";
@ -106,6 +118,8 @@ function log(...aMessageArgs) {
Logger.log.apply(Logger, ["SignInToWebsiteController"].concat(aMessageArgs));
}
log("persona uri =", kPersonaUri);
/*
* ContentInterface encapsulates the our content functions. There are only two:
*
@ -122,6 +136,7 @@ let ContentInterface = {
},
sendChromeEvent: function SignInToWebsiteController_sendChromeEvent(detail) {
detail.uri = kPersonaUri;
this._getBrowser().shell.sendChromeEvent(detail);
}
};
@ -271,9 +286,9 @@ Pipe.prototype = {
mm = frameLoader.messageManager;
try {
mm.loadFrameScript(kIdentityShimFile, true);
log("Loaded shim " + kIdentityShimFile + "\n");
log("Loaded shim", kIdentityShimFile);
} catch (e) {
log("Error loading ", kIdentityShimFile, " as a frame script: ", e);
log("Error loading", kIdentityShimFile, "as a frame script:", e);
}
// There are two messages that the delegate can send back: a "do

Просмотреть файл

@ -94,7 +94,7 @@ function checkValueSubmittedIsInvalid()
}
function testSubmissions() {
SpecialPowers.focus(input);
input.focus();
sendString(testData[valueIndex]);
submitMethod();
}
@ -186,7 +186,7 @@ function runTest()
for (data of gValidData) {
input.value = "";
SpecialPowers.focus(input);
input.focus();
sendString(data);
input.blur();
is(input.value, data, "valid user input should not be sanitized");
@ -194,7 +194,7 @@ function runTest()
for (data of gInvalidData) {
input.value = "";
SpecialPowers.focus(input);
input.focus();
sendString(data);
input.blur();
is(input.value, "", "invalid user input should be sanitized");

Просмотреть файл

@ -12,6 +12,7 @@
#include <stagefright/MetaData.h>
#include <stagefright/OMXClient.h>
#include <stagefright/OMXCodec.h>
#include <OMX.h>
#include "mozilla/Preferences.h"
#include "mozilla/Types.h"
@ -171,6 +172,14 @@ public:
}
};
static sp<IOMX> sOMX = nullptr;
static sp<IOMX> GetOMX() {
if(sOMX.get() == nullptr) {
sOMX = new OMX;
}
return sOMX;
}
bool OmxDecoder::Init() {
#ifdef PR_LOGGING
if (!gOmxDecoderLog) {
@ -297,14 +306,28 @@ bool OmxDecoder::Init() {
if (!strcasecmp(audioMime, "audio/raw")) {
audioSource = audioTrack;
} else {
// try to load hardware codec in mediaserver process.
int flags = kHardwareCodecsOnly;
audioSource = OMXCodec::Create(omx,
audioTrack->getFormat(),
false, // decoder
audioTrack);
audioTrack,
nullptr,
flags);
}
if (audioSource == nullptr) {
NS_WARNING("Couldn't create OMX audio source");
return false;
// try to load software codec in this process.
int flags = kSoftwareCodecsOnly;
audioSource = OMXCodec::Create(GetOMX(),
audioTrack->getFormat(),
false, // decoder
audioTrack,
nullptr,
flags);
if (audioSource == nullptr) {
NS_WARNING("Couldn't create OMX audio source");
return false;
}
}
if (audioSource->start() != OK) {
NS_WARNING("Couldn't start OMX audio source");

Просмотреть файл

@ -687,6 +687,7 @@ WebappsApplicationMgmt.prototype = {
dump("-- webapps.js uninstall " + aApp.manifestURL + "\n");
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: aApp.origin,
manifestURL: aApp.manifestURL,
oid: this._id,
requestID: this.getRequestId(request) });
return request;

Просмотреть файл

@ -820,10 +820,10 @@ this.DOMApplicationRegistry = {
this.getSelf(msg, mm);
break;
case "Webapps:Uninstall":
this.uninstall(msg, mm);
this.doUninstall(msg, mm);
break;
case "Webapps:Launch":
this.launchApp(msg, mm);
this.doLaunch(msg, mm);
break;
case "Webapps:CheckInstalled":
this.checkInstalled(msg, mm);
@ -835,7 +835,7 @@ this.DOMApplicationRegistry = {
this.getNotInstalled(msg, mm);
break;
case "Webapps:GetAll":
this.getAll(msg, mm);
this.doGetAll(msg, mm);
break;
case "Webapps:InstallPackage":
this.doInstallPackage(msg, mm);
@ -917,21 +917,48 @@ this.DOMApplicationRegistry = {
});
},
launchApp: function launchApp(aData, aMm) {
let app = this.getAppByManifestURL(aData.manifestURL);
doLaunch: function (aData, aMm) {
this.launch(
aData.manifestURL,
aData.startPoint,
function onsuccess() {
aMm.sendAsyncMessage("Webapps:Launch:Return:OK", aData);
},
function onfailure(reason) {
aMm.sendAsyncMessage("Webapps:Launch:Return:KO", aData);
}
);
},
launch: function launch(aManifestURL, aStartPoint, aOnSuccess, aOnFailure) {
let app = this.getAppByManifestURL(aManifestURL);
if (!app) {
aMm.sendAsyncMessage("Webapps:Launch:Return:KO", aData);
aOnFailure("NO_SUCH_APP");
return;
}
// Fire an error when trying to launch an app that is not
// yet fully installed.
if (app.installState == "pending") {
aMm.sendAsyncMessage("Webapps:Launch:Return:KO", aData);
aOnFailure("PENDING_APP_NOT_LAUNCHABLE");
return;
}
Services.obs.notifyObservers(aMm, "webapps-launch", JSON.stringify(aData));
// We have to clone the app object as nsIDOMApplication objects are
// stringified as an empty object. (see bug 830376)
let appClone = AppsUtils.cloneAppObject(app);
appClone.startPoint = aStartPoint;
Services.obs.notifyObservers(null, "webapps-launch", JSON.stringify(appClone));
aOnSuccess();
},
close: function close(aApp) {
debug("close");
// We have to clone the app object as nsIDOMApplication objects are
// stringified as an empty object. (see bug 830376)
let appClone = AppsUtils.cloneAppObject(aApp);
Services.obs.notifyObservers(null, "webapps-close", JSON.stringify(appClone));
},
cancelDownload: function cancelDownload(aManifestURL, aError) {
@ -2526,67 +2553,79 @@ this.DOMApplicationRegistry = {
}
},
uninstall: function(aData, aMm) {
debug("uninstall " + aData.origin);
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.origin != aData.origin) {
continue;
}
dump("-- webapps.js uninstall " + app.manifestURL + "\n");
if (!app.removable) {
debug("Error: cannot unintall a non-removable app.");
break;
}
// Check if we are downloading something for this app, and cancel the
// download if needed.
this.cancelDownload(app.manifestURL);
// Clean up the deprecated manifest cache if needed.
if (id in this._manifestCache) {
delete this._manifestCache[id];
}
// Clear private data first.
this._clearPrivateData(app.localId, false);
// Then notify observers.
Services.obs.notifyObservers(aMm, "webapps-uninstall", JSON.stringify(aData));
let appNote = JSON.stringify(AppsUtils.cloneAppObject(app));
appNote.id = id;
if (supportSystemMessages()) {
this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
this._unregisterActivities(aResult[0].manifest, app);
}).bind(this));
}
let dir = this._getAppDir(id);
try {
dir.remove(true);
} catch (e) {}
delete this.webapps[id];
this._saveApps((function() {
aData.manifestURL = app.manifestURL;
this.broadcastMessage("Webapps:Uninstall:Broadcast:Return:OK", aData);
doUninstall: function(aData, aMm) {
this.uninstall(aData.manifestURL,
function onsuccess() {
aMm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
this.broadcastMessage("Webapps:RemoveApp", { id: id });
}).bind(this));
},
function onfailure() {
// Fall-through, fails to uninstall the desired app because:
// - we cannot find the app to be uninstalled.
// - the app to be uninstalled is not removable.
aMm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
}
);
},
uninstall: function(aManifestURL, aOnSuccess, aOnFailure) {
debug("uninstall " + aManifestURL);
let app = this.getAppByManifestURL(aManifestURL);
if (!app) {
aOnFailure("NO_SUCH_APP");
return;
}
let id = app.id;
if (!app.removable) {
debug("Error: cannot uninstall a non-removable app.");
aOnFailure("NON_REMOVABLE_APP");
return;
}
// Fall-through, fails to uninstall the desired app because:
// - we cannot find the app to be uninstalled.
// - the app to be uninstalled is not removable.
aMm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
// Check if we are downloading something for this app, and cancel the
// download if needed.
this.cancelDownload(app.manifestURL);
// Clean up the deprecated manifest cache if needed.
if (id in this._manifestCache) {
delete this._manifestCache[id];
}
// Clear private data first.
this._clearPrivateData(app.localId, false);
// Then notify observers.
// We have to clone the app object as nsIDOMApplication objects are
// stringified as an empty object. (see bug 830376)
let appClone = AppsUtils.cloneAppObject(app);
Services.obs.notifyObservers(null, "webapps-uninstall", JSON.stringify(appClone));
if (supportSystemMessages()) {
this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
this._unregisterActivities(aResult[0].manifest, app);
}).bind(this));
}
let dir = this._getAppDir(id);
try {
dir.remove(true);
} catch (e) {}
delete this.webapps[id];
this._saveApps((function() {
this.broadcastMessage("Webapps:Uninstall:Broadcast:Return:OK", appClone);
// Catch exception on callback call to ensure notifying observers after
try {
aOnSuccess();
} catch(e) {
Cu.reportError("DOMApplicationRegistry: Exception on app uninstall: " +
ex + "\n" + ex.stack);
}
Services.obs.notifyObservers(this, "webapps-sync-uninstall", JSON.stringify(appClone));
this.broadcastMessage("Webapps:RemoveApp", { id: id });
}).bind(this));
},
getSelf: function(aData, aMm) {
@ -2681,8 +2720,16 @@ this.DOMApplicationRegistry = {
}).bind(this));
},
getAll: function(aData, aMm) {
aData.apps = [];
doGetAll: function(aData, aMm) {
this.getAll(function (apps) {
aData.apps = apps;
aMm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
});
},
getAll: function(aCallback) {
debug("getAll");
let apps = [];
let tmp = [];
for (let id in this.webapps) {
@ -2690,14 +2737,14 @@ this.DOMApplicationRegistry = {
if (!this._isLaunchable(app.origin))
continue;
aData.apps.push(app);
apps.push(app);
tmp.push({ id: id });
}
this._readManifests(tmp, (function(aResult) {
for (let i = 0; i < aResult.length; i++)
aData.apps[i].manifest = aResult[i].manifest;
aMm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
apps[i].manifest = aResult[i].manifest;
aCallback(apps);
}).bind(this));
},

Двоичные данные
dom/apps/tests/unit/data/app.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,189 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Components.utils.import("resource://gre/modules/devtools/dbg-server.jsm");
Components.utils.import("resource://gre/modules/devtools/dbg-client.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
let gClient, gActor;
let gAppId = "actor-test";
add_test(function testSetup() {
// Initialize a loopback remote protocol connection
DebuggerServer.init(function () { return true; });
// We need to register browser actors to have `listTabs` working
// and also have a root actor
DebuggerServer.addBrowserActors();
DebuggerServer.addActors("chrome://browser/content/dbg-webapps-actors.js");
// Setup client and actor used in all tests
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function onConnect() {
gClient.listTabs(function onListTabs(aResponse) {
gActor = aResponse.webappsActor;
run_next_test();
});
});
});
add_test(function testLaunchInexistantApp() {
let request = {to: gActor, type: "launch", manifestURL: "http://foo.com"};
gClient.request(request, function (aResponse) {
do_check_eq(aResponse.error, "NO_SUCH_APP");
run_next_test();
});
});
add_test(function testCloseInexistantApp() {
let request = {to: gActor, type: "close", manifestURL: "http://foo.com"};
gClient.request(request, function (aResponse) {
do_check_eq(aResponse.error, "missingParameter");
do_check_eq(aResponse.message, "No application for http://foo.com");
run_next_test();
});
});
// Install a test app
add_test(function testInstallPackaged() {
// Copy our test webapp to tmp folder, where the actor retrieves it
let zip = do_get_file("data/app.zip");
let appDir = FileUtils.getDir("TmpD", ["b2g", gAppId], true, true);
zip.copyTo(appDir, "application.zip");
let request = {to: gActor, type: "install", appId: gAppId};
gClient.request(request, function (aResponse) {
do_check_eq(aResponse.appId, gAppId);
});
// The install request is asynchronous and send back an event to tell
// if the installation succeed or failed
gClient.addListener("webappsEvent", function (aState, aType, aPacket) {
do_check_eq(aType.appId, gAppId);
do_check_eq("error" in aType, false);
run_next_test();
});
});
// Now check that the app appear in getAll
add_test(function testGetAll() {
let request = {to: gActor, type: "getAll"};
gClient.request(request, function (aResponse) {
do_check_true("apps" in aResponse);
let apps = aResponse.apps;
do_check_true(apps.length > 0);
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
if (app.id == gAppId) {
do_check_eq(app.name, "Test app");
do_check_eq(app.manifest.description, "Testing webapps actor");
do_check_eq(app.manifest.launch_path, "/index.html");
do_check_eq(app.origin, "app://" + gAppId);
do_check_eq(app.installOrigin, app.origin);
do_check_eq(app.manifestURL, app.origin + "/manifest.webapp");
run_next_test();
return;
}
}
do_throw("Unable to find the test app by its id");
});
});
add_test(function testLaunchApp() {
let manifestURL = "app://" + gAppId + "/manifest.webapp";
let startPoint = "/index.html";
let request = {
to: gActor, type: "launch",
manifestURL: manifestURL,
startPoint: startPoint
};
Services.obs.addObserver(function observer(subject, topic, data) {
Services.obs.removeObserver(observer, topic);
let json = JSON.parse(data);
do_check_eq(json.manifestURL, manifestURL);
do_check_eq(json.startPoint, startPoint);
run_next_test();
}, "webapps-launch", false);
gClient.request(request, function (aResponse) {
do_check_false("error" in aResponse);
});
});
add_test(function testCloseApp() {
let manifestURL = "app://" + gAppId + "/manifest.webapp";
let request = {
to: gActor, type: "close",
manifestURL: manifestURL
};
Services.obs.addObserver(function observer(subject, topic, data) {
Services.obs.removeObserver(observer, topic);
let json = JSON.parse(data);
do_check_eq(json.manifestURL, manifestURL);
run_next_test();
}, "webapps-close", false);
gClient.request(request, function (aResponse) {
do_check_false("error" in aResponse);
});
});
add_test(function testUninstall() {
let origin = "app://" + gAppId;
let manifestURL = origin + "/manifest.webapp";
let request = {
to: gActor, type: "uninstall",
manifestURL: manifestURL
};
let gotFirstUninstallEvent = false;
Services.obs.addObserver(function observer(subject, topic, data) {
Services.obs.removeObserver(observer, topic);
let json = JSON.parse(data);
do_check_eq(json.manifestURL, manifestURL);
do_check_eq(json.origin, origin);
gotFirstUninstallEvent = true;
}, "webapps-uninstall", false);
Services.obs.addObserver(function observer(subject, topic, data) {
Services.obs.removeObserver(observer, topic);
let json = JSON.parse(data);
do_check_eq(json.manifestURL, manifestURL);
do_check_eq(json.origin, origin);
do_check_eq(json.id, gAppId);
do_check_true(gotFirstUninstallEvent);
run_next_test();
}, "webapps-sync-uninstall", false);
gClient.request(request, function (aResponse) {
do_check_false("error" in aResponse);
});
});
// Close the test remote connection before leaving this test
add_test(function testTearDown() {
gClient.close(function () {
run_next_test();
});
});
function run_test() {
// We have to setup a profile, otherwise indexed db used by webapps
// will throw random exception when trying to get profile folder
do_get_profile();
// We also need a valid nsIXulAppInfo service as Webapps.jsm is querying it
Components.utils.import("resource://testing-common/AppInfo.jsm");
updateAppInfo();
// We have to toggle this flag in order to have apps being listed in getAll
// as only launchable apps are returned
Components.utils.import('resource://gre/modules/Webapps.jsm');
DOMApplicationRegistry.allAppsLaunchable = true;
run_next_test();
}

Просмотреть файл

@ -3,3 +3,5 @@ head =
tail =
[test_manifestSanitizer.js]
[test_webappsActor.js]
run-if = toolkit == "gonk"

Просмотреть файл

@ -2696,14 +2696,7 @@ RadioInterfaceLayer.prototype = {
let options = this._fragmentText(message, null, strict7BitEncoding);
options.rilMessageType = "sendSMS";
options.number = PhoneNumberUtils.normalize(number);
let requestStatusReport;
try {
requestStatusReport =
Services.prefs.getBoolPref("dom.sms.requestStatusReport");
} catch (e) {
requestStatusReport = false;
}
options.requestStatusReport = requestStatusReport;
options.requestStatusReport = true;
if (options.segmentMaxSeq > 1) {
options.segmentRef16Bit = this.segmentRef16Bit;
options.segmentRef = this.nextSegmentRef;

Просмотреть файл

@ -4068,7 +4068,6 @@ pref("dom.sms.enabled", false);
// Enable Latin characters replacement with corresponding ones in GSM SMS
// 7-bit default alphabet.
pref("dom.sms.strict7BitEncoding", false);
pref("dom.sms.requestStatusReport", false);
// WebContacts
pref("dom.mozContacts.enabled", false);

Просмотреть файл

@ -60,11 +60,11 @@ let specialPowersObserver = new specialpowers.SpecialPowersObserver();
specialPowersObserver.init();
let mm = container.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
container.focus();
mm.addMessageListener("SPPrefService", specialPowersObserver);
mm.addMessageListener("SPProcessCrashService", specialPowersObserver);
mm.addMessageListener("SPPingService", specialPowersObserver);
mm.addMessageListener("SpecialPowers.Quit", specialPowersObserver);
mm.addMessageListener("SpecialPowers.Focus", specialPowersObserver);
mm.addMessageListener("SPPermissionManager", specialPowersObserver);
mm.loadFrameScript(CHILD_LOGGER_SCRIPT, true);

Просмотреть файл

@ -72,6 +72,14 @@ ChromePowers.prototype.quit = function() {
SpecialPowers._sendSyncMessage("SpecialPowers.Quit", {});
};
ChromePowers.prototype.focus = function(aWindow) {
// We come in here as SpecialPowers.focus, but SpecialPowers is really ChromePowers.
// For some reason this.<func> resolves to TestRunner, so using SpecialPowers
// allows us to use the ChromePowers object which we defined below.
if (aWindow)
aWindow.focus();
};
ChromePowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) {
aCallback();
};

Просмотреть файл

@ -233,11 +233,10 @@ TestRunner._makeIframe = function (url, retry) {
if (url != "about:blank" &&
(("hasFocus" in document && !document.hasFocus()) ||
("activeElement" in document && document.activeElement != iframe))) {
// typically calling ourselves from setTimeout is sufficient
// but we'll try focus() just in case that's needed
contentAsyncEvent("Focus");
window.focus();
SpecialPowers.focus();
iframe.focus();
if (retry < 3) {
window.setTimeout('TestRunner._makeIframe("'+url+'", '+(retry+1)+')', 1000);
@ -282,8 +281,6 @@ TestRunner.runTests = function (/*url...*/) {
TestRunner._urls = flattenArguments(arguments);
$('testframe').src="";
TestRunner._checkForHangs();
window.focus();
$('testframe').focus();
TestRunner.runNextTest();
};
@ -301,8 +298,6 @@ TestRunner.resetTests = function(listURLs) {
TestRunner._urls = listURLs;
$('testframe').src="";
TestRunner._checkForHangs();
window.focus();
$('testframe').focus();
TestRunner.runNextTest();
}

Просмотреть файл

@ -56,6 +56,7 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
this._messageManager.addMessageListener("SPProcessCrashService", this);
this._messageManager.addMessageListener("SPPingService", this);
this._messageManager.addMessageListener("SpecialPowers.Quit", this);
this._messageManager.addMessageListener("SpecialPowers.Focus", this);
this._messageManager.addMessageListener("SPPermissionManager", this);
this._messageManager.addMessageListener("SPWebAppService", this);
@ -144,6 +145,9 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
appStartup.quit(Ci.nsIAppStartup.eForceQuit);
break;
case "SpecialPowers.Focus":
aMessage.target.focus();
break;
default:
return this._receiveMessage(aMessage);
}

Просмотреть файл

@ -1256,8 +1256,12 @@ SpecialPowersAPI.prototype = {
return this.focusManager.focusedWindow;
},
focus: function(window) {
window.focus();
focus: function(aWindow) {
// This is called inside TestRunner._makeIframe without aWindow, because of assertions in oop mochitests
// With aWindow, it is called in SimpleTest.waitForFocus to allow popup window opener focus switching
if (aWindow)
aWindow.focus();
sendAsyncMessage("SpecialPowers.Focus", {});
},
getClipboardData: function(flavor) {

Просмотреть файл

@ -2,6 +2,7 @@
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
[include:dom/apps/tests/unit/xpcshell.ini]
[include:dom/mobilemessage/tests/xpcshell.ini]
[include:dom/mms/tests/xpcshell.ini]
[include:dom/system/gonk/tests/xpcshell.ini]

Просмотреть файл

@ -166,7 +166,7 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform,
//clip to buffer size
crop.IntersectRect(crop, aBufferRect);
crop.RoundOut();
crop.Round();
if (crop.IsEmpty()) {
LOGD("Skip layer");
@ -175,7 +175,7 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform,
//propagate buffer clipping back to visible rect
visibleRectScreen = aTransform.TransformBounds(crop);
visibleRectScreen.RoundOut();
visibleRectScreen.Round();
// Map from layer space to buffer space
crop -= aBufferRect.TopLeft();
@ -193,6 +193,52 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform,
return true;
}
/**
* Prepares hwc layer visible region required for hwc composition
*
* @param aVisible Input. Layer's unclipped visible region
* The origin is the top-left corner of the layer
* @param aTransform Input. Layer's transformation matrix
* It transforms from layer space to screen space
* @param aClip Input. A clipping rectangle.
* The origin is the top-left corner of the screen
* @param aBufferRect Input. The layer's buffer bounds
* The origin is the top-left corner of the layer
* @param aVisibleRegionScreen Output. Visible region in screen space.
* The origin is the top-left corner of the screen
* @return true if the layer should be rendered.
* false if the layer can be skipped
*/
static bool
PrepareVisibleRegion(const nsIntRegion& aVisible,
const gfxMatrix& aTransform,
nsIntRect aClip, nsIntRect aBufferRect,
RectVector* aVisibleRegionScreen) {
nsIntRegionRectIterator rect(aVisible);
bool isVisible = false;
while (const nsIntRect* visibleRect = rect.Next()) {
hwc_rect_t visibleRectScreen;
gfxRect screenRect;
screenRect.IntersectRect(gfxRect(*visibleRect), aBufferRect);
screenRect = aTransform.TransformBounds(screenRect);
screenRect.IntersectRect(screenRect, aClip);
screenRect.Round();
if (screenRect.IsEmpty()) {
continue;
}
visibleRectScreen.left = screenRect.x;
visibleRectScreen.top = screenRect.y;
visibleRectScreen.right = screenRect.XMost();
visibleRectScreen.bottom = screenRect.YMost();
aVisibleRegionScreen->push_back(visibleRectScreen);
isVisible = true;
}
return isVisible;
}
/**
* Calculates the layer's clipping rectangle
*
@ -251,21 +297,11 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
}
float opacity = aLayer->GetEffectiveOpacity();
if (opacity <= 0) {
LOGD("Layer is fully transparent so skip rendering");
return true;
}
else if (opacity < 1) {
if (opacity < 1) {
LOGD("Layer has planar semitransparency which is unsupported");
return false;
}
if (visibleRegion.GetNumRects() > 1) {
// FIXME/bug 808339
LOGD("Layer has nontrivial visible region");
return false;
}
nsIntRect clip;
if (!CalculateClipRect(aParentTransform * aGLWorldTransform,
aLayer->GetEffectiveClipRect(),
@ -302,9 +338,13 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
LayerOGL* layerGL = static_cast<LayerOGL*>(aLayer->ImplData());
LayerRenderState state = layerGL->GetRenderState();
nsIntSize surfaceSize;
if (!state.mSurface ||
state.mSurface->type() != SurfaceDescriptor::TSurfaceDescriptorGralloc) {
if (state.mSurface &&
state.mSurface->type() == SurfaceDescriptor::TSurfaceDescriptorGralloc) {
surfaceSize = state.mSurface->get_SurfaceDescriptorGralloc().size();
}
else {
if (aLayer->AsColorLayer() && mColorFill) {
fillColor = true;
} else {
@ -338,10 +378,10 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
} else {
if(state.mHasOwnOffset) {
bufferRect = nsIntRect(state.mOffset.x, state.mOffset.y,
int(buffer->getWidth()), int(buffer->getHeight()));
surfaceSize.width, surfaceSize.height);
} else {
bufferRect = nsIntRect(visibleRect.x, visibleRect.y,
int(buffer->getWidth()), int(buffer->getHeight()));
surfaceSize.width, surfaceSize.height);
}
}
@ -385,12 +425,30 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
hwcLayer.transform |= state.YFlipped() ? HWC_TRANSFORM_FLIP_V : 0;
hwc_region_t region;
region.numRects = 1;
region.rects = &(hwcLayer.displayFrame);
if (visibleRegion.GetNumRects() > 1) {
mVisibleRegions.push_back(RectVector());
RectVector* visibleRects = &(mVisibleRegions.back());
if(!PrepareVisibleRegion(visibleRegion,
transform * aGLWorldTransform,
clip,
bufferRect,
visibleRects)) {
return true;
}
region.numRects = visibleRects->size();
region.rects = &((*visibleRects)[0]);
} else {
region.numRects = 1;
region.rects = &(hwcLayer.displayFrame);
}
hwcLayer.visibleRegionScreen = region;
} else {
hwcLayer.flags |= HWC_COLOR_FILL;
ColorLayer* colorLayer = static_cast<ColorLayer*>(layerGL->GetLayer());
ColorLayer* colorLayer = aLayer->AsColorLayer();
if (colorLayer->GetColor().a < 1.0) {
LOGD("Color layer has semitransparency which is unsupported");
return false;
}
hwcLayer.transform = colorLayer->GetColor().Packed();
}
@ -412,6 +470,10 @@ HwcComposer2D::TryRender(Layer* aRoot,
mList->numHwLayers = 0;
}
// XXX: The clear() below means all rect vectors will be have to be
// reallocated. We may want to avoid this if possible
mVisibleRegions.clear();
if (!PrepareLayerList(aRoot,
mScreenRect,
gfxMatrix(),

Просмотреть файл

@ -20,6 +20,8 @@
#include "Composer2D.h"
#include "HWComposer.h"
#include "Layers.h"
#include <vector>
#include <list>
namespace mozilla {
@ -28,6 +30,10 @@ class ContainerLayer;
class Layer;
}
//Holds a dynamically allocated vector of rectangles
//used to decribe the complex visible region of a layer
typedef std::vector<hwc_rect_t> RectVector;
class HwcComposer2D : public android::HWComposer,
public mozilla::layers::Composer2D {
public:
@ -54,6 +60,9 @@ private:
nsIntRect mScreenRect;
int mMaxLayerCount;
bool mColorFill;
//Holds all the dynamically allocated RectVectors needed
//to render the current frame
std::list<RectVector> mVisibleRegions;
};
} // namespace mozilla