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/. */
7 #include "ContentHandlerService.h"
8 #include "HandlerServiceChild.h"
9 #include "ContentChild.h"
10 #include "nsIMutableArray.h"
11 #include "nsIMIMEInfo.h"
12 #include "nsIStringEnumerator.h"
13 #include "nsReadableUtils.h"
14 #include "nsMIMEInfoImpl.h"
15 #include "nsMIMEInfoChild.h"
17 using mozilla::dom::ContentChild
;
18 using mozilla::dom::HandlerInfo
;
19 using mozilla::dom::PHandlerServiceChild
;
24 NS_IMPL_ISUPPORTS(ContentHandlerService
, nsIHandlerService
)
26 ContentHandlerService::ContentHandlerService() {}
28 /* static */ already_AddRefed
<nsIHandlerService
>
29 ContentHandlerService::Create() {
30 if (XRE_IsContentProcess()) {
31 RefPtr service
= new ContentHandlerService();
32 if (NS_SUCCEEDED(service
->Init())) {
33 return service
.forget();
38 nsCOMPtr
<nsIHandlerService
> service
=
39 do_GetService("@mozilla.org/uriloader/handler-service-parent;1");
40 return service
.forget();
43 nsresult
ContentHandlerService::Init() {
44 if (!XRE_IsContentProcess()) {
45 return NS_ERROR_FAILURE
;
47 ContentChild
* cpc
= ContentChild::GetSingleton();
49 mHandlerServiceChild
= new HandlerServiceChild();
50 if (!cpc
->SendPHandlerServiceConstructor(mHandlerServiceChild
)) {
51 mHandlerServiceChild
= nullptr;
52 return NS_ERROR_UNEXPECTED
;
57 void ContentHandlerService::nsIHandlerInfoToHandlerInfo(
58 nsIHandlerInfo
* aInfo
, HandlerInfo
* aHandlerInfo
) {
61 nsCOMPtr
<nsIMIMEInfo
> mimeInfo
= do_QueryInterface(aInfo
);
62 bool isMIMEInfo
= !!mimeInfo
;
64 aInfo
->GetDescription(description
);
65 bool alwaysAskBeforeHandling
;
66 aInfo
->GetAlwaysAskBeforeHandling(&alwaysAskBeforeHandling
);
67 nsCOMPtr
<nsIHandlerApp
> app
;
68 aInfo
->GetPreferredApplicationHandler(getter_AddRefs(app
));
70 nsString detailedDescription
;
73 app
->GetDetailedDescription(detailedDescription
);
75 HandlerApp
happ(name
, detailedDescription
);
76 nsTArray
<HandlerApp
> happs
;
77 nsCOMPtr
<nsIMutableArray
> apps
;
78 aInfo
->GetPossibleApplicationHandlers(getter_AddRefs(apps
));
81 apps
->GetLength(&length
);
82 for (unsigned int i
= 0; i
< length
; i
++) {
83 apps
->QueryElementAt(i
, NS_GET_IID(nsIHandlerApp
), getter_AddRefs(app
));
85 app
->GetDetailedDescription(detailedDescription
);
86 happs
.AppendElement(HandlerApp(name
, detailedDescription
));
90 nsTArray
<nsCString
> extensions
;
93 nsCOMPtr
<nsIUTF8StringEnumerator
> extensionsIter
;
94 mimeInfo
->GetFileExtensions(getter_AddRefs(extensionsIter
));
97 while (NS_SUCCEEDED(extensionsIter
->HasMore(&hasMore
)) && hasMore
) {
98 nsAutoCString extension
;
99 if (NS_SUCCEEDED(extensionsIter
->GetNext(extension
))) {
100 extensions
.AppendElement(std::move(extension
));
106 nsHandlerInfoAction action
;
107 aInfo
->GetPreferredAction(&action
);
108 HandlerInfo
info(type
, isMIMEInfo
, description
, alwaysAskBeforeHandling
,
109 std::move(extensions
), happ
, happs
, action
);
110 *aHandlerInfo
= info
;
113 NS_IMETHODIMP
RemoteHandlerApp::GetName(nsAString
& aName
) {
114 aName
.Assign(mAppChild
.name());
118 NS_IMETHODIMP
RemoteHandlerApp::SetName(const nsAString
& aName
) {
119 return NS_ERROR_NOT_IMPLEMENTED
;
122 NS_IMETHODIMP
RemoteHandlerApp::GetDetailedDescription(
123 nsAString
& aDetailedDescription
) {
124 aDetailedDescription
.Assign(mAppChild
.detailedDescription());
128 NS_IMETHODIMP
RemoteHandlerApp::SetDetailedDescription(
129 const nsAString
& aDetailedDescription
) {
130 return NS_ERROR_NOT_IMPLEMENTED
;
133 NS_IMETHODIMP
RemoteHandlerApp::Equals(nsIHandlerApp
* aHandlerApp
,
135 return NS_ERROR_NOT_IMPLEMENTED
;
138 NS_IMETHODIMP
RemoteHandlerApp::LaunchWithURI(
139 nsIURI
* aURI
, BrowsingContext
* aBrowsingContext
) {
140 return NS_ERROR_NOT_IMPLEMENTED
;
143 NS_IMPL_ISUPPORTS(RemoteHandlerApp
, nsIHandlerApp
)
145 static inline void CopyHandlerInfoTonsIHandlerInfo(
146 const HandlerInfo
& info
, nsIHandlerInfo
* aHandlerInfo
) {
147 HandlerApp preferredApplicationHandler
= info
.preferredApplicationHandler();
148 nsCOMPtr
<nsIHandlerApp
> preferredApp(
149 new RemoteHandlerApp(preferredApplicationHandler
));
150 aHandlerInfo
->SetPreferredApplicationHandler(preferredApp
);
151 nsCOMPtr
<nsIMutableArray
> possibleHandlers
;
152 aHandlerInfo
->GetPossibleApplicationHandlers(
153 getter_AddRefs(possibleHandlers
));
154 possibleHandlers
->AppendElement(preferredApp
);
156 aHandlerInfo
->SetPreferredAction(info
.preferredAction());
157 aHandlerInfo
->SetAlwaysAskBeforeHandling(info
.alwaysAskBeforeHandling());
159 if (info
.isMIMEInfo()) {
160 nsCOMPtr
<nsIMIMEInfo
> mimeInfo(do_QueryInterface(aHandlerInfo
));
162 "parent and child don't agree on whether this is a MIME info");
163 mimeInfo
->SetFileExtensions(StringJoin(","_ns
, info
.extensions()));
167 ContentHandlerService::~ContentHandlerService() {}
169 NS_IMETHODIMP
ContentHandlerService::AsyncInit() {
170 return NS_ERROR_NOT_IMPLEMENTED
;
173 NS_IMETHODIMP
ContentHandlerService::Enumerate(nsISimpleEnumerator
** _retval
) {
174 return NS_ERROR_NOT_IMPLEMENTED
;
177 NS_IMETHODIMP
ContentHandlerService::FillHandlerInfo(
178 nsIHandlerInfo
* aHandlerInfo
, const nsACString
& aOverrideType
) {
179 HandlerInfo info
, returnedInfo
;
180 nsIHandlerInfoToHandlerInfo(aHandlerInfo
, &info
);
181 mHandlerServiceChild
->SendFillHandlerInfo(info
, aOverrideType
, &returnedInfo
);
182 CopyHandlerInfoTonsIHandlerInfo(returnedInfo
, aHandlerInfo
);
186 NS_IMETHODIMP
ContentHandlerService::GetMIMEInfoFromOS(
187 const nsACString
& aMIMEType
, const nsACString
& aFileExt
, bool* aFound
,
188 nsIMIMEInfo
** aMIMEInfo
) {
189 nsresult rv
= NS_ERROR_FAILURE
;
190 HandlerInfo returnedInfo
;
191 if (!mHandlerServiceChild
->SendGetMIMEInfoFromOS(aMIMEType
, aFileExt
, &rv
,
192 &returnedInfo
, aFound
)) {
193 return NS_ERROR_FAILURE
;
196 if (NS_WARN_IF(NS_FAILED(rv
))) {
200 RefPtr
<nsChildProcessMIMEInfo
> mimeInfo
=
201 new nsChildProcessMIMEInfo(returnedInfo
.type());
202 CopyHandlerInfoTonsIHandlerInfo(returnedInfo
, mimeInfo
);
203 mimeInfo
.forget(aMIMEInfo
);
207 NS_IMETHODIMP
ContentHandlerService::Store(nsIHandlerInfo
* aHandlerInfo
) {
208 return NS_ERROR_NOT_IMPLEMENTED
;
211 NS_IMETHODIMP
ContentHandlerService::Exists(nsIHandlerInfo
* aHandlerInfo
,
214 nsIHandlerInfoToHandlerInfo(aHandlerInfo
, &info
);
215 mHandlerServiceChild
->SendExists(info
, _retval
);
219 NS_IMETHODIMP
ContentHandlerService::Remove(nsIHandlerInfo
* aHandlerInfo
) {
220 return NS_ERROR_NOT_IMPLEMENTED
;
224 ContentHandlerService::ExistsForProtocolOS(const nsACString
& aProtocolScheme
,
226 if (!mHandlerServiceChild
->SendExistsForProtocolOS(aProtocolScheme
,
228 return NS_ERROR_FAILURE
;
234 ContentHandlerService::ExistsForProtocol(const nsACString
& aProtocolScheme
,
236 if (!mHandlerServiceChild
->SendExistsForProtocol(aProtocolScheme
, aRetval
)) {
237 return NS_ERROR_FAILURE
;
242 NS_IMETHODIMP
ContentHandlerService::GetTypeFromExtension(
243 const nsACString
& aFileExtension
, nsACString
& _retval
) {
244 _retval
.Assign(*mExtToTypeMap
.LookupOrInsertWith(aFileExtension
, [&] {
246 mHandlerServiceChild
->SendGetTypeFromExtension(aFileExtension
, &type
);
247 return MakeUnique
<nsCString
>(type
);
252 NS_IMETHODIMP
ContentHandlerService::GetApplicationDescription(
253 const nsACString
& aProtocolScheme
, nsAString
& aRetVal
) {
254 nsresult rv
= NS_ERROR_FAILURE
;
255 nsAutoCString
scheme(aProtocolScheme
);
257 mHandlerServiceChild
->SendGetApplicationDescription(scheme
, &rv
, &desc
);
258 aRetVal
.Assign(desc
);
263 } // namespace mozilla