Merge birch to m-c.

This commit is contained in:
Ryan VanderMeulen 2013-05-31 11:22:14 -04:00
commit bb504e6c5e
25 changed files with 257 additions and 40 deletions

View File

@ -139,6 +139,7 @@ else
$(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
endif
cp -RL $(srcdir)/b2g.icns $(DIST)/$(APP_NAME).app/Contents/Resources/$(MOZ_APP_NAME).icns
printf "APPLMOZB" > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
else # MOZ_WIDGET_TOOLKIT != cocoa

BIN
b2g/app/b2g.icns Normal file

Binary file not shown.

View File

@ -1009,7 +1009,7 @@ let RemoteDebugger = {
}
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js");
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
DebuggerServer.addActors('chrome://browser/content/dbg-webapps-actors.js');
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
}
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;

View File

@ -10,7 +10,6 @@ chrome.jar:
content/arrow.svg (content/arrow.svg)
* content/dbg-browser-actors.js (content/dbg-browser-actors.js)
* content/dbg-webapps-actors.js (content/dbg-webapps-actors.js)
content/forms.js (content/forms.js)
* content/settings.js (content/settings.js)
* content/shell.xul (content/shell.xul)

View File

@ -404,7 +404,7 @@ DecoderTraits::CreateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
if (IsOmxSupportedType(aType)) {
// AMR audio is enabled for MMS, but we are discouraging Web and App
// developers from using AMR, thus we only allow AMR to be played on WebApps.
if (aType.EqualsASCII("audio/amr") || aType.EqualsASCII("video/3gpp")) {
if (aType.EqualsASCII("audio/amr")) {
HTMLMediaElement* element = aOwner->GetMediaElement();
if (!element) {
return nullptr;

View File

@ -92,11 +92,15 @@ this.AlarmService = {
},
set _currentAlarm(aAlarm) {
this._alarm = aAlarm;
if (!aAlarm)
if (!aAlarm) {
return;
}
if (!this._alarmHalService.setAlarm(this._getAlarmTime(aAlarm) / 1000, 0))
let alarmTimeInMs = this._getAlarmTime(aAlarm);
let ns = (alarmTimeInMs % 1000) * 1000000;
if (!this._alarmHalService.setAlarm(alarmTimeInMs / 1000, ns)) {
throw Components.results.NS_ERROR_FAILURE;
}
},
receiveMessage: function receiveMessage(aMessage) {

View File

@ -590,6 +590,7 @@ WebappsApplication.prototype = {
this.progress = app.progress || msg.progress || 0;
this.readyToApplyDownload = app.readyToApplyDownload;
this.updateTime = app.updateTime;
this.origin = app.origin;
switch(msg.type) {
case "error":

View File

@ -84,6 +84,11 @@ this.DOMApplicationRegistry = {
webapps: { },
children: [ ],
allAppsLaunchable: false,
#ifdef MOZ_OFFICIAL_BRANDING
get allowSideloadingCertified() false,
#else
get allowSideloadingCertified() true,
#endif
init: function() {
this.messages = ["Webapps:Install", "Webapps:Uninstall",
@ -127,6 +132,10 @@ this.DOMApplicationRegistry = {
let appDir = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], false);
for (let id in this.webapps) {
let app = this.webapps[id];
if (!app) {
delete this.webapps[id];
continue;
}
app.id = id;
@ -1136,6 +1145,8 @@ this.DOMApplicationRegistry = {
DOMApplicationRegistry._writeFile(manFile,
JSON.stringify(aManifest),
function() { });
app = DOMApplicationRegistry.webapps[aId];
// Set state and fire events.
app.downloading = false;
app.downloadAvailable = false;
@ -2044,7 +2055,7 @@ this.DOMApplicationRegistry = {
manifest = new ManifestHelper(jsonManifest, app.manifestURL);
this.downloadPackage(manifest, appObject, false, (function(aId, aManifest) {
// Success! Move the zip out of TmpD.
let app = DOMApplicationRegistry.webapps[id];
let app = DOMApplicationRegistry.webapps[aId];
let zipFile = FileUtils.getFile("TmpD", ["webapps", aId, "application.zip"], true);
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
zipFile.moveTo(dir, "application.zip");
@ -2552,15 +2563,65 @@ this.DOMApplicationRegistry = {
app.appStatus = AppsUtils.getAppManifestStatus(manifest);
}
// Check if the app declares which origin it will use.
if (isSigned &&
app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED &&
manifest.origin !== undefined) {
let uri;
try {
uri = Services.io.newURI(manifest.origin, null, null);
} catch(e) {
throw "INVALID_ORIGIN";
}
if (uri.scheme != "app") {
throw "INVALID_ORIGIN";
}
// Changing the origin during an update is not allowed.
if (aIsUpdate && uri.prePath != app.origin) {
throw "INVALID_ORIGIN_CHANGE";
}
debug("Setting origin to " + uri.prePath +
" for " + app.manifestURL);
let newId = uri.prePath.substring(6); // "app://".length
if (newId in self.webapps) {
throw "DUPLICATE_ORIGIN";
}
app.origin = uri.prePath;
// Update the registry.
app.id = newId;
self.webapps[newId] = app;
delete self.webapps[id];
// Rename the directories where the files are installed.
[DIRECTORY_NAME, "TmpD"].forEach(function(aDir) {
let parent = FileUtils.getDir(aDir,
["webapps"], true, true);
let dir = FileUtils.getDir(aDir,
["webapps", id], true, true);
dir.moveTo(parent, newId);
});
// Signals that we need to swap the old id with the new app.
self.broadcastMessage("Webapps:RemoveApp", { id: id });
self.broadcastMessage("Webapps:AddApp", { id: newId,
app: app });
}
if (aOnSuccess) {
aOnSuccess(id, manifest);
aOnSuccess(app.id, manifest);
}
} catch (e) {
// Something bad happened when reading the package.
// Unrecoverable error, don't bug the user.
// Apps with installState 'pending' does not produce any
// notification, so we are safe with its current
// downladAvailable state.
// downloadAvailable state.
if (app.installState !== "pending") {
app.downloadAvailable = false;
}

View File

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

View File

@ -68,7 +68,7 @@ IndexedDBHelper.prototype = {
};
req.onerror = function (aEvent) {
if (DEBUG) debug("Failed to open database:" + self.dbName);
aFailureCb(aEvent.target.errorMessage);
aFailureCb(aEvent.target.error.name);
};
req.onblocked = function (aEvent) {
if (DEBUG) debug("Opening database request is blocked.");

View File

@ -67,6 +67,17 @@ NS_IMETHODIMP
TelephonyListener::NotifyError(int32_t aCallIndex,
const nsAString& aError)
{
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
// In order to not miss any related call state transition.
// It's possible that 3G network signal lost for unknown reason.
// If a call is released abnormally, NotifyError() will be called,
// instead of CallStateChanged(). We need to reset the call array state
// via setting CALL_STATE_DISCONNECTED
hfp->HandleCallStateChanged(aCallIndex,
nsITelephonyProvider::CALL_STATE_DISCONNECTED,
EmptyString(), false, true);
NS_WARNING("Reset the call state due to call transition ends abnormally");
NS_WARNING(aError.get());
return NS_OK;
}

View File

@ -20,6 +20,13 @@ browserElementTestHelpers.addPermission();
browserElementTestHelpers.enableProcessPriorityManager();
function runTest() {
// To test bug 870480, run this test while holding the CPU and high-priority
// wake locks. Without the fix for bug 870480, we won't set the priority of
// the child process if the main process holds these wake locks and the test
// will hang.
navigator.requestWakeLock('cpu');
navigator.requestWakeLock('high-priority');
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('mozapptype', 'critical');
@ -86,8 +93,8 @@ function runTest() {
[expectMozbrowserEvent(iframe, 'showmodalprompt').then(checkAlertInfo),
expectPriorityChange(childID, priority).then(checkGracePeriod)]
).then(function(results) {
// expectMozbrowserEvent returns the function to call to unblock the
// alert. It comes to us as the first element of the results array.
// checkAlertInfo returns the function to call to unblock the alert.
// It comes to us as the first element of the results array.
results[0]();
});
}

View File

@ -30,6 +30,7 @@
[include:toolkit/components/contentprefs/tests/unit/xpcshell.ini]
[include:toolkit/components/contentprefs/tests/unit_cps2/xpcshell.ini]
[include:toolkit/devtools/server/tests/unit/xpcshell.ini]
[include:toolkit/devtools/apps/tests/unit/xpcshell.ini]
[include:toolkit/devtools/sourcemap/tests/unit/xpcshell.ini]
[include:toolkit/components/passwordmgr/test/unit/xpcshell.ini]
# Bug 676989: tests hang on Android

View File

@ -5,6 +5,7 @@
[include:dom/apps/tests/unit/xpcshell.ini]
[include:dom/mobilemessage/tests/xpcshell.ini]
[include:dom/system/gonk/tests/xpcshell.ini]
[include:toolkit/devtools/apps/tests/unit/xpcshell.ini]
[include:toolkit/devtools/debugger/tests/unit/xpcshell.ini]
[include:toolkit/devtools/sourcemap/tests/unit/xpcshell.ini]
[include:toolkit/mozapps/downloads/tests/unit/xpcshell.ini]

View File

@ -0,0 +1,15 @@
# 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/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
#libs::
# $(INSTALL) $(IFLAGS1) $(srcdir)/*.jsm $(FINAL_TARGET)/modules/devtools

View File

@ -0,0 +1,7 @@
# vim: set filetype=python:
# 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/.
TEST_DIRS += ['tests']

View File

@ -0,0 +1,15 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
XPCSHELL_TESTS = unit
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MODULE = 'test_webapps_actor'

View File

@ -7,6 +7,11 @@ 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");
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
const Cr = Components.results;
let gClient, gActor;
let gAppId = "actor-test";
@ -16,7 +21,6 @@ add_test(function testSetup() {
// 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());
@ -61,6 +65,12 @@ add_test(function testInstallPackaged() {
// if the installation succeed or failed
gClient.addListener("webappsEvent", function (aState, aType, aPacket) {
do_check_eq(aType.appId, gAppId);
if ("error" in aType) {
do_print("Error: " + aType.error);
}
if ("message" in aType) {
do_print("Error message: " + aType.message);
}
do_check_eq("error" in aType, false);
run_next_test();
@ -175,6 +185,10 @@ function run_test() {
// will throw random exception when trying to get profile folder
do_get_profile();
// The webapps dir isn't registered on b2g xpcshell tests,
// we have to manually set it to the directory service.
do_get_webappsdir();
// We also need a valid nsIXulAppInfo service as Webapps.jsm is querying it
Components.utils.import("resource://testing-common/AppInfo.jsm");
updateAppInfo();
@ -187,3 +201,39 @@ function run_test() {
run_next_test();
}
function do_get_webappsdir() {
var webappsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
webappsDir.append("test_webapps");
if (!webappsDir.exists())
webappsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
var coreAppsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
coreAppsDir.append("test_coreapps");
if (!coreAppsDir.exists())
coreAppsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
// Register our own provider for the profile directory.
// It will return our special docshell profile directory.
var provider = {
getFile: function(prop, persistent) {
persistent.value = true;
if (prop == "webappsDir") {
return webappsDir.clone();
}
else if (prop == "coreAppsDir") {
return coreAppsDir.clone();
}
throw Cr.NS_ERROR_FAILURE;
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
Services.dirsvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
}

View File

@ -0,0 +1,5 @@
[DEFAULT]
head =
tail =
[test_webappsActor.js]

View File

@ -9,5 +9,6 @@ PARALLEL_DIRS += [
'client',
'gcli',
'sourcemap',
'webconsole'
'webconsole',
'apps'
]

View File

@ -8,12 +8,6 @@ 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"]
@ -22,17 +16,21 @@ function debug(aMsg) {
*/
}
#ifdef MOZ_WIDGET_GONK
const DIRECTORY_NAME = "webappsDir";
#else
const DIRECTORY_NAME = "ProfD";
#endif
/**
* Creates a WebappsActor. WebappsActor provides remote access to
* install apps.
*/
function WebappsActor(aConnection) { debug("init"); }
function WebappsActor(aConnection) {
debug("init");
// Load actor dependencies lazily as this actor require extra environnement
// preparation to work (like have a profile setup in xpcshell tests)
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");
}
WebappsActor.prototype = {
actorPrefix: "webapps",
@ -46,7 +44,7 @@ WebappsActor.prototype = {
aApp.installState = "installed";
aApp.removable = true;
aApp.id = aId;
aApp.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true).path;
aApp.basePath = reg.getWebAppsBasePath();
aApp.localId = (aId in reg.webapps) ? reg.webapps[aId].localId
: reg._nextLocalId();
@ -128,15 +126,14 @@ WebappsActor.prototype = {
let appType = self._getAppType(aManifest.type);
// In production builds, don't allow installation of certified apps.
#ifdef MOZ_OFFICIAL_BRANDING
if (appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
if (!DOMApplicationRegistry.allowSideloadingCertified &&
appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
self._sendError("Installing certified apps is not allowed.", aId);
return;
}
#endif
// The destination directory for this app.
let installDir = FileUtils.getDir(DIRECTORY_NAME,
["webapps", aId], true);
let installDir = DOMApplicationRegistry._getAppDir(aId);
manFile.moveTo(installDir, "manifest.webapp");
// Read the origin and manifest url from metadata.json
@ -186,8 +183,7 @@ WebappsActor.prototype = {
run: function run() {
try {
// The destination directory for this app.
let installDir = FileUtils.getDir(DIRECTORY_NAME,
["webapps", aId], true);
let installDir = DOMApplicationRegistry._getAppDir(aId);
// Move application.zip to the destination directory, and
// extract manifest.webapp there.
@ -210,12 +206,12 @@ WebappsActor.prototype = {
let appType = self._getAppType(aManifest.type);
// In production builds, don't allow installation of certified apps.
#ifdef MOZ_OFFICIAL_BRANDING
if (appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
if (!DOMApplicationRegistry.allowSideloadingCertified &&
appType == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
self._sendError("Installing certified apps is not allowed.", aId);
return;
}
#endif
let origin = "app://" + aId;
// Create a fake app object with the minimum set of properties we need.

View File

@ -184,6 +184,7 @@ var DebuggerServer = {
this.addActors("resource://gre/modules/devtools/server/actors/profiler.js");
this.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js");
this.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
},
/**

View File

@ -713,13 +713,44 @@ nsMemoryInfoDumper::OpenTempFile(const nsACString &aFilename, nsIFile* *aFile)
NS_ENSURE_SUCCESS(rv, rv);
}
#ifdef ANDROID
// /data/local/tmp is a true tmp directory; anyone can create a file there,
// but only the user which created the file can remove it. We want non-root
// users to be able to remove these files, so we write them into a
// subdirectory of the temp directory and chmod 777 that directory.
rv = (*aFile)->AppendNative(NS_LITERAL_CSTRING("memory-reports"));
NS_ENSURE_SUCCESS(rv, rv);
// It's OK if this fails; that probably just means that the directory already
// exists.
(*aFile)->Create(nsIFile::DIRECTORY_TYPE, 0777);
nsAutoCString dirPath;
rv = (*aFile)->GetNativePath(dirPath);
NS_ENSURE_SUCCESS(rv, rv);
while (chmod(dirPath.get(), 0777) == -1 && errno == EINTR) {}
#endif
nsCOMPtr<nsIFile> file(*aFile);
rv = file->AppendNative(aFilename);
NS_ENSURE_SUCCESS(rv, rv);
rv = file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
rv = file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0666);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef ANDROID
// Make this file world-read/writable; the permissions passed to the
// CreateUnique call above are not sufficient on Android, which runs with a
// umask.
nsAutoCString path;
rv = file->GetNativePath(path);
NS_ENSURE_SUCCESS(rv, rv);
while (chmod(path.get(), 0666) == -1 && errno == EINTR) {}
#endif
return NS_OK;
}
@ -906,6 +937,11 @@ DumpProcessMemoryInfoToTempDir(const nsAString& aIdentifier)
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mrFinalFile));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef ANDROID
rv = mrFinalFile->AppendNative(NS_LITERAL_CSTRING("memory-reports"));
NS_ENSURE_SUCCESS(rv, rv);
#endif
rv = mrFinalFile->AppendNative(mrFilename);
NS_ENSURE_SUCCESS(rv, rv);