Merge mozilla-central and birch

This commit is contained in:
Ed Morley 2013-05-22 11:26:36 +01:00
commit 948330f52b
10 changed files with 359 additions and 17 deletions

View File

@ -41,6 +41,12 @@ TelephonyListener::CallStateChanged(uint32_t aCallIndex,
return NS_OK;
}
NS_IMETHODIMP
TelephonyListener::EnumerateCallStateComplete()
{
return NS_OK;
}
NS_IMETHODIMP
TelephonyListener::EnumerateCallState(uint32_t aCallIndex,
uint16_t aCallState,

View File

@ -693,7 +693,8 @@ ContactDB.prototype = {
}
},
_clearDispatcher: function CDB_clearDispatcher(aCursorId) {
clearDispatcher: function CDB_clearDispatcher(aCursorId) {
if (DEBUG) debug("clearDispatcher: " + aCursorId);
if (aCursorId in this._dispatcher) {
delete this._dispatcher[aCursorId];
}
@ -709,7 +710,7 @@ ContactDB.prototype = {
// object store again.
if (aCachedResults && aCachedResults.length > 0) {
let newTxnFn = this.newTxn.bind(this);
let clearDispatcherFn = this._clearDispatcher.bind(this, aCursorId);
let clearDispatcherFn = this.clearDispatcher.bind(this, aCursorId);
this._dispatcher[aCursorId] = new ContactDispatcher(aCachedResults, aFullContacts,
aSuccessCb, newTxnFn, clearDispatcherFn);
this._dispatcher[aCursorId].sendNow();

View File

@ -31,6 +31,7 @@ let ContactService = {
"Contact:Remove", "Contacts:RegisterForMessages",
"child-process-shutdown", "Contacts:GetRevision"];
this._children = [];
this._cursors = {};
this._messages.forEach(function(msgName) {
ppmm.addMessageListener(msgName, this);
}.bind(this));
@ -54,6 +55,8 @@ let ContactService = {
if (this._db)
this._db.close();
this._db = null;
this._children = null;
this._cursors = null;
},
assertPermission: function(aMessage, aPerm) {
@ -98,15 +101,24 @@ let ContactService = {
if (!this.assertPermission(aMessage, "contacts-read")) {
return null;
}
if (!this._cursors[mm]) {
this._cursors[mm] = [];
}
this._cursors[mm].push(msg.cursorId);
this._db.getAll(
function(aContacts) {
try {
mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contacts: aContacts});
if (aContacts === null) {
let index = this._cursors[mm].indexOf(msg.cursorId);
this._cursors[mm].splice(index, 1);
}
} catch (e) {
if (DEBUG) debug("Child is dead, DB should stop sending contacts");
throw e;
}
},
}.bind(this),
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { errorMsg: aErrorMsg }); },
msg.findOptions, msg.cursorId);
break;
@ -188,6 +200,12 @@ let ContactService = {
if (DEBUG) debug("Unregister index: " + index);
this._children.splice(index, 1);
}
if (this._cursors[mm]) {
for (let id of this._cursors[mm]) {
this._db.clearDispatcher(id);
}
delete this._cursors[mm];
}
break;
default:
if (DEBUG) debug("WRONG MESSAGE NAME: " + aMessage.name);

View File

@ -408,6 +408,27 @@ let steps = [
}
},
clearDatabase,
addContacts,
function() {
if (!SpecialPowers.isMainProcess()) {
// We stop calling continue() intentionally here to see if the cursor gets
// cleaned up properly in the parent.
ok(true, "Leaking a cursor");
req = mozContacts.getAll({
sortBy: "familyName",
sortOrder: "ascending"
});
req.onsuccess = function(event) {
next();
};
req.onerror = onFailure;
} else {
next();
}
},
clearDatabase,
function() {
@ -422,8 +443,9 @@ function next() {
ok(false, "Shouldn't get here!");
return;
}
let i = index++;
try {
steps[index++]();
steps[i]();
} catch(ex) {
ok(false, "Caught exception", ex);
}

View File

@ -397,6 +397,10 @@ MobileConnection::GetCallBarringOption(const JS::Value& aOption,
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -410,6 +414,10 @@ MobileConnection::SetCallBarringOption(const JS::Value& aOption,
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}

View File

@ -30,6 +30,21 @@ function sendEmulatorCommand(cmd, callback) {
});
}
function setEmulatorOperatorNamesAndMccMnc(which, longName, shortName,
mcc, mnc, callback) {
let cmd = "operator set " + which + " " + longName + "," +
shortName + "," + mcc + mnc;
sendEmulatorCommand(cmd, function (result) {
let re = new RegExp("^" + longName + "," +
shortName + "," + mcc + mnc);
ok(result[which].match(re), "Long/short name and mcc/mnc should be changed.");
if (callback) {
window.setTimeout(callback, 0);
}
});
}
function setEmulatorOperatorNames(which, longName, shortName, callback) {
let cmd = "operator set " + which + " " + longName + "," + shortName;
sendEmulatorCommand(cmd, function (result) {
@ -87,13 +102,36 @@ function testMobileOperatorNames() {
doTestMobileOperatorNames("Mozilla", "", function () {
doTestMobileOperatorNames("", "B2G", function () {
doTestMobileOperatorNames("", "", function () {
doTestMobileOperatorNames("Android", "Android", testRoamingCheck);
doTestMobileOperatorNames("Android", "Android", testOperatorPLMNList);
});
});
});
});
}
function doTestOperatorPLMNList(mcc, mnc, expectedLongName,
expectedShortName, callback) {
log("Testing mcc = " + mcc + ", mnc = " + mnc + ":");
waitForVoiceChange(function () {
is(network.longName, expectedLongName, "network.longName");
is(network.shortName, expectedShortName, "network.shortName");
is(network.mcc, mcc, "network.mcc");
is(network.mnc, mnc, "network.mnc");
window.setTimeout(callback, 0);
});
setEmulatorOperatorNamesAndMccMnc(OPERATOR_HOME, "Android", "Android", mcc, mnc);
}
function testOperatorPLMNList() {
doTestOperatorPLMNList("123", "456", "Android", "Android", function() {
doTestOperatorPLMNList("310", "070", "AT&T", "", function() {
doTestOperatorPLMNList("310", "260", "Android", "Android", testRoamingCheck);
});
});
}
// See bug 797972 - B2G RIL: False roaming situation
//
// Steps to test:

View File

@ -1274,6 +1274,11 @@ RILContentHelper.prototype = {
handleEnumerateCalls: function handleEnumerateCalls(calls) {
debug("handleEnumerateCalls: " + JSON.stringify(calls));
let callback = this._enumerateTelephonyCallbacks.shift();
if (!calls.length) {
callback.enumerateCallStateComplete();
return;
}
for (let i in calls) {
let call = calls[i];
let keepGoing;
@ -1291,6 +1296,8 @@ RILContentHelper.prototype = {
break;
}
}
callback.enumerateCallStateComplete();
},
handleGetAvailableNetworks: function handleGetAvailableNetworks(message) {

View File

@ -19,12 +19,14 @@
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#include "nsTArrayHelpers.h"
#include "nsThreadUtils.h"
#include "TelephonyCall.h"
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
USING_TELEPHONY_NAMESPACE
using namespace mozilla::dom;
namespace {
@ -56,8 +58,27 @@ public:
}
};
class Telephony::EnumerationAck : public nsRunnable
{
nsRefPtr<Telephony> mTelephony;
public:
EnumerationAck(Telephony* aTelephony)
: mTelephony(aTelephony)
{
MOZ_ASSERT(mTelephony);
}
NS_IMETHOD Run()
{
mTelephony->NotifyCallsChanged(nullptr);
return NS_OK;
}
};
Telephony::Telephony()
: mActiveCall(nullptr), mCallsArray(nullptr), mRooted(false)
: mActiveCall(nullptr), mCallsArray(nullptr), mRooted(false),
mEnumerated(false)
{
if (!gTelephonyList) {
gTelephonyList = new TelephonyList();
@ -145,13 +166,15 @@ Telephony::NoteDialedCallFromOtherInstance(const nsAString& aNumber)
nsresult
Telephony::NotifyCallsChanged(TelephonyCall* aCall)
{
if (aCall->CallState() == nsITelephonyProvider::CALL_STATE_DIALING ||
aCall->CallState() == nsITelephonyProvider::CALL_STATE_ALERTING ||
aCall->CallState() == nsITelephonyProvider::CALL_STATE_CONNECTED) {
NS_ASSERTION(!mActiveCall, "Already have an active call!");
mActiveCall = aCall;
} else if (mActiveCall && mActiveCall->CallIndex() == aCall->CallIndex()) {
mActiveCall = nullptr;
if (aCall) {
if (aCall->CallState() == nsITelephonyProvider::CALL_STATE_DIALING ||
aCall->CallState() == nsITelephonyProvider::CALL_STATE_ALERTING ||
aCall->CallState() == nsITelephonyProvider::CALL_STATE_CONNECTED) {
NS_ASSERTION(!mActiveCall, "Already have an active call!");
mActiveCall = aCall;
} else if (mActiveCall && mActiveCall->CallIndex() == aCall->CallIndex()) {
mActiveCall = nullptr;
}
}
return DispatchCallEvent(NS_LITERAL_STRING("callschanged"), aCall);
@ -233,6 +256,8 @@ DOMCI_DATA(Telephony, Telephony)
NS_IMPL_ISUPPORTS1(Telephony::Listener, nsITelephonyListener)
// nsIDOMTelephony
NS_IMETHODIMP
Telephony::Dial(const nsAString& aNumber, nsIDOMTelephonyCall** aResult)
{
@ -362,7 +387,176 @@ Telephony::StopTone()
}
NS_IMPL_EVENT_HANDLER(Telephony, incoming)
NS_IMPL_EVENT_HANDLER(Telephony, callschanged)
NS_IMETHODIMP
Telephony::GetOncallschanged(JSContext* aCx, JS::Value* aValue)
{
GetEventHandler(nsGkAtoms::oncallschanged, aCx, aValue);
return NS_OK;
}
NS_IMETHODIMP
Telephony::SetOncallschanged(JSContext* aCx, const JS::Value& aValue)
{
JS::Value value;
GetEventHandler(nsGkAtoms::oncallschanged, aCx, &value);
if (aValue == value) {
// The event handler is being set to itself.
return NS_OK;
}
nsresult rv = SetEventHandler(nsGkAtoms::oncallschanged, aCx, aValue);
if (NS_FAILED(rv)) {
return rv;
}
// Fire oncallschanged on the next tick if the calls array is ready.
EnqueueEnumerationAck();
return NS_OK;
}
// nsIDOMEventTarget
NS_IMETHODIMP
Telephony::AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener, bool aUseCapture,
bool aWantsUntrusted, uint8_t aArgc)
{
nsresult rv = nsDOMEventTargetHelper::AddEventListener(aType, aListener,
aUseCapture,
aWantsUntrusted,
aArgc);
NS_ENSURE_SUCCESS(rv, rv);
if (aType.EqualsLiteral("callschanged")) {
// Fire oncallschanged on the next tick if the calls array is ready.
EnqueueEnumerationAck();
}
return NS_OK;
}
void
Telephony::AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener, bool aUseCapture,
const Nullable<bool>& aWantsUntrusted,
ErrorResult& aRv)
{
nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture,
aWantsUntrusted, aRv);
if (aRv.Failed()) {
return;
}
if (aType.EqualsLiteral("callschanged")) {
// Fire oncallschanged on the next tick if the calls array is ready.
EnqueueEnumerationAck();
}
}
NS_IMETHODIMP
Telephony::AddSystemEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture, bool aWantsUntrusted,
uint8_t aArgc)
{
nsresult rv = nsDOMEventTargetHelper::AddSystemEventListener(aType, aListener,
aUseCapture,
aWantsUntrusted,
aArgc);
NS_ENSURE_SUCCESS(rv, rv);
if (aType.EqualsLiteral("callschanged")) {
// Fire oncallschanged on the next tick if the calls array is ready.
EnqueueEnumerationAck();
}
return NS_OK;
}
NS_IMETHODIMP
Telephony::RemoveEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture)
{
return nsDOMEventTargetHelper::RemoveEventListener(aType, aListener, false);
}
NS_IMETHODIMP
Telephony::RemoveSystemEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture)
{
return nsDOMEventTargetHelper::RemoveSystemEventListener(aType, aListener,
aUseCapture);
}
NS_IMETHODIMP
Telephony::DispatchEvent(nsIDOMEvent* aEvt, bool* aRetval)
{
return nsDOMEventTargetHelper::DispatchEvent(aEvt, aRetval);
}
EventTarget*
Telephony::GetTargetForDOMEvent()
{
return nsDOMEventTargetHelper::GetTargetForDOMEvent();
}
EventTarget*
Telephony::GetTargetForEventTargetChain()
{
return nsDOMEventTargetHelper::GetTargetForEventTargetChain();
}
nsresult
Telephony::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
return nsDOMEventTargetHelper::PreHandleEvent(aVisitor);
}
nsresult
Telephony::WillHandleEvent(nsEventChainPostVisitor& aVisitor)
{
return nsDOMEventTargetHelper::WillHandleEvent(aVisitor);
}
nsresult
Telephony::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
{
return nsDOMEventTargetHelper::PostHandleEvent(aVisitor);
}
nsresult
Telephony::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus)
{
return nsDOMEventTargetHelper::DispatchDOMEvent(aEvent, aDOMEvent,
aPresContext,
aEventStatus);
}
nsEventListenerManager*
Telephony::GetListenerManager(bool aMayCreate)
{
return nsDOMEventTargetHelper::GetListenerManager(aMayCreate);
}
nsIScriptContext*
Telephony::GetContextForEventHandlers(nsresult* aRv)
{
return nsDOMEventTargetHelper::GetContextForEventHandlers(aRv);
}
JSContext*
Telephony::GetJSContextForEventHandlers()
{
return nsDOMEventTargetHelper::GetJSContextForEventHandlers();
}
// nsITelephonyListener
NS_IMETHODIMP
Telephony::CallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
@ -440,6 +634,19 @@ Telephony::CallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
return NS_OK;
}
NS_IMETHODIMP
Telephony::EnumerateCallStateComplete()
{
MOZ_ASSERT(!mEnumerated);
mEnumerated = true;
if (NS_FAILED(NotifyCallsChanged(nullptr))) {
NS_WARNING("Failed to notify calls changed!");
}
return NS_OK;
}
NS_IMETHODIMP
Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState,
const nsAString& aNumber, bool aIsActive,
@ -506,7 +713,9 @@ nsresult
Telephony::DispatchCallEvent(const nsAString& aType,
nsIDOMTelephonyCall* aCall)
{
MOZ_ASSERT(aCall);
// We will notify enumeration being completed by firing oncallschanged.
// We only ever have a null call with that event type.
MOZ_ASSERT(aCall || aType.EqualsLiteral("callschanged"));
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMCallEvent(getter_AddRefs(event), this, nullptr, nullptr);
@ -520,6 +729,19 @@ Telephony::DispatchCallEvent(const nsAString& aType,
return DispatchTrustedEvent(callEvent);
}
void
Telephony::EnqueueEnumerationAck()
{
if (!mEnumerated) {
return;
}
nsCOMPtr<nsIRunnable> task = new EnumerationAck(this);
if (NS_FAILED(NS_DispatchToCurrentThread(task))) {
NS_WARNING("Failed to dispatch to current thread!");
}
}
nsresult
NS_NewTelephony(nsPIDOMWindow* aWindow, nsIDOMTelephony** aTelephony)
{

View File

@ -30,6 +30,9 @@ class Telephony : public nsDOMEventTargetHelper,
*/
class Listener;
class EnumerationAck;
friend class EnumerationAck;
nsCOMPtr<nsITelephonyProvider> mProvider;
nsRefPtr<Listener> mListener;
@ -41,17 +44,25 @@ class Telephony : public nsDOMEventTargetHelper,
JSObject* mCallsArray;
bool mRooted;
bool mEnumerated;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMTELEPHONY
NS_DECL_NSITELEPHONYLISTENER
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
NS_DECL_NSIDOMEVENTTARGET
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
Telephony,
nsDOMEventTargetHelper)
using nsDOMEventTargetHelper::RemoveEventListener;
virtual void AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture,
const mozilla::dom::Nullable<bool>& aWantsUntrusted,
mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
static already_AddRefed<Telephony>
Create(nsPIDOMWindow* aOwner, nsITelephonyProvider* aProvider);
@ -106,6 +117,9 @@ private:
nsresult
DispatchCallEvent(const nsAString& aType,
nsIDOMTelephonyCall* aCall);
void
EnqueueEnumerationAck();
};
END_TELEPHONY_NAMESPACE

View File

@ -4,7 +4,7 @@
#include "nsISupports.idl"
[scriptable, uuid(bde19ba2-83c8-4df7-a014-28fe71535527)]
[scriptable, uuid(37fde795-7ff4-40fd-925b-3ebc07ba0cd1)]
interface nsITelephonyListener : nsISupports
{
/**
@ -30,6 +30,12 @@ interface nsITelephonyListener : nsISupports
in boolean isOutgoing,
in boolean isEmergency);
/**
* Called when enumeration asked by nsITelephonyProvider::enumerateCalls
* is completed.
*/
void enumerateCallStateComplete();
/**
* Called when nsITelephonyProvider is asked to enumerate the current
* telephony call state (nsITelephonyProvider::enumerateCalls). This is