From d97443504dca7793f782a18e63ddcc965c720e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20Desr=C3=A9?= Date: Tue, 14 May 2013 12:00:09 -0700 Subject: [PATCH 1/7] Bug 852848 - Add support for app-specific redirections r=bz,ferjm --- docshell/base/nsDocShell.cpp | 26 ++++++++++++++++++ dom/apps/src/AppsService.js | 37 ++++++++++++++++++++++++++ dom/apps/src/AppsUtils.jsm | 7 ++--- dom/apps/src/Webapps.jsm | 32 ++++++++++++++++++++-- dom/interfaces/apps/nsIAppsService.idl | 9 ++++++- 5 files changed, 105 insertions(+), 6 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 5b22686f8e10..7ca5cd76cacf 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -202,6 +202,8 @@ #include "nsIAppShellService.h" #include "nsAppShellCID.h" +#include "nsIAppsService.h" + static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); @@ -6436,6 +6438,30 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel, if (!oldURI || !newURI) { return; } + + // Check if we have a redirect registered for this url. + uint32_t appId; + nsresult rv = GetAppId(&appId); + if (NS_FAILED(rv)) { + return; + } + + if (appId != nsIScriptSecurityManager::NO_APP_ID && + appId != nsIScriptSecurityManager::UNKNOWN_APP_ID) { + nsCOMPtr appsService = + do_GetService(APPS_SERVICE_CONTRACTID); + NS_ASSERTION(appsService, "No AppsService available"); + nsCOMPtr redirect; + rv = appsService->GetRedirect(appId, newURI, getter_AddRefs(redirect)); + if (NS_SUCCEEDED(rv) && redirect) { + aNewChannel->Cancel(NS_BINDING_ABORTED); + rv = LoadURI(redirect, nullptr, 0, false); + if (NS_SUCCEEDED(rv)) { + return; + } + } + } + // On session restore we get a redirect from page to itself. Don't count it. bool equals = false; if (mTiming && diff --git a/dom/apps/src/AppsService.js b/dom/apps/src/AppsService.js index f4bade00ced2..fe364235b07d 100644 --- a/dom/apps/src/AppsService.js +++ b/dom/apps/src/AppsService.js @@ -13,6 +13,7 @@ const Ci = Components.interfaces; const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}"); @@ -78,6 +79,42 @@ AppsService.prototype = { return DOMApplicationRegistry.getAppInfo(aAppId); }, + getRedirect: function getRedirect(aLocalId, aURI) { + debug("getRedirect for " + aLocalId + " " + aURI.spec); + if (aLocalId == Ci.nsIScriptSecurityManager.NO_APP_ID || + aLocalId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) { + return null; + } + + let app = DOMApplicationRegistry.getAppByLocalId(aLocalId); + if (app && app.redirects) { + let spec = aURI.spec; + for (let i = 0; i < app.redirects.length; i++) { + let redirect = app.redirects[i]; + if (spec.startsWith(redirect.from)) { + // Prepend the app origin to the redirection. We need that since + // the origin of packaged apps is a uuid created at install time. + let to = app.origin + redirect.to; + // If we have a ? or a # in the current URL, add this part to the + // redirection. + let index = -1; + index = spec.indexOf('?'); + if (index == -1) { + index = spec.indexOf('#'); + } + + if (index != -1) { + to += spec.substring(index); + } + debug('App specific redirection from ' + spec + ' to ' + to); + return Services.io.newURI(to, null, null); + } + } + } else { + return null; + } + }, + classID : APPS_SERVICE_CID, QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService]) } diff --git a/dom/apps/src/AppsUtils.jsm b/dom/apps/src/AppsUtils.jsm index d88ebf0380e2..6c9ea2d82df1 100644 --- a/dom/apps/src/AppsUtils.jsm +++ b/dom/apps/src/AppsUtils.jsm @@ -20,13 +20,13 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() { // Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js -this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper"]; +this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper", "isAbsoluteURI"]; function debug(s) { //dump("-*- AppsUtils.jsm: " + s + "\n"); } -function isAbsoluteURI(aURI) { +this.isAbsoluteURI = function(aURI) { let foo = Services.io.newURI("http://foo", null, null); let bar = Services.io.newURI("http://bar", null, null); return Services.io.newURI(aURI, null, foo).prePath != foo.prePath || @@ -92,7 +92,8 @@ this.AppsUtils = { installerAppId: aApp.installerAppId || Ci.nsIScriptSecurityManager.NO_APP_ID, installerIsBrowser: !!aApp.installerIsBrowser, storeId: aApp.storeId || "", - storeVersion: aApp.storeVersion || 0 + storeVersion: aApp.storeVersion || 0, + redirects: aApp.redirects }; }, diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index 5898e294b945..8e1e25b0d441 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -196,6 +196,24 @@ this.DOMApplicationRegistry = { this._saveApps(); }, + // Ensure that the .to property in redirects is a relative URL. + sanitizeRedirects: function sanitizeRedirects(aSource) { + if (!aSource) { + return null; + } + + let res = []; + for (let i = 0; i < aSource.length; i++) { + let redirect = aSource[i]; + if (redirect.from && redirect.to && + isAbsoluteURI(redirect.from) && + !isAbsoluteURI(redirect.to)) { + res.push(redirect); + } + } + return res.length > 0 ? res : null; + }, + // Registers all the activities and system messages. registerAppsHandlers: function registerAppsHandlers(aRunUpdate) { this.notifyAppsRegistryStart(); @@ -211,7 +229,11 @@ this.DOMApplicationRegistry = { // twice this._readManifests(ids, (function readCSPs(aResults) { aResults.forEach(function registerManifest(aResult) { - this.webapps[aResult.id].csp = aResult.manifest.csp || ""; + let app = this.webapps[aResult.id]; + app.csp = aResult.manifest.csp || ""; + if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) { + app.redirects = this.sanitizeRedirects(aResult.redirects); + } }, this); }).bind(this)); @@ -673,6 +695,9 @@ this.DOMApplicationRegistry = { let manifest = aResult.manifest; app.name = manifest.name; app.csp = manifest.csp || ""; + if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) { + app.redirects = this.sanitizeRedirects(manifest.redirects); + } this._registerSystemMessages(manifest, app); appsToRegister.push({ manifest: manifest, app: app }); }, this); @@ -1327,11 +1352,14 @@ this.DOMApplicationRegistry = { return [toHexString(hash.charCodeAt(i)) for (i in hash)].join(""); }, - // Updates the activities and system message handlers. + // Updates the redirect mapping, activities and system message handlers. // aOldManifest can be null if we don't have any handler to unregister. updateAppHandlers: function(aOldManifest, aNewManifest, aApp) { debug("updateAppHandlers: old=" + aOldManifest + " new=" + aNewManifest); this.notifyAppsRegistryStart(); + if (aApp.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) { + aApp.redirects = this.sanitizeRedirects(aNewManifest.redirects); + } if (supportSystemMessages()) { if (aOldManifest) { diff --git a/dom/interfaces/apps/nsIAppsService.idl b/dom/interfaces/apps/nsIAppsService.idl index f820ba225cd3..63287ff3c9e7 100644 --- a/dom/interfaces/apps/nsIAppsService.idl +++ b/dom/interfaces/apps/nsIAppsService.idl @@ -6,6 +6,7 @@ interface mozIDOMApplication; interface mozIApplication; +interface nsIURI; %{C++ #define APPS_SERVICE_CID { 0x05072afa, 0x92fe, 0x45bf, { 0xae, 0x22, 0x39, 0xb6, 0x9c, 0x11, 0x70, 0x58 } } @@ -16,7 +17,7 @@ interface mozIApplication; * This service allows accessing some DOMApplicationRegistry methods from * non-javascript code. */ -[scriptable, uuid(1113c6e3-28a2-4315-be10-8b3230eecc0f)] +[scriptable, uuid(27b995cf-bec8-47de-aa48-6117c950fce3)] interface nsIAppsService : nsISupports { mozIDOMApplication getAppByManifestURL(in DOMString manifestURL); @@ -63,6 +64,12 @@ interface nsIAppsService : nsISupports jsval getAppInfo(in DOMString appId); + /** + * Returns a URI to redirect to when we get a redirection to 'uri'. + * Returns null if no redirection is declared for this uri. + */ + nsIURI getRedirect(in unsigned long localId, in nsIURI uri); + /** * Returns the localId if the app was installed from a store */ From 2567640baec3367b2c7b6ef2e0061384d1aaefb8 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Tue, 14 May 2013 13:17:22 -0700 Subject: [PATCH 2/7] Bug 862353: Remove unnecessary code checking for mozSettings twice in Geolocation tests. r=reuben --- dom/tests/mochitest/geolocation/geolocation_common.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dom/tests/mochitest/geolocation/geolocation_common.js b/dom/tests/mochitest/geolocation/geolocation_common.js index e16439408432..c38b2bc98f13 100644 --- a/dom/tests/mochitest/geolocation/geolocation_common.js +++ b/dom/tests/mochitest/geolocation/geolocation_common.js @@ -99,11 +99,6 @@ function check_geolocation(location) { function toggleGeolocationSetting(value, callback) { var mozSettings = window.navigator.mozSettings; - if (!mozSettings) { - addLoadEvent(toggleGeolocationSetting.bind(null, value, callback)); - return; - } - var lock = mozSettings.createLock(); var geoenabled = {"geolocation.enabled": value}; From dc3cd58064628a3b6030a7dcb4b384088784d7c5 Mon Sep 17 00:00:00 2001 From: Albert Crespell Date: Tue, 23 Apr 2013 09:27:05 +0200 Subject: [PATCH 3/7] Bug 783966 - Process netd's InterfaceChange(600) and BandwidthControl(601) message. r=vchang --- dom/system/gonk/NetworkManager.js | 4 ++++ dom/system/gonk/net_worker.js | 34 +++++++++++++++++++++++++++++++ ipc/netd/Netd.cpp | 3 +-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js index 2324f0cd69b3..81e69560deb4 100644 --- a/dom/system/gonk/NetworkManager.js +++ b/dom/system/gonk/NetworkManager.js @@ -401,6 +401,10 @@ NetworkManager.prototype = { debug("NetworkManager received message from worker: " + JSON.stringify(e.data)); let response = e.data; let id = response.id; + if (id == 'broadcast') { + Services.obs.notifyObservers(null, response.topic, response.reason); + return; + } let callback = this.controlCallbacks[id]; if (callback) { callback.call(this, response); diff --git a/dom/system/gonk/net_worker.js b/dom/system/gonk/net_worker.js index 71cadd46340a..a0fcc1e69363 100644 --- a/dom/system/gonk/net_worker.js +++ b/dom/system/gonk/net_worker.js @@ -24,6 +24,9 @@ const SYS_USB_STATE_PROPERTY = "sys.usb.state"; const USB_FUNCTION_RNDIS = "rndis"; const USB_FUNCTION_ADB = "adb"; +const kNetdInterfaceChangedTopic = "netd-interface-change"; +const kNetdBandwidthControlTopic = "netd-bandwidth-control"; + // Retry 20 times (2 seconds) for usb state transition. const USB_FUNCTION_RETRY_TIMES = 20; // Check "sys.usb.state" every 100ms. @@ -41,12 +44,21 @@ const NETD_COMMAND_ERROR = 500; // 6xx - Unsolicited broadcasts const NETD_COMMAND_UNSOLICITED = 600; +// Broadcast messages +const NETD_COMMAND_INTERFACE_CHANGE = 600; +const NETD_COMMAND_BANDWIDTH_CONTROLLER = 601; + importScripts("systemlibs.js"); function netdResponseType(code) { return Math.floor(code/100)*100; } +function isBroadcastMessage(code) { + let type = netdResponseType(code); + return (type == NETD_COMMAND_UNSOLICITED); +} + function isError(code) { let type = netdResponseType(code); return (type != NETD_COMMAND_PROCEEDING && type != NETD_COMMAND_OKAY); @@ -57,6 +69,22 @@ function isComplete(code) { return (type != NETD_COMMAND_PROCEEDING); } +function sendBroadcastMessage(code, reason) { + let topic = null; + switch (code) { + case NETD_COMMAND_INTERFACE_CHANGE: + topic = "netd-interface-change"; + break; + case NETD_COMMAND_BANDWIDTH_CONTROLLER: + topic = "netd-bandwidth-control"; + break; + } + + if (topic) { + postMessage({id: 'broadcast', topic: topic, reason: reason}); + } +} + let gWifiFailChain = [stopSoftAP, setIpForwardingEnabled, stopTethering]; @@ -253,6 +281,12 @@ function onNetdMessage(data) { // 1xx response code regards as command is proceeding, we need to wait for // final response code such as 2xx, 4xx and 5xx before sending next command. + if (isBroadcastMessage(code)) { + sendBroadcastMessage(code, reason); + nextNetdCommand(); + return; + } + if (isComplete(code)) { gPending = false; } diff --git a/ipc/netd/Netd.cpp b/ipc/netd/Netd.cpp index 8accd58db34f..c0f4bc2d3722 100644 --- a/ipc/netd/Netd.cpp +++ b/ipc/netd/Netd.cpp @@ -156,8 +156,7 @@ void NetdClient::OnLineRead(int aFd, nsDependentCSubstring& aMessage) // integer response code followed by the rest of the line. // Fish out the response code. int responseCode = strtol(aMessage.Data(), nullptr, 10); - // TODO, Bug 783966, handle InterfaceChange(600) and BandwidthControl(601). - if (!errno && responseCode < 600) { + if (!errno) { NetdCommand* response = new NetdCommand(); // Passing all the response message, including the line terminator. response->mSize = aMessage.Length(); From 4be181127dbb8723f7517671798006c160147107 Mon Sep 17 00:00:00 2001 From: Patrick Wang Date: Mon, 13 May 2013 17:38:49 +0800 Subject: [PATCH 4/7] Bug 871463 - allow to fallback to software codec in emulator. r=doublec --- content/media/omx/OmxDecoder.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/content/media/omx/OmxDecoder.cpp b/content/media/omx/OmxDecoder.cpp index 924a345e84c7..5af5645c3c37 100644 --- a/content/media/omx/OmxDecoder.cpp +++ b/content/media/omx/OmxDecoder.cpp @@ -256,6 +256,13 @@ bool OmxDecoder::Init() { // for (h.264). So if we don't get a hardware decoder, just give // up. int flags = kHardwareCodecsOnly; + + char propQemu[PROPERTY_VALUE_MAX]; + property_get("ro.kernel.qemu", propQemu, ""); + if (!strncmp(propQemu, "1", 1)) { + // If we are in emulator, allow to fall back to software. + flags = 0; + } videoSource = OMXCodec::Create(omx, videoTrack->getFormat(), false, // decoder From 536fafeb07feab6be2fbbc163b061aebefc6e6ec Mon Sep 17 00:00:00 2001 From: Eric Chou Date: Wed, 15 May 2013 16:53:45 +0800 Subject: [PATCH 5/7] Bug 872238 - After CreateUnique(), append file leaf name to dsf.mPath, not dsf.mFile.mPath, r=dhylands This is a followup to bug 858416. --- dom/devicestorage/nsDeviceStorage.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 4b5c4fcb9108..063e193749d8 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -750,16 +750,17 @@ DeviceStorageFile::CreateUnique(nsAString& aFileName, NS_ENSURE_SUCCESS(rv, nullptr); // CreateUnique may cause the filename to change. So we need to update mPath to reflect that. - - int32_t lastSlashIndex = dsf->mPath.RFindChar('/'); - if (lastSlashIndex == kNotFound) { - dsf->mPath.AssignLiteral(""); - } else { - dsf->mPath = Substring(dsf->mPath, 0, lastSlashIndex); - } nsString leafName; dsf->mFile->GetLeafName(leafName); - dsf->AppendRelativePath(leafName); + + int32_t lastSlashIndex = dsf->mPath.RFindChar('/'); + if (lastSlashIndex == kNotFound) { + dsf->mPath.Assign(leafName); + } else { + // Include the last '/' + dsf->mPath = Substring(dsf->mPath, 0, lastSlashIndex + 1); + dsf->mPath.Append(leafName); + } return dsf.forget(); } From c005576fa2ea5311031092fd30913f606bc50c38 Mon Sep 17 00:00:00 2001 From: Eric Chou Date: Wed, 15 May 2013 17:12:48 +0800 Subject: [PATCH 6/7] Bug 871366 - Cut operator name if it is longer than 16 characters, r=gyeh --- dom/bluetooth/BluetoothHfpManager.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dom/bluetooth/BluetoothHfpManager.cpp b/dom/bluetooth/BluetoothHfpManager.cpp index e70d4147b2b4..77bd1fea5d49 100644 --- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -658,6 +658,19 @@ BluetoothHfpManager::HandleVoiceConnectionChanged() NS_ENSURE_TRUE(network, NS_ERROR_FAILURE); network->GetLongName(mOperatorName); + // According to GSM 07.07, " indicates if the format is alphanumeric + // or numeric; long alphanumeric format can be upto 16 characters long and + // short format up to 8 characters (refer GSM MoU SE.13 [9])..." + // However, we found that the operator name may sometimes be longer than 16 + // characters. After discussion, we decided to fix this here but not in RIL + // or modem. + // + // Please see Bug 871366 for more information. + if (mOperatorName.Length() > 16) { + NS_WARNING("The operator name was longer than 16 characters. We cut it."); + mOperatorName.Left(mOperatorName, 16); + } + return NS_OK; } From 2cbf53d5af4eb805521e6ec6a5d6c92c027ceab3 Mon Sep 17 00:00:00 2001 From: Gene Lian Date: Wed, 15 May 2013 12:42:27 +0800 Subject: [PATCH 7/7] Bug 872373 - B2G MMS: sendMMS(...) fails to create a proper thread ID for send/sending event. r=vicamo a=leo+ --- dom/mobilemessage/src/MmsMessage.cpp | 2 ++ dom/mobilemessage/src/ipc/SmsTypes.ipdlh | 1 + 2 files changed, 3 insertions(+) diff --git a/dom/mobilemessage/src/MmsMessage.cpp b/dom/mobilemessage/src/MmsMessage.cpp index a1ba6b075562..41cdc565ab47 100644 --- a/dom/mobilemessage/src/MmsMessage.cpp +++ b/dom/mobilemessage/src/MmsMessage.cpp @@ -61,6 +61,7 @@ MmsMessage::MmsMessage(int32_t aId, MmsMessage::MmsMessage(const mobilemessage::MmsMessageData& aData) : mId(aData.id()) + , mThreadId(aData.threadId()) , mDelivery(aData.delivery()) , mDeliveryStatus(aData.deliveryStatus()) , mSender(aData.sender()) @@ -281,6 +282,7 @@ MmsMessage::GetData(ContentParent* aParent, NS_ASSERTION(aParent, "aParent is null"); aData.id() = mId; + aData.threadId() = mThreadId; aData.delivery() = mDelivery; aData.deliveryStatus() = mDeliveryStatus; aData.sender().Assign(mSender); diff --git a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh index 79260f968392..b0f17cc79613 100644 --- a/dom/mobilemessage/src/ipc/SmsTypes.ipdlh +++ b/dom/mobilemessage/src/ipc/SmsTypes.ipdlh @@ -48,6 +48,7 @@ struct MmsAttachmentData struct MmsMessageData { int32_t id; + uint64_t threadId; DeliveryState delivery; DeliveryStatus[] deliveryStatus; nsString sender;