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 "ServiceWorkerCloneData.h"
8
9 #include <utility>
10 #include "mozilla/RefPtr.h"
11 #include "mozilla/dom/DOMTypes.h"
12 #include "mozilla/dom/StructuredCloneHolder.h"
13 #include "nsISerialEventTarget.h"
14 #include "nsProxyRelease.h"
15 #include "nsThreadUtils.h"
16
17 namespace mozilla {
18 namespace dom {
19
~ServiceWorkerCloneData()20 ServiceWorkerCloneData::~ServiceWorkerCloneData() {
21 RefPtr<ipc::SharedJSAllocatedData> sharedData = TakeSharedData();
22 if (sharedData) {
23 NS_ProxyRelease(__func__, mEventTarget, sharedData.forget());
24 }
25 }
26
ServiceWorkerCloneData()27 ServiceWorkerCloneData::ServiceWorkerCloneData()
28 : ipc::StructuredCloneData(
29 StructuredCloneHolder::StructuredCloneScope::UnknownDestination,
30 StructuredCloneHolder::TransferringSupported),
31 mEventTarget(GetCurrentSerialEventTarget()),
32 mIsErrorMessageData(false) {
33 MOZ_DIAGNOSTIC_ASSERT(mEventTarget);
34 }
35
36 bool ServiceWorkerCloneData::
StealFromAndBuildClonedMessageDataForBackgroundParent(ClonedOrErrorMessageData & aFromClonedData,mozilla::ipc::PBackgroundParent * aParent,ClonedOrErrorMessageData & aToClonedData)37 StealFromAndBuildClonedMessageDataForBackgroundParent(
38 ClonedOrErrorMessageData& aFromClonedData,
39 mozilla::ipc::PBackgroundParent* aParent,
40 ClonedOrErrorMessageData& aToClonedData) {
41 if (aFromClonedData.type() == ClonedOrErrorMessageData::TErrorMessageData) {
42 mIsErrorMessageData = true;
43 aToClonedData = ErrorMessageData();
44 return true;
45 }
46
47 MOZ_DIAGNOSTIC_ASSERT(aFromClonedData.type() ==
48 ClonedOrErrorMessageData::TClonedMessageData);
49
50 StructuredCloneData::StealFromClonedMessageDataForBackgroundParent(
51 aFromClonedData);
52
53 ClonedMessageData messageData;
54 if (!StructuredCloneData::BuildClonedMessageDataForBackgroundParent(
55 aParent, messageData)) {
56 return false;
57 }
58
59 aToClonedData = std::move(messageData);
60
61 return true;
62 }
63
BuildClonedMessageDataForBackgroundChild(mozilla::ipc::PBackgroundChild * aChild,ClonedOrErrorMessageData & aClonedData)64 bool ServiceWorkerCloneData::BuildClonedMessageDataForBackgroundChild(
65 mozilla::ipc::PBackgroundChild* aChild,
66 ClonedOrErrorMessageData& aClonedData) {
67 if (IsErrorMessageData()) {
68 aClonedData = ErrorMessageData();
69 return true;
70 }
71
72 MOZ_DIAGNOSTIC_ASSERT(
73 CloneScope() ==
74 StructuredCloneHolder::StructuredCloneScope::DifferentProcess);
75
76 ClonedMessageData messageData;
77 if (!StructuredCloneData::BuildClonedMessageDataForBackgroundChild(
78 aChild, messageData)) {
79 return false;
80 }
81
82 aClonedData = std::move(messageData);
83
84 return true;
85 }
86
CopyFromClonedMessageDataForBackgroundParent(const ClonedOrErrorMessageData & aClonedData)87 void ServiceWorkerCloneData::CopyFromClonedMessageDataForBackgroundParent(
88 const ClonedOrErrorMessageData& aClonedData) {
89 if (aClonedData.type() == ClonedOrErrorMessageData::TErrorMessageData) {
90 mIsErrorMessageData = true;
91 return;
92 }
93
94 MOZ_DIAGNOSTIC_ASSERT(aClonedData.type() ==
95 ClonedOrErrorMessageData::TClonedMessageData);
96
97 StructuredCloneData::CopyFromClonedMessageDataForBackgroundParent(
98 aClonedData);
99 }
100
CopyFromClonedMessageDataForBackgroundChild(const ClonedOrErrorMessageData & aClonedData)101 void ServiceWorkerCloneData::CopyFromClonedMessageDataForBackgroundChild(
102 const ClonedOrErrorMessageData& aClonedData) {
103 if (aClonedData.type() == ClonedOrErrorMessageData::TErrorMessageData) {
104 mIsErrorMessageData = true;
105 return;
106 }
107
108 MOZ_DIAGNOSTIC_ASSERT(aClonedData.type() ==
109 ClonedOrErrorMessageData::TClonedMessageData);
110
111 StructuredCloneData::CopyFromClonedMessageDataForBackgroundChild(aClonedData);
112 }
113
SetAsErrorMessageData()114 void ServiceWorkerCloneData::SetAsErrorMessageData() {
115 MOZ_ASSERT(CloneScope() ==
116 StructuredCloneHolder::StructuredCloneScope::SameProcess);
117
118 mIsErrorMessageData = true;
119 }
120
IsErrorMessageData() const121 bool ServiceWorkerCloneData::IsErrorMessageData() const {
122 return mIsErrorMessageData;
123 }
124
125 } // namespace dom
126 } // namespace mozilla
127