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"
112 static bool sDoNotTrackEnabled
= false;
113 static uint32_t sDoNotTrackValue
= 1;
114 static bool sVibratorEnabled
= false;
115 static uint32_t sMaxVibrateMS
= 0;
116 static uint32_t sMaxVibrateListLen
= 0;
122 Preferences::AddBoolVarCache(&sDoNotTrackEnabled
,
123 "privacy.donottrackheader.enabled",
125 Preferences::AddUintVarCache(&sDoNotTrackValue
,
126 "privacy.donottrackheader.value",
128 Preferences::AddBoolVarCache(&sVibratorEnabled
,
129 "dom.vibrator.enabled", true);
130 Preferences::AddUintVarCache(&sMaxVibrateMS
,
131 "dom.vibrator.max_vibrate_ms", 10000);
132 Preferences::AddUintVarCache(&sMaxVibrateListLen
,
133 "dom.vibrator.max_vibrate_list_len", 128);
136 Navigator::Navigator(nsPIDOMWindow
* aWindow
)
139 MOZ_ASSERT(aWindow
->IsInnerWindow(), "Navigator must get an inner window!");
143 Navigator::~Navigator()
148 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Navigator
)
149 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
150 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDOMNavigator
)
151 NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator
)
152 NS_INTERFACE_MAP_ENTRY(nsIMozNavigatorNetwork
)
155 NS_IMPL_CYCLE_COLLECTING_ADDREF(Navigator
)
156 NS_IMPL_CYCLE_COLLECTING_RELEASE(Navigator
)
158 NS_IMPL_CYCLE_COLLECTION_CLASS(Navigator
)
160 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Navigator
)
162 NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow
)
163 NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedResolveResults
)
164 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
165 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
167 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator
)
168 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins
)
169 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMimeTypes
)
170 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation
)
171 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification
)
172 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager
)
173 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager
)
174 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager
)
175 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony
)
176 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection
)
178 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections
)
179 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast
)
180 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager
)
181 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail
)
184 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBluetooth
)
186 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
187 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager
)
189 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager
)
190 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagesManager
)
191 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageStores
)
192 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager
)
193 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer
)
195 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow
)
196 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedResolveResults
)
197 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
198 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
200 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Navigator
)
203 Navigator::Invalidate()
205 // Don't clear mWindow here so we know we've got a non-null mWindow
206 // until we're unlinked.
209 mPlugins
->Invalidate();
213 mMimeTypes
= nullptr;
215 // If there is a page transition, make sure delete the geolocation object.
217 mGeolocation
->Shutdown();
218 mGeolocation
= nullptr;
222 mNotification
->Shutdown();
223 mNotification
= nullptr;
226 if (mBatteryManager
) {
227 mBatteryManager
->Shutdown();
228 mBatteryManager
= nullptr;
233 mFMRadio
->Shutdown();
239 mPowerManager
->Shutdown();
240 mPowerManager
= nullptr;
243 if (mMobileMessageManager
) {
244 mMobileMessageManager
->Shutdown();
245 mMobileMessageManager
= nullptr;
249 mTelephony
= nullptr;
253 mConnection
->Shutdown();
254 mConnection
= nullptr;
258 if (mMobileConnections
) {
259 mMobileConnections
= nullptr;
262 if (mCellBroadcast
) {
263 mCellBroadcast
= nullptr;
267 mIccManager
->Shutdown();
268 mIccManager
= nullptr;
272 mVoicemail
= nullptr;
278 mBluetooth
= nullptr;
282 mCameraManager
= nullptr;
284 if (mMessagesManager
) {
285 mMessagesManager
= nullptr;
288 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
289 if (mAudioChannelManager
) {
290 mAudioChannelManager
= nullptr;
294 uint32_t len
= mDeviceStorageStores
.Length();
295 for (uint32_t i
= 0; i
< len
; ++i
) {
296 mDeviceStorageStores
[i
]->Shutdown();
298 mDeviceStorageStores
.Clear();
301 mTimeManager
= nullptr;
304 mServiceWorkerContainer
= nullptr;
307 //*****************************************************************************
308 // Navigator::nsIDOMNavigator
309 //*****************************************************************************
312 Navigator::GetUserAgent(nsAString
& aUserAgent
)
314 nsresult rv
= NS_GetNavigatorUserAgent(aUserAgent
);
315 NS_ENSURE_SUCCESS(rv
, rv
);
317 if (!mWindow
|| !mWindow
->GetDocShell()) {
321 nsIDocument
* doc
= mWindow
->GetExtantDoc();
326 nsCOMPtr
<nsIURI
> codebaseURI
;
327 doc
->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI
));
332 nsCOMPtr
<nsISiteSpecificUserAgent
> siteSpecificUA
=
333 do_GetService("@mozilla.org/dom/site-specific-user-agent;1");
334 NS_ENSURE_TRUE(siteSpecificUA
, NS_OK
);
336 return siteSpecificUA
->GetUserAgentForURIAndWindow(codebaseURI
, mWindow
,
341 Navigator::GetAppCodeName(nsAString
& aAppCodeName
)
345 nsCOMPtr
<nsIHttpProtocolHandler
>
346 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
347 NS_ENSURE_SUCCESS(rv
, rv
);
349 nsAutoCString appName
;
350 rv
= service
->GetAppName(appName
);
351 CopyASCIItoUTF16(appName
, aAppCodeName
);
357 Navigator::GetAppVersion(nsAString
& aAppVersion
)
359 return NS_GetNavigatorAppVersion(aAppVersion
);
363 Navigator::GetAppName(nsAString
& aAppName
)
365 NS_GetNavigatorAppName(aAppName
);
370 * Returns the value of Accept-Languages (HTTP header) as a nsTArray of
371 * languages. The value is set in the preference by the user ("Content
374 * "en", "en-US" and "i-cherokee" and "" are valid languages tokens.
376 * An empty array will be returned if there is no valid languages.
379 Navigator::GetAcceptLanguages(nsTArray
<nsString
>& aLanguages
)
381 // E.g. "de-de, en-us,en".
382 const nsAdoptingString
& acceptLang
=
383 Preferences::GetLocalizedString("intl.accept_languages");
385 // Split values on commas.
386 nsCharSeparatedTokenizer
langTokenizer(acceptLang
, ',');
387 while (langTokenizer
.hasMoreTokens()) {
388 nsDependentSubstring lang
= langTokenizer
.nextToken();
390 // Replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
391 // NOTE: we should probably rely on the pref being set correctly.
392 if (lang
.Length() > 2 && lang
[2] == char16_t('_')) {
393 lang
.Replace(2, 1, char16_t('-'));
396 // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
397 // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
398 // NOTE: we should probably rely on the pref being set correctly.
399 if (lang
.Length() > 2) {
400 nsCharSeparatedTokenizer
localeTokenizer(lang
, '-');
403 while (localeTokenizer
.hasMoreTokens()) {
404 const nsSubstring
& code
= localeTokenizer
.nextToken();
406 if (code
.Length() == 2 && !first
) {
407 nsAutoString
upper(code
);
409 lang
.Replace(pos
, code
.Length(), upper
);
412 pos
+= code
.Length() + 1; // 1 is the separator
417 aLanguages
.AppendElement(lang
);
422 * Do not use UI language (chosen app locale) here but the first value set in
423 * the Accept Languages header, see ::GetAcceptLanguages().
425 * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for
429 Navigator::GetLanguage(nsAString
& aLanguage
)
431 nsTArray
<nsString
> languages
;
432 GetLanguages(languages
);
433 if (languages
.Length() >= 1) {
434 aLanguage
.Assign(languages
[0]);
436 aLanguage
.Truncate();
443 Navigator::GetLanguages(nsTArray
<nsString
>& aLanguages
)
445 GetAcceptLanguages(aLanguages
);
447 // The returned value is cached by the binding code. The window listen to the
448 // accept languages change and will clear the cache when needed. It has to
449 // take care of dispatching the DOM event already and the invalidation and the
450 // event has to be timed correctly.
454 Navigator::GetPlatform(nsAString
& aPlatform
)
456 return NS_GetNavigatorPlatform(aPlatform
);
460 Navigator::GetOscpu(nsAString
& aOSCPU
)
462 if (!nsContentUtils::IsCallerChrome()) {
463 const nsAdoptingString
& override
=
464 Preferences::GetString("general.oscpu.override");
474 nsCOMPtr
<nsIHttpProtocolHandler
>
475 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
476 NS_ENSURE_SUCCESS(rv
, rv
);
479 rv
= service
->GetOscpu(oscpu
);
480 CopyASCIItoUTF16(oscpu
, aOSCPU
);
486 Navigator::GetVendor(nsAString
& aVendor
)
493 Navigator::GetVendorSub(nsAString
& aVendorSub
)
495 aVendorSub
.Truncate();
500 Navigator::GetProduct(nsAString
& aProduct
)
502 aProduct
.AssignLiteral("Gecko");
507 Navigator::GetProductSub(nsAString
& aProductSub
)
509 // Legacy build ID hardcoded for backward compatibility (bug 776376)
510 aProductSub
.AssignLiteral("20100101");
515 Navigator::GetMimeTypes(ErrorResult
& aRv
)
519 aRv
.Throw(NS_ERROR_UNEXPECTED
);
522 mMimeTypes
= new nsMimeTypeArray(mWindow
);
529 Navigator::GetPlugins(ErrorResult
& aRv
)
533 aRv
.Throw(NS_ERROR_UNEXPECTED
);
536 mPlugins
= new nsPluginArray(mWindow
);
543 // Values for the network.cookie.cookieBehavior pref are documented in
544 // nsCookieService.cpp.
545 #define COOKIE_BEHAVIOR_REJECT 2
548 Navigator::CookieEnabled()
551 (Preferences::GetInt("network.cookie.cookieBehavior",
552 COOKIE_BEHAVIOR_REJECT
) != COOKIE_BEHAVIOR_REJECT
);
554 // Check whether an exception overrides the global cookie behavior
555 // Note that the code for getting the URI here matches that in
556 // nsHTMLDocument::SetCookie.
557 if (!mWindow
|| !mWindow
->GetDocShell()) {
558 return cookieEnabled
;
561 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetExtantDoc();
563 return cookieEnabled
;
566 nsCOMPtr
<nsIURI
> codebaseURI
;
567 doc
->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI
));
570 // Not a codebase, so technically can't set cookies, but let's
571 // just return the default value.
572 return cookieEnabled
;
575 nsCOMPtr
<nsICookiePermission
> permMgr
=
576 do_GetService(NS_COOKIEPERMISSION_CONTRACTID
);
577 NS_ENSURE_TRUE(permMgr
, cookieEnabled
);
579 // Pass null for the channel, just like the cookie service does.
580 nsCookieAccess access
;
581 nsresult rv
= permMgr
->CanAccess(codebaseURI
, nullptr, &access
);
582 NS_ENSURE_SUCCESS(rv
, cookieEnabled
);
584 if (access
!= nsICookiePermission::ACCESS_DEFAULT
) {
585 cookieEnabled
= access
!= nsICookiePermission::ACCESS_DENY
;
588 return cookieEnabled
;
594 return !NS_IsOffline();
598 Navigator::GetBuildID(nsAString
& aBuildID
)
600 if (!nsContentUtils::IsCallerChrome()) {
601 const nsAdoptingString
& override
=
602 Preferences::GetString("general.buildID.override");
610 nsCOMPtr
<nsIXULAppInfo
> appInfo
=
611 do_GetService("@mozilla.org/xre/app-info;1");
613 return NS_ERROR_NOT_IMPLEMENTED
;
616 nsAutoCString buildID
;
617 nsresult rv
= appInfo
->GetAppBuildID(buildID
);
623 AppendASCIItoUTF16(buildID
, aBuildID
);
628 Navigator::GetDoNotTrack(nsAString
&aResult
)
630 if (sDoNotTrackEnabled
) {
631 if (sDoNotTrackValue
== 0) {
632 aResult
.AssignLiteral("0");
634 aResult
.AssignLiteral("1");
637 aResult
.AssignLiteral("unspecified");
644 Navigator::JavaEnabled(ErrorResult
& aRv
)
646 Telemetry::AutoTimer
<Telemetry::CHECK_JAVA_ENABLED
> telemetryTimer
;
648 // Return true if we have a handler for the java mime
649 nsAdoptingString javaMIME
= Preferences::GetString("plugin.java.mime");
650 NS_ENSURE_TRUE(!javaMIME
.IsEmpty(), false);
654 aRv
.Throw(NS_ERROR_UNEXPECTED
);
657 mMimeTypes
= new nsMimeTypeArray(mWindow
);
662 nsMimeType
*mimeType
= mMimeTypes
->NamedItem(javaMIME
);
664 return mimeType
&& mimeType
->GetEnabledPlugin();
668 Navigator::RefreshMIMEArray()
671 mMimeTypes
->Refresh();
677 class VibrateWindowListener
: public nsIDOMEventListener
680 VibrateWindowListener(nsIDOMWindow
* aWindow
, nsIDocument
* aDocument
)
682 mWindow
= do_GetWeakReference(aWindow
);
683 mDocument
= do_GetWeakReference(aDocument
);
685 NS_NAMED_LITERAL_STRING(visibilitychange
, "visibilitychange");
686 aDocument
->AddSystemEventListener(visibilitychange
,
688 true, /* use capture */
689 false /* wants untrusted */);
692 virtual ~VibrateWindowListener()
696 void RemoveListener();
699 NS_DECL_NSIDOMEVENTLISTENER
706 NS_IMPL_ISUPPORTS(VibrateWindowListener
, nsIDOMEventListener
)
708 StaticRefPtr
<VibrateWindowListener
> gVibrateWindowListener
;
711 VibrateWindowListener::HandleEvent(nsIDOMEvent
* aEvent
)
713 nsCOMPtr
<nsIDocument
> doc
=
714 do_QueryInterface(aEvent
->InternalDOMEvent()->GetTarget());
716 if (!doc
|| doc
->Hidden()) {
717 // It's important that we call CancelVibrate(), not Vibrate() with an
718 // empty list, because Vibrate() will fail if we're no longer focused, but
719 // CancelVibrate() will succeed, so long as nobody else has started a new
720 // vibration pattern.
721 nsCOMPtr
<nsIDOMWindow
> window
= do_QueryReferent(mWindow
);
722 hal::CancelVibrate(window
);
724 gVibrateWindowListener
= nullptr;
725 // Careful: The line above might have deleted |this|!
732 VibrateWindowListener::RemoveListener()
734 nsCOMPtr
<EventTarget
> target
= do_QueryReferent(mDocument
);
738 NS_NAMED_LITERAL_STRING(visibilitychange
, "visibilitychange");
739 target
->RemoveSystemEventListener(visibilitychange
, this,
740 true /* use capture */);
743 } // anonymous namespace
746 Navigator::AddIdleObserver(MozIdleObserver
& aIdleObserver
, ErrorResult
& aRv
)
749 aRv
.Throw(NS_ERROR_UNEXPECTED
);
752 CallbackObjectHolder
<MozIdleObserver
, nsIIdleObserver
> holder(&aIdleObserver
);
753 nsCOMPtr
<nsIIdleObserver
> obs
= holder
.ToXPCOMCallback();
754 if (NS_FAILED(mWindow
->RegisterIdleObserver(obs
))) {
755 NS_WARNING("Failed to add idle observer.");
760 Navigator::RemoveIdleObserver(MozIdleObserver
& aIdleObserver
, ErrorResult
& aRv
)
763 aRv
.Throw(NS_ERROR_UNEXPECTED
);
766 CallbackObjectHolder
<MozIdleObserver
, nsIIdleObserver
> holder(&aIdleObserver
);
767 nsCOMPtr
<nsIIdleObserver
> obs
= holder
.ToXPCOMCallback();
768 if (NS_FAILED(mWindow
->UnregisterIdleObserver(obs
))) {
769 NS_WARNING("Failed to remove idle observer.");
774 Navigator::Vibrate(uint32_t aDuration
)
776 nsAutoTArray
<uint32_t, 1> pattern
;
777 pattern
.AppendElement(aDuration
);
778 return Vibrate(pattern
);
782 Navigator::Vibrate(const nsTArray
<uint32_t>& aPattern
)
788 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetExtantDoc();
794 // Hidden documents cannot start or stop a vibration.
798 nsTArray
<uint32_t> pattern(aPattern
);
800 if (pattern
.Length() > sMaxVibrateListLen
) {
801 pattern
.SetLength(sMaxVibrateListLen
);
804 for (size_t i
= 0; i
< pattern
.Length(); ++i
) {
805 if (pattern
[i
] > sMaxVibrateMS
) {
806 pattern
[i
] = sMaxVibrateMS
;
810 // The spec says we check sVibratorEnabled after we've done the sanity
811 // checking on the pattern.
812 if (pattern
.IsEmpty() || !sVibratorEnabled
) {
816 // Add a listener to cancel the vibration if the document becomes hidden,
817 // and remove the old visibility listener, if there was one.
819 if (!gVibrateWindowListener
) {
820 // If gVibrateWindowListener is null, this is the first time we've vibrated,
821 // and we need to register a listener to clear gVibrateWindowListener on
823 ClearOnShutdown(&gVibrateWindowListener
);
826 gVibrateWindowListener
->RemoveListener();
828 gVibrateWindowListener
= new VibrateWindowListener(mWindow
, doc
);
830 hal::Vibrate(pattern
, mWindow
);
834 //*****************************************************************************
835 // Pointer Events interface
836 //*****************************************************************************
839 Navigator::MaxTouchPoints()
841 nsCOMPtr
<nsIWidget
> widget
= widget::WidgetUtils::DOMWindowToWidget(mWindow
);
843 NS_ENSURE_TRUE(widget
, 0);
844 return widget
->GetMaxTouchPoints();
847 //*****************************************************************************
848 // Navigator::nsIDOMClientInformation
849 //*****************************************************************************
852 Navigator::RegisterContentHandler(const nsAString
& aMIMEType
,
853 const nsAString
& aURI
,
854 const nsAString
& aTitle
,
857 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
861 nsCOMPtr
<nsIWebContentHandlerRegistrar
> registrar
=
862 do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID
);
867 aRv
= registrar
->RegisterContentHandler(aMIMEType
, aURI
, aTitle
,
868 mWindow
->GetOuterWindow());
872 Navigator::RegisterProtocolHandler(const nsAString
& aProtocol
,
873 const nsAString
& aURI
,
874 const nsAString
& aTitle
,
877 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
881 nsCOMPtr
<nsIWebContentHandlerRegistrar
> registrar
=
882 do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID
);
887 aRv
= registrar
->RegisterProtocolHandler(aProtocol
, aURI
, aTitle
,
888 mWindow
->GetOuterWindow());
892 Navigator::MozIsLocallyAvailable(const nsAString
&aURI
,
896 nsCOMPtr
<nsIURI
> uri
;
897 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), aURI
);
903 // This method of checking the cache will only work for http/https urls.
905 rv
= uri
->SchemeIs("http", &match
);
912 rv
= uri
->SchemeIs("https", &match
);
918 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
923 // Same origin check.
924 JSContext
*cx
= nsContentUtils::GetCurrentJSContext();
926 aRv
.Throw(NS_ERROR_FAILURE
);
930 rv
= nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx
, uri
);
936 // These load flags cause an error to be thrown if there is no
937 // valid cache entry, and skip the load if there is.
938 // If the cache is busy, assume that it is not yet available rather
939 // than waiting for it to become available.
940 uint32_t loadFlags
= nsIChannel::INHIBIT_CACHING
|
941 nsICachingChannel::LOAD_NO_NETWORK_IO
|
942 nsICachingChannel::LOAD_ONLY_IF_MODIFIED
|
943 nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
;
946 loadFlags
|= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE
|
947 nsICachingChannel::LOAD_ONLY_FROM_CACHE
|
948 nsIRequest::LOAD_FROM_CACHE
;
952 aRv
.Throw(NS_ERROR_UNEXPECTED
);
956 nsCOMPtr
<nsILoadGroup
> loadGroup
;
957 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetDoc();
959 loadGroup
= doc
->GetDocumentLoadGroup();
962 nsCOMPtr
<nsIChannel
> channel
;
963 rv
= NS_NewChannel(getter_AddRefs(channel
), uri
,
964 nullptr, loadGroup
, nullptr, loadFlags
);
970 nsCOMPtr
<nsIInputStream
> stream
;
971 rv
= channel
->Open(getter_AddRefs(stream
));
980 rv
= channel
->GetStatus(&status
);
986 if (NS_FAILED(status
)) {
990 nsCOMPtr
<nsIHttpChannel
> httpChannel
= do_QueryInterface(channel
);
992 rv
= httpChannel
->GetRequestSucceeded(&isAvailable
);
1001 Navigator::GetDeviceStorage(const nsAString
& aType
, ErrorResult
& aRv
)
1003 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1004 aRv
.Throw(NS_ERROR_FAILURE
);
1008 nsRefPtr
<nsDOMDeviceStorage
> storage
;
1009 nsDOMDeviceStorage::CreateDeviceStorageFor(mWindow
, aType
,
1010 getter_AddRefs(storage
));
1016 mDeviceStorageStores
.AppendElement(storage
);
1021 Navigator::GetDeviceStorages(const nsAString
& aType
,
1022 nsTArray
<nsRefPtr
<nsDOMDeviceStorage
> >& aStores
,
1025 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1026 aRv
.Throw(NS_ERROR_FAILURE
);
1030 nsDOMDeviceStorage::CreateDeviceStoragesFor(mWindow
, aType
, aStores
);
1032 mDeviceStorageStores
.AppendElements(aStores
);
1036 Navigator::GetGeolocation(ErrorResult
& aRv
)
1039 return mGeolocation
;
1042 if (!mWindow
|| !mWindow
->GetOuterWindow() || !mWindow
->GetDocShell()) {
1043 aRv
.Throw(NS_ERROR_FAILURE
);
1047 mGeolocation
= new Geolocation();
1048 if (NS_FAILED(mGeolocation
->Init(mWindow
->GetOuterWindow()))) {
1049 mGeolocation
= nullptr;
1050 aRv
.Throw(NS_ERROR_FAILURE
);
1054 return mGeolocation
;
1057 class BeaconStreamListener MOZ_FINAL
: public nsIStreamListener
1060 BeaconStreamListener() {}
1063 NS_DECL_NSISTREAMLISTENER
1064 NS_DECL_NSIREQUESTOBSERVER
1067 NS_IMPL_ISUPPORTS(BeaconStreamListener
,
1073 BeaconStreamListener::OnStartRequest(nsIRequest
*aRequest
,
1074 nsISupports
*aContext
)
1076 aRequest
->Cancel(NS_ERROR_NET_INTERRUPT
);
1077 return NS_BINDING_ABORTED
;
1081 BeaconStreamListener::OnStopRequest(nsIRequest
*aRequest
,
1082 nsISupports
*aContext
,
1089 BeaconStreamListener::OnDataAvailable(nsIRequest
*aRequest
,
1091 nsIInputStream
*inStr
,
1092 uint64_t sourceOffset
,
1100 Navigator::SendBeacon(const nsAString
& aUrl
,
1101 const Nullable
<ArrayBufferViewOrBlobOrStringOrFormData
>& aData
,
1105 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1109 nsCOMPtr
<nsIDocument
> doc
= mWindow
->GetDoc();
1111 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1115 nsIURI
* documentURI
= doc
->GetDocumentURI();
1117 aRv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
1121 nsCOMPtr
<nsIURI
> uri
;
1122 nsresult rv
= nsContentUtils::NewURIWithDocumentCharset(
1123 getter_AddRefs(uri
),
1126 doc
->GetDocBaseURI());
1127 if (NS_FAILED(rv
)) {
1128 aRv
.Throw(NS_ERROR_DOM_URL_MISMATCH_ERR
);
1132 // Check whether this is a sane URI to load
1133 // Explicitly disallow things like chrome:, javascript:, and data: URIs
1134 nsCOMPtr
<nsIPrincipal
> principal
= doc
->NodePrincipal();
1135 nsCOMPtr
<nsIScriptSecurityManager
> secMan
= nsContentUtils::GetSecurityManager();
1136 uint32_t flags
= nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL
1137 & nsIScriptSecurityManager::DISALLOW_SCRIPT
;
1138 rv
= secMan
->CheckLoadURIWithPrincipal(principal
,
1141 if (NS_FAILED(rv
)) {
1147 // Check whether the CSP allows us to load
1148 int16_t shouldLoad
= nsIContentPolicy::ACCEPT
;
1149 rv
= NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_BEACON
,
1153 EmptyCString(), //mime guess
1156 nsContentUtils::GetContentPolicy(),
1157 nsContentUtils::GetSecurityManager());
1158 if (NS_FAILED(rv
) || NS_CP_REJECTED(shouldLoad
)) {
1159 // Disallowed by content policy
1160 aRv
.Throw(NS_ERROR_CONTENT_BLOCKED
);
1164 nsCOMPtr
<nsIChannel
> channel
;
1165 nsCOMPtr
<nsIChannelPolicy
> channelPolicy
;
1166 nsCOMPtr
<nsIContentSecurityPolicy
> csp
;
1167 rv
= principal
->GetCsp(getter_AddRefs(csp
));
1168 if (NS_FAILED(rv
)) {
1169 aRv
.Throw(NS_ERROR_FAILURE
);
1174 channelPolicy
= do_CreateInstance(NSCHANNELPOLICY_CONTRACTID
);
1175 channelPolicy
->SetContentSecurityPolicy(csp
);
1176 channelPolicy
->SetLoadType(nsIContentPolicy::TYPE_BEACON
);
1178 rv
= NS_NewChannel(getter_AddRefs(channel
),
1183 nsIRequest::LOAD_NORMAL
,
1185 if (NS_FAILED(rv
)) {
1190 nsCOMPtr
<nsIPrivateBrowsingChannel
> pbChannel
= do_QueryInterface(channel
);
1192 nsIDocShell
* docShell
= mWindow
->GetDocShell();
1193 nsCOMPtr
<nsILoadContext
> loadContext
= do_QueryInterface(docShell
);
1195 rv
= pbChannel
->SetPrivate(loadContext
->UsePrivateBrowsing());
1196 if (NS_FAILED(rv
)) {
1197 NS_WARNING("Setting the privacy status on the beacon channel failed");
1202 nsCOMPtr
<nsIHttpChannel
> httpChannel
= do_QueryInterface(channel
);
1204 // Beacon spec only supports HTTP requests at this time
1205 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
1208 httpChannel
->SetReferrer(documentURI
);
1210 // Anything that will need to refer to the window during the request
1211 // will need to be done now. For example, detection of whether any
1212 // cookies set by this request are foreign. Note that ThirdPartyUtil
1213 // (nsIThirdPartyUtil.isThirdPartyChannel) does a secondary check between
1214 // the channel URI and the cookie URI even when forceAllowThirdPartyCookie
1215 // is set, so this is safe with regard to redirects.
1216 nsCOMPtr
<nsIHttpChannelInternal
> httpChannelInternal(do_QueryInterface(channel
));
1217 nsCOMPtr
<mozIThirdPartyUtil
> thirdPartyUtil
= do_GetService(THIRDPARTYUTIL_CONTRACTID
);
1218 if (!httpChannelInternal
) {
1219 aRv
.Throw(NS_ERROR_DOM_BAD_URI
);
1222 bool isForeign
= true;
1223 thirdPartyUtil
->IsThirdPartyWindow(mWindow
, uri
, &isForeign
);
1224 httpChannelInternal
->SetForceAllowThirdPartyCookie(!isForeign
);
1227 if (!aData
.IsNull()) {
1228 nsCOMPtr
<nsIInputStream
> in
;
1230 if (aData
.Value().IsString()) {
1231 nsCString stringData
= NS_ConvertUTF16toUTF8(aData
.Value().GetAsString());
1232 nsCOMPtr
<nsIStringInputStream
> strStream
= do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID
, &rv
);
1233 if (NS_FAILED(rv
)) {
1234 aRv
.Throw(NS_ERROR_FAILURE
);
1237 rv
= strStream
->SetData(stringData
.BeginReading(), stringData
.Length());
1238 if (NS_FAILED(rv
)) {
1239 aRv
.Throw(NS_ERROR_FAILURE
);
1242 mimeType
.AssignLiteral("text/plain;charset=UTF-8");
1245 } else if (aData
.Value().IsArrayBufferView()) {
1247 nsCOMPtr
<nsIStringInputStream
> strStream
= do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID
, &rv
);
1248 if (NS_FAILED(rv
)) {
1249 aRv
.Throw(NS_ERROR_FAILURE
);
1253 ArrayBufferView
& view
= aData
.Value().GetAsArrayBufferView();
1254 view
.ComputeLengthAndData();
1255 rv
= strStream
->SetData(reinterpret_cast<char*>(view
.Data()),
1258 if (NS_FAILED(rv
)) {
1259 aRv
.Throw(NS_ERROR_FAILURE
);
1262 mimeType
.AssignLiteral("application/octet-stream");
1265 } else if (aData
.Value().IsBlob()) {
1266 nsCOMPtr
<nsIDOMBlob
> blob
= aData
.Value().GetAsBlob();
1267 rv
= blob
->GetInternalStream(getter_AddRefs(in
));
1268 if (NS_FAILED(rv
)) {
1269 aRv
.Throw(NS_ERROR_FAILURE
);
1273 rv
= blob
->GetType(type
);
1274 if (NS_FAILED(rv
)) {
1275 aRv
.Throw(NS_ERROR_FAILURE
);
1278 mimeType
= NS_ConvertUTF16toUTF8(type
);
1280 } else if (aData
.Value().IsFormData()) {
1281 nsFormData
& form
= aData
.Value().GetAsFormData();
1283 nsAutoCString charset
;
1284 form
.GetSendInfo(getter_AddRefs(in
),
1289 MOZ_ASSERT(false, "switch statements not in sync");
1290 aRv
.Throw(NS_ERROR_FAILURE
);
1294 nsCOMPtr
<nsIUploadChannel2
> uploadChannel
= do_QueryInterface(channel
);
1295 if (!uploadChannel
) {
1296 aRv
.Throw(NS_ERROR_FAILURE
);
1299 uploadChannel
->ExplicitSetUploadStream(in
, mimeType
, -1,
1300 NS_LITERAL_CSTRING("POST"),
1303 httpChannel
->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
1306 nsCOMPtr
<nsISupportsPriority
> p
= do_QueryInterface(channel
);
1308 p
->SetPriority(nsISupportsPriority::PRIORITY_LOWEST
);
1311 nsRefPtr
<nsCORSListenerProxy
> cors
= new nsCORSListenerProxy(new BeaconStreamListener(),
1315 // Start a preflight if cross-origin and content type is not whitelisted
1316 rv
= secMan
->CheckSameOriginURI(documentURI
, uri
, false);
1317 bool crossOrigin
= NS_FAILED(rv
);
1318 nsAutoCString contentType
, parsedCharset
;
1319 rv
= NS_ParseContentType(mimeType
, contentType
, parsedCharset
);
1321 contentType
.Length() > 0 &&
1322 !contentType
.Equals(APPLICATION_WWW_FORM_URLENCODED
) &&
1323 !contentType
.Equals(MULTIPART_FORM_DATA
) &&
1324 !contentType
.Equals(TEXT_PLAIN
)) {
1325 nsCOMPtr
<nsIChannel
> preflightChannel
;
1326 nsTArray
<nsCString
> unsafeHeaders
;
1327 unsafeHeaders
.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
1328 rv
= NS_StartCORSPreflight(channel
,
1333 getter_AddRefs(preflightChannel
));
1335 rv
= channel
->AsyncOpen(cors
, nullptr);
1337 if (NS_FAILED(rv
)) {
1344 #ifdef MOZ_MEDIA_NAVIGATOR
1346 Navigator::MozGetUserMedia(const MediaStreamConstraints
& aConstraints
,
1347 NavigatorUserMediaSuccessCallback
& aOnSuccess
,
1348 NavigatorUserMediaErrorCallback
& aOnError
,
1351 CallbackObjectHolder
<NavigatorUserMediaSuccessCallback
,
1352 nsIDOMGetUserMediaSuccessCallback
> holder1(&aOnSuccess
);
1353 nsCOMPtr
<nsIDOMGetUserMediaSuccessCallback
> onsuccess
=
1354 holder1
.ToXPCOMCallback();
1356 CallbackObjectHolder
<NavigatorUserMediaErrorCallback
,
1357 nsIDOMGetUserMediaErrorCallback
> holder2(&aOnError
);
1358 nsCOMPtr
<nsIDOMGetUserMediaErrorCallback
> onerror
= holder2
.ToXPCOMCallback();
1360 if (!mWindow
|| !mWindow
->GetOuterWindow() ||
1361 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1362 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1366 bool privileged
= nsContentUtils::IsChromeDoc(mWindow
->GetExtantDoc());
1368 MediaManager
* manager
= MediaManager::Get();
1369 aRv
= manager
->GetUserMedia(privileged
, mWindow
, aConstraints
,
1370 onsuccess
, onerror
);
1374 Navigator::MozGetUserMediaDevices(const MediaStreamConstraints
& aConstraints
,
1375 MozGetUserMediaDevicesSuccessCallback
& aOnSuccess
,
1376 NavigatorUserMediaErrorCallback
& aOnError
,
1377 uint64_t aInnerWindowID
,
1380 CallbackObjectHolder
<MozGetUserMediaDevicesSuccessCallback
,
1381 nsIGetUserMediaDevicesSuccessCallback
> holder1(&aOnSuccess
);
1382 nsCOMPtr
<nsIGetUserMediaDevicesSuccessCallback
> onsuccess
=
1383 holder1
.ToXPCOMCallback();
1385 CallbackObjectHolder
<NavigatorUserMediaErrorCallback
,
1386 nsIDOMGetUserMediaErrorCallback
> holder2(&aOnError
);
1387 nsCOMPtr
<nsIDOMGetUserMediaErrorCallback
> onerror
= holder2
.ToXPCOMCallback();
1389 if (!mWindow
|| !mWindow
->GetOuterWindow() ||
1390 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1391 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1395 MediaManager
* manager
= MediaManager::Get();
1396 aRv
= manager
->GetUserMediaDevices(mWindow
, aConstraints
, onsuccess
, onerror
,
1401 DesktopNotificationCenter
*
1402 Navigator::GetMozNotification(ErrorResult
& aRv
)
1404 if (mNotification
) {
1405 return mNotification
;
1408 if (!mWindow
|| !mWindow
->GetDocShell()) {
1409 aRv
.Throw(NS_ERROR_FAILURE
);
1413 mNotification
= new DesktopNotificationCenter(mWindow
);
1414 return mNotification
;
1419 using mozilla::dom::FMRadio
;
1422 Navigator::GetMozFMRadio(ErrorResult
& aRv
)
1426 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1430 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1432 mFMRadio
= new FMRadio();
1433 mFMRadio
->Init(mWindow
);
1439 #endif // MOZ_B2G_FM
1441 //*****************************************************************************
1442 // Navigator::nsINavigatorBattery
1443 //*****************************************************************************
1445 battery::BatteryManager
*
1446 Navigator::GetBattery(ErrorResult
& aRv
)
1448 if (!mBatteryManager
) {
1450 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1453 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1455 mBatteryManager
= new battery::BatteryManager(mWindow
);
1456 mBatteryManager
->Init();
1459 return mBatteryManager
;
1462 /* static */ already_AddRefed
<Promise
>
1463 Navigator::GetDataStores(nsPIDOMWindow
* aWindow
,
1464 const nsAString
& aName
,
1467 if (!aWindow
|| !aWindow
->GetDocShell()) {
1468 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1472 nsRefPtr
<DataStoreService
> service
= DataStoreService::GetOrCreate();
1474 aRv
.Throw(NS_ERROR_FAILURE
);
1478 nsCOMPtr
<nsISupports
> promise
;
1479 aRv
= service
->GetDataStores(aWindow
, aName
, getter_AddRefs(promise
));
1481 nsRefPtr
<Promise
> p
= static_cast<Promise
*>(promise
.get());
1485 already_AddRefed
<Promise
>
1486 Navigator::GetDataStores(const nsAString
& aName
, ErrorResult
& aRv
)
1488 return GetDataStores(mWindow
, aName
, aRv
);
1491 already_AddRefed
<Promise
>
1492 Navigator::GetFeature(const nsAString
& aName
)
1494 nsCOMPtr
<nsIGlobalObject
> go
= do_QueryInterface(mWindow
);
1495 nsRefPtr
<Promise
> p
= new Promise(go
);
1497 #if defined(XP_LINUX)
1498 if (aName
.EqualsLiteral("hardware.memory")) {
1499 // with seccomp enabled, fopen() should be in a non-sandboxed process
1500 if (XRE_GetProcessType() == GeckoProcessType_Default
) {
1501 uint32_t memLevel
= mozilla::hal::GetTotalSystemMemoryLevel();
1502 if (memLevel
== 0) {
1503 p
->MaybeReject(NS_ERROR_NOT_AVAILABLE
);
1506 p
->MaybeResolve((int)memLevel
);
1508 mozilla::dom::ContentChild
* cc
=
1509 mozilla::dom::ContentChild::GetSingleton();
1510 nsRefPtr
<Promise
> ipcRef(p
);
1511 cc
->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef
.forget().take()));
1514 } // hardware.memory
1516 // resolve with <undefined> because the feature name is not supported
1517 p
->MaybeResolve(JS::UndefinedHandleValue
);
1524 Navigator::GetMozPower(ErrorResult
& aRv
)
1526 if (!mPowerManager
) {
1528 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1531 mPowerManager
= PowerManager::CreateInstance(mWindow
);
1532 if (!mPowerManager
) {
1533 // We failed to get the power manager service?
1534 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1538 return mPowerManager
;
1541 already_AddRefed
<WakeLock
>
1542 Navigator::RequestWakeLock(const nsAString
&aTopic
, ErrorResult
& aRv
)
1545 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1549 nsRefPtr
<power::PowerManagerService
> pmService
=
1550 power::PowerManagerService::GetInstance();
1551 // Maybe it went away for some reason... Or maybe we're just called
1552 // from our XPCOM method.
1554 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1558 return pmService
->NewWakeLock(aTopic
, mWindow
, aRv
);
1561 nsIDOMMozMobileMessageManager
*
1562 Navigator::GetMozMobileMessage()
1564 if (!mMobileMessageManager
) {
1565 // Check that our window has not gone away
1566 NS_ENSURE_TRUE(mWindow
, nullptr);
1567 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1569 mMobileMessageManager
= new MobileMessageManager();
1570 mMobileMessageManager
->Init(mWindow
);
1573 return mMobileMessageManager
;
1577 Navigator::GetMozTelephony(ErrorResult
& aRv
)
1581 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1584 mTelephony
= Telephony::Create(mWindow
, aRv
);
1591 already_AddRefed
<Promise
>
1592 Navigator::GetMobileIdAssertion(ErrorResult
& aRv
)
1594 if (!mWindow
|| !mWindow
->GetDocShell()) {
1595 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1599 nsCOMPtr
<nsIMobileIdentityService
> service
=
1600 do_GetService("@mozilla.org/mobileidentity-service;1");
1602 aRv
.Throw(NS_ERROR_FAILURE
);
1606 nsCOMPtr
<nsISupports
> promise
;
1607 aRv
= service
->GetMobileIdAssertion(mWindow
, getter_AddRefs(promise
));
1609 nsRefPtr
<Promise
> p
= static_cast<Promise
*>(promise
.get());
1616 MobileConnectionArray
*
1617 Navigator::GetMozMobileConnections(ErrorResult
& aRv
)
1619 if (!mMobileConnections
) {
1621 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1624 mMobileConnections
= new MobileConnectionArray(mWindow
);
1627 return mMobileConnections
;
1631 Navigator::GetMozCellBroadcast(ErrorResult
& aRv
)
1633 if (!mCellBroadcast
) {
1635 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1638 mCellBroadcast
= CellBroadcast::Create(mWindow
, aRv
);
1641 return mCellBroadcast
;
1645 Navigator::GetMozVoicemail(ErrorResult
& aRv
)
1649 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1653 aRv
= NS_NewVoicemail(mWindow
, getter_AddRefs(mVoicemail
));
1663 Navigator::GetMozIccManager(ErrorResult
& aRv
)
1667 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1670 NS_ENSURE_TRUE(mWindow
->GetDocShell(), nullptr);
1672 mIccManager
= new IccManager(mWindow
);
1677 #endif // MOZ_B2G_RIL
1681 Navigator::GetGamepads(nsTArray
<nsRefPtr
<Gamepad
> >& aGamepads
,
1685 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1688 NS_ENSURE_TRUE_VOID(mWindow
->GetDocShell());
1689 nsGlobalWindow
* win
= static_cast<nsGlobalWindow
*>(mWindow
.get());
1690 win
->SetHasGamepadEventListener(true);
1691 win
->GetGamepads(aGamepads
);
1695 //*****************************************************************************
1696 // Navigator::nsIMozNavigatorNetwork
1697 //*****************************************************************************
1700 Navigator::GetProperties(nsINetworkProperties
** aProperties
)
1703 NS_IF_ADDREF(*aProperties
= GetConnection(rv
));
1707 network::Connection
*
1708 Navigator::GetConnection(ErrorResult
& aRv
)
1712 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1715 mConnection
= new network::Connection();
1716 mConnection
->Init(mWindow
);
1723 bluetooth::BluetoothManager
*
1724 Navigator::GetMozBluetooth(ErrorResult
& aRv
)
1728 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1731 mBluetooth
= bluetooth::BluetoothManager::Create(mWindow
);
1739 Navigator::EnsureMessagesManager()
1741 if (mMessagesManager
) {
1745 NS_ENSURE_STATE(mWindow
);
1748 nsCOMPtr
<nsIDOMNavigatorSystemMessages
> messageManager
=
1749 do_CreateInstance("@mozilla.org/system-message-manager;1", &rv
);
1751 nsCOMPtr
<nsIDOMGlobalPropertyInitializer
> gpi
=
1752 do_QueryInterface(messageManager
);
1753 NS_ENSURE_TRUE(gpi
, NS_ERROR_FAILURE
);
1755 // We don't do anything with the return value.
1757 JS::Rooted
<JS::Value
> prop_val(cx
);
1758 rv
= gpi
->Init(mWindow
, &prop_val
);
1759 NS_ENSURE_SUCCESS(rv
, rv
);
1761 mMessagesManager
= messageManager
.forget();
1767 Navigator::MozHasPendingMessage(const nsAString
& aType
, ErrorResult
& aRv
)
1769 // The WebIDL binding is responsible for the pref check here.
1770 nsresult rv
= EnsureMessagesManager();
1771 if (NS_FAILED(rv
)) {
1776 bool result
= false;
1777 rv
= mMessagesManager
->MozHasPendingMessage(aType
, &result
);
1778 if (NS_FAILED(rv
)) {
1786 Navigator::MozSetMessageHandler(const nsAString
& aType
,
1787 systemMessageCallback
* aCallback
,
1790 // The WebIDL binding is responsible for the pref check here.
1791 nsresult rv
= EnsureMessagesManager();
1792 if (NS_FAILED(rv
)) {
1797 CallbackObjectHolder
<systemMessageCallback
, nsIDOMSystemMessageCallback
>
1799 nsCOMPtr
<nsIDOMSystemMessageCallback
> callback
= holder
.ToXPCOMCallback();
1801 rv
= mMessagesManager
->MozSetMessageHandler(aType
, callback
);
1802 if (NS_FAILED(rv
)) {
1807 #ifdef MOZ_TIME_MANAGER
1809 Navigator::GetMozTime(ErrorResult
& aRv
)
1812 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1816 if (!mTimeManager
) {
1817 mTimeManager
= new time::TimeManager(mWindow
);
1820 return mTimeManager
;
1825 Navigator::GetMozCameras(ErrorResult
& aRv
)
1827 if (!mCameraManager
) {
1829 !mWindow
->GetOuterWindow() ||
1830 mWindow
->GetOuterWindow()->GetCurrentInnerWindow() != mWindow
) {
1831 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
1835 mCameraManager
= nsDOMCameraManager::CreateInstance(mWindow
);
1838 return mCameraManager
;
1841 already_AddRefed
<workers::ServiceWorkerContainer
>
1842 Navigator::ServiceWorker()
1844 MOZ_ASSERT(mWindow
);
1846 if (!mServiceWorkerContainer
) {
1847 mServiceWorkerContainer
= new workers::ServiceWorkerContainer(mWindow
);
1850 nsRefPtr
<workers::ServiceWorkerContainer
> ref
= mServiceWorkerContainer
;
1851 return ref
.forget();
1855 Navigator::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const
1857 size_t n
= aMallocSizeOf(this);
1859 // TODO: add SizeOfIncludingThis() to nsMimeTypeArray, bug 674113.
1860 // TODO: add SizeOfIncludingThis() to nsPluginArray, bug 674114.
1861 // TODO: add SizeOfIncludingThis() to Geolocation, bug 674115.
1862 // TODO: add SizeOfIncludingThis() to DesktopNotificationCenter, bug 674116.
1868 Navigator::SetWindow(nsPIDOMWindow
*aInnerWindow
)
1870 NS_ASSERTION(aInnerWindow
->IsInnerWindow(),
1871 "Navigator must get an inner window!");
1872 mWindow
= aInnerWindow
;
1876 Navigator::OnNavigation()
1882 #ifdef MOZ_MEDIA_NAVIGATOR
1883 // Inform MediaManager in case there are live streams or pending callbacks.
1884 MediaManager
*manager
= MediaManager::Get();
1886 manager
->OnNavigation(mWindow
->WindowID());
1889 if (mCameraManager
) {
1890 mCameraManager
->OnNavigation(mWindow
->WindowID());
1895 Navigator::CheckPermission(const char* type
)
1897 return CheckPermission(mWindow
, type
);
1902 Navigator::CheckPermission(nsPIDOMWindow
* aWindow
, const char* aType
)
1908 nsCOMPtr
<nsIPermissionManager
> permMgr
=
1909 services::GetPermissionManager();
1910 NS_ENSURE_TRUE(permMgr
, false);
1912 uint32_t permission
= nsIPermissionManager::DENY_ACTION
;
1913 permMgr
->TestPermissionFromWindow(aWindow
, aType
, &permission
);
1914 return permission
== nsIPermissionManager::ALLOW_ACTION
;
1917 #ifdef MOZ_AUDIO_CHANNEL_MANAGER
1918 system::AudioChannelManager
*
1919 Navigator::GetMozAudioChannelManager(ErrorResult
& aRv
)
1921 if (!mAudioChannelManager
) {
1923 aRv
.Throw(NS_ERROR_UNEXPECTED
);
1926 mAudioChannelManager
= new system::AudioChannelManager();
1927 mAudioChannelManager
->Init(mWindow
);
1930 return mAudioChannelManager
;
1935 Navigator::DoNewResolve(JSContext
* aCx
, JS::Handle
<JSObject
*> aObject
,
1936 JS::Handle
<jsid
> aId
,
1937 JS::MutableHandle
<JSPropertyDescriptor
> aDesc
)
1939 // Note: The infallibleInit call below depends on this check.
1940 if (!JSID_IS_STRING(aId
)) {
1944 nsScriptNameSpaceManager
* nameSpaceManager
= GetNameSpaceManager();
1945 if (!nameSpaceManager
) {
1946 return Throw(aCx
, NS_ERROR_NOT_INITIALIZED
);
1949 nsDependentJSString name
;
1950 name
.infallibleInit(aId
);
1952 const nsGlobalNameStruct
* name_struct
=
1953 nameSpaceManager
->LookupNavigatorName(name
);
1958 JS::Rooted
<JSObject
*> naviObj(aCx
,
1959 js::CheckedUnwrap(aObject
,
1960 /* stopAtOuter = */ false));
1962 return Throw(aCx
, NS_ERROR_DOM_SECURITY_ERR
);
1965 if (name_struct
->mType
== nsGlobalNameStruct::eTypeNewDOMBinding
) {
1966 ConstructNavigatorProperty construct
= name_struct
->mConstructNavigatorProperty
;
1967 MOZ_ASSERT(construct
);
1969 JS::Rooted
<JSObject
*> domObject(aCx
);
1971 // Make sure to do the creation of our object in the compartment
1972 // of naviObj, especially since we plan to cache that object.
1973 JSAutoCompartment
ac(aCx
, naviObj
);
1975 // Check whether our constructor is enabled after we unwrap Xrays, since
1976 // we don't want to define an interface on the Xray if it's disabled in
1977 // the target global, even if it's enabled in the Xray's global.
1978 if (name_struct
->mConstructorEnabled
&&
1979 !(*name_struct
->mConstructorEnabled
)(aCx
, naviObj
)) {
1983 if (name
.EqualsLiteral("mozSettings")) {
1984 bool hasPermission
= CheckPermission("settings-read") ||
1985 CheckPermission("settings-write");
1986 if (!hasPermission
) {
1987 FillPropertyDescriptor(aDesc
, aObject
, JS::NullValue(), false);
1992 if (name
.EqualsLiteral("mozDownloadManager")) {
1993 if (!CheckPermission("downloads")) {
1994 FillPropertyDescriptor(aDesc
, aObject
, JS::NullValue(), false);
1999 nsISupports
* existingObject
= mCachedResolveResults
.GetWeak(name
);
2000 if (existingObject
) {
2001 // We know all of our WebIDL objects here are wrappercached, so just go
2002 // ahead and WrapObject() them. We can't use WrapNewBindingObject,
2003 // because we don't have the concrete type.
2004 JS::Rooted
<JS::Value
> wrapped(aCx
);
2005 if (!dom::WrapObject(aCx
, existingObject
, &wrapped
)) {
2008 domObject
= &wrapped
.toObject();
2010 domObject
= construct(aCx
, naviObj
);
2012 return Throw(aCx
, NS_ERROR_FAILURE
);
2015 // Store the value in our cache
2016 nsISupports
* native
= UnwrapDOMObjectToISupports(domObject
);
2018 mCachedResolveResults
.Put(name
, native
);
2022 if (!JS_WrapObject(aCx
, &domObject
)) {
2026 FillPropertyDescriptor(aDesc
, aObject
, JS::ObjectValue(*domObject
), false);
2030 NS_ASSERTION(name_struct
->mType
== nsGlobalNameStruct::eTypeNavigatorProperty
,
2033 nsresult rv
= NS_OK
;
2035 nsCOMPtr
<nsISupports
> native
;
2036 bool hadCachedNative
= mCachedResolveResults
.Get(name
, getter_AddRefs(native
));
2038 JS::Rooted
<JS::Value
> prop_val(aCx
);
2039 if (hadCachedNative
) {
2040 okToUseNative
= true;
2042 native
= do_CreateInstance(name_struct
->mCID
, &rv
);
2043 if (NS_FAILED(rv
)) {
2044 return Throw(aCx
, rv
);
2047 nsCOMPtr
<nsIDOMGlobalPropertyInitializer
> gpi(do_QueryInterface(native
));
2051 return Throw(aCx
, NS_ERROR_UNEXPECTED
);
2054 rv
= gpi
->Init(mWindow
, &prop_val
);
2055 if (NS_FAILED(rv
)) {
2056 return Throw(aCx
, rv
);
2060 okToUseNative
= !prop_val
.isObjectOrNull();
2063 if (okToUseNative
) {
2064 // Make sure to do the creation of our object in the compartment
2065 // of naviObj, especially since we plan to cache that object.
2066 JSAutoCompartment
ac(aCx
, naviObj
);
2068 rv
= nsContentUtils::WrapNative(aCx
, native
, &prop_val
);
2070 if (NS_FAILED(rv
)) {
2071 return Throw(aCx
, rv
);
2074 // Now that we know we managed to wrap this thing properly, go ahead and
2075 // cache it as needed.
2076 if (!hadCachedNative
) {
2077 mCachedResolveResults
.Put(name
, native
);
2081 if (!JS_WrapValue(aCx
, &prop_val
)) {
2082 return Throw(aCx
, NS_ERROR_UNEXPECTED
);
2085 FillPropertyDescriptor(aDesc
, aObject
, prop_val
, false);
2089 struct NavigatorNameEnumeratorClosure
2091 NavigatorNameEnumeratorClosure(JSContext
* aCx
, JSObject
* aWrapper
,
2092 nsTArray
<nsString
>& aNames
)
2094 mWrapper(aCx
, aWrapper
),
2100 JS::Rooted
<JSObject
*> mWrapper
;
2101 nsTArray
<nsString
>& mNames
;
2104 static PLDHashOperator
2105 SaveNavigatorName(const nsAString
& aName
,
2106 const nsGlobalNameStruct
& aNameStruct
,
2109 NavigatorNameEnumeratorClosure
* closure
=
2110 static_cast<NavigatorNameEnumeratorClosure
*>(aClosure
);
2111 if (!aNameStruct
.mConstructorEnabled
||
2112 aNameStruct
.mConstructorEnabled(closure
->mCx
, closure
->mWrapper
)) {
2113 closure
->mNames
.AppendElement(aName
);
2115 return PL_DHASH_NEXT
;
2119 Navigator::GetOwnPropertyNames(JSContext
* aCx
, nsTArray
<nsString
>& aNames
,
2122 nsScriptNameSpaceManager
*nameSpaceManager
= GetNameSpaceManager();
2123 if (!nameSpaceManager
) {
2124 NS_ERROR("Can't get namespace manager.");
2125 aRv
.Throw(NS_ERROR_UNEXPECTED
);
2129 NavigatorNameEnumeratorClosure
closure(aCx
, GetWrapper(), aNames
);
2130 nameSpaceManager
->EnumerateNavigatorNames(SaveNavigatorName
, &closure
);
2134 Navigator::WrapObject(JSContext
* cx
)
2136 return NavigatorBinding::Wrap(cx
, this);
2141 Navigator::HasWakeLockSupport(JSContext
* /* unused*/, JSObject
* /*unused */)
2143 nsCOMPtr
<nsIPowerManagerService
> pmService
=
2144 do_GetService(POWERMANAGERSERVICE_CONTRACTID
);
2145 // No service means no wake lock support
2151 Navigator::HasMobileMessageSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2153 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2155 #ifndef MOZ_WEBSMS_BACKEND
2159 // First of all, the general pref has to be turned on.
2160 bool enabled
= false;
2161 Preferences::GetBool("dom.sms.enabled", &enabled
);
2166 NS_ENSURE_TRUE(win
, false);
2167 NS_ENSURE_TRUE(win
->GetDocShell(), false);
2169 if (!CheckPermission(win
, "sms")) {
2178 Navigator::HasCameraSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2180 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2181 return win
&& nsDOMCameraManager::CheckPermission(win
);
2186 Navigator::HasWifiManagerSupport(JSContext
* /* unused */,
2189 // On XBL scope, the global object is NOT |window|. So we have
2190 // to use nsContentUtils::GetObjectPrincipal to get the principal
2191 // and test directly with permission manager.
2193 nsIPrincipal
* principal
= nsContentUtils::ObjectPrincipal(aGlobal
);
2195 nsCOMPtr
<nsIPermissionManager
> permMgr
=
2196 services::GetPermissionManager();
2197 NS_ENSURE_TRUE(permMgr
, false);
2199 uint32_t permission
= nsIPermissionManager::DENY_ACTION
;
2200 permMgr
->TestPermissionFromPrincipal(principal
, "wifi-manage", &permission
);
2201 return nsIPermissionManager::ALLOW_ACTION
== permission
;
2207 Navigator::HasNFCSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2209 // Do not support NFC if NFC content helper does not exist.
2210 nsCOMPtr
<nsISupports
> contentHelper
= do_GetService("@mozilla.org/nfc/content-helper;1");
2211 if (!contentHelper
) {
2215 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2216 return win
&& (CheckPermission(win
, "nfc-read") ||
2217 CheckPermission(win
, "nfc-write"));
2221 #ifdef MOZ_TIME_MANAGER
2224 Navigator::HasTimeSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2226 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2227 return win
&& CheckPermission(win
, "time");
2229 #endif // MOZ_TIME_MANAGER
2231 #ifdef MOZ_MEDIA_NAVIGATOR
2234 Navigator::HasUserMediaSupport(JSContext
* /* unused */,
2235 JSObject
* /* unused */)
2237 // Make enabling peerconnection enable getUserMedia() as well
2238 return Preferences::GetBool("media.navigator.enabled", false) ||
2239 Preferences::GetBool("media.peerconnection.enabled", false);
2241 #endif // MOZ_MEDIA_NAVIGATOR
2245 Navigator::HasInputMethodSupport(JSContext
* /* unused */,
2248 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2249 if (!win
|| !Preferences::GetBool("dom.mozInputMethod.enabled", false)) {
2253 if (Preferences::GetBool("dom.mozInputMethod.testing", false)) {
2257 return CheckPermission(win
, "input") ||
2258 CheckPermission(win
, "input-manage");
2263 Navigator::HasDataStoreSupport(nsIPrincipal
* aPrincipal
)
2265 workers::AssertIsOnMainThread();
2267 // First of all, the general pref has to be turned on.
2268 bool enabled
= false;
2269 Preferences::GetBool("dom.datastore.enabled", &enabled
);
2274 // Just for testing, we can enable DataStore for any kind of app.
2275 if (Preferences::GetBool("dom.testing.datastore_enabled_for_hosted_apps", false)) {
2280 if (NS_FAILED(aPrincipal
->GetAppStatus(&status
))) {
2284 // Only support DataStore API for certified apps for now.
2285 return status
== nsIPrincipal::APP_STATUS_CERTIFIED
;
2288 // A WorkerMainThreadRunnable to synchronously dispatch the call of
2289 // HasDataStoreSupport() from the worker thread to the main thread.
2290 class HasDataStoreSupportRunnable MOZ_FINAL
2291 : public workers::WorkerMainThreadRunnable
2296 HasDataStoreSupportRunnable(workers::WorkerPrivate
* aWorkerPrivate
)
2297 : workers::WorkerMainThreadRunnable(aWorkerPrivate
)
2300 MOZ_ASSERT(aWorkerPrivate
);
2301 aWorkerPrivate
->AssertIsOnWorkerThread();
2306 MainThreadRun() MOZ_OVERRIDE
2308 workers::AssertIsOnMainThread();
2310 mResult
= Navigator::HasDataStoreSupport(mWorkerPrivate
->GetPrincipal());
2318 Navigator::HasDataStoreSupport(JSContext
* aCx
, JSObject
* aGlobal
)
2320 // If the caller is on the worker thread, dispatch this to the main thread.
2321 if (!NS_IsMainThread()) {
2322 workers::WorkerPrivate
* workerPrivate
=
2323 workers::GetWorkerPrivateFromContext(aCx
);
2324 workerPrivate
->AssertIsOnWorkerThread();
2326 nsRefPtr
<HasDataStoreSupportRunnable
> runnable
=
2327 new HasDataStoreSupportRunnable(workerPrivate
);
2328 runnable
->Dispatch(aCx
);
2330 return runnable
->mResult
;
2333 workers::AssertIsOnMainThread();
2335 JS::Rooted
<JSObject
*> global(aCx
, aGlobal
);
2337 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(global
);
2342 nsIDocument
* doc
= win
->GetExtantDoc();
2343 if (!doc
|| !doc
->NodePrincipal()) {
2347 return HasDataStoreSupport(doc
->NodePrincipal());
2352 Navigator::HasNetworkStatsSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2354 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2355 return CheckPermission(win
, "networkstats-manage");
2360 Navigator::HasFeatureDetectionSupport(JSContext
* /* unused */, JSObject
* aGlobal
)
2362 nsCOMPtr
<nsPIDOMWindow
> win
= GetWindowFromGlobal(aGlobal
);
2363 return CheckPermission(win
, "feature-detection");
2368 already_AddRefed
<nsPIDOMWindow
>
2369 Navigator::GetWindowFromGlobal(JSObject
* aGlobal
)
2371 nsCOMPtr
<nsPIDOMWindow
> win
=
2372 do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal
));
2373 MOZ_ASSERT(!win
|| win
->IsInnerWindow());
2374 return win
.forget();
2378 } // namespace mozilla
2381 NS_GetNavigatorUserAgent(nsAString
& aUserAgent
)
2385 nsCOMPtr
<nsIHttpProtocolHandler
>
2386 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2387 NS_ENSURE_SUCCESS(rv
, rv
);
2390 rv
= service
->GetUserAgent(ua
);
2391 CopyASCIItoUTF16(ua
, aUserAgent
);
2397 NS_GetNavigatorPlatform(nsAString
& aPlatform
)
2399 if (!nsContentUtils::IsCallerChrome()) {
2400 const nsAdoptingString
& override
=
2401 mozilla::Preferences::GetString("general.platform.override");
2404 aPlatform
= override
;
2411 nsCOMPtr
<nsIHttpProtocolHandler
>
2412 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2413 NS_ENSURE_SUCCESS(rv
, rv
);
2415 // Sorry for the #if platform ugliness, but Communicator is likewise
2416 // hardcoded and we are seeking backward compatibility here (bug 47080).
2418 aPlatform
.AssignLiteral("Win64");
2419 #elif defined(WIN32)
2420 aPlatform
.AssignLiteral("Win32");
2421 #elif defined(XP_MACOSX) && defined(__ppc__)
2422 aPlatform
.AssignLiteral("MacPPC");
2423 #elif defined(XP_MACOSX) && defined(__i386__)
2424 aPlatform
.AssignLiteral("MacIntel");
2425 #elif defined(XP_MACOSX) && defined(__x86_64__)
2426 aPlatform
.AssignLiteral("MacIntel");
2428 // XXX Communicator uses compiled-in build-time string defines
2429 // to indicate the platform it was compiled *for*, not what it is
2430 // currently running *on* which is what this does.
2432 rv
= service
->GetOscpu(plat
);
2433 CopyASCIItoUTF16(plat
, aPlatform
);
2439 NS_GetNavigatorAppVersion(nsAString
& aAppVersion
)
2441 if (!nsContentUtils::IsCallerChrome()) {
2442 const nsAdoptingString
& override
=
2443 mozilla::Preferences::GetString("general.appversion.override");
2446 aAppVersion
= override
;
2453 nsCOMPtr
<nsIHttpProtocolHandler
>
2454 service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX
"http", &rv
));
2455 NS_ENSURE_SUCCESS(rv
, rv
);
2458 rv
= service
->GetAppVersion(str
);
2459 CopyASCIItoUTF16(str
, aAppVersion
);
2460 NS_ENSURE_SUCCESS(rv
, rv
);
2462 aAppVersion
.AppendLiteral(" (");
2464 rv
= service
->GetPlatform(str
);
2465 NS_ENSURE_SUCCESS(rv
, rv
);
2467 AppendASCIItoUTF16(str
, aAppVersion
);
2468 aAppVersion
.Append(char16_t(')'));
2474 NS_GetNavigatorAppName(nsAString
& aAppName
)
2476 if (!nsContentUtils::IsCallerChrome()) {
2477 const nsAdoptingString
& override
=
2478 mozilla::Preferences::GetString("general.appname.override");
2481 aAppName
= override
;
2486 aAppName
.AssignLiteral("Netscape");