1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=2 et tw=78: */
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/. */
8 #include "base/basictypes.h"
10 #include "Navigator.h"
11 #include "nsIXULAppInfo.h"
12 #include "nsPluginArray.h"
13 #include "nsMimeTypeArray.h"
14 #include "mozilla/MemoryReporting.h"
15 #include "mozilla/dom/DesktopNotification.h"
16 #include "nsGeolocation.h"
17 #include "nsIHttpProtocolHandler.h"
18 #include "nsIContentPolicy.h"
19 #include "nsIContentSecurityPolicy.h"
20 #include "nsContentPolicyUtils.h"
21 #include "nsCrossSiteListenerProxy.h"
22 #include "nsISupportsPriority.h"
23 #include "nsICachingChannel.h"
24 #include "nsIWebContentHandlerRegistrar.h"
25 #include "nsICookiePermission.h"
26 #include "nsIScriptSecurityManager.h"
27 #include "nsCharSeparatedTokenizer.h"
28 #include "nsContentUtils.h"
29 #include "nsUnicharUtils.h"
30 #include "mozilla/Preferences.h"
31 #include "mozilla/Telemetry.h"
32 #include "BatteryManager.h"
33 #include "mozilla/dom/PowerManager.h"
34 #include "mozilla/dom/WakeLock.h"
35 #include "mozilla/dom/power/PowerManagerService.h"
36 #include "mozilla/dom/MobileMessageManager.h"
37 #include "mozilla/dom/ServiceWorkerContainer.h"
38 #include "mozilla/dom/Telephony.h"
39 #include "mozilla/Hal.h"
40 #include "nsISiteSpecificUserAgent.h"
41 #include "mozilla/ClearOnShutdown.h"
42 #include "mozilla/StaticPtr.h"
43 #include "Connection.h"
44 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
45 #include "nsGlobalWindow.h"
47 #include "nsIMobileIdentityService.h"
50 #include "mozilla/dom/IccManager.h"
51 #include "mozilla/dom/CellBroadcast.h"
52 #include "mozilla/dom/MobileConnectionArray.h"
53 #include "mozilla/dom/Voicemail.h"
55 #include "nsIIdleObserver.h"
56 #include "nsIPermissionManager.h"
57 #include "nsMimeTypes.h"
58 #include "nsNetUtil.h"
59 #include "nsIHttpChannel.h"
60 #include "nsIHttpChannelInternal.h"
61 #include "TimeManager.h"
62 #include "DeviceStorage.h"
63 #include "nsIDOMNavigatorSystemMessages.h"
64 #include "nsStreamUtils.h"
65 #include "nsIAppsService.h"
66 #include "mozIApplication.h"
67 #include "WidgetUtils.h"
68 #include "mozIThirdPartyUtil.h"
69 #include "nsChannelPolicy.h"
71 #ifdef MOZ_MEDIA_NAVIGATOR
72 #include "MediaManager.h"
75 #include "BluetoothManager.h"
77 #include "DOMCameraManager.h"
79 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
80 #include "AudioChannelManager.h"
84 #include "mozilla/dom/FMRadio.h"
87 #include "nsIDOMGlobalPropertyInitializer.h"
88 #include "mozilla/dom/DataStoreService.h"
89 #include "nsJSUtils.h"
91 #include "nsScriptNameSpaceManager.h"
93 #include "mozilla/dom/NavigatorBinding.h"
94 #include "mozilla/dom/Promise.h"
96 #include "nsIUploadChannel2.h"
97 #include "nsFormData.h"
98 #include "nsIPrivateBrowsingChannel.h"
99 #include "nsIDocShell.h"
101 #include "WorkerPrivate.h"
102 #include "WorkerRunnable.h"
104 #if defined(XP_LINUX)
105 #include "mozilla/Hal.h"
107 #include "mozilla/dom/ContentChild.h"
109 #include "mozilla/dom/FeatureList.h"
111 #ifdef MOZ_WIDGET_GONK
112 #include <cutils/properties.h>
118 static bool sDoNotTrackEnabled
= false;
119 static uint32_t sDoNotTrackValue
= 1;
120 static bool sVibratorEnabled
= false;
121 static uint32_t sMaxVibrateMS
= 0;
122 static uint32_t sMaxVibrateListLen
= 0;
128 Preferences::AddBoolVarCache(&sDoNotTrackEnabled
,
129 "privacy.donottrackheader.enabled",
131 Preferences::AddUintVarCache(&sDoNotTrackValue
,
132 "privacy.donottrackheader.value",
134 Preferences::AddBoolVarCache(&sVibratorEnabled
,
135 "dom.vibrator.enabled", true);
136 Preferences::AddUintVarCache(&sMaxVibrateMS
,
137 "dom.vibrator.max_vibrate_ms", 10000);
138 Preferences::AddUintVarCache(&sMaxVibrateListLen
,
139 "dom.vibrator.max_vibrate_list_len", 128);
142 Navigator::Navigator(nsPIDOMWindow
* aWindow
)
145 MOZ_ASSERT(aWindow
->IsInnerWindow(), "Navigator must get an inner window!");
149 Navigator::~Navigator()
154 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Navigator
)
155 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
156 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDOMNavigator
)
157 NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator
)
158 NS_INTERFACE_MAP_ENTRY(nsIMozNavigatorNetwork
)
161 NS_IMPL_CYCLE_COLLECTING_ADDREF(Navigator
)
162 NS_IMPL_CYCLE_COLLECTING_RELEASE(Navigator
)
164 NS_IMPL_CYCLE_COLLECTION_CLASS(Navigator
)
166 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Navigator
)
168 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow
)
169 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedResolveResults
)
170 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
171 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
173 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator
)
174 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins
)
175 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMimeTypes
)
176 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation
)
177 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification
)
178 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager
)
179 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager
)
180 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager
)
181 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony
)
182 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection
)
184 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections
)
185 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast
)
186 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager
)
187 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail
)
190 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBluetooth
)
192 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
193 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager
)
195 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager
)
196 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagesManager
)
197 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageStores
)
198 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager
)
199 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer
)
201 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow
)
202 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedResolveResults
)
203 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
204 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
206 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Navigator
)
209 Navigator::Invalidate()
211 // Don't clear mWindow here so we know we've got a non-null mWindow
212 // until we're unlinked.
215 mPlugins
->Invalidate();
219 mMimeTypes
= nullptr;
221 // If there is a page transition, make sure delete the geolocation object.
223 mGeolocation
->Shutdown();
224 mGeolocation
= nullptr;
228 mNotification
->Shutdown();
229 mNotification
= nullptr;
232 if (mBatteryManager
) {
233 mBatteryManager
->Shutdown();
234 mBatteryManager
= nullptr;
239 mFMRadio
->Shutdown();
245 mPowerManager
->Shutdown();
246 mPowerManager
= nullptr;
249 if (mMobileMessageManager
) {
250 mMobileMessageManager
->Shutdown();
251 mMobileMessageManager
= nullptr;
255 mTelephony
= nullptr;
259 mConnection
->Shutdown();
260 mConnection
= nullptr;
264 if (mMobileConnections
) {
265 mMobileConnections
= nullptr;
268 if (mCellBroadcast
) {
269 mCellBroadcast
= nullptr;
273 mIccManager
->Shutdown();
274 mIccManager
= nullptr;
278 mVoicemail
= nullptr;
284 mBluetooth
= nullptr;
288 mCameraManager
= nullptr;
290 if (mMessagesManager
) {
291 mMessagesManager
= nullptr;
294 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
295 if (mAudioChannelManager
) {
296 mAudioChannelManager
= nullptr;
300 uint32_t len
= mDeviceStorageStores
.Length();
301 for (uint32_t i
= 0; i
< len
; ++i
) {
302 mDeviceStorageStores
[i
]->Shutdown();
304 mDeviceStorageStores
.Clear();
307 mTimeManager
= nullptr;
310 mServiceWorkerContainer
= nullptr;
313 //*****************************************************************************
314 // Navigator::nsIDOMNavigator
315 //*****************************************************************************
318 Navigator::GetUserAgent(nsAString
& aUserAgent
)
320 nsCOMPtr
<nsIURI
> codebaseURI
;
321 nsCOMPtr
<nsPIDOMWindow
> window
;
323 if (mWindow
&& mWindow
->GetDocShell()) {
325 nsIDocument
* doc
= mWindow
->GetExtantDoc();
327 doc
->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI
));
331 return GetUserAgent(window
, codebaseURI
, nsContentUtils::IsCallerChrome(),
336 Navigator::GetAppCodeName(nsAString
& aAppCodeName
)
340 nsCOMPtr
<nsIHttpProtocolHandler
>
341 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
342 NS_ENSURE_SUCCESS(rv
, rv
);
344 nsAutoCString appName
;
345 rv
= service
->GetAppName(appName
);
346 CopyASCIItoUTF16(appName
, aAppCodeName
);
352 Navigator::GetAppVersion(nsAString
& aAppVersion
)
354 return GetAppVersion(aAppVersion
, /* aUsePrefOverriddenValue */ true);
358 Navigator::GetAppName(nsAString
& aAppName
)
360 AppName(aAppName
, /* aUsePrefOverriddenValue */ true);
365 * Returns the value of Accept-Languages (HTTP header) as a nsTArray of
366 * languages. The value is set in the preference by the user ("Content
369 * "en", "en-US" and "i-cherokee" and "" are valid languages tokens.
371 * An empty array will be returned if there is no valid languages.
374 Navigator::GetAcceptLanguages(nsTArray
<nsString
>& aLanguages
)
378 // E.g. "de-de, en-us,en".
379 const nsAdoptingString
& acceptLang
=
380 Preferences::GetLocalizedString("intl.accept_languages");
382 // Split values on commas.
383 nsCharSeparatedTokenizer
langTokenizer(acceptLang
, ',');
384 while (langTokenizer
.hasMoreTokens()) {
385 nsDependentSubstring lang
= langTokenizer
.nextToken();
387 // Replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
388 // NOTE: we should probably rely on the pref being set correctly.
389 if (lang
.Length() > 2 && lang
[2] == char16_t('_')) {
390 lang
.Replace(2, 1, char16_t('-'));
393 // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
394 // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
395 // NOTE: we should probably rely on the pref being set correctly.
396 if (lang
.Length() > 2) {
397 nsCharSeparatedTokenizer
localeTokenizer(lang
, '-');
400 while (localeTokenizer
.hasMoreTokens()) {
401 const nsSubstring
& code
= localeTokenizer
.nextToken();
403 if (code
.Length() == 2 && !first
) {
404 nsAutoString
upper(code
);
406 lang
.Replace(pos
, code
.Length(), upper
);
409 pos
+= code
.Length() + 1; // 1 is the separator
414 aLanguages
.AppendElement(lang
);
419 * Do not use UI language (chosen app locale) here but the first value set in
420 * the Accept Languages header, see ::GetAcceptLanguages().
422 * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for
426 Navigator::GetLanguage(nsAString
& aLanguage
)
428 nsTArray
<nsString
> languages
;
429 GetLanguages(languages
);
430 if (languages
.Length() >= 1) {
431 aLanguage
.Assign(languages
[0]);
433 aLanguage
.Truncate();
440 Navigator::GetLanguages(nsTArray
<nsString
>& aLanguages
)
442 GetAcceptLanguages(aLanguages
);
444 // The returned value is cached by the binding code. The window listen to the
445 // accept languages change and will clear the cache when needed. It has to
446 // take care of dispatching the DOM event already and the invalidation and the
447 // event has to be timed correctly.
451 Navigator::GetPlatform(nsAString
& aPlatform
)
453 return GetPlatform(aPlatform
, /* aUsePrefOverriddenValue */ true);
457 Navigator::GetOscpu(nsAString
& aOSCPU
)
459 if (!nsContentUtils::IsCallerChrome()) {
460 const nsAdoptingString
& override
=
461 Preferences::GetString("general.oscpu.override");
471 nsCOMPtr
<nsIHttpProtocolHandler
>
472 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
473 NS_ENSURE_SUCCESS(rv
, rv
);
476 rv
= service
->GetOscpu(oscpu
);
477 CopyASCIItoUTF16(oscpu
, aOSCPU
);
483 Navigator::GetVendor(nsAString
& aVendor
)
490 Navigator::GetVendorSub(nsAString
& aVendorSub
)
492 aVendorSub
.Truncate();
497 Navigator::GetProduct(nsAString
& aProduct
)
499 aProduct
.AssignLiteral("Gecko");
504 Navigator::GetProductSub(nsAString
& aProductSub
)
506 // Legacy build ID hardcoded for backward compatibility (bug 776376)
507 aProductSub
.AssignLiteral("20100101");
512 Navigator::GetMimeTypes(ErrorResult
& aRv
)
516 aRv
.Throw(NS_ERROR_UNEXPECTED
);
519 mMimeTypes
= new nsMimeTypeArray(mWindow
);
526 Navigator::GetPlugins(ErrorResult
& aRv
)
530 aRv
.Throw(NS_ERROR_UNEXPECTED
);
533 mPlugins
= new nsPluginArray(mWindow
);
540 // Values for the network.cookie.cookieBehavior pref are documented in
541 // nsCookieService.cpp.
542 #define COOKIE_BEHAVIOR_REJECT 2
545 Navigator::CookieEnabled()
548 (Preferences::GetInt("network.cookie.cookieBehavior",
549 COOKIE_BEHAVIOR_REJECT
) != COOKIE_BEHAVIOR_REJECT
);
551 // Check whether an exception overrides the global cookie behavior
552 // Note that the code for getting the URI here matches that in
553 // nsHTMLDocument::SetCookie.
554 if (!mWindow
|| !mWindow
->GetDocShell()) {
555 return cookieEnabled
;
558 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetExtantDoc();
560 return cookieEnabled
;
563 nsCOMPtr
<nsIURI
> codebaseURI
;
564 doc
->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI
));
567 // Not a codebase, so technically can't set cookies, but let's
568 // just return the default value.
569 return cookieEnabled
;
572 nsCOMPtr
<nsICookiePermission
> permMgr
=
573 do_GetService(NS_COOKIEPERMISSION_CONTRACTID
);
574 NS_ENSURE_TRUE(permMgr
, cookieEnabled
);
576 // Pass null for the channel, just like the cookie service does.
577 nsCookieAccess access
;
578 nsresult rv
= permMgr
->CanAccess(codebaseURI
, nullptr, &access
);
579 NS_ENSURE_SUCCESS(rv
, cookieEnabled
);
581 if (access
!= nsICookiePermission::ACCESS_DEFAULT
) {
582 cookieEnabled
= access
!= nsICookiePermission::ACCESS_DENY
;
585 return cookieEnabled
;
591 return !NS_IsOffline();
595 Navigator::GetBuildID(nsAString
& aBuildID
)
597 if (!nsContentUtils::IsCallerChrome()) {
598 const nsAdoptingString
& override
=
599 Preferences::GetString("general.buildID.override");
607 nsCOMPtr
<nsIXULAppInfo
> appInfo
=
608 do_GetService("@mozilla.org/xre/app-info;1");
610 return NS_ERROR_NOT_IMPLEMENTED
;
613 nsAutoCString buildID
;
614 nsresult rv
= appInfo
->GetAppBuildID(buildID
);
620 AppendASCIItoUTF16(buildID
, aBuildID
);
625 Navigator::GetDoNotTrack(nsAString
&aResult
)
627 if (sDoNotTrackEnabled
) {
628 if (sDoNotTrackValue
== 0) {
629 aResult
.AssignLiteral("0");
631 aResult
.AssignLiteral("1");
634 aResult
.AssignLiteral("unspecified");
641 Navigator::JavaEnabled(ErrorResult
& aRv
)
643 Telemetry::AutoTimer
<Telemetry::CHECK_JAVA_ENABLED
> telemetryTimer
;
645 // Return true if we have a handler for the java mime
646 nsAdoptingString javaMIME
= Preferences::GetString("plugin.java.mime");
647 NS_ENSURE_TRUE(!javaMIME
.IsEmpty(), false);
651 aRv
.Throw(NS_ERROR_UNEXPECTED
);
654 mMimeTypes
= new nsMimeTypeArray(mWindow
);
659 nsMimeType
*mimeType
= mMimeTypes
->NamedItem(javaMIME
);
661 return mimeType
&& mimeType
->GetEnabledPlugin();
665 Navigator::RefreshMIMEArray()
668 mMimeTypes
->Refresh();
674 class VibrateWindowListener
: public nsIDOMEventListener
677 VibrateWindowListener(nsIDOMWindow
* aWindow
, nsIDocument
* aDocument
)
679 mWindow
= do_GetWeakReference(aWindow
);
680 mDocument
= do_GetWeakReference(aDocument
);
682 NS_NAMED_LITERAL_STRING(visibilitychange
, "visibilitychange");
683 aDocument
->AddSystemEventListener(visibilitychange
,
685 true, /* use capture */
686 false /* wants untrusted */);
689 void RemoveListener();
692 NS_DECL_NSIDOMEVENTLISTENER
695 virtual ~VibrateWindowListener()
703 NS_IMPL_ISUPPORTS(VibrateWindowListener
, nsIDOMEventListener
)
705 StaticRefPtr
<VibrateWindowListener
> gVibrateWindowListener
;
708 VibrateWindowListener::HandleEvent(nsIDOMEvent
* aEvent
)
710 nsCOMPtr
<nsIDocument
> doc
=
711 do_QueryInterface(aEvent
->InternalDOMEvent()->GetTarget());
713 if (!doc
|| doc
->Hidden()) {
714 // It's important that we call CancelVibrate(), not Vibrate() with an
715 // empty list, because Vibrate() will fail if we're no longer focused, but
716 // CancelVibrate() will succeed, so long as nobody else has started a new
717 // vibration pattern.
718 nsCOMPtr
<nsIDOMWindow
> window
= do_QueryReferent(mWindow
);
719 hal::CancelVibrate(window
);
721 gVibrateWindowListener
= nullptr;
722 // Careful: The line above might have deleted |this|!
729 VibrateWindowListener::RemoveListener()
731 nsCOMPtr
<EventTarget
> target
= do_QueryReferent(mDocument
);
735 NS_NAMED_LITERAL_STRING(visibilitychange
, "visibilitychange");
736 target
->RemoveSystemEventListener(visibilitychange
, this,
737 true /* use capture */);
740 } // anonymous namespace
743 Navigator::AddIdleObserver(MozIdleObserver
& aIdleObserver
, ErrorResult
& aRv
)
746 aRv
.Throw(NS_ERROR_UNEXPECTED
);
749 CallbackObjectHolder
<MozIdleObserver
, nsIIdleObserver
> holder(&aIdleObserver
);
750 nsCOMPtr
<nsIIdleObserver
> obs
= holder
.ToXPCOMCallback();
751 if (NS_FAILED(mWindow
->RegisterIdleObserver(obs
))) {
752 NS_WARNING("Failed to add idle observer.");
757 Navigator::RemoveIdleObserver(MozIdleObserver
& aIdleObserver
, ErrorResult
& aRv
)
760 aRv
.Throw(NS_ERROR_UNEXPECTED
);
763 CallbackObjectHolder
<MozIdleObserver
, nsIIdleObserver
> holder(&aIdleObserver
);
764 nsCOMPtr
<nsIIdleObserver
> obs
= holder
.ToXPCOMCallback();
765 if (NS_FAILED(mWindow
->UnregisterIdleObserver(obs
))) {
766 NS_WARNING("Failed to remove idle observer.");
771 Navigator::Vibrate(uint32_t aDuration
)
773 nsAutoTArray
<uint32_t, 1> pattern
;
774 pattern
.AppendElement(aDuration
);
775 return Vibrate(pattern
);
779 Navigator::Vibrate(const nsTArray
<uint32_t>& aPattern
)
785 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetExtantDoc();
791 // Hidden documents cannot start or stop a vibration.
795 nsTArray
<uint32_t> pattern(aPattern
);
797 if (pattern
.Length() > sMaxVibrateListLen
) {
798 pattern
.SetLength(sMaxVibrateListLen
);
801 for (size_t i
= 0; i
< pattern
.Length(); ++i
) {
802 if (pattern
[i
] > sMaxVibrateMS
) {
803 pattern
[i
] = sMaxVibrateMS
;
807 // The spec says we check sVibratorEnabled after we've done the sanity
808 // checking on the pattern.
809 if (!sVibratorEnabled
) {
813 // Add a listener to cancel the vibration if the document becomes hidden,
814 // and remove the old visibility listener, if there was one.
816 if (!gVibrateWindowListener
) {
817 // If gVibrateWindowListener is null, this is the first time we've vibrated,
818 // and we need to register a listener to clear gVibrateWindowListener on
820 ClearOnShutdown(&gVibrateWindowListener
);
823 gVibrateWindowListener
->RemoveListener();
825 gVibrateWindowListener
= new VibrateWindowListener(mWindow
, doc
);
827 hal::Vibrate(pattern
, mWindow
);
831 //*****************************************************************************
832 // Pointer Events interface
833 //*****************************************************************************
836 Navigator::MaxTouchPoints()
838 nsCOMPtr
<nsIWidget
> widget
= widget::WidgetUtils::DOMWindowToWidget(mWindow
);
840 NS_ENSURE_TRUE(widget
, 0);
841 return widget
->GetMaxTouchPoints();
844 //*****************************************************************************
845 // Navigator::nsIDOMClientInformation
846 //*****************************************************************************
849 Navigator::RegisterContentHandler(const nsAString
& aMIMEType
,
850 const nsAString
& aURI
,
851 const nsAString
& aTitle
,
854 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
858 nsCOMPtr
<nsIWebContentHandlerRegistrar
> registrar
=
859 do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID
);
864 aRv
= registrar
->RegisterContentHandler(aMIMEType
, aURI
, aTitle
,
865 mWindow
->GetOuterWindow());
869 Navigator::RegisterProtocolHandler(const nsAString
& aProtocol
,
870 const nsAString
& aURI
,
871 const nsAString
& aTitle
,
874 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
878 nsCOMPtr
<nsIWebContentHandlerRegistrar
> registrar
=
879 do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID
);
884 aRv
= registrar
->RegisterProtocolHandler(aProtocol
, aURI
, aTitle
,
885 mWindow
->GetOuterWindow());
889 Navigator::MozIsLocallyAvailable(const nsAString
&aURI
,
893 nsCOMPtr
<nsIURI
> uri
;
894 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), aURI
);
900 // This method of checking the cache will only work for http/https urls.
902 rv
= uri
->SchemeIs("http", &match
);
909 rv
= uri
->SchemeIs("https", &match
);
915 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
920 // Same origin check.
921 JSContext
*cx
= nsContentUtils::GetCurrentJSContext();
923 aRv
.Throw(NS_ERROR_FAILURE
);
927 rv
= nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx
, uri
);
933 // These load flags cause an error to be thrown if there is no
934 // valid cache entry, and skip the load if there is.
935 // If the cache is busy, assume that it is not yet available rather
936 // than waiting for it to become available.
937 uint32_t loadFlags
= nsIChannel::INHIBIT_CACHING
|
938 nsICachingChannel::LOAD_NO_NETWORK_IO
|
939 nsICachingChannel::LOAD_ONLY_IF_MODIFIED
|
940 nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
;
943 loadFlags
|= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE
|
944 nsICachingChannel::LOAD_ONLY_FROM_CACHE
|
945 nsIRequest::LOAD_FROM_CACHE
;
949 aRv
.Throw(NS_ERROR_UNEXPECTED
);
953 nsCOMPtr
<nsILoadGroup
> loadGroup
;
954 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetDoc();
956 loadGroup
= doc
->GetDocumentLoadGroup();
959 nsCOMPtr
<nsIChannel
> channel
;
960 rv
= NS_NewChannel(getter_AddRefs(channel
), uri
,
961 nullptr, loadGroup
, nullptr, loadFlags
);
967 nsCOMPtr
<nsIInputStream
> stream
;
968 rv
= channel
->Open(getter_AddRefs(stream
));
977 rv
= channel
->GetStatus(&status
);
983 if (NS_FAILED(status
)) {
987 nsCOMPtr
<nsIHttpChannel
> httpChannel
= do_QueryInterface(channel
);
989 rv
= httpChannel
->GetRequestSucceeded(&isAvailable
);
998 Navigator::GetDeviceStorage(const nsAString
& aType
, ErrorResult
& aRv
)
1000 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1001 aRv
.Throw(NS_ERROR_FAILURE
);
1005 nsRefPtr
<nsDOMDeviceStorage
> storage
;
1006 nsDOMDeviceStorage::CreateDeviceStorageFor(mWindow
, aType
,
1007 getter_AddRefs(storage
));
1013 mDeviceStorageStores
.AppendElement(storage
);
1018 Navigator::GetDeviceStorages(const nsAString
& aType
,
1019 nsTArray
<nsRefPtr
<nsDOMDeviceStorage
> >& aStores
,
1022 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1023 aRv
.Throw(NS_ERROR_FAILURE
);
1027 nsDOMDeviceStorage::CreateDeviceStoragesFor(mWindow
, aType
, aStores
);
1029 mDeviceStorageStores
.AppendElements(aStores
);
1033 Navigator::GetGeolocation(ErrorResult
& aRv
)
1036 return mGeolocation
;
1039 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1040 aRv
.Throw(NS_ERROR_FAILURE
);
1044 mGeolocation
= new Geolocation();
1045 if (NS_FAILED(mGeolocation
->Init(mWindow
->GetOuterWindow()))) {
1046 mGeolocation
= nullptr;
1047 aRv
.Throw(NS_ERROR_FAILURE
);
1051 return mGeolocation
;
1054 class BeaconStreamListener MOZ_FINAL
: public nsIStreamListener
1056 ~BeaconStreamListener() {}
1059 BeaconStreamListener() {}
1062 NS_DECL_NSISTREAMLISTENER
1063 NS_DECL_NSIREQUESTOBSERVER
1066 NS_IMPL_ISUPPORTS(BeaconStreamListener
,
1072 BeaconStreamListener::OnStartRequest(nsIRequest
*aRequest
,
1073 nsISupports
*aContext
)
1075 aRequest
->Cancel(NS_ERROR_NET_INTERRUPT
);
1076 return NS_BINDING_ABORTED
;
1080 BeaconStreamListener::OnStopRequest(nsIRequest
*aRequest
,
1081 nsISupports
*aContext
,
1088 BeaconStreamListener::OnDataAvailable(nsIRequest
*aRequest
,
1090 nsIInputStream
*inStr
,
1091 uint64_t sourceOffset
,
1099 Navigator::SendBeacon(const nsAString
& aUrl
,
1100 const Nullable
<ArrayBufferViewOrBlobOrStringOrFormData
>& aData
,
1104 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1108 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetDoc();
1110 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1114 nsIURI
* documentURI
= doc
->GetDocumentURI();
1116 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1120 nsCOMPtr
<nsIURI
> uri
;
1121 nsresult rv
= nsContentUtils::NewURIWithDocumentCharset(
1122 getter_AddRefs(uri
),
1125 doc
->GetDocBaseURI());
1126 if (NS_FAILED(rv
)) {
1127 aRv
.Throw(NS_ERROR_DOM_URL_MISMATCH_ERR
);
1131 // Check whether this is a sane URI to load
1132 // Explicitly disallow things like chrome:, javascript:, and data: URIs
1133 nsCOMPtr
<nsIPrincipal
> principal
= doc
->NodePrincipal();
1134 nsCOMPtr
<nsIScriptSecurityManager
> secMan
= nsContentUtils::GetSecurityManager();
1135 uint32_t flags
= nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL
1136 & nsIScriptSecurityManager::DISALLOW_SCRIPT
;
1137 rv
= secMan
->CheckLoadURIWithPrincipal(principal
,
1140 if (NS_FAILED(rv
)) {
1146 // Check whether the CSP allows us to load
1147 int16_t shouldLoad
= nsIContentPolicy::ACCEPT
;
1148 rv
= NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_BEACON
,
1152 EmptyCString(), //mime guess
1155 nsContentUtils::GetContentPolicy(),
1156 nsContentUtils::GetSecurityManager());
1157 if (NS_FAILED(rv
) || NS_CP_REJECTED(shouldLoad
)) {
1158 // Disallowed by content policy
1159 aRv
.Throw(NS_ERROR_CONTENT_BLOCKED
);
1163 nsCOMPtr
<nsIChannel
> channel
;
1164 nsCOMPtr
<nsIChannelPolicy
> channelPolicy
;
1165 nsCOMPtr
<nsIContentSecurityPolicy
> csp
;
1166 rv
= principal
->GetCsp(getter_AddRefs(csp
));
1167 if (NS_FAILED(rv
)) {
1168 aRv
.Throw(NS_ERROR_FAILURE
);
1173 channelPolicy
= do_CreateInstance(NSCHANNELPOLICY_CONTRACTID
);
1174 channelPolicy
->SetContentSecurityPolicy(csp
);
1175 channelPolicy
->SetLoadType(nsIContentPolicy::TYPE_BEACON
);
1177 rv
= NS_NewChannel(getter_AddRefs(channel
),
1182 nsIRequest::LOAD_NORMAL
,
1184 if (NS_FAILED(rv
)) {
1189 nsCOMPtr
<nsIPrivateBrowsingChannel
> pbChannel
= do_QueryInterface(channel
);
1191 nsIDocShell
* docShell
= mWindow
->GetDocShell();
1192 nsCOMPtr
<nsILoadContext
> loadContext
= do_QueryInterface(docShell
);
1194 rv
= pbChannel
->SetPrivate(loadContext
->UsePrivateBrowsing());
1195 if (NS_FAILED(rv
)) {
1196 NS_WARNING("Setting the privacy status on the beacon channel failed");
1201 nsCOMPtr
<nsIHttpChannel
> httpChannel
= do_QueryInterface(channel
);
1203 // Beacon spec only supports HTTP requests at this time
1204 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
1207 httpChannel
->SetReferrer(documentURI
);
1209 // Anything that will need to refer to the window during the request
1210 // will need to be done now. For example, detection of whether any
1211 // cookies set by this request are foreign. Note that ThirdPartyUtil
1212 // (nsIThirdPartyUtil.isThirdPartyChannel) does a secondary check between
1213 // the channel URI and the cookie URI even when forceAllowThirdPartyCookie
1214 // is set, so this is safe with regard to redirects.
1215 nsCOMPtr
<nsIHttpChannelInternal
> httpChannelInternal(do_QueryInterface(channel
));
1216 nsCOMPtr
<mozIThirdPartyUtil
> thirdPartyUtil
= do_GetService(THIRDPARTYUTIL_CONTRACTID
);
1217 if (!httpChannelInternal
) {
1218 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
1221 bool isForeign
= true;
1222 thirdPartyUtil
->IsThirdPartyWindow(mWindow
, uri
, &isForeign
);
1223 httpChannelInternal
->SetForceAllowThirdPartyCookie(!isForeign
);
1226 if (!aData
.IsNull()) {
1227 nsCOMPtr
<nsIInputStream
> in
;
1229 if (aData
.Value().IsString()) {
1230 nsCString stringData
= NS_ConvertUTF16toUTF8(aData
.Value().GetAsString());
1231 nsCOMPtr
<nsIStringInputStream
> strStream
= do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID
, &rv
);
1232 if (NS_FAILED(rv
)) {
1233 aRv
.Throw(NS_ERROR_FAILURE
);
1236 rv
= strStream
->SetData(stringData
.BeginReading(), stringData
.Length());
1237 if (NS_FAILED(rv
)) {
1238 aRv
.Throw(NS_ERROR_FAILURE
);
1241 mimeType
.AssignLiteral("text/plain;charset=UTF-8");
1244 } else if (aData
.Value().IsArrayBufferView()) {
1246 nsCOMPtr
<nsIStringInputStream
> strStream
= do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID
, &rv
);
1247 if (NS_FAILED(rv
)) {
1248 aRv
.Throw(NS_ERROR_FAILURE
);
1252 const ArrayBufferView
& view
= aData
.Value().GetAsArrayBufferView();
1253 view
.ComputeLengthAndData();
1254 rv
= strStream
->SetData(reinterpret_cast<char*>(view
.Data()),
1257 if (NS_FAILED(rv
)) {
1258 aRv
.Throw(NS_ERROR_FAILURE
);
1261 mimeType
.AssignLiteral("application/octet-stream");
1264 } else if (aData
.Value().IsBlob()) {
1265 nsCOMPtr
<nsIDOMBlob
> blob
= aData
.Value().GetAsBlob();
1266 rv
= blob
->GetInternalStream(getter_AddRefs(in
));
1267 if (NS_FAILED(rv
)) {
1268 aRv
.Throw(NS_ERROR_FAILURE
);
1272 rv
= blob
->GetType(type
);
1273 if (NS_FAILED(rv
)) {
1274 aRv
.Throw(NS_ERROR_FAILURE
);
1277 mimeType
= NS_ConvertUTF16toUTF8(type
);
1279 } else if (aData
.Value().IsFormData()) {
1280 nsFormData
& form
= aData
.Value().GetAsFormData();
1282 nsAutoCString charset
;
1283 form
.GetSendInfo(getter_AddRefs(in
),
1288 MOZ_ASSERT(false, "switch statements not in sync");
1289 aRv
.Throw(NS_ERROR_FAILURE
);
1293 nsCOMPtr
<nsIUploadChannel2
> uploadChannel
= do_QueryInterface(channel
);
1294 if (!uploadChannel
) {
1295 aRv
.Throw(NS_ERROR_FAILURE
);
1298 uploadChannel
->ExplicitSetUploadStream(in
, mimeType
, -1,
1299 NS_LITERAL_CSTRING("POST"),
1302 httpChannel
->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
1305 nsCOMPtr
<nsISupportsPriority
> p
= do_QueryInterface(channel
);
1307 p
->SetPriority(nsISupportsPriority::PRIORITY_LOWEST
);
1310 nsRefPtr
<nsCORSListenerProxy
> cors
= new nsCORSListenerProxy(new BeaconStreamListener(),
1314 rv
= cors
->Init(channel
, true);
1315 NS_ENSURE_SUCCESS(rv
, false);
1317 // Start a preflight if cross-origin and content type is not whitelisted
1318 rv
= secMan
->CheckSameOriginURI(documentURI
, uri
, false);
1319 bool crossOrigin
= NS_FAILED(rv
);
1320 nsAutoCString contentType
, parsedCharset
;
1321 rv
= NS_ParseContentType(mimeType
, contentType
, parsedCharset
);
1323 contentType
.Length() > 0 &&
1324 !contentType
.Equals(APPLICATION_WWW_FORM_URLENCODED
) &&
1325 !contentType
.Equals(MULTIPART_FORM_DATA
) &&
1326 !contentType
.Equals(TEXT_PLAIN
)) {
1328 // we need to set the sameOriginChecker as a notificationCallback
1329 // so we can tell the channel not to follow redirects
1330 nsCOMPtr
<nsIInterfaceRequestor
> soc
= nsContentUtils::GetSameOriginChecker();
1331 channel
->SetNotificationCallbacks(soc
);
1333 nsCOMPtr
<nsIChannel
> preflightChannel
;
1334 nsTArray
<nsCString
> unsafeHeaders
;
1335 unsafeHeaders
.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
1336 rv
= NS_StartCORSPreflight(channel
,
1341 getter_AddRefs(preflightChannel
));
1343 rv
= channel
->AsyncOpen(cors
, nullptr);
1345 if (NS_FAILED(rv
)) {
1352 #ifdef MOZ_MEDIA_NAVIGATOR
1354 Navigator::MozGetUserMedia(const MediaStreamConstraints
& aConstraints
,
1355 NavigatorUserMediaSuccessCallback
& aOnSuccess
,
1356 NavigatorUserMediaErrorCallback
& aOnError
,
1359 CallbackObjectHolder
<NavigatorUserMediaSuccessCallback
,
1360 nsIDOMGetUserMediaSuccessCallback
> holder1(&aOnSuccess
);
1361 nsCOMPtr
<nsIDOMGetUserMediaSuccessCallback
> onsuccess
=
1362 holder1
.ToXPCOMCallback();
1364 CallbackObjectHolder
<NavigatorUserMediaErrorCallback
,
1365 nsIDOMGetUserMediaErrorCallback
> holder2(&aOnError
);
1366 nsCOMPtr
<nsIDOMGetUserMediaErrorCallback
> onerror
= holder2
.ToXPCOMCallback();
1368 if (!mWindow
|| !mWindow
->GetOuterWindow() ||
1369 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1370 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1374 bool privileged
= nsContentUtils::IsChromeDoc(mWindow
->GetExtantDoc());
1376 MediaManager
* manager
= MediaManager::Get();
1377 aRv
= manager
->GetUserMedia(privileged
, mWindow
, aConstraints
,
1378 onsuccess
, onerror
);
1382 Navigator::MozGetUserMediaDevices(const MediaStreamConstraints
& aConstraints
,
1383 MozGetUserMediaDevicesSuccessCallback
& aOnSuccess
,
1384 NavigatorUserMediaErrorCallback
& aOnError
,
1385 uint64_t aInnerWindowID
,
1388 CallbackObjectHolder
<MozGetUserMediaDevicesSuccessCallback
,
1389 nsIGetUserMediaDevicesSuccessCallback
> holder1(&aOnSuccess
);
1390 nsCOMPtr
<nsIGetUserMediaDevicesSuccessCallback
> onsuccess
=
1391 holder1
.ToXPCOMCallback();
1393 CallbackObjectHolder
<NavigatorUserMediaErrorCallback
,
1394 nsIDOMGetUserMediaErrorCallback
> holder2(&aOnError
);
1395 nsCOMPtr
<nsIDOMGetUserMediaErrorCallback
> onerror
= holder2
.ToXPCOMCallback();
1397 if (!mWindow
|| !mWindow
->GetOuterWindow() ||
1398 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1399 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1403 MediaManager
* manager
= MediaManager::Get();
1404 aRv
= manager
->GetUserMediaDevices(mWindow
, aConstraints
, onsuccess
, onerror
,
1409 DesktopNotificationCenter
*
1410 Navigator::GetMozNotification(ErrorResult
& aRv
)
1412 if (mNotification
) {
1413 return mNotification
;
1416 if (!mWindow
|| !mWindow
->GetDocShell()) {
1417 aRv
.Throw(NS_ERROR_FAILURE
);
1421 mNotification
= new DesktopNotificationCenter(mWindow
);
1422 return mNotification
;
1427 using mozilla::dom::FMRadio
;
1430 Navigator::GetMozFMRadio(ErrorResult
& aRv
)
1434 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1438 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1440 mFMRadio
= new FMRadio();
1441 mFMRadio
->Init(mWindow
);
1447 #endif // MOZ_B2G_FM
1449 //*****************************************************************************
1450 // Navigator::nsINavigatorBattery
1451 //*****************************************************************************
1453 battery::BatteryManager
*
1454 Navigator::GetBattery(ErrorResult
& aRv
)
1456 if (!mBatteryManager
) {
1458 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1461 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1463 mBatteryManager
= new battery::BatteryManager(mWindow
);
1464 mBatteryManager
->Init();
1467 return mBatteryManager
;
1470 /* static */ already_AddRefed
<Promise
>
1471 Navigator::GetDataStores(nsPIDOMWindow
* aWindow
,
1472 const nsAString
& aName
,
1473 const nsAString
& aOwner
,
1476 if (!aWindow
|| !aWindow
->GetDocShell()) {
1477 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1481 nsRefPtr
<DataStoreService
> service
= DataStoreService::GetOrCreate();
1483 aRv
.Throw(NS_ERROR_FAILURE
);
1487 nsCOMPtr
<nsISupports
> promise
;
1488 aRv
= service
->GetDataStores(aWindow
, aName
, aOwner
, getter_AddRefs(promise
));
1490 nsRefPtr
<Promise
> p
= static_cast<Promise
*>(promise
.get());
1494 already_AddRefed
<Promise
>
1495 Navigator::GetDataStores(const nsAString
& aName
,
1496 const nsAString
& aOwner
,
1499 return GetDataStores(mWindow
, aName
, aOwner
, aRv
);
1502 already_AddRefed
<Promise
>
1503 Navigator::GetFeature(const nsAString
& aName
, ErrorResult
& aRv
)
1505 nsCOMPtr
<nsIGlobalObject
> go
= do_QueryInterface(mWindow
);
1506 nsRefPtr
<Promise
> p
= Promise::Create(go
, aRv
);
1511 #if defined(XP_LINUX)
1512 if (aName
.EqualsLiteral("hardware.memory")) {
1513 // with seccomp enabled, fopen() should be in a non-sandboxed process
1514 if (XRE_GetProcessType() == GeckoProcessType_Default
) {
1515 uint32_t memLevel
= mozilla::hal::GetTotalSystemMemoryLevel();
1516 if (memLevel
== 0) {
1517 p
->MaybeReject(NS_ERROR_NOT_AVAILABLE
);
1520 p
->MaybeResolve((int)memLevel
);
1522 mozilla::dom::ContentChild
* cc
=
1523 mozilla::dom::ContentChild::GetSingleton();
1524 nsRefPtr
<Promise
> ipcRef(p
);
1525 cc
->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef
.forget().take()));
1528 } // hardware.memory
1531 #ifdef MOZ_WIDGET_GONK
1532 if (aName
.EqualsLiteral("acl.version")) {
1533 char value
[PROPERTY_VALUE_MAX
];
1534 uint32_t len
= property_get("persist.acl.version", value
, nullptr);
1536 p
->MaybeResolve(NS_ConvertUTF8toUTF16(value
));
1542 p
->MaybeResolve(JS::UndefinedHandleValue
);
1546 already_AddRefed
<Promise
>
1547 Navigator::HasFeature(const nsAString
& aName
, ErrorResult
& aRv
)
1549 nsCOMPtr
<nsIGlobalObject
> go
= do_QueryInterface(mWindow
);
1550 nsRefPtr
<Promise
> p
= Promise::Create(go
, aRv
);
1555 // Hardcoded manifest features. Some are still b2g specific.
1556 const char manifestFeatures
[][64] = {
1558 , "manifest.redirects"
1560 , "manifest.chrome.navigation"
1561 , "manifest.precompile"
1565 nsAutoCString feature
= NS_ConvertUTF16toUTF8(aName
);
1566 for (uint32_t i
= 0; i
< MOZ_ARRAY_LENGTH(manifestFeatures
); i
++) {
1567 if (feature
.Equals(manifestFeatures
[i
])) {
1568 p
->MaybeResolve(true);
1573 NS_NAMED_LITERAL_STRING(apiWindowPrefix
, "api.window.");
1574 if (StringBeginsWith(aName
, apiWindowPrefix
)) {
1575 const nsAString
& featureName
= Substring(aName
, apiWindowPrefix
.Length());
1577 // Temporary hardcoded entry points due to technical constraints
1578 if (featureName
.EqualsLiteral("Navigator.mozTCPSocket")) {
1579 p
->MaybeResolve(Preferences::GetBool("dom.mozTCPSocket.enabled"));
1583 if (featureName
.EqualsLiteral("Navigator.mozMobileConnections") ||
1584 featureName
.EqualsLiteral("MozMobileNetworkInfo")) {
1585 p
->MaybeResolve(Preferences::GetBool("dom.mobileconnection.enabled"));
1589 if (featureName
.EqualsLiteral("Navigator.mozInputMethod")) {
1590 p
->MaybeResolve(Preferences::GetBool("dom.mozInputMethod.enabled"));
1594 if (featureName
.EqualsLiteral("Navigator.mozContacts")) {
1595 p
->MaybeResolve(true);
1599 if (featureName
.EqualsLiteral("Navigator.getDeviceStorage")) {
1600 p
->MaybeResolve(Preferences::GetBool("device.storage.enabled"));
1604 if (featureName
.EqualsLiteral("Navigator.mozNetworkStats")) {
1605 p
->MaybeResolve(Preferences::GetBool("dom.mozNetworkStats.enabled"));
1609 if (featureName
.EqualsLiteral("Navigator.push")) {
1610 p
->MaybeResolve(Preferences::GetBool("services.push.enabled"));
1614 if (featureName
.EqualsLiteral("Navigator.mozAlarms")) {
1615 p
->MaybeResolve(Preferences::GetBool("dom.mozAlarms.enabled"));
1619 if (featureName
.EqualsLiteral("Navigator.mozCameras")) {
1620 p
->MaybeResolve(true);
1625 if (featureName
.EqualsLiteral("Navigator.getMobileIdAssertion")) {
1626 p
->MaybeResolve(true);
1631 if (featureName
.EqualsLiteral("XMLHttpRequest.mozSystem")) {
1632 p
->MaybeResolve(true);
1636 if (IsFeatureDetectible(featureName
)) {
1637 p
->MaybeResolve(true);
1639 p
->MaybeResolve(JS::UndefinedHandleValue
);
1644 // resolve with <undefined> because the feature name is not supported
1645 p
->MaybeResolve(JS::UndefinedHandleValue
);
1651 Navigator::GetMozPower(ErrorResult
& aRv
)
1653 if (!mPowerManager
) {
1655 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1658 mPowerManager
= PowerManager::CreateInstance(mWindow
);
1659 if (!mPowerManager
) {
1660 // We failed to get the power manager service?
1661 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1665 return mPowerManager
;
1668 already_AddRefed
<WakeLock
>
1669 Navigator::RequestWakeLock(const nsAString
&aTopic
, ErrorResult
& aRv
)
1672 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1676 nsRefPtr
<power::PowerManagerService
> pmService
=
1677 power::PowerManagerService::GetInstance();
1678 // Maybe it went away for some reason... Or maybe we're just called
1679 // from our XPCOM method.
1681 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1685 return pmService
->NewWakeLock(aTopic
, mWindow
, aRv
);
1688 MobileMessageManager
*
1689 Navigator::GetMozMobileMessage()
1691 if (!mMobileMessageManager
) {
1692 // Check that our window has not gone away
1693 NS_ENSURE_TRUE(mWindow
, nullptr);
1694 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1696 mMobileMessageManager
= new MobileMessageManager(mWindow
);
1697 mMobileMessageManager
->Init();
1700 return mMobileMessageManager
;
1704 Navigator::GetMozTelephony(ErrorResult
& aRv
)
1708 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1711 mTelephony
= Telephony::Create(mWindow
, aRv
);
1718 already_AddRefed
<Promise
>
1719 Navigator::GetMobileIdAssertion(const MobileIdOptions
& aOptions
,
1722 if (!mWindow
|| !mWindow
->GetDocShell()) {
1723 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1727 nsCOMPtr
<nsIMobileIdentityService
> service
=
1728 do_GetService("@mozilla.org/mobileidentity-service;1");
1730 aRv
.Throw(NS_ERROR_FAILURE
);
1734 JSContext
*cx
= nsContentUtils::GetCurrentJSContext();
1736 aRv
.Throw(NS_ERROR_FAILURE
);
1740 JS::Rooted
<JS::Value
> optionsValue(cx
);
1741 if (!ToJSValue(cx
, aOptions
, &optionsValue
)) {
1742 aRv
.Throw(NS_ERROR_FAILURE
);
1746 nsCOMPtr
<nsISupports
> promise
;
1747 aRv
= service
->GetMobileIdAssertion(mWindow
,
1749 getter_AddRefs(promise
));
1751 nsRefPtr
<Promise
> p
= static_cast<Promise
*>(promise
.get());
1758 MobileConnectionArray
*
1759 Navigator::GetMozMobileConnections(ErrorResult
& aRv
)
1761 if (!mMobileConnections
) {
1763 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1766 mMobileConnections
= new MobileConnectionArray(mWindow
);
1769 return mMobileConnections
;
1773 Navigator::GetMozCellBroadcast(ErrorResult
& aRv
)
1775 if (!mCellBroadcast
) {
1777 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1780 mCellBroadcast
= CellBroadcast::Create(mWindow
, aRv
);
1783 return mCellBroadcast
;
1787 Navigator::GetMozVoicemail(ErrorResult
& aRv
)
1791 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1795 aRv
= NS_NewVoicemail(mWindow
, getter_AddRefs(mVoicemail
));
1805 Navigator::GetMozIccManager(ErrorResult
& aRv
)
1809 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1812 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1814 mIccManager
= new IccManager(mWindow
);
1819 #endif // MOZ_B2G_RIL
1823 Navigator::GetGamepads(nsTArray
<nsRefPtr
<Gamepad
> >& aGamepads
,
1827 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1830 NS_ENSURE_TRUE_VOID(mWindow
->GetDocShell());
1831 nsGlobalWindow
* win
= static_cast<nsGlobalWindow
*>(mWindow
.get());
1832 win
->SetHasGamepadEventListener(true);
1833 win
->GetGamepads(aGamepads
);
1837 //*****************************************************************************
1838 // Navigator::nsIMozNavigatorNetwork
1839 //*****************************************************************************
1842 Navigator::GetProperties(nsINetworkProperties
** aProperties
)
1845 NS_IF_ADDREF(*aProperties
= GetConnection(rv
));
1849 network::Connection
*
1850 Navigator::GetConnection(ErrorResult
& aRv
)
1854 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1857 mConnection
= new network::Connection();
1858 mConnection
->Init(mWindow
);
1865 bluetooth::BluetoothManager
*
1866 Navigator::GetMozBluetooth(ErrorResult
& aRv
)
1870 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1873 mBluetooth
= bluetooth::BluetoothManager::Create(mWindow
);
1881 Navigator::EnsureMessagesManager()
1883 if (mMessagesManager
) {
1887 NS_ENSURE_STATE(mWindow
);
1890 nsCOMPtr
<nsIDOMNavigatorSystemMessages
> messageManager
=
1891 do_CreateInstance("@mozilla.org/system-message-manager;1", &rv
);
1893 nsCOMPtr
<nsIDOMGlobalPropertyInitializer
> gpi
=
1894 do_QueryInterface(messageManager
);
1895 NS_ENSURE_TRUE(gpi
, NS_ERROR_FAILURE
);
1897 // We don't do anything with the return value.
1899 JS::Rooted
<JS::Value
> prop_val(cx
);
1900 rv
= gpi
->Init(mWindow
, &prop_val
);
1901 NS_ENSURE_SUCCESS(rv
, rv
);
1903 mMessagesManager
= messageManager
.forget();
1909 Navigator::MozHasPendingMessage(const nsAString
& aType
, ErrorResult
& aRv
)
1911 // The WebIDL binding is responsible for the pref check here.
1912 nsresult rv
= EnsureMessagesManager();
1913 if (NS_FAILED(rv
)) {
1918 bool result
= false;
1919 rv
= mMessagesManager
->MozHasPendingMessage(aType
, &result
);
1920 if (NS_FAILED(rv
)) {
1928 Navigator::MozSetMessageHandler(const nsAString
& aType
,
1929 systemMessageCallback
* aCallback
,
1932 // The WebIDL binding is responsible for the pref check here.
1933 nsresult rv
= EnsureMessagesManager();
1934 if (NS_FAILED(rv
)) {
1939 CallbackObjectHolder
<systemMessageCallback
, nsIDOMSystemMessageCallback
>
1941 nsCOMPtr
<nsIDOMSystemMessageCallback
> callback
= holder
.ToXPCOMCallback();
1943 rv
= mMessagesManager
->MozSetMessageHandler(aType
, callback
);
1944 if (NS_FAILED(rv
)) {
1949 #ifdef MOZ_TIME_MANAGER
1951 Navigator::GetMozTime(ErrorResult
& aRv
)
1954 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1958 if (!mTimeManager
) {
1959 mTimeManager
= new time::TimeManager(mWindow
);
1962 return mTimeManager
;
1967 Navigator::GetMozCameras(ErrorResult
& aRv
)
1969 if (!mCameraManager
) {
1971 !mWindow
->GetOuterWindow() ||
1972 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1973 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1977 mCameraManager
= nsDOMCameraManager::CreateInstance(mWindow
);
1980 return mCameraManager
;
1983 already_AddRefed
<ServiceWorkerContainer
>
1984 Navigator::ServiceWorker()
1986 MOZ_ASSERT(mWindow
);
1988 if (!mServiceWorkerContainer
) {
1989 mServiceWorkerContainer
= new ServiceWorkerContainer(mWindow
);
1992 nsRefPtr
<ServiceWorkerContainer
> ref
= mServiceWorkerContainer
;
1993 return ref
.forget();
1997 Navigator::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const
1999 size_t n
= aMallocSizeOf(this);
2001 // TODO: add SizeOfIncludingThis() to nsMimeTypeArray, bug 674113.
2002 // TODO: add SizeOfIncludingThis() to nsPluginArray, bug 674114.
2003 // TODO: add SizeOfIncludingThis() to Geolocation, bug 674115.
2004 // TODO: add SizeOfIncludingThis() to DesktopNotificationCenter, bug 674116.
2010 Navigator::SetWindow(nsPIDOMWindow
*aInnerWindow
)
2012 NS_ASSERTION(aInnerWindow
->IsInnerWindow(),
2013 "Navigator must get an inner window!");
2014 mWindow
= aInnerWindow
;
2018 Navigator::OnNavigation()
2024 #ifdef MOZ_MEDIA_NAVIGATOR
2025 // Inform MediaManager in case there are live streams or pending callbacks.
2026 MediaManager
*manager
= MediaManager::Get();
2028 manager
->OnNavigation(mWindow
->WindowID());
2031 if (mCameraManager
) {
2032 mCameraManager
->OnNavigation(mWindow
->WindowID());
2037 Navigator::CheckPermission(const char* type
)
2039 return CheckPermission(mWindow
, type
);
2044 Navigator::CheckPermission(nsPIDOMWindow
* aWindow
, const char* aType
)
2050 nsCOMPtr
<nsIPermissionManager
> permMgr
=
2051 services::GetPermissionManager();
2052 NS_ENSURE_TRUE(permMgr
, false);
2054 uint32_t permission
= nsIPermissionManager::DENY_ACTION
;
2055 permMgr
->TestPermissionFromWindow(aWindow
, aType
, &permission
);
2056 return permission
== nsIPermissionManager::ALLOW_ACTION
;
2059 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
2060 system::AudioChannelManager
*
2061 Navigator::GetMozAudioChannelManager(ErrorResult
& aRv
)
2063 if (!mAudioChannelManager
) {
2065 aRv
.Throw(NS_ERROR_UNEXPECTED
);
2068 mAudioChannelManager
= new system::AudioChannelManager();
2069 mAudioChannelManager
->Init(mWindow
);
2072 return mAudioChannelManager
;
2077 Navigator::DoNewResolve(JSContext
* aCx
, JS::Handle
<JSObject
*> aObject
,
2078 JS::Handle
<jsid
> aId
,
2079 JS::MutableHandle
<JSPropertyDescriptor
> aDesc
)
2081 if (!JSID_IS_STRING(aId
)) {
2085 nsScriptNameSpaceManager
* nameSpaceManager
= GetNameSpaceManager();
2086 if (!nameSpaceManager
) {
2087 return Throw(aCx
, NS_ERROR_NOT_INITIALIZED
);
2090 nsAutoJSString name
;
2091 if (!name
.init(aCx
, JSID_TO_STRING(aId
))) {
2095 const nsGlobalNameStruct
* name_struct
=
2096 nameSpaceManager
->LookupNavigatorName(name
);
2101 JS::Rooted
<JSObject
*> naviObj(aCx
,
2102 js::CheckedUnwrap(aObject
,
2103 /* stopAtOuter = */ false));
2105 return Throw(aCx
, NS_ERROR_DOM_SECURITY_ERR
);
2108 if (name_struct
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
) {
2109 ConstructNavigatorProperty construct
= name_struct
->mConstructNavigatorProperty
;
2110 MOZ_ASSERT(construct
);
2112 JS::Rooted
<JSObject
*> domObject(aCx
);
2114 // Make sure to do the creation of our object in the compartment
2115 // of naviObj, especially since we plan to cache that object.
2116 JSAutoCompartment
ac(aCx
, naviObj
);
2118 // Check whether our constructor is enabled after we unwrap Xrays, since
2119 // we don't want to define an interface on the Xray if it's disabled in
2120 // the target global, even if it's enabled in the Xray's global.
2121 if (name_struct
->mConstructorEnabled
&&
2122 !(*name_struct
->mConstructorEnabled
)(aCx
, naviObj
)) {
2126 if (name
.EqualsLiteral("mozSettings")) {
2127 bool hasPermission
= CheckPermission("settings-api-read") ||
2128 CheckPermission("settings-api-write");
2129 if (!hasPermission
) {
2130 FillPropertyDescriptor(aDesc
, aObject
, JS::NullValue(), false);
2135 if (name
.EqualsLiteral("mozDownloadManager")) {
2136 if (!CheckPermission("downloads")) {
2137 FillPropertyDescriptor(aDesc
, aObject
, JS::NullValue(), false);
2142 nsISupports
* existingObject
= mCachedResolveResults
.GetWeak(name
);
2143 if (existingObject
) {
2144 // We know all of our WebIDL objects here are wrappercached, so just go
2145 // ahead and WrapObject() them. We can't use WrapNewBindingObject,
2146 // because we don't have the concrete type.
2147 JS::Rooted
<JS::Value
> wrapped(aCx
);
2148 if (!dom::WrapObject(aCx
, existingObject
, &wrapped
)) {
2151 domObject
= &wrapped
.toObject();
2153 domObject
= construct(aCx
, naviObj
);
2155 return Throw(aCx
, NS_ERROR_FAILURE
);
2158 // Store the value in our cache
2159 nsISupports
* native
= UnwrapDOMObjectToISupports(domObject
);
2161 mCachedResolveResults
.Put(name
, native
);
2165 if (!JS_WrapObject(aCx
, &domObject
)) {
2169 FillPropertyDescriptor(aDesc
, aObject
, JS::ObjectValue(*domObject
), false);
2173 NS_ASSERTION(name_struct
->mType
== nsGlobalNameStruct::eTypeNavigatorProperty
,
2176 nsresult rv
= NS_OK
;
2178 nsCOMPtr
<nsISupports
> native
;
2179 bool hadCachedNative
= mCachedResolveResults
.Get(name
, getter_AddRefs(native
));
2181 JS::Rooted
<JS::Value
> prop_val(aCx
);
2182 if (hadCachedNative
) {
2183 okToUseNative
= true;
2185 native
= do_CreateInstance(name_struct
->mCID
, &rv
);
2186 if (NS_FAILED(rv
)) {
2187 return Throw(aCx
, rv
);
2190 nsCOMPtr
<nsIDOMGlobalPropertyInitializer
> gpi(do_QueryInterface(native
));
2194 return Throw(aCx
, NS_ERROR_UNEXPECTED
);
2197 rv
= gpi
->Init(mWindow
, &prop_val
);
2198 if (NS_FAILED(rv
)) {
2199 return Throw(aCx
, rv
);
2203 okToUseNative
= !prop_val
.isObjectOrNull();
2206 if (okToUseNative
) {
2207 // Make sure to do the creation of our object in the compartment
2208 // of naviObj, especially since we plan to cache that object.
2209 JSAutoCompartment
ac(aCx
, naviObj
);
2211 rv
= nsContentUtils::WrapNative(aCx
, native
, &prop_val
);
2213 if (NS_FAILED(rv
)) {
2214 return Throw(aCx
, rv
);
2217 // Now that we know we managed to wrap this thing properly, go ahead and
2218 // cache it as needed.
2219 if (!hadCachedNative
) {
2220 mCachedResolveResults
.Put(name
, native
);
2224 if (!JS_WrapValue(aCx
, &prop_val
)) {
2225 return Throw(aCx
, NS_ERROR_UNEXPECTED
);
2228 FillPropertyDescriptor(aDesc
, aObject
, prop_val
, false);
2232 struct NavigatorNameEnumeratorClosure
2234 NavigatorNameEnumeratorClosure(JSContext
* aCx
, JSObject
* aWrapper
,
2235 nsTArray
<nsString
>& aNames
)
2237 mWrapper(aCx
, aWrapper
),
2243 JS::Rooted
<JSObject
*> mWrapper
;
2244 nsTArray
<nsString
>& mNames
;
2247 static PLDHashOperator
2248 SaveNavigatorName(const nsAString
& aName
,
2249 const nsGlobalNameStruct
& aNameStruct
,
2252 NavigatorNameEnumeratorClosure
* closure
=
2253 static_cast<NavigatorNameEnumeratorClosure
*>(aClosure
);
2254 if (!aNameStruct
.mConstructorEnabled
||
2255 aNameStruct
.mConstructorEnabled(closure
->mCx
, closure
->mWrapper
)) {
2256 closure
->mNames
.AppendElement(aName
);
2258 return PL_DHASH_NEXT
;
2262 Navigator::GetOwnPropertyNames(JSContext
* aCx
, nsTArray
<nsString
>& aNames
,
2265 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
2266 if (!nameSpaceManager
) {
2267 NS_ERROR("Can't get namespace manager.");
2268 aRv
.Throw(NS_ERROR_UNEXPECTED
);
2272 NavigatorNameEnumeratorClosure
closure(aCx
, GetWrapper(), aNames
);
2273 nameSpaceManager
->EnumerateNavigatorNames(SaveNavigatorName
, &closure
);
2277 Navigator::WrapObject(JSContext
* cx
)
2279 return NavigatorBinding::Wrap(cx
, this);
2284 Navigator::HasWakeLockSupport(JSContext
* /* unused*/, JSObject
* /*unused */)
2286 nsCOMPtr
<nsIPowerManagerService
> pmService
=
2287 do_GetService(POWERMANAGERSERVICE_CONTRACTID
);
2288 // No service means no wake lock support
2294 Navigator::HasCameraSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2296 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2297 return win
&& nsDOMCameraManager::CheckPermission(win
);
2302 Navigator::HasWifiManagerSupport(JSContext
* /* unused */,
2305 // On XBL scope, the global object is NOT |window|. So we have
2306 // to use nsContentUtils::GetObjectPrincipal to get the principal
2307 // and test directly with permission manager.
2309 nsIPrincipal
* principal
= nsContentUtils::ObjectPrincipal(aGlobal
);
2311 nsCOMPtr
<nsIPermissionManager
> permMgr
=
2312 services::GetPermissionManager();
2313 NS_ENSURE_TRUE(permMgr
, false);
2315 uint32_t permission
= nsIPermissionManager::DENY_ACTION
;
2316 permMgr
->TestPermissionFromPrincipal(principal
, "wifi-manage", &permission
);
2317 return nsIPermissionManager::ALLOW_ACTION
== permission
;
2323 Navigator::HasNFCSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2325 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2327 // Do not support NFC if NFC content helper does not exist.
2328 nsCOMPtr
<nsISupports
> contentHelper
= do_GetService("@mozilla.org/nfc/content-helper;1");
2329 return !!contentHelper
;
2333 #ifdef MOZ_MEDIA_NAVIGATOR
2336 Navigator::HasUserMediaSupport(JSContext
* /* unused */,
2337 JSObject
* /* unused */)
2339 // Make enabling peerconnection enable getUserMedia() as well
2340 return Preferences::GetBool("media.navigator.enabled", false) ||
2341 Preferences::GetBool("media.peerconnection.enabled", false);
2343 #endif // MOZ_MEDIA_NAVIGATOR
2347 Navigator::HasInputMethodSupport(JSContext
* /* unused */,
2350 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2351 if (!win
|| !Preferences::GetBool("dom.mozInputMethod.enabled", false)) {
2355 if (Preferences::GetBool("dom.mozInputMethod.testing", false)) {
2359 return CheckPermission(win
, "input") ||
2360 CheckPermission(win
, "input-manage");
2365 Navigator::HasDataStoreSupport(nsIPrincipal
* aPrincipal
)
2367 workers::AssertIsOnMainThread();
2369 return DataStoreService::CheckPermission(aPrincipal
);
2372 // A WorkerMainThreadRunnable to synchronously dispatch the call of
2373 // HasDataStoreSupport() from the worker thread to the main thread.
2374 class HasDataStoreSupportRunnable MOZ_FINAL
2375 : public workers::WorkerMainThreadRunnable
2380 explicit HasDataStoreSupportRunnable(workers::WorkerPrivate
* aWorkerPrivate
)
2381 : workers::WorkerMainThreadRunnable(aWorkerPrivate
)
2384 MOZ_ASSERT(aWorkerPrivate
);
2385 aWorkerPrivate
->AssertIsOnWorkerThread();
2390 MainThreadRun() MOZ_OVERRIDE
2392 workers::AssertIsOnMainThread();
2394 mResult
= Navigator::HasDataStoreSupport(mWorkerPrivate
->GetPrincipal());
2402 Navigator::HasDataStoreSupport(JSContext
* aCx
, JSObject
* aGlobal
)
2404 // If the caller is on the worker thread, dispatch this to the main thread.
2405 if (!NS_IsMainThread()) {
2406 workers::WorkerPrivate
* workerPrivate
=
2407 workers::GetWorkerPrivateFromContext(aCx
);
2408 workerPrivate
->AssertIsOnWorkerThread();
2410 nsRefPtr
<HasDataStoreSupportRunnable
> runnable
=
2411 new HasDataStoreSupportRunnable(workerPrivate
);
2412 runnable
->Dispatch(aCx
);
2414 return runnable
->mResult
;
2417 workers::AssertIsOnMainThread();
2419 JS::Rooted
<JSObject
*> global(aCx
, aGlobal
);
2421 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(global
);
2426 nsIDocument
* doc
= win
->GetExtantDoc();
2427 if (!doc
|| !doc
->NodePrincipal()) {
2431 return HasDataStoreSupport(doc
->NodePrincipal());
2437 Navigator::HasMobileIdSupport(JSContext
* aCx
, JSObject
* aGlobal
)
2439 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2444 nsIDocument
* doc
= win
->GetExtantDoc();
2449 nsIPrincipal
* principal
= doc
->NodePrincipal();
2451 nsCOMPtr
<nsIPermissionManager
> permMgr
= services::GetPermissionManager();
2452 NS_ENSURE_TRUE(permMgr
, false);
2454 uint32_t permission
= nsIPermissionManager::UNKNOWN_ACTION
;
2455 permMgr
->TestPermissionFromPrincipal(principal
, "mobileid", &permission
);
2456 return permission
== nsIPermissionManager::PROMPT_ACTION
||
2457 permission
== nsIPermissionManager::ALLOW_ACTION
;
2462 already_AddRefed
<nsPIDOMWindow
>
2463 Navigator::GetWindowFromGlobal(JSObject
* aGlobal
)
2465 nsCOMPtr
<nsPIDOMWindow
> win
=
2466 do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal
));
2467 MOZ_ASSERT(!win
|| win
->IsInnerWindow());
2468 return win
.forget();
2472 Navigator::GetPlatform(nsAString
& aPlatform
, bool aUsePrefOverriddenValue
)
2474 MOZ_ASSERT(NS_IsMainThread());
2476 if (aUsePrefOverriddenValue
&& !nsContentUtils::IsCallerChrome()) {
2477 const nsAdoptingString
& override
=
2478 mozilla::Preferences::GetString("general.platform.override");
2481 aPlatform
= override
;
2488 nsCOMPtr
<nsIHttpProtocolHandler
>
2489 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2490 NS_ENSURE_SUCCESS(rv
, rv
);
2492 // Sorry for the #if platform ugliness, but Communicator is likewise
2493 // hardcoded and we are seeking backward compatibility here (bug 47080).
2495 aPlatform
.AssignLiteral("Win64");
2496 #elif defined(WIN32)
2497 aPlatform
.AssignLiteral("Win32");
2498 #elif defined(XP_MACOSX) && defined(__ppc__)
2499 aPlatform
.AssignLiteral("MacPPC");
2500 #elif defined(XP_MACOSX) && defined(__i386__)
2501 aPlatform
.AssignLiteral("MacIntel");
2502 #elif defined(XP_MACOSX) && defined(__x86_64__)
2503 aPlatform
.AssignLiteral("MacIntel");
2505 // XXX Communicator uses compiled-in build-time string defines
2506 // to indicate the platform it was compiled *for*, not what it is
2507 // currently running *on* which is what this does.
2509 rv
= service
->GetOscpu(plat
);
2510 CopyASCIItoUTF16(plat
, aPlatform
);
2516 /* static */ nsresult
2517 Navigator::GetAppVersion(nsAString
& aAppVersion
, bool aUsePrefOverriddenValue
)
2519 MOZ_ASSERT(NS_IsMainThread());
2521 if (aUsePrefOverriddenValue
&& !nsContentUtils::IsCallerChrome()) {
2522 const nsAdoptingString
& override
=
2523 mozilla::Preferences::GetString("general.appversion.override");
2526 aAppVersion
= override
;
2533 nsCOMPtr
<nsIHttpProtocolHandler
>
2534 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2535 NS_ENSURE_SUCCESS(rv
, rv
);
2538 rv
= service
->GetAppVersion(str
);
2539 CopyASCIItoUTF16(str
, aAppVersion
);
2540 NS_ENSURE_SUCCESS(rv
, rv
);
2542 aAppVersion
.AppendLiteral(" (");
2544 rv
= service
->GetPlatform(str
);
2545 NS_ENSURE_SUCCESS(rv
, rv
);
2547 AppendASCIItoUTF16(str
, aAppVersion
);
2548 aAppVersion
.Append(char16_t(')'));
2554 Navigator::AppName(nsAString
& aAppName
, bool aUsePrefOverriddenValue
)
2556 MOZ_ASSERT(NS_IsMainThread());
2558 if (aUsePrefOverriddenValue
&& !nsContentUtils::IsCallerChrome()) {
2559 const nsAdoptingString
& override
=
2560 mozilla::Preferences::GetString("general.appname.override");
2563 aAppName
= override
;
2568 aAppName
.AssignLiteral("Netscape");
2572 Navigator::GetUserAgent(nsPIDOMWindow
* aWindow
, nsIURI
* aURI
,
2573 bool aIsCallerChrome
,
2574 nsAString
& aUserAgent
)
2576 MOZ_ASSERT(NS_IsMainThread());
2578 if (!aIsCallerChrome
) {
2579 const nsAdoptingString
& override
=
2580 mozilla::Preferences::GetString("general.useragent.override");
2583 aUserAgent
= override
;
2589 nsCOMPtr
<nsIHttpProtocolHandler
>
2590 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2591 if (NS_WARN_IF(NS_FAILED(rv
))) {
2596 rv
= service
->GetUserAgent(ua
);
2597 if (NS_WARN_IF(NS_FAILED(rv
))) {
2601 CopyASCIItoUTF16(ua
, aUserAgent
);
2603 if (!aWindow
|| !aURI
) {
2607 MOZ_ASSERT(aWindow
->GetDocShell());
2609 nsCOMPtr
<nsISiteSpecificUserAgent
> siteSpecificUA
=
2610 do_GetService("@mozilla.org/dom/site-specific-user-agent;1");
2611 if (!siteSpecificUA
) {
2615 return siteSpecificUA
->GetUserAgentForURIAndWindow(aURI
, aWindow
, aUserAgent
);
2619 } // namespace mozilla