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 "nsWebNavigationInfo.h"
8 #include "nsIWebNavigation.h"
9 #include "nsServiceManagerUtils.h"
10 #include "nsIDocumentLoaderFactory.h"
11 #include "nsIPluginHost.h"
12 #include "nsIDocShell.h"
13 #include "nsContentUtils.h"
14 #include "imgLoader.h"
15 #include "nsPluginHost.h"
16
NS_IMPL_ISUPPORTS(nsWebNavigationInfo,nsIWebNavigationInfo)17 NS_IMPL_ISUPPORTS(nsWebNavigationInfo, nsIWebNavigationInfo)
18
19 nsresult nsWebNavigationInfo::Init() {
20 nsresult rv;
21 mCategoryManager = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
22 NS_ENSURE_SUCCESS(rv, rv);
23
24 return NS_OK;
25 }
26
27 NS_IMETHODIMP
IsTypeSupported(const nsACString & aType,nsIWebNavigation * aWebNav,uint32_t * aIsTypeSupported)28 nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
29 nsIWebNavigation* aWebNav,
30 uint32_t* aIsTypeSupported) {
31 NS_PRECONDITION(aIsTypeSupported, "null out param?");
32
33 // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
34 // an nsSHistory, but not much we can do with that). So if we start using
35 // it here, we need to be careful to get to the docshell correctly.
36
37 // For now just report what the Gecko-Content-Viewers category has
38 // to say for itself.
39 *aIsTypeSupported = nsIWebNavigationInfo::UNSUPPORTED;
40
41 // We want to claim that the type for PDF documents is unsupported,
42 // so that the internal PDF viewer's stream converted will get used.
43 if (aType.LowerCaseEqualsLiteral("application/pdf") &&
44 nsContentUtils::IsPDFJSEnabled()) {
45 return NS_OK;
46 }
47
48 const nsCString& flatType = PromiseFlatCString(aType);
49 nsresult rv = IsTypeSupportedInternal(flatType, aIsTypeSupported);
50 NS_ENSURE_SUCCESS(rv, rv);
51
52 if (*aIsTypeSupported) {
53 return rv;
54 }
55
56 // As of FF 52, we only support flash and test plugins, so if the mime types
57 // don't match for that, exit before we start loading plugins.
58 if (!nsPluginHost::CanUsePluginForMIMEType(aType)) {
59 return NS_OK;
60 }
61
62 // If this request is for a docShell that isn't going to allow plugins,
63 // there's no need to try and find a plugin to handle it.
64 nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebNav));
65 bool allowed;
66 if (docShell && NS_SUCCEEDED(docShell->GetAllowPlugins(&allowed)) &&
67 !allowed) {
68 return NS_OK;
69 }
70
71 // Try reloading plugins in case they've changed.
72 nsCOMPtr<nsIPluginHost> pluginHost =
73 do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
74 if (pluginHost) {
75 // false will ensure that currently running plugins will not
76 // be shut down
77 rv = pluginHost->ReloadPlugins();
78 if (NS_SUCCEEDED(rv)) {
79 // OK, we reloaded plugins and there were new ones
80 // (otherwise NS_ERROR_PLUGINS_PLUGINSNOTCHANGED would have
81 // been returned). Try checking whether we can handle the
82 // content now.
83 return IsTypeSupportedInternal(flatType, aIsTypeSupported);
84 }
85 }
86
87 return NS_OK;
88 }
89
IsTypeSupportedInternal(const nsCString & aType,uint32_t * aIsSupported)90 nsresult nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
91 uint32_t* aIsSupported) {
92 NS_PRECONDITION(aIsSupported, "Null out param?");
93
94 nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
95
96 nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
97 nsContentUtils::FindInternalContentViewer(aType, &vtype);
98
99 switch (vtype) {
100 case nsContentUtils::TYPE_UNSUPPORTED:
101 *aIsSupported = nsIWebNavigationInfo::UNSUPPORTED;
102 break;
103
104 case nsContentUtils::TYPE_PLUGIN:
105 *aIsSupported = nsIWebNavigationInfo::PLUGIN;
106 break;
107
108 case nsContentUtils::TYPE_UNKNOWN:
109 *aIsSupported = nsIWebNavigationInfo::OTHER;
110 break;
111
112 case nsContentUtils::TYPE_CONTENT:
113 // XXXbz we only need this because images register for the same
114 // contractid as documents, so we can't tell them apart based on
115 // contractid.
116 if (imgLoader::SupportImageWithMimeType(aType.get())) {
117 *aIsSupported = nsIWebNavigationInfo::IMAGE;
118 } else {
119 *aIsSupported = nsIWebNavigationInfo::OTHER;
120 }
121 break;
122 }
123
124 return NS_OK;
125 }
126