Bug 885171. Make Navigator wrappercached and cycle-collected, and have it hold a strong reference to its window always. r=smaug

This commit is contained in:
Boris Zbarsky 2013-06-20 14:34:38 -04:00
parent 7b7e834fc1
commit 6a7a1954ff
2 changed files with 118 additions and 140 deletions

View File

@ -100,7 +100,7 @@ Navigator::Init()
}
Navigator::Navigator(nsPIDOMWindow* aWindow)
: mWindow(do_GetWeakReference(aWindow))
: mWindow(aWindow)
{
NS_ASSERTION(aWindow->IsInnerWindow(),
"Navigator must get an inner window!");
@ -111,7 +111,8 @@ Navigator::~Navigator()
Invalidate();
}
NS_INTERFACE_MAP_BEGIN(Navigator)
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(nsIDOMClientInformation)
@ -152,13 +153,19 @@ NS_INTERFACE_MAP_BEGIN(Navigator)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(Navigator)
NS_IMPL_RELEASE(Navigator)
NS_IMPL_CYCLE_COLLECTING_ADDREF(Navigator)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Navigator)
// We seem to manually break cycles through most of our members in Invalidate.
// That said, if those members get set _after_ the window calls Invalidate on
// us, then what?
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(Navigator, mWindow)
void
Navigator::Invalidate()
{
mWindow = nullptr;
// Don't clear mWindow here so we know we've got a non-null mWindow
// until we're unlinked.
if (mPlugins) {
mPlugins->Invalidate();
@ -256,14 +263,6 @@ Navigator::Invalidate()
}
}
nsPIDOMWindow *
Navigator::GetWindow()
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
return win;
}
//*****************************************************************************
// Navigator::nsIDOMNavigator
//*****************************************************************************
@ -274,12 +273,11 @@ Navigator::GetUserAgent(nsAString& aUserAgent)
nsresult rv = NS_GetNavigatorUserAgent(aUserAgent);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetDocShell()) {
return NS_OK;
}
nsIDocument* doc = win->GetExtantDoc();
nsIDocument* doc = mWindow->GetExtantDoc();
if (!doc) {
return NS_OK;
}
@ -294,7 +292,8 @@ Navigator::GetUserAgent(nsAString& aUserAgent)
do_GetService("@mozilla.org/dom/site-specific-user-agent;1");
NS_ENSURE_TRUE(siteSpecificUA, NS_OK);
return siteSpecificUA->GetUserAgentForURIAndWindow(codebaseURI, win, aUserAgent);
return siteSpecificUA->GetUserAgentForURIAndWindow(codebaseURI, mWindow,
aUserAgent);
}
NS_IMETHODIMP
@ -446,6 +445,7 @@ NS_IMETHODIMP
Navigator::GetMimeTypes(nsIDOMMimeTypeArray** aMimeTypes)
{
if (!mMimeTypes) {
NS_ENSURE_STATE(mWindow);
mMimeTypes = new nsMimeTypeArray(this);
}
@ -458,9 +458,9 @@ NS_IMETHODIMP
Navigator::GetPlugins(nsIDOMPluginArray** aPlugins)
{
if (!mPlugins) {
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
NS_ENSURE_STATE(mWindow);
mPlugins = new nsPluginArray(this, win ? win->GetDocShell() : nullptr);
mPlugins = new nsPluginArray(this, mWindow->GetDocShell());
mPlugins->Init();
}
@ -483,13 +483,11 @@ Navigator::GetCookieEnabled(bool* aCookieEnabled)
// Check whether an exception overrides the global cookie behavior
// Note that the code for getting the URI here matches that in
// nsHTMLDocument::SetCookie.
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetDocShell()) {
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
if (!doc) {
return NS_OK;
}
@ -579,6 +577,7 @@ Navigator::JavaEnabled(bool* aReturn)
*aReturn = false;
if (!mMimeTypes) {
NS_ENSURE_STATE(mWindow);
mMimeTypes = new nsMimeTypeArray(this);
}
@ -716,6 +715,8 @@ GetVibrationDurationFromJsval(const JS::Value& aJSVal, JSContext* cx,
NS_IMETHODIMP
Navigator::AddIdleObserver(nsIIdleObserver* aIdleObserver)
{
NS_ENSURE_STATE(mWindow);
if (!nsContentUtils::IsIdleObserverAPIEnabled()) {
NS_WARNING("The IdleObserver API has been disabled.");
return NS_OK;
@ -723,14 +724,11 @@ Navigator::AddIdleObserver(nsIIdleObserver* aIdleObserver)
NS_ENSURE_ARG_POINTER(aIdleObserver);
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED);
if (!CheckPermission("idle")) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (NS_FAILED(win->RegisterIdleObserver(aIdleObserver))) {
if (NS_FAILED(mWindow->RegisterIdleObserver(aIdleObserver))) {
NS_WARNING("Failed to add idle observer.");
}
@ -740,6 +738,8 @@ Navigator::AddIdleObserver(nsIIdleObserver* aIdleObserver)
NS_IMETHODIMP
Navigator::RemoveIdleObserver(nsIIdleObserver* aIdleObserver)
{
NS_ENSURE_STATE(mWindow);
if (!nsContentUtils::IsIdleObserverAPIEnabled()) {
NS_WARNING("The IdleObserver API has been disabled");
return NS_OK;
@ -747,9 +747,7 @@ Navigator::RemoveIdleObserver(nsIIdleObserver* aIdleObserver)
NS_ENSURE_ARG_POINTER(aIdleObserver);
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED);
if (NS_FAILED(win->UnregisterIdleObserver(aIdleObserver))) {
if (NS_FAILED(mWindow->UnregisterIdleObserver(aIdleObserver))) {
NS_WARNING("Failed to remove idle observer.");
}
return NS_OK;
@ -758,10 +756,9 @@ Navigator::RemoveIdleObserver(nsIIdleObserver* aIdleObserver)
NS_IMETHODIMP
Navigator::Vibrate(const JS::Value& aPattern, JSContext* cx)
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);
NS_ENSURE_STATE(mWindow);
nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
if (doc->Hidden()) {
// Hidden documents cannot start or stop a vibration.
@ -823,9 +820,9 @@ Navigator::Vibrate(const JS::Value& aPattern, JSContext* cx)
else {
gVibrateWindowListener->RemoveListener();
}
gVibrateWindowListener = new VibrateWindowListener(win, doc);
gVibrateWindowListener = new VibrateWindowListener(mWindow, doc);
hal::Vibrate(pattern, win);
hal::Vibrate(pattern, mWindow);
return NS_OK;
}
@ -838,9 +835,7 @@ Navigator::RegisterContentHandler(const nsAString& aMIMEType,
const nsAString& aURI,
const nsAString& aTitle)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
return NS_OK;
}
@ -851,7 +846,7 @@ Navigator::RegisterContentHandler(const nsAString& aMIMEType,
}
return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle,
win->GetOuterWindow());
mWindow->GetOuterWindow());
}
NS_IMETHODIMP
@ -859,9 +854,7 @@ Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
const nsAString& aURI,
const nsAString& aTitle)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
return NS_OK;
}
@ -872,7 +865,7 @@ Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
}
return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
win->GetOuterWindow());
mWindow->GetOuterWindow());
}
NS_IMETHODIMP
@ -919,12 +912,10 @@ Navigator::MozIsLocallyAvailable(const nsAString &aURI,
nsIRequest::LOAD_FROM_CACHE;
}
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win) {
return NS_ERROR_FAILURE;
}
NS_ENSURE_STATE(mWindow);
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsIDocument> doc = win->GetDoc();
nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
if (doc) {
loadGroup = doc->GetDocumentLoadGroup();
}
@ -966,14 +957,13 @@ NS_IMETHODIMP Navigator::GetDeviceStorage(const nsAString &aType, nsIDOMDeviceSt
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
return NS_ERROR_FAILURE;
}
nsRefPtr<nsDOMDeviceStorage> storage;
nsDOMDeviceStorage::CreateDeviceStorageFor(win, aType, getter_AddRefs(storage));
nsDOMDeviceStorage::CreateDeviceStorageFor(mWindow, aType,
getter_AddRefs(storage));
if (!storage) {
return NS_OK;
@ -993,14 +983,12 @@ NS_IMETHODIMP Navigator::GetDeviceStorages(const nsAString &aType, nsIVariant**
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
return NS_ERROR_FAILURE;
}
nsTArray<nsRefPtr<nsDOMDeviceStorage> > stores;
nsDOMDeviceStorage::CreateDeviceStoragesFor(win, aType, stores, false);
nsDOMDeviceStorage::CreateDeviceStoragesFor(mWindow, aType, stores, false);
nsCOMPtr<nsIWritableVariant> result = do_CreateInstance("@mozilla.org/variant;1");
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
@ -1037,9 +1025,7 @@ NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) {
return NS_ERROR_FAILURE;
}
@ -1048,7 +1034,7 @@ NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
return NS_ERROR_FAILURE;
}
if (NS_FAILED(mGeolocation->Init(win->GetOuterWindow()))) {
if (NS_FAILED(mGeolocation->Init(mWindow->GetOuterWindow()))) {
mGeolocation = nullptr;
return NS_ERROR_FAILURE;
}
@ -1072,16 +1058,16 @@ Navigator::MozGetUserMedia(nsIMediaStreamOptions* aParams,
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
if (!win || !win->GetOuterWindow() ||
win->GetOuterWindow()->GetCurrentInnerWindow() != win) {
if (!mWindow || !mWindow->GetOuterWindow() ||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
return NS_ERROR_NOT_AVAILABLE;
}
bool privileged = nsContentUtils::IsChromeDoc(win->GetExtantDoc());
bool privileged = nsContentUtils::IsChromeDoc(mWindow->GetExtantDoc());
MediaManager* manager = MediaManager::Get();
return manager->GetUserMedia(privileged, win, aParams, aOnSuccess, aOnError);
return manager->GetUserMedia(privileged, mWindow, aParams, aOnSuccess,
aOnError);
}
//*****************************************************************************
@ -1091,9 +1077,8 @@ NS_IMETHODIMP
Navigator::MozGetUserMediaDevices(nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
nsIDOMGetUserMediaErrorCallback* aOnError)
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
if (!win || !win->GetOuterWindow() ||
win->GetOuterWindow()->GetCurrentInnerWindow() != win) {
if (!mWindow || !mWindow->GetOuterWindow() ||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -1103,7 +1088,7 @@ Navigator::MozGetUserMediaDevices(nsIGetUserMediaDevicesSuccessCallback* aOnSucc
}
MediaManager* manager = MediaManager::Get();
return manager->GetUserMediaDevices(win, aOnSuccess, aOnError);
return manager->GetUserMediaDevices(mWindow, aOnSuccess, aOnError);
}
#endif
@ -1121,10 +1106,9 @@ NS_IMETHODIMP Navigator::GetMozNotification(nsISupports** aRetVal)
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
NS_ENSURE_TRUE(win && win->GetDocShell(), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(mWindow && mWindow->GetDocShell(), NS_ERROR_FAILURE);
mNotification = new DesktopNotificationCenter(win);
mNotification = new DesktopNotificationCenter(mWindow);
NS_ADDREF(*aRetVal = mNotification);
return NS_OK;
@ -1140,11 +1124,11 @@ Navigator::GetBattery(nsISupports** aBattery)
if (!mBatteryManager) {
*aBattery = nullptr;
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
NS_ENSURE_TRUE(win && win->GetDocShell(), NS_OK);
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
mBatteryManager = new battery::BatteryManager();
mBatteryManager->Init(win);
mBatteryManager->Init(mWindow);
}
NS_ADDREF(*aBattery = mBatteryManager);
@ -1158,10 +1142,8 @@ Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
*aPower = nullptr;
if (!mPowerManager) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
mPowerManager = PowerManager::CheckPermissionAndCreateInstance(window);
NS_ENSURE_STATE(mWindow);
mPowerManager = PowerManager::CheckPermissionAndCreateInstance(mWindow);
NS_ENSURE_TRUE(mPowerManager, NS_OK);
}
@ -1174,16 +1156,15 @@ Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
NS_IMETHODIMP
Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLock)
{
*aWakeLock = nullptr;
NS_ENSURE_STATE(mWindow);
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);
*aWakeLock = nullptr;
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_TRUE(pmService, NS_OK);
return pmService->NewWakeLock(aTopic, win, aWakeLock);
return pmService->NewWakeLock(aTopic, mWindow, aWakeLock);
}
//*****************************************************************************
@ -1196,10 +1177,10 @@ Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
*aSmsManager = nullptr;
if (!mSmsManager) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
mSmsManager = SmsManager::CreateInstanceIfAllowed(window);
mSmsManager = SmsManager::CreateInstanceIfAllowed(mWindow);
NS_ENSURE_TRUE(mSmsManager, NS_OK);
}
@ -1227,15 +1208,15 @@ Navigator::GetMozMobileMessage(nsIDOMMozMobileMessageManager** aMobileMessageMan
NS_ENSURE_TRUE(enabled, NS_OK);
if (!mMobileMessageManager) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
if (!CheckPermission("sms")) {
return NS_OK;
}
mMobileMessageManager = new MobileMessageManager();
mMobileMessageManager->Init(window);
mMobileMessageManager->Init(mWindow);
}
NS_ADDREF(*aMobileMessageManager = mMobileMessageManager);
@ -1255,14 +1236,13 @@ Navigator::GetMozCellBroadcast(nsIDOMMozCellBroadcast** aCellBroadcast)
*aCellBroadcast = nullptr;
if (!mCellBroadcast) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
NS_ENSURE_STATE(mWindow);
if (!CheckPermission("cellbroadcast")) {
return NS_OK;
}
nsresult rv = NS_NewCellBroadcast(window, getter_AddRefs(mCellBroadcast));
nsresult rv = NS_NewCellBroadcast(mWindow, getter_AddRefs(mCellBroadcast));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1280,10 +1260,8 @@ Navigator::GetMozTelephony(nsIDOMTelephony** aTelephony)
nsCOMPtr<nsIDOMTelephony> telephony = mTelephony;
if (!telephony) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsresult rv = NS_NewTelephony(window, getter_AddRefs(mTelephony));
NS_ENSURE_STATE(mWindow);
nsresult rv = NS_NewTelephony(mWindow, getter_AddRefs(mTelephony));
NS_ENSURE_SUCCESS(rv, rv);
// mTelephony may be null here!
@ -1304,14 +1282,12 @@ Navigator::GetMozVoicemail(nsIDOMMozVoicemail** aVoicemail)
*aVoicemail = nullptr;
if (!mVoicemail) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
NS_ENSURE_STATE(mWindow);
if (!CheckPermission("voicemail")) {
return NS_OK;
}
nsresult rv = NS_NewVoicemail(window, getter_AddRefs(mVoicemail));
nsresult rv = NS_NewVoicemail(mWindow, getter_AddRefs(mVoicemail));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1329,15 +1305,15 @@ Navigator::GetMozIccManager(nsIDOMMozIccManager** aIccManager)
*aIccManager = nullptr;
if (!mIccManager) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
mIccManager = new icc::IccManager();
mIccManager->Init(window);
mIccManager->Init(mWindow);
}
NS_ADDREF(*aIccManager = mIccManager);
@ -1357,9 +1333,9 @@ Navigator::GetGamepads(nsIVariant** aRetVal)
NS_ENSURE_ARG_POINTER(aRetVal);
*aRetVal = nullptr;
nsCOMPtr<nsPIDOMWindow> pwin(do_QueryReferent(mWindow));
NS_ENSURE_TRUE(pwin && pwin->GetDocShell(), NS_OK);
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(pwin.get());
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(mWindow.get());
nsAutoTArray<nsRefPtr<Gamepad>, 2> gamepads;
win->GetGamepads(gamepads);
@ -1392,11 +1368,11 @@ Navigator::GetMozConnection(nsIDOMMozConnection** aConnection)
*aConnection = nullptr;
if (!mConnection) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
NS_ENSURE_STATE(mWindow);
NS_ENSURE_TRUE(mWindow->GetDocShell(), NS_OK);
mConnection = new network::Connection();
mConnection->Init(window);
mConnection->Init(mWindow);
}
NS_ADDREF(*aConnection = mConnection);
@ -1413,16 +1389,14 @@ Navigator::GetMozMobileConnection(nsIDOMMozMobileConnection** aMobileConnection)
*aMobileConnection = nullptr;
if (!mMobileConnection) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
NS_ENSURE_STATE(mWindow);
if (!CheckPermission("mobileconnection") &&
!CheckPermission("mobilenetwork")) {
return NS_OK;
}
mMobileConnection = new network::MobileConnection();
mMobileConnection->Init(window);
mMobileConnection->Init(mWindow);
}
NS_ADDREF(*aMobileConnection = mMobileConnection);
@ -1441,10 +1415,8 @@ Navigator::GetMozBluetooth(nsIDOMBluetoothManager** aBluetooth)
nsCOMPtr<nsIDOMBluetoothManager> bluetooth = mBluetooth;
if (!bluetooth) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsresult rv = NS_NewBluetoothManager(window, getter_AddRefs(mBluetooth));
NS_ENSURE_STATE(mWindow);
nsresult rv = NS_NewBluetoothManager(mWindow, getter_AddRefs(mBluetooth));
NS_ENSURE_SUCCESS(rv, rv);
bluetooth = mBluetooth;
@ -1465,8 +1437,7 @@ Navigator::EnsureMessagesManager()
return NS_OK;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
NS_ENSURE_STATE(mWindow);
nsresult rv;
nsCOMPtr<nsIDOMNavigatorSystemMessages> messageManager =
@ -1479,7 +1450,7 @@ Navigator::EnsureMessagesManager()
// We don't do anything with the return value.
AutoJSContext cx;
JS::Rooted<JS::Value> prop_val(cx);
rv = gpi->Init(window, prop_val.address());
rv = gpi->Init(mWindow, prop_val.address());
NS_ENSURE_SUCCESS(rv, rv);
mMessagesManager = messageManager.forget();
@ -1524,12 +1495,13 @@ Navigator::GetMozTime(nsISupports** aTime)
{
*aTime = nullptr;
NS_ENSURE_STATE(mWindow);
if (!CheckPermission("time")) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!mTimeManager) {
mTimeManager = new time::TimeManager(GetWindow());
mTimeManager = new time::TimeManager(mWindow);
}
NS_ADDREF(*aTime = mTimeManager);
@ -1545,14 +1517,14 @@ NS_IMETHODIMP
Navigator::GetMozCameras(nsISupports** aCameraManager)
{
if (!mCameraManager) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
if (!win->GetOuterWindow() || win->GetOuterWindow()->GetCurrentInnerWindow() != win) {
if (!mWindow ||
!mWindow->GetOuterWindow() ||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
return NS_ERROR_NOT_AVAILABLE;
}
mCameraManager = nsDOMCameraManager::CheckPermissionAndCreateInstance(win);
mCameraManager =
nsDOMCameraManager::CheckPermissionAndCreateInstance(mWindow);
NS_ENSURE_TRUE(mCameraManager, NS_OK);
}
@ -1580,14 +1552,13 @@ Navigator::SetWindow(nsPIDOMWindow *aInnerWindow)
{
NS_ASSERTION(aInnerWindow->IsInnerWindow(),
"Navigator must get an inner window!");
mWindow = do_GetWeakReference(aInnerWindow);
mWindow = aInnerWindow;
}
void
Navigator::OnNavigation()
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
if (!win) {
if (!mWindow) {
return;
}
@ -1595,26 +1566,27 @@ Navigator::OnNavigation()
// Inform MediaManager in case there are live streams or pending callbacks.
MediaManager *manager = MediaManager::Get();
if (manager) {
manager->OnNavigation(win->WindowID());
manager->OnNavigation(mWindow->WindowID());
}
#endif
if (mCameraManager) {
mCameraManager->OnNavigation(win->WindowID());
mCameraManager->OnNavigation(mWindow->WindowID());
}
}
bool
Navigator::CheckPermission(const char* type)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, false);
if (!mWindow) {
return false;
}
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, false);
uint32_t permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromWindow(window, type, &permission);
permMgr->TestPermissionFromWindow(mWindow, type, &permission);
return permission == nsIPermissionManager::ALLOW_ACTION;
}
@ -1628,10 +1600,9 @@ Navigator::GetMozAudioChannelManager(nsISupports** aAudioChannelManager)
*aAudioChannelManager = nullptr;
if (!mAudioChannelManager) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
NS_ENSURE_STATE(mWindow);
mAudioChannelManager = new system::AudioChannelManager();
mAudioChannelManager->Init(window);
mAudioChannelManager->Init(mWindow);
}
NS_ADDREF(*aAudioChannelManager = mAudioChannelManager);

View File

@ -29,6 +29,7 @@
#include "nsIDOMNavigatorTime.h"
#include "nsWeakReference.h"
#include "DeviceStorage.h"
#include "nsWrapperCache.h"
class nsPluginArray;
class nsMimeTypeArray;
@ -141,12 +142,15 @@ class Navigator : public nsIDOMNavigator
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
, public nsIMozNavigatorAudioChannelManager
#endif
, public nsWrapperCache
{
public:
Navigator(nsPIDOMWindow *aInnerWindow);
virtual ~Navigator();
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Navigator,
nsIDOMNavigator)
NS_DECL_NSIDOMNAVIGATOR
NS_DECL_NSIDOMCLIENTINFORMATION
NS_DECL_NSIDOMNAVIGATORDEVICESTORAGE
@ -187,7 +191,10 @@ public:
static void Init();
void Invalidate();
nsPIDOMWindow *GetWindow();
nsPIDOMWindow *GetWindow()
{
return mWindow;
}
void RefreshMIMEArray();
@ -241,7 +248,7 @@ private:
nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
nsRefPtr<time::TimeManager> mTimeManager;
nsWeakPtr mWindow;
nsCOMPtr<nsPIDOMWindow> mWindow;
};
} // namespace dom