зеркало из https://github.com/mozilla/gecko-dev.git
Bug 823958 - DOM impl- Make sure event listeners will be notified when calls array is ready (part 2/4). r=bent
This commit is contained in:
Родитель
8729362b8d
Коммит
b6a0ab6e75
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче