dom/telephony/TelephonyCall.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     2 /* vim: set ts=2 et sw=2 tw=40: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "TelephonyCall.h"
     8 #include "mozilla/dom/TelephonyCallBinding.h"
    10 #include "mozilla/dom/DOMError.h"
    12 #include "CallEvent.h"
    13 #include "Telephony.h"
    14 #include "TelephonyCallGroup.h"
    16 using namespace mozilla::dom;
    17 using mozilla::ErrorResult;
    18 using mozilla::dom::telephony::kOutgoingPlaceholderCallIndex;
    20 // static
    21 already_AddRefed<TelephonyCall>
    22 TelephonyCall::Create(Telephony* aTelephony, uint32_t aServiceId,
    23                       const nsAString& aNumber, uint16_t aCallState,
    24                       uint32_t aCallIndex, bool aEmergency, bool aIsConference,
    25                       bool aSwitchable, bool aMergeable)
    26 {
    27   NS_ASSERTION(aTelephony, "Null pointer!");
    28   NS_ASSERTION(!aNumber.IsEmpty(), "Empty number!");
    29   NS_ASSERTION(aCallIndex >= 1, "Invalid call index!");
    31   nsRefPtr<TelephonyCall> call = new TelephonyCall(aTelephony->GetOwner());
    33   call->mTelephony = aTelephony;
    34   call->mServiceId = aServiceId;
    35   call->mNumber = aNumber;
    36   call->mCallIndex = aCallIndex;
    37   call->mError = nullptr;
    38   call->mEmergency = aEmergency;
    39   call->mGroup = aIsConference ? aTelephony->ConferenceGroup() : nullptr;
    40   call->mSwitchable = aSwitchable;
    41   call->mMergeable = aMergeable;
    43   call->ChangeStateInternal(aCallState, false);
    45   return call.forget();
    46 }
    48 TelephonyCall::TelephonyCall(nsPIDOMWindow* aOwner)
    49   : DOMEventTargetHelper(aOwner),
    50     mCallIndex(kOutgoingPlaceholderCallIndex),
    51     mCallState(nsITelephonyProvider::CALL_STATE_UNKNOWN),
    52     mLive(false)
    53 {
    54 }
    56 TelephonyCall::~TelephonyCall()
    57 {
    58 }
    60 JSObject*
    61 TelephonyCall::WrapObject(JSContext* aCx)
    62 {
    63   return TelephonyCallBinding::Wrap(aCx, this);
    64 }
    66 void
    67 TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
    68 {
    69   nsRefPtr<TelephonyCall> kungFuDeathGrip(this);
    71   nsString stateString;
    72   switch (aCallState) {
    73     case nsITelephonyProvider::CALL_STATE_DIALING:
    74       stateString.AssignLiteral("dialing");
    75       break;
    76     case nsITelephonyProvider::CALL_STATE_ALERTING:
    77       stateString.AssignLiteral("alerting");
    78       break;
    79     case nsITelephonyProvider::CALL_STATE_CONNECTING:
    80       stateString.AssignLiteral("connecting");
    81       break;
    82     case nsITelephonyProvider::CALL_STATE_CONNECTED:
    83       stateString.AssignLiteral("connected");
    84       break;
    85     case nsITelephonyProvider::CALL_STATE_HOLDING:
    86       stateString.AssignLiteral("holding");
    87       break;
    88     case nsITelephonyProvider::CALL_STATE_HELD:
    89       stateString.AssignLiteral("held");
    90       break;
    91     case nsITelephonyProvider::CALL_STATE_RESUMING:
    92       stateString.AssignLiteral("resuming");
    93       break;
    94     case nsITelephonyProvider::CALL_STATE_DISCONNECTING:
    95       stateString.AssignLiteral("disconnecting");
    96       break;
    97     case nsITelephonyProvider::CALL_STATE_DISCONNECTED:
    98       stateString.AssignLiteral("disconnected");
    99       break;
   100     case nsITelephonyProvider::CALL_STATE_INCOMING:
   101       stateString.AssignLiteral("incoming");
   102       break;
   103     default:
   104       NS_NOTREACHED("Unknown state!");
   105   }
   107   mState = stateString;
   108   mCallState = aCallState;
   110   if (aCallState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
   111     NS_ASSERTION(mLive, "Should be live!");
   112     mLive = false;
   113     if (mGroup) {
   114       mGroup->RemoveCall(this);
   115     } else {
   116       mTelephony->RemoveCall(this);
   117     }
   118   } else if (!mLive) {
   119     mLive = true;
   120     if (mGroup) {
   121       mGroup->AddCall(this);
   122     } else {
   123       mTelephony->AddCall(this);
   124     }
   125   }
   127   if (aFireEvents) {
   128     nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("statechange"), this);
   129     if (NS_FAILED(rv)) {
   130       NS_WARNING("Failed to dispatch specific event!");
   131     }
   133     // This can change if the statechange handler called back here... Need to
   134     // figure out something smarter.
   135     if (mCallState == aCallState) {
   136       rv = DispatchCallEvent(stateString, this);
   137       if (NS_FAILED(rv)) {
   138         NS_WARNING("Failed to dispatch specific event!");
   139       }
   140     }
   141   }
   142 }
   144 nsresult
   145 TelephonyCall::DispatchCallEvent(const nsAString& aType,
   146                                  TelephonyCall* aCall)
   147 {
   148   MOZ_ASSERT(aCall);
   150   nsRefPtr<CallEvent> event = CallEvent::Create(this, aType, aCall, false, false);
   152   return DispatchTrustedEvent(event);
   153 }
   155 void
   156 TelephonyCall::NotifyError(const nsAString& aError)
   157 {
   158   // Set the error string
   159   NS_ASSERTION(!mError, "Already have an error?");
   161   mError = new DOMError(GetOwner(), aError);
   163   // Do the state transitions
   164   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_DISCONNECTED, true);
   166   nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("error"), this);
   167   if (NS_FAILED(rv)) {
   168     NS_WARNING("Failed to dispatch error event!");
   169   }
   170 }
   172 void
   173 TelephonyCall::ChangeGroup(TelephonyCallGroup* aGroup)
   174 {
   175   mGroup = aGroup;
   177   nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("groupchange"), this);
   178   if (NS_FAILED(rv)) {
   179     NS_WARNING("Failed to dispatch error event!");
   180   }
   181 }
   183 NS_IMPL_CYCLE_COLLECTION_INHERITED(TelephonyCall,
   184                                    DOMEventTargetHelper,
   185                                    mTelephony,
   186                                    mError,
   187                                    mGroup);
   189 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
   190 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
   192 NS_IMPL_ADDREF_INHERITED(TelephonyCall, DOMEventTargetHelper)
   193 NS_IMPL_RELEASE_INHERITED(TelephonyCall, DOMEventTargetHelper)
   195 // TelephonyCall WebIDL
   197 already_AddRefed<DOMError>
   198 TelephonyCall::GetError() const
   199 {
   200   nsRefPtr<DOMError> error = mError;
   201   return error.forget();
   202 }
   204 already_AddRefed<TelephonyCallGroup>
   205 TelephonyCall::GetGroup() const
   206 {
   207   nsRefPtr<TelephonyCallGroup> group = mGroup;
   208   return group.forget();
   209 }
   211 void
   212 TelephonyCall::Answer(ErrorResult& aRv)
   213 {
   214   if (mCallState != nsITelephonyProvider::CALL_STATE_INCOMING) {
   215     NS_WARNING("Answer on non-incoming call ignored!");
   216     return;
   217   }
   219   nsresult rv = mTelephony->Provider()->AnswerCall(mServiceId, mCallIndex);
   220   if (NS_FAILED(rv)) {
   221     aRv.Throw(rv);
   222     return;
   223   }
   225   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_CONNECTING, true);
   226 }
   228 void
   229 TelephonyCall::HangUp(ErrorResult& aRv)
   230 {
   231   if (mCallState == nsITelephonyProvider::CALL_STATE_DISCONNECTING ||
   232       mCallState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
   233     NS_WARNING("HangUp on previously disconnected call ignored!");
   234     return;
   235   }
   237   nsresult rv = mCallState == nsITelephonyProvider::CALL_STATE_INCOMING ?
   238                 mTelephony->Provider()->RejectCall(mServiceId, mCallIndex) :
   239                 mTelephony->Provider()->HangUp(mServiceId, mCallIndex);
   240   if (NS_FAILED(rv)) {
   241     aRv.Throw(rv);
   242     return;
   243   }
   245   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_DISCONNECTING, true);
   246 }
   248 void
   249 TelephonyCall::Hold(ErrorResult& aRv)
   250 {
   251   if (mCallState != nsITelephonyProvider::CALL_STATE_CONNECTED) {
   252     NS_WARNING("Hold non-connected call ignored!");
   253     return;
   254   }
   256   if (mGroup) {
   257     NS_WARNING("Hold a call in conference ignored!");
   258     return;
   259   }
   261   if (!mSwitchable) {
   262     NS_WARNING("Hold a non-switchable call ignored!");
   263     return;
   264   }
   266   nsresult rv = mTelephony->Provider()->HoldCall(mServiceId, mCallIndex);
   267   if (NS_FAILED(rv)) {
   268     aRv.Throw(rv);
   269     return;
   270   }
   272   if (!mSecondNumber.IsEmpty()) {
   273     // No state transition when we switch two numbers within one TelephonyCall
   274     // object. Otherwise, the state here will be inconsistent with the backend
   275     // RIL and will never be right.
   276     return;
   277   }
   279   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_HOLDING, true);
   280 }
   282 void
   283 TelephonyCall::Resume(ErrorResult& aRv)
   284 {
   285   if (mCallState != nsITelephonyProvider::CALL_STATE_HELD) {
   286     NS_WARNING("Resume non-held call ignored!");
   287     return;
   288   }
   290   if (mGroup) {
   291     NS_WARNING("Resume a call in conference ignored!");
   292     return;
   293   }
   295   if (!mSwitchable) {
   296     NS_WARNING("Resume a non-switchable call ignored!");
   297     return;
   298   }
   300   nsresult rv = mTelephony->Provider()->ResumeCall(mServiceId, mCallIndex);
   301   if (NS_FAILED(rv)) {
   302     aRv.Throw(rv);
   303     return;
   304   }
   306   ChangeStateInternal(nsITelephonyProvider::CALL_STATE_RESUMING, true);
   307 }

mercurial