mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
fffeb135bb
- Bug 1040668 part 2 - Parse and compute text emphasis properties. r=dbaron (0fb79d4709) - Bug 1040668 part 3 - Add helper function gfxTextRun::GetAdvanceForGlyph. r=jfkthame (f1cf02f5ff) - Bug 1216427 - Tests for backspacing over a character with variation selector, and over Regional Indicator flag symbols. r=emk (18957bfe77) - Bug 1216427 - part 1 - Ensure a character+VS sequence or a ligated Regional-Indicator flag symbol is deleted as a single unit when backspacing. r=emk (2776ff8f4a) - Bug 1216427 - part 2 - Ensure mouse selection does not split up a Regional Indicator flag symbol. r=emk (58eb82e6a1) - Bug 1040668 part 4 - Add helper function for ensuring a glyph is a complex glyph. r=jfkthame (ba17f7d0c4) - Bug 1040668 part 5 - Avoid unnecessary allocation inside EnsureComplexGlyph helper function. r=jfkthame (4968a7c68e) - Bug 1040668 part 6 - Add some specifier on gfxTextRun and gfxShapedWord so that compilers are able to reason out certain optimizations. r=jfkthame (69ca3eb959) - Bug 1040668 part 7 - Add NO_EMPHASIS_MARK flag in CompressedGlyph. r=jfkthame (34e9d8a6a6) - Bug 1227001 part 1 - Remove SetupBreakSinksFlags from BuildTextRunsScanner. r=jfkthame (520b1ba111) - Bug 1227001 part 2 - Remove no longer used mExistingTextRun from BreaSink. r=jfkthame (201782a78c) - Bug 1227001 part 3 - Remove no longer used mChangedBreaks from BreakSink. r=jfkthame (e754e2b13f) - Bug 1040668 part 8 - Setup text emphasis for text run. r=jfkthame (376377180e) - Bug 1040668 part 9 - Compute overflow from text-shadow after text decorations. r=dbaron (05c9bd08c2) - Bug 1040668 part 10 - Implement emphasis mark rendering. r=jfkthame (4d270afca8) - Bug 1040668 part 11 - Move line leadings adjusting code into a separate function in nsLineLayout. r=dholbert (fd4dd20ca5) - Bug 1040668 part 12 - Add line leadings for emphasis marks if necessary. r=dholbert (138add5ff7) - Bug 1040668 part 13 - Move first part of nsStyleFont::GetLanguage to nsPresContext::GetContentLanguage. r=dbaron (1e872d2a58) - Bug 1040668 part 14 - Add helper function nsStyleUtil::MatchesLanguagePrefix for doing simple language matching. r=dbaron (9322a02369) - Bug 1040668 part 15 - Make the default value of text-emphasis-position aware of the language. r=dbaron (6587c628da) - Bug 1040668 part 16 - Add reftests for text-emphasis. r=dbaron (9940d65182) - Bug 1040668 followup - Use monospace for text-emphasis reftests. rs=dbaron on a CLOSED TREE (fb7598c3ea) - Bug 1040668 followup 2 - Disable failing reftests of text-emphasis on Windows XP. (7c3f24ac22) - Bug 1040668 followup 3 - Wrap lang attribute mapping code in NS_STYLE_INHERIT_BIT test. r=dbaron (640e3b7b8f) - Bug 1219145 - nsRefreshDriver::IsJankCritical(). r=hiro To refine its alerts, Performance Stats API needs to be able to know whether a long-running operation is actually causing user-visible jank in the current process. This patch introduces a trivial API that lets clients ask the refresh driver whether any kind of animation is ongoing. (7c0868d7c4) - more missing XP theme stuff (637af0c6a0) - Bug 1210261. Tick root refresh driver last. r=mattwoodrow (dae1a325fa) - Bug 1221674 Part 2: Correct for negative content delay values. r=avih (9b9811c41c) - Bug 1211334 - Check if presshell is still available after dispatching transition events; r=mats (8a044a462c) - Bug 1211599 - Only allow whitelisted histograms to have > 100 buckets. r=nfroyd (d467e84130) - Bug 1219733 - Allow a 'bug_numbers' field in Histograms.json entries. r=vladan (8e63a713ec) - Bug 1222044 - Only allow lists of alert_emails r=vladan (1d5fcb009d) - Bug 1168263 - Add a flags parameter to GetResultingTransformMatrix instead of using bools. r=roc (ec5224f9af) - Bug 1168263 - Remove TransformRectOut since it's unused. r=roc (d20a79ae0e) - Bug 1215406 - Part 1: Remove NS_STYLE_ANIMATION_DIRECTION_XXX and NS_STYLE_ANIMATION_FILL_MODE_XXX. r=heycam (4bd7f8116b) - Bug 1215406 - Part 2: Change the types of direction and fillmode in StyleAnimation. r=heycam (e06323c81b) - Bug 1215406 - Part 3: Change the types of direction and fillmode in AnimationTiming. r=heycam (e5454d3ea5) - Bug 1215406 - Part 4: Add KeyframeEffectOptions. r=smaug Add KeyframeEffectOptions in KeyframeEffect.webidl (0ce3372fd1) - Bug 1215406 - Part 5: Implement KeyframeEffectOptions in KeyframeEffectReadOnly constructor. r=birtles (a472e9ac5f) - tch 2 - Use an enum class for NS_STYLE_BOX_SIZING_*. r=heycam (4897b7b8ff) - Bug 1218195, mark MutationObserver as observing in all the nested DOM mutations, r=bz (48a4aa8a91) - Bug 1172870 - Part 3 - Fix openWindow mochitest to work on e10s (574cc6fa4d) - Bug 1223265 - Fix -Wunreachable-code and -Wimplicit-fallthrough warnings in dom/bindings and dom/ipc. r=khuey (9eab632140) - Bug 1189195 - Fix PContentPermissionRequest shutdown () r=fabrice (6bc1a681f5) - Bug 1210508 - Handle null OriginAttributes from JS-implemented nsILoadContext. r=me (2f71edb9d7) - Bug 1224596 part 1. Add a version of WorkerMainThreadRunnable::Dispatch that takes an ErrorResult to report failure to dispatch on. r=khuey (e60a0fb115) - Bug 1224596 part 2. Switch Navigator to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (d9298a4763) - Bug 1224596 part 3. Make some WebSocket(Impl) methods whose return value is totally ignored void. r=khuey (1d04b52d44) - Bug 1224596 part 4. Switch WebSocket to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (aa06e6417b) - Bug 1224596 part 5. Switch nsPerformance to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (0303b7de09) - Bug 1224596 part 6. Switch BroadcastChannel to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (feacc21f63) - Bug 1224636. Fix some code in ImageBitmap that rejects a promise with an ErrorResult, then keeps trying to use that ErrorResult. r=kaku (89b769fe07) - Bug 1224596 part 7. Switch ImageBitmap to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (e21b0a4a0a) - Bug 1183954, Don't leak nsStructuredCloneContainer (use of 'auto' is error prone), r=leak (1a9b30f2ca) - Bug 1114554 - Patch 9 - Fixed crash in b2g-desktop tests. r=nsm (6b12c6d121) - Bug 1189090 - Rework the nsISupports implementation in the ScopeCheckingGetCallback and its subclasses; r=nsm (6bea544597) - Bug 1187018 - Ensure feature is nulled out if it does not get added. r=khuey (9d7439498a) - Bug 1224596 part 8. Switch Notification to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (03f0f6877f) - Bug 1196079 - Always try to release Notification via normal WorkerRunnable first. r=wchen (c093253d6f) - Bug 1203324 - disable notifications on serviceworkers. r=ehsan,wchen (aa39310dc1) - Bug 1199901 - GetOrigin() fails cleanly instead of asserting principal. r=wchen (148c634a4f) - Bug 1199901 - Clear mObserver when WorkerNotificationObserver is destroyed. r=wchen (6d5cd99183) - Bug 1199901 - Bustage fix due to rebase. a=bustage (344bd62af5) - Bug 1225470 Report a message to the console when a service worker waitUntil() is rejected. r=baku (610da2eec6) - Bug 1217909 P1 Report service worker exceptions to controlled documents. r=catalinb (f8bd4677d5) - Bug 1216566 - Fix a bug in nsIServiceWorkerManager.getAllRegistrations;r=catalinb (ed3e14ab43) - Bug 1219205 - ServiceWorkerInfo should be an XPCOM object;r=catalinb (677a6f1ffd) - Bug 1217909 P2 Track registering documents as weak reference so SWM can report errors to them. r=catalinb (4233dc3edc) - Bug 1217909 P3 Refactor service worker register()/update() to reject only with SecurityErr or TypeErr. r=catalinb (c6891a7fae) - Bug 1220740 - nsIServiceWorkerRegistrationInfo should emit an event when its scriptSpec property changes;r=amarchesini (5772bb5914) - Bug 1207727 - Add WPT tests for service worker update algorithm. r=bkelly (a4812571a1) - Bug 1217367 - Service workers update algorithm optimization. r=bkelly (e377debad1) - Bug 1226479. Change ErrorResult::ThrowTypeError/ThrowRangeError to take string references, not pointers. r=mccr8 (0804899666) - Bug 1224659 - Worker DataStore code should not use ErrorResult cross threads, r=bz (aef03b0fdd) - Bug 1224596 part 9. Switch DataStore to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (1eb1c427f2) - Bug 1224596 part 10. Switch DataStoreCursor to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (114af8021b) - Bug 1224596 part 11. Switch WorkerNavigator to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (b2347a0c49) - Bug 1224596 part 12. Switch ServiceWorkerRegistration to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (d1ff076836) - Bug 1224596 part 13. Switch gfxUtils to using the new WorkerMainThreadRunnable::Dispatch signature. r=khuey (a523997588) - Bug 1224007 part 1. Rename ThrowMethodFailed to MaybeSetPendingException and make it an ErrorResult instance method. r=peterv (bdf0891f54) - Bug 1224007 part 2. Make the various ErrorResult::Report* methods private, so consumers all go through MaybeSetPendingException and rename them to more clearly indicate what they're actually doing. r=peterv (48f483c153) - Bug 1203151 - Allow disabling of screen wakelocks for video elements. r=baku (6bd9ff6916) - Bug 1224007 part 4. Fix some cases in which ErrorResult instances are destroyed without doing anything useful with exceptions on them. r=peterv (e328785e5d) - Bug 1224007 part 5. Get rid of ErrorResult::StealJSException. r=peterv (db19cfb31e) - Bug 1224007 part 3. Push down WouldReportJSException into MaybeSetPendingException, since anyone calling the latter will propagate the JS exception as needed. r=peterv (1d3b7b415d) - Bug 1224007 part 6. Change MaybeSetPendingException to set the ErrorResult state to "not failed", just like SuppressException and StealNSResult already do, and assert in the destructor that the ErrorResult is not Failed(). (a028838e8d) - Bug 1213815 - Update URLSearchParams and URLUtils in webidl files, r=bz (28fb8f7de5) - Bug 1213815 - dom/webidl/HTMLHyperlinkElementUtils and URL don't need to throw exceptions as we did before, r=bz (b13dc3bcb9) - Bug 1224596 part 14. Switch URL to using the new WorkerMainThreadRunnable::Dispatch signature. r=baku (232677e50e) - fix updating the backport (9e958da5ca) - Bug 1224596 part 16. Switch Fetch to using the new WorkerMainThreadRunnable::Dispatch signature. r=bkelly (939e338f22) - Bug 1224596 part 17. Remove the old WorkerMainThreadRunnable::Dispatch signature. r=khuey (5a70429ec8) - Bug 1143575. Don't report negative frame delays. r=cpearce (7d8bc0f753) - Bug 1187371 - Get rid of dom.broadcastChannel.enabled pref, r=bz (9335b7ae90) - Bug 1196514 - remove dom.messagechannel.enabled pref, r=smaug (31e06119b4) - Bug 1166356 - Properly detect double-caching in nsXULPrototypeCache; r=ehsan (29df9ffb2d) - Bug 1168916 - Get rid of redundant pref callback in nsXULPrototypeCache; r=janv (9f37fff405) - Bug 1139099: Dispatch DOMDocElementInserted to match the document-element-inserted observer notification. r=mrbkap (6565e4b924) - Bug 1187068 - Tell the cycle collector about nsContentSink::mCSSLoader. r=heycam (4ae23eb26c) - Bug 1172189 - Fix overflow in nsXULContentSink.cpp. r=ehsan (cc6330f5de) - Bug 1126010 - XULContentSinkImpl::mParser should be an nsRefPtr. r=smaug (d6bb567692) - Bug 1147946, part 7 - Remove trailing whitespace from nsXULContentSink.cpp. r=baku (cdcadbfeeb) - Bug 1147946, part 1 - Tuck elses in nsXULContentSink.cpp. r=baku (26fd806676) - Bug 1147946, part 2 - Move body of check inside prior if in XULContentSinkImpl::OpenScript(). r=baku (b509455bdb) - Bug 1147946, part 3 - Eliminate unused case for non-JS scripting languages in XULContentSinkImpl::OpenScript(). r=baku (4136933cc2) - Bug 1147946, part 4 - Use an early return in XULContentSinkImpl::OpenScript(). r=baku (c3e293474b) - Bug 1147946, part 5 - Don't use the generic nsIProgrammingLanguage enum in XULContentSinkImpl::OpenScript(). r=baku (89a124e23f) - Bug 1147946, part 6 - Remove some useless null checks on infallible new in XULContentSinkImpl. r=baku (1ac57e8c3a) - Bug 1221351 P1 ServiceWorkerContainer and ServiceWorkerRegistration should not crash for null window owner. r=catalinb (1a72748632) - Bug 1212867 - Node.isEqualNode() should ignore internal subsets; r=bzBug (99b166ffee) - Bug 492933 - getElementsByTagName should match on localName not tagName, r=smaug (d0c6ceabf1) - Bug 912470 part 1 - Implement Encoding Standard-compliant big5 decoder. r=emk. (c680b0ae9b) - Bug 1170932: Test handling of unmapped characters in unicode-to-codepage encoders (ca36bcbd35) - fix style (95a90bfe3a) - Bug 1170794 - patch 2 - Improve the length check of the input in nsUnicode*::GetMaxLength, r=dveditz (aa864d656f) - Bug 1170794 followup: Add 'override' annotations to Convert() & Reset() methods in intl/uconv. rs=ehsan (bb3e6e492e) - Bug 1176462 - Remove nsTableDecoderSupport. r=smontagu (f4a86c44b3) - Bug 1169248 - Fix GBK/GB18030 encoders. r=smontagu (ed946e1ee1) - Bug 1155539 - Remove obsolete encoding decoder telemetry probes. r=emk. (44e15bfb40) - Bug 912470 part 2 - Implement Encoding Standard-compliant big5 encoder. r=emk. (5cca2dc4a0) - Bug 912470 addendum - Pass override static analysis. r=emk. (c163bffeb4) - Bug 1170932: Improve error handling for the gbk encoder, r=emk (30e95b34a5) - Bug 1202366 - Implement the encoder error mode "HTML" for nsFormSubmission without nsISaveAsCharset. r=NOT_emk. (ebc8b542dd) - update manifest (6cc19172cc) - Bug 1197309 - remove PR_snprintf calls in intl/; r=froydnj (79fcdfa845) - Bug 1214619 - Remove nsISaveAsCharset as much as possible without breaking extensions in popular use. r=emk. (89b71b3d87) - Bug 1214857. Store the document-is-HTML state directly in nsContentList instead of refetching from the node being matched. r=smaug (4c4fbf469e) - Bug 1221351 P2 Add a web-platform-test to check for crash when calling .register() on closed window. r=catalinb (eeb30c1bba) - Bug 1221351 P3 Fix test name in register-closed-window.https.html. a=testonly (5bfa840044) - Bug 1224436: Remove enumerator usage in ServiceWorkerManager.cpp. r=njn (b8cb094d3c) - Bug 1223716. Make HTMLCollection check for the element being HTML before checking for its name inside its named getter. r=bkelly (977e0bff5a) - Bug 1180737 - Add update-test.py and update test to latest version. r=bkelly. (59faa36d5c) - Bug 1217909 P4 Extend wpt tests to verify update() promise values for different script failures. r=catalinb (a2f7352a3a) - Bug 1217909 P5 Add wpt test case for fetch event handlers that throw. r=catalinb (56a77f611c) - Bug 1217909 P6 Fix wpt registration.https.html to expect TypeError for script evaluation errors. r=catalinb (3de8a45688) - Bug 1217909 P7 Fix mochitest to expect TypeError when serviceWorker.register() rejects. r=catalinb (6e8841c41e) - Bug 1217909 P8 Track navigation interceptions per scope in ServiceWorkerManager. r=catalinb (6705ba8337) - Bug 1217909 P9 Report exceptions to windows performing an intercepted navigation. r=catalinb (52f9fece14) - Bug 1217909 P10 Remove stale nsTArray when the last registering document for a scope is removed. r=catalinb (b739bcc3b2) - Bug 1217909 P11 Only report errors to documents that are active and not in the bfcache. r=catalinb (5ffd633af2) - Bug 1223378 Tighten service worker register() principal checks. r=baku (478785f2cc) - Bug 1189685 - Part 1: Ensure that the state of all ServiceWorker instances is up to date when dispatching statechange events; r=bkelly (2bd9b78c58) - Bug 1189685 - Part 2: Make synced-state.https.html pass; r=bkelly (029f942d8c) - Bug 1220740 - nsIServiceWorkerRegistrationInfo should emit an event when its worker properties change;r=amarchesini (8243a3debc) - Bug 1186856 ServiceWorker .register() should always stop current registration from uninstalling. r=jdm (ec7d6e0e7c) - Bug 1224941 Don't crash during ServiceWorker life cycle event dispatch if window is gone. r=baku (a3f45af3e4) - Bug 1180754 - Get serviceworkerobject-scripturl test passing. r=bkelly (c7979bef47) - Bug 1201498 - Service worker update should compare scriptURL to worker URL without fragment, r=bkelly (914f630528) - Bug 594505 - Remove obsolete comment since this bug has now been fixed. r=me DONTBUILD (44f3a15b91) - Bug 1221840. Support repeating images in 1 axis. r=seth (449ea3e97e) - const-var (5433688051) - Bug 1574573 - Disambiguate a use of Handle in XPCShellEnvironment.cpp r=Ehsan (15b44177d1) - clean up warnings (6e64313d0c)
2783 lines
71 KiB
C++
2783 lines
71 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
// Needs to be first.
|
|
#include "base/basictypes.h"
|
|
|
|
#include "Navigator.h"
|
|
#include "nsIXULAppInfo.h"
|
|
#include "nsPluginArray.h"
|
|
#include "nsMimeTypeArray.h"
|
|
#include "mozilla/MemoryReporting.h"
|
|
#include "mozilla/dom/DesktopNotification.h"
|
|
#include "mozilla/dom/File.h"
|
|
#include "nsGeolocation.h"
|
|
#include "nsIClassOfService.h"
|
|
#include "nsIHttpProtocolHandler.h"
|
|
#include "nsIContentPolicy.h"
|
|
#include "nsIContentSecurityPolicy.h"
|
|
#include "nsContentPolicyUtils.h"
|
|
#include "nsCORSListenerProxy.h"
|
|
#include "nsISupportsPriority.h"
|
|
#include "nsICachingChannel.h"
|
|
#include "nsIWebContentHandlerRegistrar.h"
|
|
#include "nsICookiePermission.h"
|
|
#include "nsIScriptSecurityManager.h"
|
|
#include "nsCharSeparatedTokenizer.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsUnicharUtils.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/Telemetry.h"
|
|
#include "BatteryManager.h"
|
|
#include "mozilla/dom/DeviceStorageAreaListener.h"
|
|
#include "mozilla/dom/PowerManager.h"
|
|
#include "mozilla/dom/WakeLock.h"
|
|
#include "mozilla/dom/power/PowerManagerService.h"
|
|
#include "mozilla/dom/CellBroadcast.h"
|
|
#include "mozilla/dom/IccManager.h"
|
|
#include "mozilla/dom/InputPortManager.h"
|
|
#include "mozilla/dom/MobileMessageManager.h"
|
|
#include "mozilla/dom/Permissions.h"
|
|
#include "mozilla/dom/Presentation.h"
|
|
#include "mozilla/dom/ServiceWorkerContainer.h"
|
|
#include "mozilla/dom/TCPSocket.h"
|
|
#include "mozilla/dom/Telephony.h"
|
|
#include "mozilla/dom/Voicemail.h"
|
|
#include "mozilla/dom/TVManager.h"
|
|
#include "mozilla/dom/VRDevice.h"
|
|
#include "mozilla/Hal.h"
|
|
#include "nsISiteSpecificUserAgent.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/StaticPtr.h"
|
|
#include "Connection.h"
|
|
#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
|
|
#include "nsGlobalWindow.h"
|
|
#ifdef MOZ_B2G
|
|
#include "nsIMobileIdentityService.h"
|
|
#endif
|
|
#ifdef MOZ_B2G_RIL
|
|
#include "mozilla/dom/MobileConnectionArray.h"
|
|
#endif
|
|
#include "nsIIdleObserver.h"
|
|
#include "nsIPermissionManager.h"
|
|
#include "nsMimeTypes.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsStringStream.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsIStringStream.h"
|
|
#include "nsIHttpChannel.h"
|
|
#include "nsIHttpChannelInternal.h"
|
|
#include "TimeManager.h"
|
|
#include "DeviceStorage.h"
|
|
#include "nsIDOMNavigatorSystemMessages.h"
|
|
#include "nsStreamUtils.h"
|
|
#include "nsIAppsService.h"
|
|
#include "mozIApplication.h"
|
|
#include "WidgetUtils.h"
|
|
|
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
|
#include "mozilla/dom/MediaDevices.h"
|
|
#include "MediaManager.h"
|
|
#endif
|
|
#ifdef MOZ_B2G_BT
|
|
#include "BluetoothManager.h"
|
|
#endif
|
|
#include "DOMCameraManager.h"
|
|
|
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
|
#include "AudioChannelManager.h"
|
|
#endif
|
|
|
|
#ifdef MOZ_B2G_FM
|
|
#include "mozilla/dom/FMRadio.h"
|
|
#endif
|
|
|
|
#include "nsIDOMGlobalPropertyInitializer.h"
|
|
#include "mozilla/dom/DataStoreService.h"
|
|
#include "nsJSUtils.h"
|
|
|
|
#include "nsScriptNameSpaceManager.h"
|
|
|
|
#include "mozilla/dom/NavigatorBinding.h"
|
|
#include "mozilla/dom/Promise.h"
|
|
|
|
#include "nsIUploadChannel2.h"
|
|
#include "nsFormData.h"
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "WorkerPrivate.h"
|
|
#include "WorkerRunnable.h"
|
|
|
|
#if defined(XP_LINUX)
|
|
#include "mozilla/Hal.h"
|
|
#endif
|
|
#include "mozilla/dom/ContentChild.h"
|
|
|
|
#include "mozilla/dom/FeatureList.h"
|
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
#include <cutils/properties.h>
|
|
#endif
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
static bool sDoNotTrackEnabled = false;
|
|
static bool sVibratorEnabled = false;
|
|
static uint32_t sMaxVibrateMS = 0;
|
|
static uint32_t sMaxVibrateListLen = 0;
|
|
|
|
/* static */
|
|
void
|
|
Navigator::Init()
|
|
{
|
|
Preferences::AddBoolVarCache(&sDoNotTrackEnabled,
|
|
"privacy.donottrackheader.enabled",
|
|
false);
|
|
Preferences::AddBoolVarCache(&sVibratorEnabled,
|
|
"dom.vibrator.enabled", true);
|
|
Preferences::AddUintVarCache(&sMaxVibrateMS,
|
|
"dom.vibrator.max_vibrate_ms", 10000);
|
|
Preferences::AddUintVarCache(&sMaxVibrateListLen,
|
|
"dom.vibrator.max_vibrate_list_len", 128);
|
|
}
|
|
|
|
Navigator::Navigator(nsPIDOMWindow* aWindow)
|
|
: mWindow(aWindow)
|
|
{
|
|
MOZ_ASSERT(aWindow->IsInnerWindow(), "Navigator must get an inner window!");
|
|
}
|
|
|
|
Navigator::~Navigator()
|
|
{
|
|
Invalidate();
|
|
}
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Navigator)
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
|
|
NS_INTERFACE_MAP_ENTRY(nsIMozNavigatorNetwork)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(Navigator)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(Navigator)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(Navigator)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Navigator)
|
|
tmp->Invalidate();
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedResolveResults)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMimeTypes)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPermissions)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryPromise)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTVManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInputPortManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
|
|
#ifdef MOZ_B2G_RIL
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections)
|
|
#endif
|
|
#ifdef MOZ_B2G_BT
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBluetooth)
|
|
#endif
|
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager)
|
|
#endif
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaDevices)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagesManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedResolveResults)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageAreaListener)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Navigator)
|
|
|
|
void
|
|
Navigator::Invalidate()
|
|
{
|
|
// Don't clear mWindow here so we know we've got a non-null mWindow
|
|
// until we're unlinked.
|
|
|
|
mMimeTypes = nullptr;
|
|
|
|
if (mPlugins) {
|
|
mPlugins->Invalidate();
|
|
mPlugins = nullptr;
|
|
}
|
|
|
|
mPermissions = nullptr;
|
|
|
|
// If there is a page transition, make sure delete the geolocation object.
|
|
if (mGeolocation) {
|
|
mGeolocation->Shutdown();
|
|
mGeolocation = nullptr;
|
|
}
|
|
|
|
if (mNotification) {
|
|
mNotification->Shutdown();
|
|
mNotification = nullptr;
|
|
}
|
|
|
|
if (mBatteryManager) {
|
|
mBatteryManager->Shutdown();
|
|
mBatteryManager = nullptr;
|
|
}
|
|
|
|
mBatteryPromise = nullptr;
|
|
|
|
#ifdef MOZ_B2G_FM
|
|
if (mFMRadio) {
|
|
mFMRadio->Shutdown();
|
|
mFMRadio = nullptr;
|
|
}
|
|
#endif
|
|
|
|
if (mPowerManager) {
|
|
mPowerManager->Shutdown();
|
|
mPowerManager = nullptr;
|
|
}
|
|
|
|
if (mCellBroadcast) {
|
|
mCellBroadcast = nullptr;
|
|
}
|
|
|
|
if (mIccManager) {
|
|
mIccManager->Shutdown();
|
|
mIccManager = nullptr;
|
|
}
|
|
|
|
if (mMobileMessageManager) {
|
|
mMobileMessageManager->Shutdown();
|
|
mMobileMessageManager = nullptr;
|
|
}
|
|
|
|
if (mTelephony) {
|
|
mTelephony = nullptr;
|
|
}
|
|
|
|
if (mVoicemail) {
|
|
mVoicemail->Shutdown();
|
|
mVoicemail = nullptr;
|
|
}
|
|
|
|
if (mTVManager) {
|
|
mTVManager = nullptr;
|
|
}
|
|
|
|
if (mInputPortManager) {
|
|
mInputPortManager = nullptr;
|
|
}
|
|
|
|
if (mConnection) {
|
|
mConnection->Shutdown();
|
|
mConnection = nullptr;
|
|
}
|
|
|
|
#ifdef MOZ_B2G_RIL
|
|
if (mMobileConnections) {
|
|
mMobileConnections = nullptr;
|
|
}
|
|
#endif
|
|
|
|
#ifdef MOZ_B2G_BT
|
|
if (mBluetooth) {
|
|
mBluetooth = nullptr;
|
|
}
|
|
#endif
|
|
|
|
mCameraManager = nullptr;
|
|
mMediaDevices = nullptr;
|
|
|
|
if (mMessagesManager) {
|
|
mMessagesManager = nullptr;
|
|
}
|
|
|
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
|
if (mAudioChannelManager) {
|
|
mAudioChannelManager = nullptr;
|
|
}
|
|
#endif
|
|
|
|
uint32_t len = mDeviceStorageStores.Length();
|
|
for (uint32_t i = 0; i < len; ++i) {
|
|
RefPtr<nsDOMDeviceStorage> ds = do_QueryReferent(mDeviceStorageStores[i]);
|
|
if (ds) {
|
|
ds->Shutdown();
|
|
}
|
|
}
|
|
mDeviceStorageStores.Clear();
|
|
|
|
if (mTimeManager) {
|
|
mTimeManager = nullptr;
|
|
}
|
|
|
|
if (mPresentation) {
|
|
mPresentation = nullptr;
|
|
}
|
|
|
|
mServiceWorkerContainer = nullptr;
|
|
|
|
if (mDeviceStorageAreaListener) {
|
|
mDeviceStorageAreaListener = nullptr;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Navigator::nsIDOMNavigator
|
|
//*****************************************************************************
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetUserAgent(nsAString& aUserAgent)
|
|
{
|
|
nsCOMPtr<nsIURI> codebaseURI;
|
|
nsCOMPtr<nsPIDOMWindow> window;
|
|
|
|
if (mWindow && mWindow->GetDocShell()) {
|
|
window = mWindow;
|
|
nsIDocument* doc = mWindow->GetExtantDoc();
|
|
if (doc) {
|
|
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
|
|
}
|
|
}
|
|
|
|
return GetUserAgent(window, codebaseURI, nsContentUtils::IsCallerChrome(),
|
|
aUserAgent);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetAppCodeName(nsAString& aAppCodeName)
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIHttpProtocolHandler>
|
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString appName;
|
|
rv = service->GetAppName(appName);
|
|
CopyASCIItoUTF16(appName, aAppCodeName);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetAppVersion(nsAString& aAppVersion)
|
|
{
|
|
return GetAppVersion(aAppVersion, /* aUsePrefOverriddenValue */ true);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetAppName(nsAString& aAppName)
|
|
{
|
|
AppName(aAppName, /* aUsePrefOverriddenValue */ true);
|
|
return NS_OK;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of Accept-Languages (HTTP header) as a nsTArray of
|
|
* languages. The value is set in the preference by the user ("Content
|
|
* Languages").
|
|
*
|
|
* "en", "en-US" and "i-cherokee" and "" are valid languages tokens.
|
|
*
|
|
* An empty array will be returned if there is no valid languages.
|
|
*/
|
|
/* static */ void
|
|
Navigator::GetAcceptLanguages(nsTArray<nsString>& aLanguages)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
aLanguages.Clear();
|
|
|
|
// E.g. "de-de, en-us,en".
|
|
const nsAdoptingString& acceptLang =
|
|
Preferences::GetLocalizedString("intl.accept_languages");
|
|
|
|
// Split values on commas.
|
|
nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
|
|
while (langTokenizer.hasMoreTokens()) {
|
|
nsDependentSubstring lang = langTokenizer.nextToken();
|
|
|
|
// Replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
|
|
// NOTE: we should probably rely on the pref being set correctly.
|
|
if (lang.Length() > 2 && lang[2] == char16_t('_')) {
|
|
lang.Replace(2, 1, char16_t('-'));
|
|
}
|
|
|
|
// Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
|
|
// only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
|
|
// NOTE: we should probably rely on the pref being set correctly.
|
|
if (lang.Length() > 2) {
|
|
nsCharSeparatedTokenizer localeTokenizer(lang, '-');
|
|
int32_t pos = 0;
|
|
bool first = true;
|
|
while (localeTokenizer.hasMoreTokens()) {
|
|
const nsSubstring& code = localeTokenizer.nextToken();
|
|
|
|
if (code.Length() == 2 && !first) {
|
|
nsAutoString upper(code);
|
|
ToUpperCase(upper);
|
|
lang.Replace(pos, code.Length(), upper);
|
|
}
|
|
|
|
pos += code.Length() + 1; // 1 is the separator
|
|
first = false;
|
|
}
|
|
}
|
|
|
|
aLanguages.AppendElement(lang);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Do not use UI language (chosen app locale) here but the first value set in
|
|
* the Accept Languages header, see ::GetAcceptLanguages().
|
|
*
|
|
* See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for
|
|
* the reasons why.
|
|
*/
|
|
NS_IMETHODIMP
|
|
Navigator::GetLanguage(nsAString& aLanguage)
|
|
{
|
|
nsTArray<nsString> languages;
|
|
GetLanguages(languages);
|
|
if (languages.Length() >= 1) {
|
|
aLanguage.Assign(languages[0]);
|
|
} else {
|
|
aLanguage.Truncate();
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
Navigator::GetLanguages(nsTArray<nsString>& aLanguages)
|
|
{
|
|
GetAcceptLanguages(aLanguages);
|
|
|
|
// The returned value is cached by the binding code. The window listen to the
|
|
// accept languages change and will clear the cache when needed. It has to
|
|
// take care of dispatching the DOM event already and the invalidation and the
|
|
// event has to be timed correctly.
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetPlatform(nsAString& aPlatform)
|
|
{
|
|
return GetPlatform(aPlatform, /* aUsePrefOverriddenValue */ true);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetOscpu(nsAString& aOSCPU)
|
|
{
|
|
if (!nsContentUtils::IsCallerChrome()) {
|
|
const nsAdoptingString& override =
|
|
Preferences::GetString("general.oscpu.override");
|
|
|
|
if (override) {
|
|
aOSCPU = override;
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIHttpProtocolHandler>
|
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString oscpu;
|
|
rv = service->GetOscpu(oscpu);
|
|
CopyASCIItoUTF16(oscpu, aOSCPU);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetVendor(nsAString& aVendor)
|
|
{
|
|
aVendor.Truncate();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetVendorSub(nsAString& aVendorSub)
|
|
{
|
|
aVendorSub.Truncate();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetProduct(nsAString& aProduct)
|
|
{
|
|
aProduct.AssignLiteral("Gecko");
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetProductSub(nsAString& aProductSub)
|
|
{
|
|
// Legacy build ID hardcoded for backward compatibility (bug 776376)
|
|
aProductSub.AssignLiteral("20100101");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsMimeTypeArray*
|
|
Navigator::GetMimeTypes(ErrorResult& aRv)
|
|
{
|
|
if (!mMimeTypes) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mMimeTypes = new nsMimeTypeArray(mWindow);
|
|
}
|
|
|
|
return mMimeTypes;
|
|
}
|
|
|
|
nsPluginArray*
|
|
Navigator::GetPlugins(ErrorResult& aRv)
|
|
{
|
|
if (!mPlugins) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mPlugins = new nsPluginArray(mWindow);
|
|
mPlugins->Init();
|
|
}
|
|
|
|
return mPlugins;
|
|
}
|
|
|
|
Permissions*
|
|
Navigator::GetPermissions(ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
if (!mPermissions) {
|
|
mPermissions = new Permissions(mWindow);
|
|
}
|
|
|
|
return mPermissions;
|
|
}
|
|
|
|
// Values for the network.cookie.cookieBehavior pref are documented in
|
|
// nsCookieService.cpp.
|
|
#define COOKIE_BEHAVIOR_REJECT 2
|
|
|
|
bool
|
|
Navigator::CookieEnabled()
|
|
{
|
|
bool cookieEnabled =
|
|
(Preferences::GetInt("network.cookie.cookieBehavior",
|
|
COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
|
|
|
|
// Check whether an exception overrides the global cookie behavior
|
|
// Note that the code for getting the URI here matches that in
|
|
// nsHTMLDocument::SetCookie.
|
|
if (!mWindow || !mWindow->GetDocShell()) {
|
|
return cookieEnabled;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
|
|
if (!doc) {
|
|
return cookieEnabled;
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> codebaseURI;
|
|
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
|
|
|
|
if (!codebaseURI) {
|
|
// Not a codebase, so technically can't set cookies, but let's
|
|
// just return the default value.
|
|
return cookieEnabled;
|
|
}
|
|
|
|
nsCOMPtr<nsICookiePermission> permMgr =
|
|
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
|
NS_ENSURE_TRUE(permMgr, cookieEnabled);
|
|
|
|
// Pass null for the channel, just like the cookie service does.
|
|
nsCookieAccess access;
|
|
nsresult rv = permMgr->CanAccess(codebaseURI, nullptr, &access);
|
|
NS_ENSURE_SUCCESS(rv, cookieEnabled);
|
|
|
|
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
|
cookieEnabled = access != nsICookiePermission::ACCESS_DENY;
|
|
}
|
|
|
|
return cookieEnabled;
|
|
}
|
|
|
|
bool
|
|
Navigator::OnLine()
|
|
{
|
|
if (mWindow && mWindow->GetDoc()) {
|
|
return !NS_IsOffline() &&
|
|
!NS_IsAppOffline(mWindow->GetDoc()->NodePrincipal());
|
|
}
|
|
|
|
return !NS_IsOffline();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetBuildID(nsAString& aBuildID)
|
|
{
|
|
if (!nsContentUtils::IsCallerChrome()) {
|
|
const nsAdoptingString& override =
|
|
Preferences::GetString("general.buildID.override");
|
|
|
|
if (override) {
|
|
aBuildID = override;
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
nsCOMPtr<nsIXULAppInfo> appInfo =
|
|
do_GetService("@mozilla.org/xre/app-info;1");
|
|
if (!appInfo) {
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
nsAutoCString buildID;
|
|
nsresult rv = appInfo->GetAppBuildID(buildID);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
aBuildID.Truncate();
|
|
AppendASCIItoUTF16(buildID, aBuildID);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetDoNotTrack(nsAString &aResult)
|
|
{
|
|
if (sDoNotTrackEnabled) {
|
|
aResult.AssignLiteral("1");
|
|
} else {
|
|
aResult.AssignLiteral("unspecified");
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
Navigator::JavaEnabled(ErrorResult& aRv)
|
|
{
|
|
Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
|
|
|
|
// Return true if we have a handler for the java mime
|
|
nsAdoptingString javaMIME = Preferences::GetString("plugin.java.mime");
|
|
NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false);
|
|
|
|
if (!mMimeTypes) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return false;
|
|
}
|
|
mMimeTypes = new nsMimeTypeArray(mWindow);
|
|
}
|
|
|
|
RefreshMIMEArray();
|
|
|
|
nsMimeType *mimeType = mMimeTypes->NamedItem(javaMIME);
|
|
|
|
return mimeType && mimeType->GetEnabledPlugin();
|
|
}
|
|
|
|
void
|
|
Navigator::RefreshMIMEArray()
|
|
{
|
|
if (mMimeTypes) {
|
|
mMimeTypes->Refresh();
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
|
|
class VibrateWindowListener : public nsIDOMEventListener
|
|
{
|
|
public:
|
|
VibrateWindowListener(nsIDOMWindow* aWindow, nsIDocument* aDocument)
|
|
{
|
|
mWindow = do_GetWeakReference(aWindow);
|
|
mDocument = do_GetWeakReference(aDocument);
|
|
|
|
NS_NAMED_LITERAL_STRING(visibilitychange, "visibilitychange");
|
|
aDocument->AddSystemEventListener(visibilitychange,
|
|
this, /* listener */
|
|
true, /* use capture */
|
|
false /* wants untrusted */);
|
|
}
|
|
|
|
void RemoveListener();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIDOMEVENTLISTENER
|
|
|
|
private:
|
|
virtual ~VibrateWindowListener()
|
|
{
|
|
}
|
|
|
|
nsWeakPtr mWindow;
|
|
nsWeakPtr mDocument;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(VibrateWindowListener, nsIDOMEventListener)
|
|
|
|
StaticRefPtr<VibrateWindowListener> gVibrateWindowListener;
|
|
|
|
NS_IMETHODIMP
|
|
VibrateWindowListener::HandleEvent(nsIDOMEvent* aEvent)
|
|
{
|
|
nsCOMPtr<nsIDocument> doc =
|
|
do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
|
|
|
|
if (!doc || doc->Hidden()) {
|
|
// It's important that we call CancelVibrate(), not Vibrate() with an
|
|
// empty list, because Vibrate() will fail if we're no longer focused, but
|
|
// CancelVibrate() will succeed, so long as nobody else has started a new
|
|
// vibration pattern.
|
|
nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
|
|
hal::CancelVibrate(window);
|
|
RemoveListener();
|
|
gVibrateWindowListener = nullptr;
|
|
// Careful: The line above might have deleted |this|!
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
VibrateWindowListener::RemoveListener()
|
|
{
|
|
nsCOMPtr<EventTarget> target = do_QueryReferent(mDocument);
|
|
if (!target) {
|
|
return;
|
|
}
|
|
NS_NAMED_LITERAL_STRING(visibilitychange, "visibilitychange");
|
|
target->RemoveSystemEventListener(visibilitychange, this,
|
|
true /* use capture */);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void
|
|
Navigator::AddIdleObserver(MozIdleObserver& aIdleObserver, ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return;
|
|
}
|
|
CallbackObjectHolder<MozIdleObserver, nsIIdleObserver> holder(&aIdleObserver);
|
|
nsCOMPtr<nsIIdleObserver> obs = holder.ToXPCOMCallback();
|
|
if (NS_FAILED(mWindow->RegisterIdleObserver(obs))) {
|
|
NS_WARNING("Failed to add idle observer.");
|
|
}
|
|
}
|
|
|
|
void
|
|
Navigator::RemoveIdleObserver(MozIdleObserver& aIdleObserver, ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return;
|
|
}
|
|
CallbackObjectHolder<MozIdleObserver, nsIIdleObserver> holder(&aIdleObserver);
|
|
nsCOMPtr<nsIIdleObserver> obs = holder.ToXPCOMCallback();
|
|
if (NS_FAILED(mWindow->UnregisterIdleObserver(obs))) {
|
|
NS_WARNING("Failed to remove idle observer.");
|
|
}
|
|
}
|
|
|
|
bool
|
|
Navigator::Vibrate(uint32_t aDuration)
|
|
{
|
|
nsAutoTArray<uint32_t, 1> pattern;
|
|
pattern.AppendElement(aDuration);
|
|
return Vibrate(pattern);
|
|
}
|
|
|
|
bool
|
|
Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
|
|
{
|
|
if (!mWindow) {
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
|
|
if (!doc) {
|
|
return false;
|
|
}
|
|
|
|
if (doc->Hidden()) {
|
|
// Hidden documents cannot start or stop a vibration.
|
|
return false;
|
|
}
|
|
|
|
nsTArray<uint32_t> pattern(aPattern);
|
|
|
|
if (pattern.Length() > sMaxVibrateListLen) {
|
|
pattern.SetLength(sMaxVibrateListLen);
|
|
}
|
|
|
|
for (size_t i = 0; i < pattern.Length(); ++i) {
|
|
if (pattern[i] > sMaxVibrateMS) {
|
|
pattern[i] = sMaxVibrateMS;
|
|
}
|
|
}
|
|
|
|
// The spec says we check sVibratorEnabled after we've done the sanity
|
|
// checking on the pattern.
|
|
if (!sVibratorEnabled) {
|
|
return true;
|
|
}
|
|
|
|
// Add a listener to cancel the vibration if the document becomes hidden,
|
|
// and remove the old visibility listener, if there was one.
|
|
|
|
if (!gVibrateWindowListener) {
|
|
// If gVibrateWindowListener is null, this is the first time we've vibrated,
|
|
// and we need to register a listener to clear gVibrateWindowListener on
|
|
// shutdown.
|
|
ClearOnShutdown(&gVibrateWindowListener);
|
|
}
|
|
else {
|
|
gVibrateWindowListener->RemoveListener();
|
|
}
|
|
gVibrateWindowListener = new VibrateWindowListener(mWindow, doc);
|
|
|
|
hal::Vibrate(pattern, mWindow);
|
|
return true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Pointer Events interface
|
|
//*****************************************************************************
|
|
|
|
uint32_t
|
|
Navigator::MaxTouchPoints()
|
|
{
|
|
nsCOMPtr<nsIWidget> widget = widget::WidgetUtils::DOMWindowToWidget(mWindow);
|
|
|
|
NS_ENSURE_TRUE(widget, 0);
|
|
return widget->GetMaxTouchPoints();
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Navigator::nsIDOMClientInformation
|
|
//*****************************************************************************
|
|
|
|
void
|
|
Navigator::RegisterContentHandler(const nsAString& aMIMEType,
|
|
const nsAString& aURI,
|
|
const nsAString& aTitle,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
return;
|
|
}
|
|
|
|
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
|
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
|
if (!registrar) {
|
|
return;
|
|
}
|
|
|
|
aRv = registrar->RegisterContentHandler(aMIMEType, aURI, aTitle,
|
|
mWindow->GetOuterWindow());
|
|
}
|
|
|
|
void
|
|
Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
|
|
const nsAString& aURI,
|
|
const nsAString& aTitle,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
return;
|
|
}
|
|
|
|
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
|
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
|
if (!registrar) {
|
|
return;
|
|
}
|
|
|
|
aRv = registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
|
|
mWindow->GetOuterWindow());
|
|
}
|
|
|
|
DeviceStorageAreaListener*
|
|
Navigator::GetDeviceStorageAreaListener(ErrorResult& aRv)
|
|
{
|
|
if (!mDeviceStorageAreaListener) {
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
mDeviceStorageAreaListener = new DeviceStorageAreaListener(mWindow);
|
|
}
|
|
|
|
return mDeviceStorageAreaListener;
|
|
}
|
|
|
|
already_AddRefed<nsDOMDeviceStorage>
|
|
Navigator::FindDeviceStorage(const nsAString& aName, const nsAString& aType)
|
|
{
|
|
auto i = mDeviceStorageStores.Length();
|
|
while (i > 0) {
|
|
--i;
|
|
RefPtr<nsDOMDeviceStorage> storage =
|
|
do_QueryReferent(mDeviceStorageStores[i]);
|
|
if (storage) {
|
|
if (storage->Equals(mWindow, aName, aType)) {
|
|
return storage.forget();
|
|
}
|
|
} else {
|
|
mDeviceStorageStores.RemoveElementAt(i);
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
already_AddRefed<nsDOMDeviceStorage>
|
|
Navigator::GetDeviceStorage(const nsAString& aType, ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsString name;
|
|
nsDOMDeviceStorage::GetDefaultStorageName(aType, name);
|
|
RefPtr<nsDOMDeviceStorage> storage = FindDeviceStorage(name, aType);
|
|
if (storage) {
|
|
return storage.forget();
|
|
}
|
|
|
|
nsDOMDeviceStorage::CreateDeviceStorageFor(mWindow, aType,
|
|
getter_AddRefs(storage));
|
|
|
|
if (!storage) {
|
|
return nullptr;
|
|
}
|
|
|
|
mDeviceStorageStores.AppendElement(
|
|
do_GetWeakReference(static_cast<DOMEventTargetHelper*>(storage)));
|
|
return storage.forget();
|
|
}
|
|
|
|
void
|
|
Navigator::GetDeviceStorages(const nsAString& aType,
|
|
nsTArray<RefPtr<nsDOMDeviceStorage> >& aStores,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
nsDOMDeviceStorage::VolumeNameArray volumes;
|
|
nsDOMDeviceStorage::GetOrderedVolumeNames(aType, volumes);
|
|
if (volumes.IsEmpty()) {
|
|
RefPtr<nsDOMDeviceStorage> storage = GetDeviceStorage(aType, aRv);
|
|
if (storage) {
|
|
aStores.AppendElement(storage.forget());
|
|
}
|
|
} else {
|
|
uint32_t len = volumes.Length();
|
|
aStores.SetCapacity(len);
|
|
for (uint32_t i = 0; i < len; ++i) {
|
|
RefPtr<nsDOMDeviceStorage> storage =
|
|
GetDeviceStorageByNameAndType(volumes[i], aType, aRv);
|
|
if (aRv.Failed()) {
|
|
break;
|
|
}
|
|
|
|
if (storage) {
|
|
aStores.AppendElement(storage.forget());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
already_AddRefed<nsDOMDeviceStorage>
|
|
Navigator::GetDeviceStorageByNameAndType(const nsAString& aName,
|
|
const nsAString& aType,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<nsDOMDeviceStorage> storage = FindDeviceStorage(aName, aType);
|
|
if (storage) {
|
|
return storage.forget();
|
|
}
|
|
nsDOMDeviceStorage::CreateDeviceStorageByNameAndType(mWindow, aName, aType,
|
|
getter_AddRefs(storage));
|
|
|
|
if (!storage) {
|
|
return nullptr;
|
|
}
|
|
|
|
mDeviceStorageStores.AppendElement(
|
|
do_GetWeakReference(static_cast<DOMEventTargetHelper*>(storage)));
|
|
return storage.forget();
|
|
}
|
|
|
|
Geolocation*
|
|
Navigator::GetGeolocation(ErrorResult& aRv)
|
|
{
|
|
if (mGeolocation) {
|
|
return mGeolocation;
|
|
}
|
|
|
|
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
mGeolocation = new Geolocation();
|
|
if (NS_FAILED(mGeolocation->Init(mWindow->GetOuterWindow()))) {
|
|
mGeolocation = nullptr;
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
return mGeolocation;
|
|
}
|
|
|
|
class BeaconStreamListener final : public nsIStreamListener
|
|
{
|
|
~BeaconStreamListener() {}
|
|
|
|
public:
|
|
BeaconStreamListener() : mLoadGroup(nullptr) {}
|
|
|
|
void SetLoadGroup(nsILoadGroup* aLoadGroup) {
|
|
mLoadGroup = aLoadGroup;
|
|
}
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSISTREAMLISTENER
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
private:
|
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
|
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(BeaconStreamListener,
|
|
nsIStreamListener,
|
|
nsIRequestObserver)
|
|
|
|
NS_IMETHODIMP
|
|
BeaconStreamListener::OnStartRequest(nsIRequest *aRequest,
|
|
nsISupports *aContext)
|
|
{
|
|
// release the loadgroup first
|
|
mLoadGroup = nullptr;
|
|
|
|
aRequest->Cancel(NS_ERROR_NET_INTERRUPT);
|
|
return NS_BINDING_ABORTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BeaconStreamListener::OnStopRequest(nsIRequest *aRequest,
|
|
nsISupports *aContext,
|
|
nsresult aStatus)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BeaconStreamListener::OnDataAvailable(nsIRequest *aRequest,
|
|
nsISupports *ctxt,
|
|
nsIInputStream *inStr,
|
|
uint64_t sourceOffset,
|
|
uint32_t count)
|
|
{
|
|
MOZ_ASSERT(false);
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
Navigator::SendBeacon(const nsAString& aUrl,
|
|
const Nullable<ArrayBufferViewOrBlobOrStringOrFormData>& aData,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
|
|
if (!doc) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return false;
|
|
}
|
|
|
|
nsIURI* documentURI = doc->GetDocumentURI();
|
|
if (!documentURI) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(
|
|
getter_AddRefs(uri),
|
|
aUrl,
|
|
doc,
|
|
doc->GetDocBaseURI());
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(NS_ERROR_DOM_URL_MISMATCH_ERR);
|
|
return false;
|
|
}
|
|
|
|
// Explicitly disallow loading data: URIs
|
|
bool isDataScheme = false;
|
|
rv = uri->SchemeIs("data", &isDataScheme);
|
|
if (NS_FAILED(rv) || isDataScheme) {
|
|
aRv.Throw(NS_ERROR_CONTENT_BLOCKED);
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
rv = NS_NewChannel(getter_AddRefs(channel),
|
|
uri,
|
|
doc,
|
|
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
|
|
nsIContentPolicy::TYPE_BEACON);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
|
if (!httpChannel) {
|
|
// Beacon spec only supports HTTP requests at this time
|
|
aRv.Throw(NS_ERROR_DOM_BAD_URI);
|
|
return false;
|
|
}
|
|
httpChannel->SetReferrer(documentURI);
|
|
|
|
nsCString mimeType;
|
|
if (!aData.IsNull()) {
|
|
nsCOMPtr<nsIInputStream> in;
|
|
|
|
if (aData.Value().IsString()) {
|
|
nsCString stringData = NS_ConvertUTF16toUTF8(aData.Value().GetAsString());
|
|
nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
rv = strStream->SetData(stringData.BeginReading(), stringData.Length());
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
mimeType.AssignLiteral("text/plain;charset=UTF-8");
|
|
in = strStream;
|
|
|
|
} else if (aData.Value().IsArrayBufferView()) {
|
|
|
|
nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
|
|
const ArrayBufferView& view = aData.Value().GetAsArrayBufferView();
|
|
view.ComputeLengthAndData();
|
|
rv = strStream->SetData(reinterpret_cast<char*>(view.Data()),
|
|
view.Length());
|
|
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
mimeType.AssignLiteral("application/octet-stream");
|
|
in = strStream;
|
|
|
|
} else if (aData.Value().IsBlob()) {
|
|
Blob& blob = aData.Value().GetAsBlob();
|
|
blob.GetInternalStream(getter_AddRefs(in), aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return false;
|
|
}
|
|
|
|
nsAutoString type;
|
|
blob.GetType(type);
|
|
mimeType = NS_ConvertUTF16toUTF8(type);
|
|
|
|
} else if (aData.Value().IsFormData()) {
|
|
nsFormData& form = aData.Value().GetAsFormData();
|
|
uint64_t len;
|
|
nsAutoCString charset;
|
|
form.GetSendInfo(getter_AddRefs(in),
|
|
&len,
|
|
mimeType,
|
|
charset);
|
|
} else {
|
|
MOZ_ASSERT(false, "switch statements not in sync");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(channel);
|
|
if (!uploadChannel) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
uploadChannel->ExplicitSetUploadStream(in, mimeType, -1,
|
|
NS_LITERAL_CSTRING("POST"),
|
|
false);
|
|
} else {
|
|
httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
|
}
|
|
|
|
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(channel);
|
|
if (p) {
|
|
p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
|
|
}
|
|
|
|
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(channel));
|
|
if (cos) {
|
|
cos->AddClassFlags(nsIClassOfService::Background);
|
|
}
|
|
|
|
// The channel needs to have a loadgroup associated with it, so that we can
|
|
// cancel the channel and any redirected channels it may create.
|
|
nsCOMPtr<nsILoadGroup> loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
|
|
nsCOMPtr<nsIInterfaceRequestor> callbacks =
|
|
do_QueryInterface(mWindow->GetDocShell());
|
|
loadGroup->SetNotificationCallbacks(callbacks);
|
|
channel->SetLoadGroup(loadGroup);
|
|
|
|
RefPtr<BeaconStreamListener> beaconListener = new BeaconStreamListener();
|
|
|
|
// Start a preflight if cross-origin and content type is not whitelisted
|
|
nsCOMPtr<nsIScriptSecurityManager> secMan = nsContentUtils::GetSecurityManager();
|
|
rv = secMan->CheckSameOriginURI(documentURI, uri, false);
|
|
bool crossOrigin = NS_FAILED(rv);
|
|
nsAutoCString contentType, parsedCharset;
|
|
rv = NS_ParseRequestContentType(mimeType, contentType, parsedCharset);
|
|
if (crossOrigin &&
|
|
mimeType.Length() > 0 &&
|
|
!contentType.Equals(APPLICATION_WWW_FORM_URLENCODED) &&
|
|
!contentType.Equals(MULTIPART_FORM_DATA) &&
|
|
!contentType.Equals(TEXT_PLAIN)) {
|
|
|
|
// we need to set the sameOriginChecker as a notificationCallback
|
|
// so we can tell the channel not to follow redirects
|
|
nsCOMPtr<nsIInterfaceRequestor> soc = nsContentUtils::SameOriginChecker();
|
|
channel->SetNotificationCallbacks(soc);
|
|
|
|
nsCOMPtr<nsIHttpChannelInternal> internalChannel =
|
|
do_QueryInterface(channel);
|
|
if (!internalChannel) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return false;
|
|
}
|
|
nsTArray<nsCString> unsafeHeaders;
|
|
unsafeHeaders.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
|
|
rv = internalChannel->SetCorsPreflightParameters(unsafeHeaders,
|
|
true,
|
|
doc->NodePrincipal());
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
aRv.Throw(rv);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
rv = channel->AsyncOpen2(beaconListener);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return false;
|
|
}
|
|
// make the beaconListener hold a strong reference to the loadgroup
|
|
// which is released in ::OnStartRequest
|
|
beaconListener->SetLoadGroup(loadGroup);
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
|
MediaDevices*
|
|
Navigator::GetMediaDevices(ErrorResult& aRv)
|
|
{
|
|
if (!mMediaDevices) {
|
|
if (!mWindow ||
|
|
!mWindow->GetOuterWindow() ||
|
|
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
|
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
|
return nullptr;
|
|
}
|
|
mMediaDevices = new MediaDevices(mWindow);
|
|
}
|
|
return mMediaDevices;
|
|
}
|
|
|
|
void
|
|
Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
|
NavigatorUserMediaSuccessCallback& aOnSuccess,
|
|
NavigatorUserMediaErrorCallback& aOnError,
|
|
ErrorResult& aRv)
|
|
{
|
|
CallbackObjectHolder<NavigatorUserMediaSuccessCallback,
|
|
nsIDOMGetUserMediaSuccessCallback> holder1(&aOnSuccess);
|
|
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onsuccess =
|
|
holder1.ToXPCOMCallback();
|
|
|
|
CallbackObjectHolder<NavigatorUserMediaErrorCallback,
|
|
nsIDOMGetUserMediaErrorCallback> holder2(&aOnError);
|
|
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onerror = holder2.ToXPCOMCallback();
|
|
|
|
if (!mWindow || !mWindow->GetOuterWindow() ||
|
|
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
|
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
|
return;
|
|
}
|
|
|
|
MediaManager* manager = MediaManager::Get();
|
|
aRv = manager->GetUserMedia(mWindow, aConstraints, onsuccess, onerror);
|
|
}
|
|
|
|
void
|
|
Navigator::MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints,
|
|
MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
|
|
NavigatorUserMediaErrorCallback& aOnError,
|
|
uint64_t aInnerWindowID,
|
|
ErrorResult& aRv)
|
|
{
|
|
CallbackObjectHolder<MozGetUserMediaDevicesSuccessCallback,
|
|
nsIGetUserMediaDevicesSuccessCallback> holder1(&aOnSuccess);
|
|
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onsuccess =
|
|
holder1.ToXPCOMCallback();
|
|
|
|
CallbackObjectHolder<NavigatorUserMediaErrorCallback,
|
|
nsIDOMGetUserMediaErrorCallback> holder2(&aOnError);
|
|
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onerror = holder2.ToXPCOMCallback();
|
|
|
|
if (!mWindow || !mWindow->GetOuterWindow() ||
|
|
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
|
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
|
return;
|
|
}
|
|
|
|
MediaManager* manager = MediaManager::Get();
|
|
aRv = manager->GetUserMediaDevices(mWindow, aConstraints, onsuccess, onerror,
|
|
aInnerWindowID);
|
|
}
|
|
#endif
|
|
|
|
DesktopNotificationCenter*
|
|
Navigator::GetMozNotification(ErrorResult& aRv)
|
|
{
|
|
if (mNotification) {
|
|
return mNotification;
|
|
}
|
|
|
|
if (!mWindow || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
mNotification = new DesktopNotificationCenter(mWindow);
|
|
return mNotification;
|
|
}
|
|
|
|
#ifdef MOZ_B2G_FM
|
|
|
|
using mozilla::dom::FMRadio;
|
|
|
|
FMRadio*
|
|
Navigator::GetMozFMRadio(ErrorResult& aRv)
|
|
{
|
|
if (!mFMRadio) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
|
|
|
|
mFMRadio = new FMRadio();
|
|
mFMRadio->Init(mWindow);
|
|
}
|
|
|
|
return mFMRadio;
|
|
}
|
|
|
|
#endif // MOZ_B2G_FM
|
|
|
|
//*****************************************************************************
|
|
// Navigator::nsINavigatorBattery
|
|
//*****************************************************************************
|
|
|
|
Promise*
|
|
Navigator::GetBattery(ErrorResult& aRv)
|
|
{
|
|
if (mBatteryPromise) {
|
|
return mBatteryPromise;
|
|
}
|
|
|
|
if (!mWindow || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
|
RefPtr<Promise> batteryPromise = Promise::Create(go, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
mBatteryPromise = batteryPromise;
|
|
|
|
if (!mBatteryManager) {
|
|
mBatteryManager = new battery::BatteryManager(mWindow);
|
|
mBatteryManager->Init();
|
|
}
|
|
|
|
mBatteryPromise->MaybeResolve(mBatteryManager);
|
|
|
|
return mBatteryPromise;
|
|
}
|
|
|
|
battery::BatteryManager*
|
|
Navigator::GetDeprecatedBattery(ErrorResult& aRv)
|
|
{
|
|
if (!mBatteryManager) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
|
|
|
|
mBatteryManager = new battery::BatteryManager(mWindow);
|
|
mBatteryManager->Init();
|
|
}
|
|
|
|
return mBatteryManager;
|
|
}
|
|
|
|
/* static */ already_AddRefed<Promise>
|
|
Navigator::GetDataStores(nsPIDOMWindow* aWindow,
|
|
const nsAString& aName,
|
|
const nsAString& aOwner,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!aWindow || !aWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
|
|
if (!service) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsISupports> promise;
|
|
aRv = service->GetDataStores(aWindow, aName, aOwner, getter_AddRefs(promise));
|
|
|
|
RefPtr<Promise> p = static_cast<Promise*>(promise.get());
|
|
return p.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
Navigator::GetDataStores(const nsAString& aName,
|
|
const nsAString& aOwner,
|
|
ErrorResult& aRv)
|
|
{
|
|
return GetDataStores(mWindow, aName, aOwner, aRv);
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
|
RefPtr<Promise> p = Promise::Create(go, aRv);
|
|
if (aRv.Failed()) {
|
|
return nullptr;
|
|
}
|
|
|
|
#if defined(XP_LINUX)
|
|
if (aName.EqualsLiteral("hardware.memory")) {
|
|
// with seccomp enabled, fopen() should be in a non-sandboxed process
|
|
if (XRE_IsParentProcess()) {
|
|
uint32_t memLevel = mozilla::hal::GetTotalSystemMemoryLevel();
|
|
if (memLevel == 0) {
|
|
p->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
|
return p.forget();
|
|
}
|
|
p->MaybeResolve((int)memLevel);
|
|
} else {
|
|
mozilla::dom::ContentChild* cc =
|
|
mozilla::dom::ContentChild::GetSingleton();
|
|
RefPtr<Promise> ipcRef(p);
|
|
cc->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef.forget().take()));
|
|
}
|
|
return p.forget();
|
|
} // hardware.memory
|
|
#endif
|
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
if (StringBeginsWith(aName, NS_LITERAL_STRING("acl.")) &&
|
|
(aName.EqualsLiteral("acl.version") || CheckPermission("external-app"))) {
|
|
char value[PROPERTY_VALUE_MAX];
|
|
nsCString propertyKey("persist.");
|
|
propertyKey.Append(NS_ConvertUTF16toUTF8(aName));
|
|
uint32_t len = property_get(propertyKey.get(), value, nullptr);
|
|
if (len > 0) {
|
|
p->MaybeResolve(NS_ConvertUTF8toUTF16(value));
|
|
return p.forget();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Mirror the dom.apps.developer_mode pref to let apps get it read-only.
|
|
if (aName.EqualsLiteral("dom.apps.developer_mode")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.apps.developer_mode", false));
|
|
return p.forget();
|
|
}
|
|
|
|
p->MaybeResolve(JS::UndefinedHandleValue);
|
|
return p.forget();
|
|
}
|
|
|
|
already_AddRefed<Promise>
|
|
Navigator::HasFeature(const nsAString& aName, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
|
RefPtr<Promise> p = Promise::Create(go, aRv);
|
|
if (aRv.Failed()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Hardcoded web-extensions feature which is b2g specific.
|
|
#ifdef MOZ_B2G
|
|
if (aName.EqualsLiteral("web-extensions")) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
#endif
|
|
|
|
// Hardcoded manifest features. Some are still b2g specific.
|
|
const char manifestFeatures[][64] = {
|
|
"manifest.origin"
|
|
, "manifest.redirects"
|
|
#ifdef MOZ_B2G
|
|
, "manifest.chrome.navigation"
|
|
, "manifest.precompile"
|
|
#endif
|
|
};
|
|
|
|
nsAutoCString feature = NS_ConvertUTF16toUTF8(aName);
|
|
for (uint32_t i = 0; i < MOZ_ARRAY_LENGTH(manifestFeatures); i++) {
|
|
if (feature.Equals(manifestFeatures[i])) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
}
|
|
|
|
NS_NAMED_LITERAL_STRING(apiWindowPrefix, "api.window.");
|
|
if (StringBeginsWith(aName, apiWindowPrefix)) {
|
|
const nsAString& featureName = Substring(aName, apiWindowPrefix.Length());
|
|
|
|
// Temporary hardcoded entry points due to technical constraints
|
|
if (featureName.EqualsLiteral("Navigator.mozTCPSocket")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.mozTCPSocket.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozMobileConnections") ||
|
|
featureName.EqualsLiteral("MozMobileNetworkInfo")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.mobileconnection.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozInputMethod")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.mozInputMethod.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozContacts")) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.getDeviceStorage")) {
|
|
p->MaybeResolve(Preferences::GetBool("device.storage.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozNetworkStats")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.mozNetworkStats.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.push")) {
|
|
p->MaybeResolve(Preferences::GetBool("services.push.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozAlarms")) {
|
|
p->MaybeResolve(Preferences::GetBool("dom.mozAlarms.enabled"));
|
|
return p.forget();
|
|
}
|
|
|
|
if (featureName.EqualsLiteral("Navigator.mozCameras")) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
|
|
#ifdef MOZ_B2G
|
|
if (featureName.EqualsLiteral("Navigator.getMobileIdAssertion")) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
#endif
|
|
|
|
if (featureName.EqualsLiteral("XMLHttpRequest.mozSystem")) {
|
|
p->MaybeResolve(true);
|
|
return p.forget();
|
|
}
|
|
|
|
if (IsFeatureDetectible(featureName)) {
|
|
p->MaybeResolve(true);
|
|
} else {
|
|
p->MaybeResolve(JS::UndefinedHandleValue);
|
|
}
|
|
return p.forget();
|
|
}
|
|
|
|
// resolve with <undefined> because the feature name is not supported
|
|
p->MaybeResolve(JS::UndefinedHandleValue);
|
|
|
|
return p.forget();
|
|
}
|
|
|
|
PowerManager*
|
|
Navigator::GetMozPower(ErrorResult& aRv)
|
|
{
|
|
if (!mPowerManager) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mPowerManager = PowerManager::CreateInstance(mWindow);
|
|
if (!mPowerManager) {
|
|
// We failed to get the power manager service?
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
}
|
|
}
|
|
|
|
return mPowerManager;
|
|
}
|
|
|
|
already_AddRefed<WakeLock>
|
|
Navigator::RequestWakeLock(const nsAString &aTopic, ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
RefPtr<power::PowerManagerService> pmService =
|
|
power::PowerManagerService::GetInstance();
|
|
// Maybe it went away for some reason... Or maybe we're just called
|
|
// from our XPCOM method.
|
|
if (!pmService) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
return pmService->NewWakeLock(aTopic, mWindow, aRv);
|
|
}
|
|
|
|
MobileMessageManager*
|
|
Navigator::GetMozMobileMessage()
|
|
{
|
|
if (!mMobileMessageManager) {
|
|
// Check that our window has not gone away
|
|
NS_ENSURE_TRUE(mWindow, nullptr);
|
|
NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
|
|
|
|
mMobileMessageManager = new MobileMessageManager(mWindow);
|
|
mMobileMessageManager->Init();
|
|
}
|
|
|
|
return mMobileMessageManager;
|
|
}
|
|
|
|
Telephony*
|
|
Navigator::GetMozTelephony(ErrorResult& aRv)
|
|
{
|
|
if (!mTelephony) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mTelephony = Telephony::Create(mWindow, aRv);
|
|
}
|
|
|
|
return mTelephony;
|
|
}
|
|
|
|
TVManager*
|
|
Navigator::GetTv()
|
|
{
|
|
if (!mTVManager) {
|
|
if (!mWindow) {
|
|
return nullptr;
|
|
}
|
|
mTVManager = TVManager::Create(mWindow);
|
|
}
|
|
|
|
return mTVManager;
|
|
}
|
|
|
|
InputPortManager*
|
|
Navigator::GetInputPortManager(ErrorResult& aRv)
|
|
{
|
|
if (!mInputPortManager) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
mInputPortManager = InputPortManager::Create(mWindow, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
return mInputPortManager;
|
|
}
|
|
|
|
already_AddRefed<LegacyMozTCPSocket>
|
|
Navigator::MozTCPSocket()
|
|
{
|
|
RefPtr<LegacyMozTCPSocket> socket = new LegacyMozTCPSocket(GetWindow());
|
|
return socket.forget();
|
|
}
|
|
|
|
#ifdef MOZ_B2G
|
|
already_AddRefed<Promise>
|
|
Navigator::GetMobileIdAssertion(const MobileIdOptions& aOptions,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsIMobileIdentityService> service =
|
|
do_GetService("@mozilla.org/mobileidentity-service;1");
|
|
if (!service) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
|
if (!cx) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
JS::Rooted<JS::Value> optionsValue(cx);
|
|
if (!ToJSValue(cx, aOptions, &optionsValue)) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsISupports> promise;
|
|
aRv = service->GetMobileIdAssertion(mWindow,
|
|
optionsValue,
|
|
getter_AddRefs(promise));
|
|
|
|
RefPtr<Promise> p = static_cast<Promise*>(promise.get());
|
|
return p.forget();
|
|
}
|
|
#endif // MOZ_B2G
|
|
|
|
#ifdef MOZ_B2G_RIL
|
|
|
|
MobileConnectionArray*
|
|
Navigator::GetMozMobileConnections(ErrorResult& aRv)
|
|
{
|
|
if (!mMobileConnections) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mMobileConnections = new MobileConnectionArray(mWindow);
|
|
}
|
|
|
|
return mMobileConnections;
|
|
}
|
|
|
|
#endif // MOZ_B2G_RIL
|
|
|
|
CellBroadcast*
|
|
Navigator::GetMozCellBroadcast(ErrorResult& aRv)
|
|
{
|
|
if (!mCellBroadcast) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mCellBroadcast = CellBroadcast::Create(mWindow, aRv);
|
|
}
|
|
|
|
return mCellBroadcast;
|
|
}
|
|
|
|
Voicemail*
|
|
Navigator::GetMozVoicemail(ErrorResult& aRv)
|
|
{
|
|
if (!mVoicemail) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
mVoicemail = Voicemail::Create(mWindow, aRv);
|
|
}
|
|
|
|
return mVoicemail;
|
|
}
|
|
|
|
IccManager*
|
|
Navigator::GetMozIccManager(ErrorResult& aRv)
|
|
{
|
|
if (!mIccManager) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
|
|
|
|
mIccManager = new IccManager(mWindow);
|
|
}
|
|
|
|
return mIccManager;
|
|
}
|
|
|
|
#ifdef MOZ_GAMEPAD
|
|
void
|
|
Navigator::GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return;
|
|
}
|
|
NS_ENSURE_TRUE_VOID(mWindow->GetDocShell());
|
|
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(mWindow.get());
|
|
win->SetHasGamepadEventListener(true);
|
|
win->GetGamepads(aGamepads);
|
|
}
|
|
#endif
|
|
|
|
already_AddRefed<Promise>
|
|
Navigator::GetVRDevices(ErrorResult& aRv)
|
|
{
|
|
if (!mWindow || !mWindow->GetDocShell()) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
|
RefPtr<Promise> p = Promise::Create(go, aRv);
|
|
if (aRv.Failed()) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(mWindow.get());
|
|
|
|
nsTArray<RefPtr<VRDevice>> vrDevs;
|
|
if (!win->GetVRDevices(vrDevs)) {
|
|
p->MaybeReject(NS_ERROR_FAILURE);
|
|
} else {
|
|
p->MaybeResolve(vrDevs);
|
|
}
|
|
|
|
return p.forget();
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Navigator::nsIMozNavigatorNetwork
|
|
//*****************************************************************************
|
|
|
|
NS_IMETHODIMP
|
|
Navigator::GetProperties(nsINetworkProperties** aProperties)
|
|
{
|
|
ErrorResult rv;
|
|
NS_IF_ADDREF(*aProperties = GetConnection(rv));
|
|
return NS_OK;
|
|
}
|
|
|
|
network::Connection*
|
|
Navigator::GetConnection(ErrorResult& aRv)
|
|
{
|
|
if (!mConnection) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mConnection = new network::Connection(mWindow);
|
|
}
|
|
|
|
return mConnection;
|
|
}
|
|
|
|
#ifdef MOZ_B2G_BT
|
|
bluetooth::BluetoothManager*
|
|
Navigator::GetMozBluetooth(ErrorResult& aRv)
|
|
{
|
|
if (!mBluetooth) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mBluetooth = bluetooth::BluetoothManager::Create(mWindow);
|
|
}
|
|
|
|
return mBluetooth;
|
|
}
|
|
#endif //MOZ_B2G_BT
|
|
|
|
nsresult
|
|
Navigator::EnsureMessagesManager()
|
|
{
|
|
if (mMessagesManager) {
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_ENSURE_STATE(mWindow);
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIDOMNavigatorSystemMessages> messageManager =
|
|
do_CreateInstance("@mozilla.org/system-message-manager;1", &rv);
|
|
|
|
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
|
|
do_QueryInterface(messageManager);
|
|
NS_ENSURE_TRUE(gpi, NS_ERROR_FAILURE);
|
|
|
|
// We don't do anything with the return value.
|
|
AutoJSContext cx;
|
|
JS::Rooted<JS::Value> prop_val(cx);
|
|
rv = gpi->Init(mWindow, &prop_val);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
mMessagesManager = messageManager.forget();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
Navigator::MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv)
|
|
{
|
|
// The WebIDL binding is responsible for the pref check here.
|
|
nsresult rv = EnsureMessagesManager();
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return false;
|
|
}
|
|
|
|
bool result = false;
|
|
rv = mMessagesManager->MozHasPendingMessage(aType, &result);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void
|
|
Navigator::MozSetMessageHandlerPromise(Promise& aPromise,
|
|
ErrorResult& aRv)
|
|
{
|
|
// The WebIDL binding is responsible for the pref check here.
|
|
aRv = EnsureMessagesManager();
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
|
|
bool result = false;
|
|
aRv = mMessagesManager->MozIsHandlingMessage(&result);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
|
|
if (!result) {
|
|
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
|
return;
|
|
}
|
|
|
|
aRv = mMessagesManager->MozSetMessageHandlerPromise(&aPromise);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
void
|
|
Navigator::MozSetMessageHandler(const nsAString& aType,
|
|
systemMessageCallback* aCallback,
|
|
ErrorResult& aRv)
|
|
{
|
|
// The WebIDL binding is responsible for the pref check here.
|
|
nsresult rv = EnsureMessagesManager();
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return;
|
|
}
|
|
|
|
CallbackObjectHolder<systemMessageCallback, nsIDOMSystemMessageCallback>
|
|
holder(aCallback);
|
|
nsCOMPtr<nsIDOMSystemMessageCallback> callback = holder.ToXPCOMCallback();
|
|
|
|
rv = mMessagesManager->MozSetMessageHandler(aType, callback);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
}
|
|
}
|
|
|
|
#ifdef MOZ_TIME_MANAGER
|
|
time::TimeManager*
|
|
Navigator::GetMozTime(ErrorResult& aRv)
|
|
{
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
|
|
if (!mTimeManager) {
|
|
mTimeManager = new time::TimeManager(mWindow);
|
|
}
|
|
|
|
return mTimeManager;
|
|
}
|
|
#endif
|
|
|
|
nsDOMCameraManager*
|
|
Navigator::GetMozCameras(ErrorResult& aRv)
|
|
{
|
|
if (!mCameraManager) {
|
|
if (!mWindow ||
|
|
!mWindow->GetOuterWindow() ||
|
|
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
|
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
|
return nullptr;
|
|
}
|
|
|
|
mCameraManager = nsDOMCameraManager::CreateInstance(mWindow);
|
|
}
|
|
|
|
return mCameraManager;
|
|
}
|
|
|
|
already_AddRefed<ServiceWorkerContainer>
|
|
Navigator::ServiceWorker()
|
|
{
|
|
MOZ_ASSERT(mWindow);
|
|
|
|
if (!mServiceWorkerContainer) {
|
|
mServiceWorkerContainer = new ServiceWorkerContainer(mWindow);
|
|
}
|
|
|
|
RefPtr<ServiceWorkerContainer> ref = mServiceWorkerContainer;
|
|
return ref.forget();
|
|
}
|
|
|
|
size_t
|
|
Navigator::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
size_t n = aMallocSizeOf(this);
|
|
|
|
// TODO: add SizeOfIncludingThis() to nsMimeTypeArray, bug 674113.
|
|
// TODO: add SizeOfIncludingThis() to nsPluginArray, bug 674114.
|
|
// TODO: add SizeOfIncludingThis() to Geolocation, bug 674115.
|
|
// TODO: add SizeOfIncludingThis() to DesktopNotificationCenter, bug 674116.
|
|
|
|
return n;
|
|
}
|
|
|
|
void
|
|
Navigator::SetWindow(nsPIDOMWindow *aInnerWindow)
|
|
{
|
|
NS_ASSERTION(aInnerWindow->IsInnerWindow(),
|
|
"Navigator must get an inner window!");
|
|
mWindow = aInnerWindow;
|
|
}
|
|
|
|
void
|
|
Navigator::OnNavigation()
|
|
{
|
|
if (!mWindow) {
|
|
return;
|
|
}
|
|
|
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
|
// If MediaManager is open let it inform any live streams or pending callbacks
|
|
MediaManager *manager = MediaManager::GetIfExists();
|
|
if (manager) {
|
|
manager->OnNavigation(mWindow->WindowID());
|
|
}
|
|
#endif
|
|
if (mCameraManager) {
|
|
mCameraManager->OnNavigation(mWindow->WindowID());
|
|
}
|
|
}
|
|
|
|
bool
|
|
Navigator::CheckPermission(const char* type)
|
|
{
|
|
return CheckPermission(mWindow, type);
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::CheckPermission(nsPIDOMWindow* aWindow, const char* aType)
|
|
{
|
|
if (!aWindow) {
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
|
services::GetPermissionManager();
|
|
NS_ENSURE_TRUE(permMgr, false);
|
|
|
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
|
permMgr->TestPermissionFromWindow(aWindow, aType, &permission);
|
|
return permission == nsIPermissionManager::ALLOW_ACTION;
|
|
}
|
|
|
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
|
system::AudioChannelManager*
|
|
Navigator::GetMozAudioChannelManager(ErrorResult& aRv)
|
|
{
|
|
if (!mAudioChannelManager) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mAudioChannelManager = new system::AudioChannelManager();
|
|
mAudioChannelManager->Init(mWindow);
|
|
}
|
|
|
|
return mAudioChannelManager;
|
|
}
|
|
#endif
|
|
|
|
bool
|
|
Navigator::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
|
JS::Handle<jsid> aId,
|
|
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
|
{
|
|
// Note: Keep this in sync with MayResolve.
|
|
if (!JSID_IS_STRING(aId)) {
|
|
return true;
|
|
}
|
|
|
|
nsScriptNameSpaceManager* nameSpaceManager = GetNameSpaceManager();
|
|
if (!nameSpaceManager) {
|
|
return Throw(aCx, NS_ERROR_NOT_INITIALIZED);
|
|
}
|
|
|
|
nsAutoJSString name;
|
|
if (!name.init(aCx, JSID_TO_STRING(aId))) {
|
|
return false;
|
|
}
|
|
|
|
const nsGlobalNameStruct* name_struct =
|
|
nameSpaceManager->LookupNavigatorName(name);
|
|
if (!name_struct) {
|
|
return true;
|
|
}
|
|
|
|
JS::Rooted<JSObject*> naviObj(aCx,
|
|
js::CheckedUnwrap(aObject,
|
|
/* stopAtWindowProxy = */ false));
|
|
if (!naviObj) {
|
|
return Throw(aCx, NS_ERROR_DOM_SECURITY_ERR);
|
|
}
|
|
|
|
if (name_struct->mType == nsGlobalNameStruct::eTypeNewDOMBinding) {
|
|
ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty;
|
|
MOZ_ASSERT(construct);
|
|
|
|
JS::Rooted<JSObject*> domObject(aCx);
|
|
{
|
|
// Make sure to do the creation of our object in the compartment
|
|
// of naviObj, especially since we plan to cache that object.
|
|
JSAutoCompartment ac(aCx, naviObj);
|
|
|
|
// Check whether our constructor is enabled after we unwrap Xrays, since
|
|
// we don't want to define an interface on the Xray if it's disabled in
|
|
// the target global, even if it's enabled in the Xray's global.
|
|
if (name_struct->mConstructorEnabled &&
|
|
!(*name_struct->mConstructorEnabled)(aCx, naviObj)) {
|
|
return true;
|
|
}
|
|
|
|
if (name.EqualsLiteral("mozSettings")) {
|
|
bool hasPermission = CheckPermission("settings-api-read") ||
|
|
CheckPermission("settings-api-write");
|
|
if (!hasPermission) {
|
|
FillPropertyDescriptor(aDesc, aObject, JS::NullValue(), false);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (name.EqualsLiteral("mozDownloadManager")) {
|
|
if (!CheckPermission("downloads")) {
|
|
FillPropertyDescriptor(aDesc, aObject, JS::NullValue(), false);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
nsISupports* existingObject = mCachedResolveResults.GetWeak(name);
|
|
if (existingObject) {
|
|
// We know all of our WebIDL objects here are wrappercached, so just go
|
|
// ahead and WrapObject() them. We can't use GetOrCreateDOMReflector,
|
|
// because we don't have the concrete type.
|
|
JS::Rooted<JS::Value> wrapped(aCx);
|
|
if (!dom::WrapObject(aCx, existingObject, &wrapped)) {
|
|
return false;
|
|
}
|
|
domObject = &wrapped.toObject();
|
|
} else {
|
|
domObject = construct(aCx, naviObj);
|
|
if (!domObject) {
|
|
return Throw(aCx, NS_ERROR_FAILURE);
|
|
}
|
|
|
|
// Store the value in our cache
|
|
nsISupports* native = UnwrapDOMObjectToISupports(domObject);
|
|
MOZ_ASSERT(native);
|
|
mCachedResolveResults.Put(name, native);
|
|
}
|
|
}
|
|
|
|
if (!JS_WrapObject(aCx, &domObject)) {
|
|
return false;
|
|
}
|
|
|
|
FillPropertyDescriptor(aDesc, aObject, JS::ObjectValue(*domObject), false);
|
|
return true;
|
|
}
|
|
|
|
NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeNavigatorProperty,
|
|
"unexpected type");
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsISupports> native;
|
|
bool hadCachedNative = mCachedResolveResults.Get(name, getter_AddRefs(native));
|
|
bool okToUseNative;
|
|
JS::Rooted<JS::Value> prop_val(aCx);
|
|
if (hadCachedNative) {
|
|
okToUseNative = true;
|
|
} else {
|
|
native = do_CreateInstance(name_struct->mCID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return Throw(aCx, rv);
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
|
|
|
|
if (gpi) {
|
|
if (!mWindow) {
|
|
return Throw(aCx, NS_ERROR_UNEXPECTED);
|
|
}
|
|
|
|
rv = gpi->Init(mWindow, &prop_val);
|
|
if (NS_FAILED(rv)) {
|
|
return Throw(aCx, rv);
|
|
}
|
|
}
|
|
|
|
okToUseNative = !prop_val.isObjectOrNull();
|
|
}
|
|
|
|
if (okToUseNative) {
|
|
// Make sure to do the creation of our object in the compartment
|
|
// of naviObj, especially since we plan to cache that object.
|
|
JSAutoCompartment ac(aCx, naviObj);
|
|
|
|
rv = nsContentUtils::WrapNative(aCx, native, &prop_val);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return Throw(aCx, rv);
|
|
}
|
|
|
|
// Now that we know we managed to wrap this thing properly, go ahead and
|
|
// cache it as needed.
|
|
if (!hadCachedNative) {
|
|
mCachedResolveResults.Put(name, native);
|
|
}
|
|
}
|
|
|
|
if (!JS_WrapValue(aCx, &prop_val)) {
|
|
return Throw(aCx, NS_ERROR_UNEXPECTED);
|
|
}
|
|
|
|
FillPropertyDescriptor(aDesc, aObject, prop_val, false);
|
|
return true;
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::MayResolve(jsid aId)
|
|
{
|
|
// Note: This function does not fail and may not have any side-effects.
|
|
// Note: Keep this in sync with DoResolve.
|
|
if (!JSID_IS_STRING(aId)) {
|
|
return false;
|
|
}
|
|
|
|
nsScriptNameSpaceManager *nameSpaceManager = PeekNameSpaceManager();
|
|
if (!nameSpaceManager) {
|
|
// Really shouldn't happen here. Fail safe.
|
|
return true;
|
|
}
|
|
|
|
nsAutoString name;
|
|
AssignJSFlatString(name, JSID_TO_FLAT_STRING(aId));
|
|
|
|
return nameSpaceManager->LookupNavigatorName(name);
|
|
}
|
|
|
|
void
|
|
Navigator::GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
|
|
if (!nameSpaceManager) {
|
|
NS_ERROR("Can't get namespace manager.");
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return;
|
|
}
|
|
|
|
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
|
for (auto i = nameSpaceManager->NavigatorNameIter(); !i.Done(); i.Next()) {
|
|
const GlobalNameMapEntry* entry = i.Get();
|
|
if (!entry->mGlobalName.mConstructorEnabled ||
|
|
entry->mGlobalName.mConstructorEnabled(aCx, wrapper)) {
|
|
aNames.AppendElement(entry->mKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
JSObject*
|
|
Navigator::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return NavigatorBinding::Wrap(cx, this, aGivenProto);
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */)
|
|
{
|
|
nsCOMPtr<nsIPowerManagerService> pmService =
|
|
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
|
// No service means no wake lock support
|
|
return !!pmService;
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasCameraSupport(JSContext* /* unused */, JSObject* aGlobal)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
|
return win && nsDOMCameraManager::CheckPermission(win);
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasWifiManagerSupport(JSContext* /* unused */,
|
|
JSObject* aGlobal)
|
|
{
|
|
// On XBL scope, the global object is NOT |window|. So we have
|
|
// to use nsContentUtils::GetObjectPrincipal to get the principal
|
|
// and test directly with permission manager.
|
|
|
|
nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aGlobal);
|
|
|
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
|
services::GetPermissionManager();
|
|
NS_ENSURE_TRUE(permMgr, false);
|
|
|
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
|
permMgr->TestPermissionFromPrincipal(principal, "wifi-manage", &permission);
|
|
return nsIPermissionManager::ALLOW_ACTION == permission;
|
|
}
|
|
|
|
#ifdef MOZ_NFC
|
|
/* static */
|
|
bool
|
|
Navigator::HasNFCSupport(JSContext* /* unused */, JSObject* aGlobal)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
|
|
|
// Do not support NFC if NFC content helper does not exist.
|
|
nsCOMPtr<nsISupports> contentHelper = do_GetService("@mozilla.org/nfc/content-helper;1");
|
|
return !!contentHelper;
|
|
}
|
|
#endif // MOZ_NFC
|
|
|
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
|
/* static */
|
|
bool
|
|
Navigator::HasUserMediaSupport(JSContext* /* unused */,
|
|
JSObject* /* unused */)
|
|
{
|
|
// Make enabling peerconnection enable getUserMedia() as well
|
|
return Preferences::GetBool("media.navigator.enabled", false) ||
|
|
Preferences::GetBool("media.peerconnection.enabled", false);
|
|
}
|
|
#endif // MOZ_MEDIA_NAVIGATOR
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasDataStoreSupport(nsIPrincipal* aPrincipal)
|
|
{
|
|
workers::AssertIsOnMainThread();
|
|
|
|
return DataStoreService::CheckPermission(aPrincipal);
|
|
}
|
|
|
|
// A WorkerMainThreadRunnable to synchronously dispatch the call of
|
|
// HasDataStoreSupport() from the worker thread to the main thread.
|
|
class HasDataStoreSupportRunnable final
|
|
: public workers::WorkerCheckAPIExposureOnMainThreadRunnable
|
|
{
|
|
public:
|
|
bool mResult;
|
|
|
|
explicit HasDataStoreSupportRunnable(workers::WorkerPrivate* aWorkerPrivate)
|
|
: workers::WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
|
|
, mResult(false)
|
|
{
|
|
MOZ_ASSERT(aWorkerPrivate);
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
|
}
|
|
|
|
protected:
|
|
virtual bool
|
|
MainThreadRun() override
|
|
{
|
|
workers::AssertIsOnMainThread();
|
|
|
|
mResult = Navigator::HasDataStoreSupport(mWorkerPrivate->GetPrincipal());
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasDataStoreSupport(JSContext* aCx, JSObject* aGlobal)
|
|
{
|
|
// If the caller is on the worker thread, dispatch this to the main thread.
|
|
if (!NS_IsMainThread()) {
|
|
workers::WorkerPrivate* workerPrivate =
|
|
workers::GetWorkerPrivateFromContext(aCx);
|
|
workerPrivate->AssertIsOnWorkerThread();
|
|
|
|
RefPtr<HasDataStoreSupportRunnable> runnable =
|
|
new HasDataStoreSupportRunnable(workerPrivate);
|
|
return runnable->Dispatch() && runnable->mResult;
|
|
}
|
|
|
|
workers::AssertIsOnMainThread();
|
|
|
|
JS::Rooted<JSObject*> global(aCx, aGlobal);
|
|
|
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
|
|
if (!win) {
|
|
return false;
|
|
}
|
|
|
|
nsIDocument* doc = win->GetExtantDoc();
|
|
if (!doc || !doc->NodePrincipal()) {
|
|
return false;
|
|
}
|
|
|
|
return HasDataStoreSupport(doc->NodePrincipal());
|
|
}
|
|
|
|
#ifdef MOZ_B2G
|
|
/* static */
|
|
bool
|
|
Navigator::HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
|
if (!win) {
|
|
return false;
|
|
}
|
|
|
|
nsIDocument* doc = win->GetExtantDoc();
|
|
if (!doc) {
|
|
return false;
|
|
}
|
|
|
|
nsIPrincipal* principal = doc->NodePrincipal();
|
|
|
|
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
|
|
NS_ENSURE_TRUE(permMgr, false);
|
|
|
|
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
|
|
permMgr->TestPermissionFromPrincipal(principal, "mobileid", &permission);
|
|
return permission == nsIPermissionManager::PROMPT_ACTION ||
|
|
permission == nsIPermissionManager::ALLOW_ACTION;
|
|
}
|
|
#endif
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::HasTVSupport(JSContext* aCx, JSObject* aGlobal)
|
|
{
|
|
JS::Rooted<JSObject*> global(aCx, aGlobal);
|
|
|
|
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
|
|
if (!win) {
|
|
return false;
|
|
}
|
|
|
|
// Just for testing, we can enable TV for any kind of app.
|
|
if (Preferences::GetBool("dom.testing.tv_enabled_for_hosted_apps", false)) {
|
|
return true;
|
|
}
|
|
|
|
nsIDocument* doc = win->GetExtantDoc();
|
|
if (!doc || !doc->NodePrincipal()) {
|
|
return false;
|
|
}
|
|
|
|
nsIPrincipal* principal = doc->NodePrincipal();
|
|
uint16_t status;
|
|
if (NS_FAILED(principal->GetAppStatus(&status))) {
|
|
return false;
|
|
}
|
|
|
|
// Only support TV Manager API for certified apps for now.
|
|
return status == nsIPrincipal::APP_STATUS_CERTIFIED;
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal)
|
|
{
|
|
return XRE_IsContentProcess();
|
|
}
|
|
|
|
bool
|
|
Navigator::MozE10sEnabled()
|
|
{
|
|
// This will only be called if IsE10sEnabled() is true.
|
|
return true;
|
|
}
|
|
|
|
/* static */
|
|
already_AddRefed<nsPIDOMWindow>
|
|
Navigator::GetWindowFromGlobal(JSObject* aGlobal)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win =
|
|
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
|
|
MOZ_ASSERT(!win || win->IsInnerWindow());
|
|
return win.forget();
|
|
}
|
|
|
|
nsresult
|
|
Navigator::GetPlatform(nsAString& aPlatform, bool aUsePrefOverriddenValue)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
|
|
const nsAdoptingString& override =
|
|
mozilla::Preferences::GetString("general.platform.override");
|
|
|
|
if (override) {
|
|
aPlatform = override;
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIHttpProtocolHandler>
|
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Sorry for the #if platform ugliness, but Communicator is likewise
|
|
// hardcoded and we are seeking backward compatibility here (bug 47080).
|
|
#if defined(_WIN64)
|
|
aPlatform.AssignLiteral("Win64");
|
|
#elif defined(WIN32)
|
|
aPlatform.AssignLiteral("Win32");
|
|
#elif defined(XP_MACOSX) && defined(__ppc__)
|
|
aPlatform.AssignLiteral("MacPPC");
|
|
#elif defined(XP_MACOSX) && defined(__i386__)
|
|
aPlatform.AssignLiteral("MacIntel");
|
|
#elif defined(XP_MACOSX) && defined(__x86_64__)
|
|
aPlatform.AssignLiteral("MacIntel");
|
|
#else
|
|
// XXX Communicator uses compiled-in build-time string defines
|
|
// to indicate the platform it was compiled *for*, not what it is
|
|
// currently running *on* which is what this does.
|
|
nsAutoCString plat;
|
|
rv = service->GetOscpu(plat);
|
|
CopyASCIItoUTF16(plat, aPlatform);
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
/* static */ nsresult
|
|
Navigator::GetAppVersion(nsAString& aAppVersion, bool aUsePrefOverriddenValue)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
|
|
const nsAdoptingString& override =
|
|
mozilla::Preferences::GetString("general.appversion.override");
|
|
|
|
if (override) {
|
|
aAppVersion = override;
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIHttpProtocolHandler>
|
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString str;
|
|
rv = service->GetAppVersion(str);
|
|
CopyASCIItoUTF16(str, aAppVersion);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aAppVersion.AppendLiteral(" (");
|
|
|
|
rv = service->GetPlatform(str);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
AppendASCIItoUTF16(str, aAppVersion);
|
|
aAppVersion.Append(char16_t(')'));
|
|
|
|
return rv;
|
|
}
|
|
|
|
/* static */ void
|
|
Navigator::AppName(nsAString& aAppName, bool aUsePrefOverriddenValue)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (aUsePrefOverriddenValue && !nsContentUtils::IsCallerChrome()) {
|
|
const nsAdoptingString& override =
|
|
mozilla::Preferences::GetString("general.appname.override");
|
|
|
|
if (override) {
|
|
aAppName = override;
|
|
return;
|
|
}
|
|
}
|
|
|
|
aAppName.AssignLiteral("Netscape");
|
|
}
|
|
|
|
nsresult
|
|
Navigator::GetUserAgent(nsPIDOMWindow* aWindow, nsIURI* aURI,
|
|
bool aIsCallerChrome,
|
|
nsAString& aUserAgent)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIHttpProtocolHandler>
|
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
nsAutoCString ua;
|
|
rv = service->GetUserAgent(ua);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
CopyASCIItoUTF16(ua, aUserAgent);
|
|
|
|
if (!aWindow || !aURI) {
|
|
return NS_OK;
|
|
}
|
|
|
|
MOZ_ASSERT(aWindow->GetDocShell());
|
|
|
|
nsCOMPtr<nsISiteSpecificUserAgent> siteSpecificUA =
|
|
do_GetService("@mozilla.org/dom/site-specific-user-agent;1");
|
|
if (!siteSpecificUA) {
|
|
return NS_OK;
|
|
}
|
|
|
|
return siteSpecificUA->GetUserAgentForURIAndWindow(aURI, aWindow, aUserAgent);
|
|
}
|
|
|
|
Presentation*
|
|
Navigator::GetPresentation(ErrorResult& aRv)
|
|
{
|
|
if (!mPresentation) {
|
|
if (!mWindow) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
mPresentation = Presentation::Create(mWindow);
|
|
}
|
|
|
|
return mPresentation;
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|