dom/telephony/TelephonyCallGroup.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.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "TelephonyCallGroup.h"
michael@0 8 #include "mozilla/dom/TelephonyCallGroupBinding.h"
michael@0 9
michael@0 10 #include "CallEvent.h"
michael@0 11 #include "CallsList.h"
michael@0 12 #include "mozilla/dom/CallGroupErrorEvent.h"
michael@0 13 #include "Telephony.h"
michael@0 14
michael@0 15 using namespace mozilla::dom;
michael@0 16 using mozilla::ErrorResult;
michael@0 17
michael@0 18 TelephonyCallGroup::TelephonyCallGroup(nsPIDOMWindow* aOwner)
michael@0 19 : DOMEventTargetHelper(aOwner)
michael@0 20 , mCallState(nsITelephonyProvider::CALL_STATE_UNKNOWN)
michael@0 21 {
michael@0 22 }
michael@0 23
michael@0 24 TelephonyCallGroup::~TelephonyCallGroup()
michael@0 25 {
michael@0 26 }
michael@0 27
michael@0 28 // static
michael@0 29 already_AddRefed<TelephonyCallGroup>
michael@0 30 TelephonyCallGroup::Create(Telephony* aTelephony)
michael@0 31 {
michael@0 32 NS_ASSERTION(aTelephony, "Null telephony!");
michael@0 33
michael@0 34 nsRefPtr<TelephonyCallGroup> group =
michael@0 35 new TelephonyCallGroup(aTelephony->GetOwner());
michael@0 36
michael@0 37 group->mTelephony = aTelephony;
michael@0 38 group->mCallsList = new CallsList(aTelephony, group);
michael@0 39
michael@0 40 return group.forget();
michael@0 41 }
michael@0 42
michael@0 43 JSObject*
michael@0 44 TelephonyCallGroup::WrapObject(JSContext* aCx)
michael@0 45 {
michael@0 46 return TelephonyCallGroupBinding::Wrap(aCx, this);
michael@0 47 }
michael@0 48
michael@0 49 void
michael@0 50 TelephonyCallGroup::AddCall(TelephonyCall* aCall)
michael@0 51 {
michael@0 52 NS_ASSERTION(!mCalls.Contains(aCall), "Already know about this one!");
michael@0 53 mCalls.AppendElement(aCall);
michael@0 54 aCall->ChangeGroup(this);
michael@0 55 NotifyCallsChanged(aCall);
michael@0 56 }
michael@0 57
michael@0 58 void
michael@0 59 TelephonyCallGroup::RemoveCall(TelephonyCall* aCall)
michael@0 60 {
michael@0 61 NS_ASSERTION(mCalls.Contains(aCall), "Didn't know about this one!");
michael@0 62 mCalls.RemoveElement(aCall);
michael@0 63 aCall->ChangeGroup(nullptr);
michael@0 64 NotifyCallsChanged(aCall);
michael@0 65 }
michael@0 66
michael@0 67 nsresult
michael@0 68 TelephonyCallGroup::NotifyError(const nsAString& aName, const nsAString& aMessage)
michael@0 69 {
michael@0 70 CallGroupErrorEventInit init;
michael@0 71 init.mBubbles = false;
michael@0 72 init.mCancelable = false;
michael@0 73 init.mName = aName;
michael@0 74 init.mMessage = aMessage;
michael@0 75
michael@0 76 nsRefPtr<CallGroupErrorEvent> event =
michael@0 77 CallGroupErrorEvent::Constructor(this, NS_LITERAL_STRING("error"), init);
michael@0 78
michael@0 79 return DispatchTrustedEvent(event);
michael@0 80 }
michael@0 81
michael@0 82 void
michael@0 83 TelephonyCallGroup::ChangeState(uint16_t aCallState)
michael@0 84 {
michael@0 85 if (mCallState == aCallState) {
michael@0 86 return;
michael@0 87 }
michael@0 88
michael@0 89 nsString stateString;
michael@0 90 switch (aCallState) {
michael@0 91 case nsITelephonyProvider::CALL_STATE_UNKNOWN:
michael@0 92 break;
michael@0 93 case nsITelephonyProvider::CALL_STATE_CONNECTED:
michael@0 94 stateString.AssignLiteral("connected");
michael@0 95 break;
michael@0 96 case nsITelephonyProvider::CALL_STATE_HOLDING:
michael@0 97 stateString.AssignLiteral("holding");
michael@0 98 break;
michael@0 99 case nsITelephonyProvider::CALL_STATE_HELD:
michael@0 100 stateString.AssignLiteral("held");
michael@0 101 break;
michael@0 102 case nsITelephonyProvider::CALL_STATE_RESUMING:
michael@0 103 stateString.AssignLiteral("resuming");
michael@0 104 break;
michael@0 105 default:
michael@0 106 NS_NOTREACHED("Unknown state!");
michael@0 107 }
michael@0 108
michael@0 109 mState = stateString;
michael@0 110 mCallState = aCallState;
michael@0 111
michael@0 112 nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("statechange"), nullptr);
michael@0 113 if (NS_FAILED(rv)) {
michael@0 114 NS_WARNING("Failed to dispatch specific event!");
michael@0 115 }
michael@0 116 if (!stateString.IsEmpty()) {
michael@0 117 // This can change if the statechange handler called back here... Need to
michael@0 118 // figure out something smarter.
michael@0 119 if (mCallState == aCallState) {
michael@0 120 rv = DispatchCallEvent(stateString, nullptr);
michael@0 121 if (NS_FAILED(rv)) {
michael@0 122 NS_WARNING("Failed to dispatch specific event!");
michael@0 123 }
michael@0 124 }
michael@0 125 }
michael@0 126
michael@0 127 for (uint32_t index = 0; index < mCalls.Length(); index++) {
michael@0 128 nsRefPtr<TelephonyCall> call = mCalls[index];
michael@0 129 call->ChangeState(aCallState);
michael@0 130
michael@0 131 MOZ_ASSERT(call->CallState() == aCallState);
michael@0 132 }
michael@0 133 }
michael@0 134
michael@0 135 nsresult
michael@0 136 TelephonyCallGroup::NotifyCallsChanged(TelephonyCall* aCall)
michael@0 137 {
michael@0 138 return DispatchCallEvent(NS_LITERAL_STRING("callschanged"), aCall);
michael@0 139 }
michael@0 140
michael@0 141 nsresult
michael@0 142 TelephonyCallGroup::DispatchCallEvent(const nsAString& aType,
michael@0 143 TelephonyCall* aCall)
michael@0 144 {
michael@0 145 nsRefPtr<CallEvent> event = CallEvent::Create(this, aType, aCall, false, false);
michael@0 146 return DispatchTrustedEvent(event);
michael@0 147 }
michael@0 148
michael@0 149 bool
michael@0 150 TelephonyCallGroup::CanConference(const TelephonyCall& aCall,
michael@0 151 TelephonyCall* aSecondCall)
michael@0 152 {
michael@0 153 if (!aCall.Mergeable()) {
michael@0 154 return false;
michael@0 155 }
michael@0 156
michael@0 157 if (!aSecondCall) {
michael@0 158 MOZ_ASSERT(!mCalls.IsEmpty());
michael@0 159
michael@0 160 return (mCallState == nsITelephonyProvider::CALL_STATE_CONNECTED &&
michael@0 161 aCall.CallState() == nsITelephonyProvider::CALL_STATE_HELD) ||
michael@0 162 (mCallState == nsITelephonyProvider::CALL_STATE_HELD &&
michael@0 163 aCall.CallState() == nsITelephonyProvider::CALL_STATE_CONNECTED);
michael@0 164 }
michael@0 165
michael@0 166 MOZ_ASSERT(mCallState == nsITelephonyProvider::CALL_STATE_UNKNOWN);
michael@0 167
michael@0 168 if (aCall.ServiceId() != aSecondCall->ServiceId()) {
michael@0 169 return false;
michael@0 170 }
michael@0 171
michael@0 172 if (!aSecondCall->Mergeable()) {
michael@0 173 return false;
michael@0 174 }
michael@0 175
michael@0 176 return (aCall.CallState() == nsITelephonyProvider::CALL_STATE_CONNECTED &&
michael@0 177 aSecondCall->CallState() == nsITelephonyProvider::CALL_STATE_HELD) ||
michael@0 178 (aCall.CallState() == nsITelephonyProvider::CALL_STATE_HELD &&
michael@0 179 aSecondCall->CallState() == nsITelephonyProvider::CALL_STATE_CONNECTED);
michael@0 180 }
michael@0 181
michael@0 182 already_AddRefed<TelephonyCall>
michael@0 183 TelephonyCallGroup::GetCall(uint32_t aServiceId, uint32_t aCallIndex)
michael@0 184 {
michael@0 185 nsRefPtr<TelephonyCall> call;
michael@0 186
michael@0 187 for (uint32_t index = 0; index < mCalls.Length(); index++) {
michael@0 188 nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
michael@0 189 if (tempCall->ServiceId() == aServiceId &&
michael@0 190 tempCall->CallIndex() == aCallIndex) {
michael@0 191 call = tempCall;
michael@0 192 break;
michael@0 193 }
michael@0 194 }
michael@0 195
michael@0 196 return call.forget();
michael@0 197 }
michael@0 198
michael@0 199 NS_IMPL_CYCLE_COLLECTION_CLASS(TelephonyCallGroup)
michael@0 200
michael@0 201 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCallGroup,
michael@0 202 DOMEventTargetHelper)
michael@0 203 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCalls)
michael@0 204 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallsList)
michael@0 205 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
michael@0 206 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 207
michael@0 208 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCallGroup,
michael@0 209 DOMEventTargetHelper)
michael@0 210 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCalls)
michael@0 211 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallsList)
michael@0 212 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTelephony)
michael@0 213 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 214
michael@0 215 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCallGroup)
michael@0 216 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 217
michael@0 218 NS_IMPL_ADDREF_INHERITED(TelephonyCallGroup, DOMEventTargetHelper)
michael@0 219 NS_IMPL_RELEASE_INHERITED(TelephonyCallGroup, DOMEventTargetHelper)
michael@0 220
michael@0 221 // WebIDL
michael@0 222 already_AddRefed<CallsList>
michael@0 223 TelephonyCallGroup::Calls() const
michael@0 224 {
michael@0 225 nsRefPtr<CallsList> list = mCallsList;
michael@0 226 return list.forget();
michael@0 227 }
michael@0 228
michael@0 229 void
michael@0 230 TelephonyCallGroup::Add(TelephonyCall& aCall,
michael@0 231 ErrorResult& aRv)
michael@0 232 {
michael@0 233 if (!CanConference(aCall, nullptr)) {
michael@0 234 aRv.Throw(NS_ERROR_NOT_AVAILABLE);
michael@0 235 return;
michael@0 236 }
michael@0 237
michael@0 238 aRv = mTelephony->Provider()->ConferenceCall(aCall.ServiceId());
michael@0 239 }
michael@0 240
michael@0 241 void
michael@0 242 TelephonyCallGroup::Add(TelephonyCall& aCall,
michael@0 243 TelephonyCall& aSecondCall,
michael@0 244 ErrorResult& aRv)
michael@0 245 {
michael@0 246 if (!CanConference(aCall, &aSecondCall)) {
michael@0 247 aRv.Throw(NS_ERROR_NOT_AVAILABLE);
michael@0 248 return;
michael@0 249 }
michael@0 250
michael@0 251 aRv = mTelephony->Provider()->ConferenceCall(aCall.ServiceId());
michael@0 252 }
michael@0 253
michael@0 254 void
michael@0 255 TelephonyCallGroup::Remove(TelephonyCall& aCall, ErrorResult& aRv)
michael@0 256 {
michael@0 257 if (mCallState != nsITelephonyProvider::CALL_STATE_CONNECTED) {
michael@0 258 NS_WARNING("Remove call from a non-connected call group. Ignore!");
michael@0 259 return;
michael@0 260 }
michael@0 261
michael@0 262 uint32_t serviceId = aCall.ServiceId();
michael@0 263 uint32_t callIndex = aCall.CallIndex();
michael@0 264
michael@0 265 nsRefPtr<TelephonyCall> call;
michael@0 266
michael@0 267 call = GetCall(serviceId, callIndex);
michael@0 268 if (call) {
michael@0 269 aRv = mTelephony->Provider()->SeparateCall(serviceId, callIndex);
michael@0 270 } else {
michael@0 271 NS_WARNING("Didn't have this call. Ignore!");
michael@0 272 }
michael@0 273 }
michael@0 274
michael@0 275 void
michael@0 276 TelephonyCallGroup::Hold(ErrorResult& aRv)
michael@0 277 {
michael@0 278 if (mCallState != nsITelephonyProvider::CALL_STATE_CONNECTED) {
michael@0 279 NS_WARNING("Hold non-connected call ignored!");
michael@0 280 return;
michael@0 281 }
michael@0 282
michael@0 283 MOZ_ASSERT(!mCalls.IsEmpty());
michael@0 284
michael@0 285 nsresult rv = mTelephony->Provider()->HoldConference(mCalls[0]->ServiceId());
michael@0 286 if (NS_FAILED(rv)) {
michael@0 287 aRv.Throw(rv);
michael@0 288 return;
michael@0 289 }
michael@0 290
michael@0 291 ChangeState(nsITelephonyProvider::CALL_STATE_HOLDING);
michael@0 292 }
michael@0 293
michael@0 294 void
michael@0 295 TelephonyCallGroup::Resume(ErrorResult& aRv)
michael@0 296 {
michael@0 297 if (mCallState != nsITelephonyProvider::CALL_STATE_HELD) {
michael@0 298 NS_WARNING("Resume non-held call ignored!");
michael@0 299 return;
michael@0 300 }
michael@0 301
michael@0 302 MOZ_ASSERT(!mCalls.IsEmpty());
michael@0 303
michael@0 304 nsresult rv = mTelephony->Provider()->ResumeConference(mCalls[0]->ServiceId());
michael@0 305 if (NS_FAILED(rv)) {
michael@0 306 aRv.Throw(rv);
michael@0 307 return;
michael@0 308 }
michael@0 309
michael@0 310 ChangeState(nsITelephonyProvider::CALL_STATE_RESUMING);
michael@0 311 }

mercurial