Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/presentation/Presentation.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 "Presentation.h"
8
9
#include <ctype.h>
10
11
#include "mozilla/dom/PresentationBinding.h"
12
#include "mozilla/dom/Promise.h"
13
#include "nsContentUtils.h"
14
#include "nsCycleCollectionParticipant.h"
15
#include "nsIDocShell.h"
16
#include "nsIPresentationService.h"
17
#include "nsIScriptSecurityManager.h"
18
#include "nsJSUtils.h"
19
#include "nsNetUtil.h"
20
#include "nsPIDOMWindow.h"
21
#include "nsSandboxFlags.h"
22
#include "nsServiceManagerUtils.h"
23
#include "PresentationReceiver.h"
24
25
namespace mozilla {
26
namespace dom {
27
28
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Presentation,
29
                                      mWindow,
30
                                      mDefaultRequest, mReceiver)
31
32
NS_IMPL_CYCLE_COLLECTING_ADDREF(Presentation)
33
NS_IMPL_CYCLE_COLLECTING_RELEASE(Presentation)
34
35
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Presentation)
36
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
37
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
38
0
NS_INTERFACE_MAP_END
39
40
/* static */ already_AddRefed<Presentation>
41
Presentation::Create(nsPIDOMWindowInner* aWindow)
42
0
{
43
0
  RefPtr<Presentation> presentation = new Presentation(aWindow);
44
0
  return presentation.forget();
45
0
}
46
47
Presentation::Presentation(nsPIDOMWindowInner* aWindow)
48
  : mWindow(aWindow)
49
0
{
50
0
}
51
52
Presentation::~Presentation()
53
0
{
54
0
}
55
56
/* virtual */ JSObject*
57
Presentation::WrapObject(JSContext* aCx,
58
                         JS::Handle<JSObject*> aGivenProto)
59
0
{
60
0
  return Presentation_Binding::Wrap(aCx, this, aGivenProto);
61
0
}
62
63
void
64
Presentation::SetDefaultRequest(PresentationRequest* aRequest)
65
0
{
66
0
  if (nsContentUtils::ShouldResistFingerprinting()) {
67
0
    return;
68
0
  }
69
0
70
0
  nsCOMPtr<nsIDocument> doc = mWindow ? mWindow->GetExtantDoc() : nullptr;
71
0
  if (NS_WARN_IF(!doc)) {
72
0
    return;
73
0
  }
74
0
75
0
  if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) {
76
0
    return;
77
0
  }
78
0
79
0
  mDefaultRequest = aRequest;
80
0
}
81
82
already_AddRefed<PresentationRequest>
83
Presentation::GetDefaultRequest() const
84
0
{
85
0
  if (nsContentUtils::ShouldResistFingerprinting()) {
86
0
    return nullptr;
87
0
  }
88
0
89
0
  RefPtr<PresentationRequest> request = mDefaultRequest;
90
0
  return request.forget();
91
0
}
92
93
already_AddRefed<PresentationReceiver>
94
Presentation::GetReceiver()
95
0
{
96
0
  if (nsContentUtils::ShouldResistFingerprinting()) {
97
0
    return nullptr;
98
0
  }
99
0
100
0
  // return the same receiver if already created
101
0
  if (mReceiver) {
102
0
    RefPtr<PresentationReceiver> receiver = mReceiver;
103
0
    return receiver.forget();
104
0
  }
105
0
106
0
  if (!HasReceiverSupport() || !IsInPresentedContent()) {
107
0
    return nullptr;
108
0
  }
109
0
110
0
  mReceiver = PresentationReceiver::Create(mWindow);
111
0
  if (NS_WARN_IF(!mReceiver)) {
112
0
    MOZ_ASSERT(mReceiver);
113
0
    return nullptr;
114
0
  }
115
0
116
0
  RefPtr<PresentationReceiver> receiver = mReceiver;
117
0
  return receiver.forget();
118
0
}
119
120
void
121
Presentation::SetStartSessionUnsettled(bool aIsUnsettled)
122
0
{
123
0
  mStartSessionUnsettled = aIsUnsettled;
124
0
}
125
126
bool
127
Presentation::IsStartSessionUnsettled() const
128
0
{
129
0
  return mStartSessionUnsettled;
130
0
}
131
132
bool
133
Presentation::HasReceiverSupport() const
134
0
{
135
0
  if (!mWindow) {
136
0
    return false;
137
0
  }
138
0
139
0
  // Grant access to browser receiving pages and their same-origin iframes. (App
140
0
  // pages should be controlled by "presentation" permission in app manifests.)
141
0
  nsCOMPtr<nsIDocShell> docShell = mWindow->GetDocShell();
142
0
  if (!docShell) {
143
0
    return false;
144
0
  }
145
0
146
0
  if (!Preferences::GetBool("dom.presentation.testing.simulate-receiver") &&
147
0
      !docShell->GetIsInMozBrowser() &&
148
0
      !docShell->GetIsTopLevelContentDocShell()) {
149
0
    return false;
150
0
  }
151
0
152
0
  nsAutoString presentationURL;
153
0
  nsContentUtils::GetPresentationURL(docShell, presentationURL);
154
0
155
0
  if (presentationURL.IsEmpty()) {
156
0
    return false;
157
0
  }
158
0
159
0
  nsCOMPtr<nsIScriptSecurityManager> securityManager =
160
0
    nsContentUtils::GetSecurityManager();
161
0
  if (!securityManager) {
162
0
    return false;
163
0
  }
164
0
165
0
  nsCOMPtr<nsIURI> presentationURI;
166
0
  nsresult rv = NS_NewURI(getter_AddRefs(presentationURI), presentationURL);
167
0
  if (NS_FAILED(rv)) {
168
0
    return false;
169
0
  }
170
0
171
0
  bool isPrivateWin = false;
172
0
  nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
173
0
  if (doc) {
174
0
    isPrivateWin =
175
0
      doc->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId > 0;
176
0
  }
177
0
178
0
  nsCOMPtr<nsIURI> docURI = mWindow->GetDocumentURI();
179
0
  return NS_SUCCEEDED(securityManager->CheckSameOriginURI(presentationURI,
180
0
                                                          docURI,
181
0
                                                          false,
182
0
                                                          isPrivateWin));
183
0
}
184
185
bool
186
Presentation::IsInPresentedContent() const
187
0
{
188
0
  if (!mWindow) {
189
0
    return false;
190
0
  }
191
0
192
0
  nsCOMPtr<nsIDocShell> docShell = mWindow->GetDocShell();
193
0
  MOZ_ASSERT(docShell);
194
0
195
0
  nsAutoString presentationURL;
196
0
  nsContentUtils::GetPresentationURL(docShell, presentationURL);
197
0
198
0
  return !presentationURL.IsEmpty();
199
0
}
200
201
} // namespace dom
202
} // namespace mozilla