mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 814625 - Part 4: DOM: Refactor. r=khuey
This commit is contained in:
parent
b9396ba2d7
commit
7a698c9040
@ -175,26 +175,58 @@ Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv)
|
||||
return telephony.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
Telephony::IsValidNumber(const nsAString& aNumber)
|
||||
{
|
||||
return !aNumber.IsEmpty();
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
Telephony::IsActiveState(uint16_t aCallState) {
|
||||
return aCallState == nsITelephonyProvider::CALL_STATE_DIALING ||
|
||||
aCallState == nsITelephonyProvider::CALL_STATE_ALERTING ||
|
||||
aCallState == nsITelephonyProvider::CALL_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
bool
|
||||
Telephony::HasDialingCall()
|
||||
{
|
||||
for (uint32_t i = 0; i < mCalls.Length(); i++) {
|
||||
const nsRefPtr<TelephonyCall>& call = mCalls[i];
|
||||
if (call->IsOutgoing() &&
|
||||
call->CallState() > nsITelephonyProvider::CALL_STATE_UNKNOWN &&
|
||||
call->CallState() < nsITelephonyProvider::CALL_STATE_CONNECTED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Telephony::MatchActiveCall(TelephonyCall* aCall)
|
||||
{
|
||||
return (mActiveCall &&
|
||||
mActiveCall->CallIndex() == aCall->CallIndex());
|
||||
}
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
Telephony::DialInternal(bool isEmergency,
|
||||
const nsAString& aNumber,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aNumber.IsEmpty()) {
|
||||
if (!IsValidNumber(aNumber)) {
|
||||
aRv.Throw(NS_ERROR_INVALID_ARG);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < mCalls.Length(); index++) {
|
||||
const nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
|
||||
if (tempCall->IsOutgoing() &&
|
||||
tempCall->CallState() < nsITelephonyProvider::CALL_STATE_CONNECTED) {
|
||||
// One call has been dialed already and we only support one outgoing call
|
||||
// at a time.
|
||||
NS_WARNING("Only permitted to dial one call at a time!");
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
// We only support one outgoing call at a time.
|
||||
if (HasDialingCall()) {
|
||||
NS_WARNING("Only permitted to dial one call at a time!");
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult rv = mProvider->Dial(aNumber, isEmergency);
|
||||
@ -206,8 +238,8 @@ Telephony::DialInternal(bool isEmergency,
|
||||
nsRefPtr<TelephonyCall> call = CreateNewDialingCall(aNumber);
|
||||
|
||||
// Notify other telephony objects that we just dialed.
|
||||
for (uint32_t index = 0; index < gTelephonyList->Length(); index++) {
|
||||
Telephony*& telephony = gTelephonyList->ElementAt(index);
|
||||
for (uint32_t i = 0; i < gTelephonyList->Length(); i++) {
|
||||
Telephony*& telephony = gTelephonyList->ElementAt(i);
|
||||
if (telephony != this) {
|
||||
nsRefPtr<Telephony> kungFuDeathGrip = telephony;
|
||||
telephony->NoteDialedCallFromOtherInstance(aNumber);
|
||||
@ -244,16 +276,11 @@ Telephony::NotifyCallsChanged(TelephonyCall* aCall)
|
||||
}
|
||||
|
||||
void
|
||||
Telephony::UpdateActiveCall(TelephonyCall* aCall, bool aIsAdding)
|
||||
Telephony::UpdateActiveCall(TelephonyCall* aCall, bool aIsActive)
|
||||
{
|
||||
if (aIsAdding) {
|
||||
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()) {
|
||||
if (aIsActive) {
|
||||
mActiveCall = aCall;
|
||||
} else if (MatchActiveCall(aCall)) {
|
||||
mActiveCall = nullptr;
|
||||
}
|
||||
}
|
||||
@ -274,32 +301,36 @@ Telephony::GetCall(uint32_t aCallIndex)
|
||||
return call.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
Telephony::MoveCall(uint32_t aCallIndex, bool aIsConference)
|
||||
already_AddRefed<TelephonyCall>
|
||||
Telephony::GetOutgoingCall()
|
||||
{
|
||||
nsRefPtr<TelephonyCall> call;
|
||||
|
||||
// Move a call to mGroup.
|
||||
if (aIsConference) {
|
||||
call = GetCall(aCallIndex);
|
||||
if (call) {
|
||||
RemoveCall(call);
|
||||
mGroup->AddCall(call);
|
||||
return true;
|
||||
for (uint32_t i = 0; i < mCalls.Length(); i++) {
|
||||
nsRefPtr<TelephonyCall>& tempCall = mCalls[i];
|
||||
if (tempCall->CallIndex() == kOutgoingPlaceholderCallIndex) {
|
||||
NS_ASSERTION(!call, "More than one outgoing call not supported!");
|
||||
NS_ASSERTION(tempCall->CallState() == nsITelephonyProvider::CALL_STATE_DIALING,
|
||||
"Something really wrong here!");
|
||||
|
||||
call = tempCall;
|
||||
// No break. We will search entire list to ensure only one outgoing call.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove a call from mGroup.
|
||||
call = mGroup->GetCall(aCallIndex);
|
||||
if (call) {
|
||||
mGroup->RemoveCall(call);
|
||||
AddCall(call);
|
||||
return true;
|
||||
return call.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
Telephony::GetCallFromEverywhere(uint32_t aCallIndex)
|
||||
{
|
||||
nsRefPtr<TelephonyCall> call = GetCall(aCallIndex);
|
||||
|
||||
if (!call) {
|
||||
call = mGroup->GetCall(aCallIndex);
|
||||
}
|
||||
|
||||
return false;
|
||||
return call.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Telephony)
|
||||
@ -444,116 +475,70 @@ Telephony::CallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
|
||||
NS_ASSERTION(aCallIndex != kOutgoingPlaceholderCallIndex,
|
||||
"This should never happen!");
|
||||
|
||||
nsRefPtr<TelephonyCall> modifiedCall;
|
||||
nsRefPtr<TelephonyCall> outgoingCall;
|
||||
nsRefPtr<TelephonyCall> modifiedCall
|
||||
= GetCallFromEverywhere(aCallIndex);
|
||||
|
||||
// Update calls array first then state of a call in mCalls.
|
||||
// Try to use the outgoing call if we don't find the modified call.
|
||||
if (!modifiedCall) {
|
||||
nsRefPtr<TelephonyCall> outgoingCall = GetOutgoingCall();
|
||||
|
||||
if (aIsConference) {
|
||||
// Add the call into mGroup if it hasn't been there, otherwise we simply
|
||||
// update its call state. We don't fire the statechange event on a call in
|
||||
// conference here. Instead, the event will be fired later in
|
||||
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
||||
// statechange events is guaranteed: first on TelephonyCallGroup then on
|
||||
// individual TelephonyCall objects.
|
||||
// If the call state isn't incoming but we do have an outgoing call then
|
||||
// we must be seeing a status update for our outgoing call.
|
||||
if (outgoingCall &&
|
||||
aCallState != nsITelephonyProvider::CALL_STATE_INCOMING) {
|
||||
outgoingCall->UpdateCallIndex(aCallIndex);
|
||||
outgoingCall->UpdateEmergency(aIsEmergency);
|
||||
modifiedCall.swap(outgoingCall);
|
||||
}
|
||||
}
|
||||
|
||||
modifiedCall = mGroup->GetCall(aCallIndex);
|
||||
if (modifiedCall) {
|
||||
modifiedCall->ChangeStateInternal(aCallState, false);
|
||||
return NS_OK;
|
||||
if (modifiedCall) {
|
||||
if (!aIsConference) {
|
||||
UpdateActiveCall(modifiedCall, aIsActive);
|
||||
}
|
||||
|
||||
// The call becomes a conference call. Remove it from Telephony::mCalls and
|
||||
// add it to mGroup.
|
||||
modifiedCall = GetCall(aCallIndex);
|
||||
if (modifiedCall) {
|
||||
modifiedCall->ChangeStateInternal(aCallState, false);
|
||||
if (modifiedCall->CallState() != aCallState) {
|
||||
// We don't fire the statechange event on a call in conference here.
|
||||
// Instead, the event will be fired later in
|
||||
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
||||
// statechange events is guaranteed: first on TelephonyCallGroup then on
|
||||
// individual TelephonyCall objects.
|
||||
bool fireEvent = !aIsConference;
|
||||
modifiedCall->ChangeStateInternal(aCallState, fireEvent);
|
||||
}
|
||||
|
||||
nsRefPtr<TelephonyCallGroup> group = modifiedCall->GetGroup();
|
||||
|
||||
if (!group && aIsConference) {
|
||||
// Add to conference.
|
||||
NS_ASSERTION(mCalls.Contains(modifiedCall), "Should in mCalls");
|
||||
mGroup->AddCall(modifiedCall);
|
||||
RemoveCall(modifiedCall);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Didn't find this call in mCalls or mGroup. Create a new call.
|
||||
nsRefPtr<TelephonyCall> call =
|
||||
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex,
|
||||
aIsEmergency, aIsConference);
|
||||
NS_ASSERTION(call, "This should never fail!");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Not a conference call. Remove the call from mGroup if it has been there.
|
||||
modifiedCall = mGroup->GetCall(aCallIndex);
|
||||
if (modifiedCall) {
|
||||
if (aCallState != nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
|
||||
if (modifiedCall->CallState() != aCallState) {
|
||||
modifiedCall->ChangeState(aCallState);
|
||||
}
|
||||
} else if (group && !aIsConference) {
|
||||
// Remove from conference.
|
||||
NS_ASSERTION(mGroup->CallsArray().Contains(modifiedCall), "Should in mGroup");
|
||||
mGroup->RemoveCall(modifiedCall);
|
||||
AddCall(modifiedCall);
|
||||
} else {
|
||||
modifiedCall->ChangeState(aCallState);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Update calls in mCalls.
|
||||
for (uint32_t index = 0; index < mCalls.Length(); index++) {
|
||||
nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
|
||||
if (tempCall->CallIndex() == kOutgoingPlaceholderCallIndex) {
|
||||
NS_ASSERTION(!outgoingCall, "More than one outgoing call not supported!");
|
||||
NS_ASSERTION(tempCall->CallState() ==
|
||||
nsITelephonyProvider::CALL_STATE_DIALING,
|
||||
"Something really wrong here!");
|
||||
// Stash this for later, we may need it if aCallIndex doesn't match one of
|
||||
// our other calls.
|
||||
outgoingCall = tempCall;
|
||||
} else if (tempCall->CallIndex() == aCallIndex) {
|
||||
// We already know about this call so just update its state.
|
||||
modifiedCall = tempCall;
|
||||
outgoingCall = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing matched above and the call state isn't incoming but we do have
|
||||
// an outgoing call then we must be seeing a status update for our outgoing
|
||||
// call.
|
||||
if (!modifiedCall &&
|
||||
aCallState != nsITelephonyProvider::CALL_STATE_INCOMING &&
|
||||
outgoingCall) {
|
||||
outgoingCall->UpdateCallIndex(aCallIndex);
|
||||
outgoingCall->UpdateEmergency(aIsEmergency);
|
||||
modifiedCall.swap(outgoingCall);
|
||||
}
|
||||
|
||||
if (modifiedCall) {
|
||||
// See if this should replace our current active call.
|
||||
if (aIsActive) {
|
||||
mActiveCall = modifiedCall;
|
||||
} else if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
|
||||
mActiveCall = nullptr;
|
||||
}
|
||||
|
||||
// Change state.
|
||||
modifiedCall->ChangeState(aCallState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Didn't know anything about this call before now.
|
||||
|
||||
// Do nothing since we didn't know anything about it before now and it's
|
||||
// ended already.
|
||||
if (aCallState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
|
||||
// Do nothing since we didn't know anything about it before now and it's
|
||||
// been ended already.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Didn't find this call in mCalls or mGroup. Create a new call.
|
||||
nsRefPtr<TelephonyCall> call =
|
||||
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex, aIsEmergency);
|
||||
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex,
|
||||
aIsEmergency, aIsConference);
|
||||
NS_ASSERTION(call, "This should never fail!");
|
||||
|
||||
NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
|
||||
NS_ASSERTION(aIsConference ? mGroup->CallsArray().Contains(call) :
|
||||
mCalls.Contains(call),
|
||||
"Should have auto-added new call!");
|
||||
|
||||
if (aCallState == nsITelephonyProvider::CALL_STATE_INCOMING) {
|
||||
nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("incoming"), call);
|
||||
@ -596,13 +581,8 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState,
|
||||
// However, it is likely to have call state changes, i.e. CallStateChanged()
|
||||
// being called, before the enumeration result comes back. We'd make sure
|
||||
// we don't somehow add duplicates due to the race condition.
|
||||
call = aIsConference ? mGroup->GetCall(aCallIndex) : GetCall(aCallIndex);
|
||||
call = GetCallFromEverywhere(aCallIndex);
|
||||
if (call) {
|
||||
// We have the call either in mCalls or in mGroup. Skip it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (MoveCall(aCallIndex, aIsConference)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -649,28 +629,22 @@ NS_IMETHODIMP
|
||||
Telephony::NotifyError(int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
nsRefPtr<TelephonyCall> callToNotify;
|
||||
if (!mCalls.IsEmpty()) {
|
||||
// The connection is not established yet. Get the latest dialing call object.
|
||||
if (aCallIndex == -1) {
|
||||
nsRefPtr<TelephonyCall>& lastCall = mCalls[mCalls.Length() - 1];
|
||||
if (lastCall->CallIndex() == kOutgoingPlaceholderCallIndex) {
|
||||
callToNotify = lastCall;
|
||||
}
|
||||
} else {
|
||||
// The connection has been established. Get the failed call.
|
||||
callToNotify = GetCall(aCallIndex);
|
||||
}
|
||||
if (mCalls.IsEmpty()) {
|
||||
NS_ERROR("No existing call!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsRefPtr<TelephonyCall> callToNotify;
|
||||
|
||||
callToNotify = (aCallIndex == -1) ? GetOutgoingCall()
|
||||
: GetCall(aCallIndex);
|
||||
|
||||
if (!callToNotify) {
|
||||
NS_ERROR("Don't call me with a bad call index!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (mActiveCall && mActiveCall->CallIndex() == callToNotify->CallIndex()) {
|
||||
mActiveCall = nullptr;
|
||||
}
|
||||
UpdateActiveCall(callToNotify, false);
|
||||
|
||||
// Set the call state to 'disconnected' and remove it from the calls list.
|
||||
callToNotify->NotifyError(aError);
|
||||
|
@ -111,7 +111,7 @@ public:
|
||||
{
|
||||
NS_ASSERTION(!mCalls.Contains(aCall), "Already know about this one!");
|
||||
mCalls.AppendElement(aCall);
|
||||
UpdateActiveCall(aCall, true);
|
||||
UpdateActiveCall(aCall, IsActiveState(aCall->CallState()));
|
||||
NotifyCallsChanged(aCall);
|
||||
}
|
||||
|
||||
@ -145,6 +145,18 @@ private:
|
||||
void
|
||||
Shutdown();
|
||||
|
||||
static bool
|
||||
IsValidNumber(const nsAString& aNumber);
|
||||
|
||||
static bool
|
||||
IsActiveState(uint16_t aCallState);
|
||||
|
||||
bool
|
||||
HasDialingCall();
|
||||
|
||||
bool
|
||||
MatchActiveCall(TelephonyCall* aCall);
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
DialInternal(bool isEmergency,
|
||||
const nsAString& aNumber,
|
||||
@ -160,20 +172,22 @@ private:
|
||||
NotifyCallsChanged(TelephonyCall* aCall);
|
||||
|
||||
nsresult
|
||||
DispatchCallEvent(const nsAString& aType,
|
||||
TelephonyCall* aCall);
|
||||
DispatchCallEvent(const nsAString& aType, TelephonyCall* aCall);
|
||||
|
||||
void
|
||||
EnqueueEnumerationAck();
|
||||
|
||||
void
|
||||
UpdateActiveCall(TelephonyCall* aCall, bool aIsAdding);
|
||||
UpdateActiveCall(TelephonyCall* aCall, bool aIsActive);
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
GetCall(uint32_t aCallIndex);
|
||||
|
||||
bool
|
||||
MoveCall(uint32_t aCallIndex, bool aIsConference);
|
||||
already_AddRefed<TelephonyCall>
|
||||
GetOutgoingCall();
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
GetCallFromEverywhere(uint32_t aCallIndex);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
Loading…
Reference in New Issue
Block a user