Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/presentation/PresentationReceiver.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
6
7
#include "PresentationReceiver.h"
8
9
#include "mozilla/dom/PresentationReceiverBinding.h"
10
#include "mozilla/dom/Promise.h"
11
#include "nsContentUtils.h"
12
#include "nsIPresentationService.h"
13
#include "nsPIDOMWindow.h"
14
#include "nsServiceManagerUtils.h"
15
#include "nsThreadUtils.h"
16
#include "PresentationConnection.h"
17
#include "PresentationConnectionList.h"
18
#include "PresentationLog.h"
19
20
namespace mozilla {
21
namespace dom {
22
23
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PresentationReceiver,
24
                                      mOwner,
25
                                      mGetConnectionListPromise,
26
                                      mConnectionList)
27
28
NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationReceiver)
29
NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationReceiver)
30
31
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationReceiver)
32
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
33
0
  NS_INTERFACE_MAP_ENTRY(nsIPresentationRespondingListener)
34
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
35
0
NS_INTERFACE_MAP_END
36
37
/* static */ already_AddRefed<PresentationReceiver>
38
PresentationReceiver::Create(nsPIDOMWindowInner* aWindow)
39
0
{
40
0
  RefPtr<PresentationReceiver> receiver = new PresentationReceiver(aWindow);
41
0
  return NS_WARN_IF(!receiver->Init()) ? nullptr : receiver.forget();
42
0
}
43
44
PresentationReceiver::PresentationReceiver(nsPIDOMWindowInner* aWindow)
45
  : mOwner(aWindow)
46
0
{
47
0
  MOZ_ASSERT(aWindow);
48
0
}
49
50
PresentationReceiver::~PresentationReceiver()
51
0
{
52
0
  Shutdown();
53
0
}
54
55
bool
56
PresentationReceiver::Init()
57
0
{
58
0
  if (NS_WARN_IF(!mOwner)) {
59
0
    return false;
60
0
  }
61
0
  mWindowId = mOwner->WindowID();
62
0
63
0
  nsCOMPtr<nsIDocShell> docShell = mOwner->GetDocShell();
64
0
  MOZ_ASSERT(docShell);
65
0
66
0
  nsContentUtils::GetPresentationURL(docShell, mUrl);
67
0
  return !mUrl.IsEmpty();
68
0
}
69
70
void PresentationReceiver::Shutdown()
71
0
{
72
0
  PRES_DEBUG("receiver shutdown:windowId[%" PRId64 "]\n", mWindowId);
73
0
74
0
  // Unregister listener for incoming sessions.
75
0
  nsCOMPtr<nsIPresentationService> service =
76
0
    do_GetService(PRESENTATION_SERVICE_CONTRACTID);
77
0
  if (NS_WARN_IF(!service)) {
78
0
    return;
79
0
  }
80
0
81
0
  Unused <<
82
0
    NS_WARN_IF(NS_FAILED(service->UnregisterRespondingListener(mWindowId)));
83
0
}
84
85
/* virtual */ JSObject*
86
PresentationReceiver::WrapObject(JSContext* aCx,
87
                                 JS::Handle<JSObject*> aGivenProto)
88
0
{
89
0
  return PresentationReceiver_Binding::Wrap(aCx, this, aGivenProto);
90
0
}
91
92
NS_IMETHODIMP
93
PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
94
                                           const nsAString& aSessionId)
95
0
{
96
0
  PRES_DEBUG("receiver session connect:id[%s], windowId[%" PRIx64 "]\n",
97
0
             NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId);
98
0
99
0
  if (NS_WARN_IF(!mOwner)) {
100
0
    return NS_ERROR_FAILURE;
101
0
  }
102
0
103
0
  if (NS_WARN_IF(aWindowId != mWindowId)) {
104
0
    return NS_ERROR_INVALID_ARG;
105
0
  }
106
0
107
0
  if (NS_WARN_IF(!mConnectionList)) {
108
0
    return NS_ERROR_FAILURE;
109
0
  }
110
0
111
0
  RefPtr<PresentationConnection> connection =
112
0
    PresentationConnection::Create(mOwner, aSessionId, mUrl,
113
0
                                   nsIPresentationService::ROLE_RECEIVER,
114
0
                                   mConnectionList);
115
0
  if (NS_WARN_IF(!connection)) {
116
0
    return NS_ERROR_NOT_AVAILABLE;
117
0
  }
118
0
119
0
  return NS_OK;
120
0
}
121
122
already_AddRefed<Promise>
123
PresentationReceiver::GetConnectionList(ErrorResult& aRv)
124
0
{
125
0
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mOwner);
126
0
  if (NS_WARN_IF(!global)) {
127
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
128
0
    return nullptr;
129
0
  }
130
0
131
0
  if (!mGetConnectionListPromise) {
132
0
    mGetConnectionListPromise = Promise::Create(global, aRv);
133
0
    if (NS_WARN_IF(aRv.Failed())) {
134
0
      return nullptr;
135
0
    }
136
0
137
0
    RefPtr<PresentationReceiver> self = this;
138
0
    nsresult rv = NS_DispatchToMainThread(NS_NewRunnableFunction(
139
0
      "dom::PresentationReceiver::GetConnectionList",
140
0
      [self]() -> void { self->CreateConnectionList(); }));
141
0
    if (NS_FAILED(rv)) {
142
0
      aRv.Throw(rv);
143
0
      return nullptr;
144
0
    }
145
0
  }
146
0
147
0
  RefPtr<Promise> promise = mGetConnectionListPromise;
148
0
  if (nsContentUtils::ShouldResistFingerprinting()) {
149
0
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
150
0
  }
151
0
  return promise.forget();
152
0
}
153
154
void
155
PresentationReceiver::CreateConnectionList()
156
0
{
157
0
  MOZ_ASSERT(mGetConnectionListPromise);
158
0
159
0
  if (mConnectionList) {
160
0
    return;
161
0
  }
162
0
163
0
  mConnectionList = new PresentationConnectionList(mOwner,
164
0
                                                   mGetConnectionListPromise);
165
0
166
0
  // Register listener for incoming sessions.
167
0
  nsCOMPtr<nsIPresentationService> service =
168
0
    do_GetService(PRESENTATION_SERVICE_CONTRACTID);
169
0
  if (NS_WARN_IF(!service)) {
170
0
    mGetConnectionListPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
171
0
    return;
172
0
  }
173
0
174
0
  nsresult rv = service->RegisterRespondingListener(mWindowId, this);
175
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
176
0
    mGetConnectionListPromise->MaybeReject(rv);
177
0
  }
178
0
}
179
180
} // namespace dom
181
} // namespace mozilla