diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index 4eb9d39e4c5..0c7740c7ceb 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -512,9 +512,9 @@ AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertName, nsIPrincipal* aPrincipal) { - if (nsAppShell::gAppShell && aAlertListener) { + if (aAlertListener) { // This will remove any observers already registered for this id - nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener)); + nsAppShell::PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener)); } nsAutoString host; @@ -1706,15 +1706,17 @@ AndroidBridge::PumpMessageLoop() NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp) { - if (nsAppShell::gAppShell) - nsAppShell::gAppShell->GetBrowserApp(aBrowserApp); + nsAppShell* const appShell = nsAppShell::Get(); + if (appShell) + appShell->GetBrowserApp(aBrowserApp); return NS_OK; } NS_IMETHODIMP nsAndroidBridge::SetBrowserApp(nsIAndroidBrowserApp *aBrowserApp) { - if (nsAppShell::gAppShell) - nsAppShell::gAppShell->SetBrowserApp(aBrowserApp); + nsAppShell* const appShell = nsAppShell::Get(); + if (appShell) + appShell->SetBrowserApp(aBrowserApp); return NS_OK; } diff --git a/widget/android/AndroidContentController.cpp b/widget/android/AndroidContentController.cpp index 6840091567b..de90012f05c 100644 --- a/widget/android/AndroidContentController.cpp +++ b/widget/android/AndroidContentController.cpp @@ -77,7 +77,7 @@ AndroidContentController::HandleSingleTap(const CSSPoint& aPoint, CSSIntPoint rounded = RoundedToInt(point); nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", rounded.x, rounded.y); - nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( + nsAppShell::PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("Gesture:SingleTap"), data)); } diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index d128d2da23f..35e0b3f2c34 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -61,8 +61,7 @@ NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *jenv, jclass jc, jobject event) { // poke the appshell - if (nsAppShell::gAppShell) - nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeFromJavaObject(jenv, event)); + nsAppShell::PostEvent(AndroidGeckoEvent::MakeFromJavaObject(jenv, event)); } NS_EXPORT void JNICALL @@ -342,7 +341,7 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, MultiTouchInput input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow()); delete wrapper; - if (input.mType < 0 || !nsAppShell::gAppShell) { + if (input.mType < 0) { return false; } @@ -350,7 +349,7 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, uint64_t blockId; nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId); if (status != nsEventStatus_eConsumeNoDefault) { - nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeApzInputEvent(input, guid, blockId, status)); + nsAppShell::PostEvent(AndroidGeckoEvent::MakeApzInputEvent(input, guid, blockId, status)); } return true; } diff --git a/widget/android/PrefsHelper.h b/widget/android/PrefsHelper.h index 06ad8e7e3a5..020bf5588ac 100644 --- a/widget/android/PrefsHelper.h +++ b/widget/android/PrefsHelper.h @@ -26,7 +26,9 @@ struct PrefsHelper bool observe) { MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(nsAppShell::gAppShell); + + nsAppShell* const appShell = nsAppShell::Get(); + MOZ_ASSERT(appShell); nsTArray namesRefArray(prefNames.GetElements()); const size_t len = namesRefArray.Length(); @@ -48,7 +50,7 @@ struct PrefsHelper } nsIAndroidBrowserApp* browserApp = nullptr; - nsAppShell::gAppShell->GetBrowserApp(&browserApp); + appShell->GetBrowserApp(&browserApp); MOZ_ASSERT(browserApp); if (observe) { @@ -63,10 +65,12 @@ struct PrefsHelper static void RemovePrefsObserver(int32_t requestId) { MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(nsAppShell::gAppShell); + + nsAppShell* const appShell = nsAppShell::Get(); + MOZ_ASSERT(appShell); nsIAndroidBrowserApp* browserApp = nullptr; - nsAppShell::gAppShell->GetBrowserApp(&browserApp); + appShell->GetBrowserApp(&browserApp); MOZ_ASSERT(browserApp); browserApp->RemovePreferenceObservers(requestId); diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index 88dfeaa37a6..6798285f417 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -75,7 +75,8 @@ PRLogModuleInfo *gWidgetLog = nullptr; nsIGeolocationUpdate *gLocationCallback = nullptr; nsAutoPtr gLastSizeChange; -nsAppShell *nsAppShell::gAppShell = nullptr; +nsAppShell* nsAppShell::sAppShell; +StaticMutex nsAppShell::sAppShellLock; NS_IMPL_ISUPPORTS_INHERITED(nsAppShell, nsBaseAppShell, nsIObserver) @@ -185,7 +186,10 @@ public: nsAppShell::nsAppShell() { - gAppShell = this; + { + StaticMutexAutoLock lock(sAppShellLock); + sAppShell = this; + } if (!XRE_IsParentProcess()) { return; @@ -217,7 +221,10 @@ nsAppShell::~nsAppShell() NS_WARNING("Discarded event on shutdown"); } - gAppShell = nullptr; + { + StaticMutexAutoLock lock(sAppShellLock); + sAppShell = nullptr; + } if (sPowerManagerService) { sPowerManagerService->RemoveWakeLockListener(sWakeLockListener); @@ -398,7 +405,11 @@ public: void nsAppShell::PostEvent(AndroidGeckoEvent* event) { - mEventQueue.Post(mozilla::MakeUnique(event)); + mozilla::StaticMutexAutoLock lock(sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(mozilla::MakeUnique(event)); } void @@ -410,7 +421,7 @@ nsAppShell::LegacyGeckoEvent::Run() switch (curEvent->Type()) { case AndroidGeckoEvent::NATIVE_POKE: - nsAppShell::gAppShell->NativeEventCallback(); + nsAppShell::Get()->NativeEventCallback(); break; case AndroidGeckoEvent::SENSOR_EVENT: { @@ -519,19 +530,19 @@ nsAppShell::LegacyGeckoEvent::Run() } case AndroidGeckoEvent::THUMBNAIL: { - if (!nsAppShell::gAppShell->mBrowserApp) + if (!nsAppShell::Get()->mBrowserApp) break; int32_t tabId = curEvent->MetaState(); const nsTArray& points = curEvent->Points(); RefCountedJavaObject* buffer = curEvent->ByteBuffer(); - RefPtr sr = new ThumbnailRunnable(nsAppShell::gAppShell->mBrowserApp, tabId, points, buffer); + RefPtr sr = new ThumbnailRunnable(nsAppShell::Get()->mBrowserApp, tabId, points, buffer); MessageLoop::current()->PostIdleTask(FROM_HERE, NewRunnableMethod(sr.get(), &ThumbnailRunnable::Run)); break; } case AndroidGeckoEvent::ZOOMEDVIEW: { - if (!nsAppShell::gAppShell->mBrowserApp) + if (!nsAppShell::Get()->mBrowserApp) break; int32_t tabId = curEvent->MetaState(); const nsTArray& points = curEvent->Points(); @@ -541,7 +552,7 @@ nsAppShell::LegacyGeckoEvent::Run() nsCOMPtr domWindow; nsCOMPtr tab; - nsAppShell::gAppShell->mBrowserApp->GetBrowserTab(tabId, getter_AddRefs(tab)); + nsAppShell::Get()->mBrowserApp->GetBrowserTab(tabId, getter_AddRefs(tab)); if (!tab) { NS_ERROR("Can't find tab!"); break; @@ -577,7 +588,7 @@ nsAppShell::LegacyGeckoEvent::Run() break; nsCOMPtr obs; - nsAppShell::gAppShell->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); + nsAppShell::Get()->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); if (!obs) break; @@ -594,7 +605,7 @@ nsAppShell::LegacyGeckoEvent::Run() break; nsCOMPtr obs; - nsAppShell::gAppShell->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); + nsAppShell::Get()->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); if (!obs) break; @@ -610,7 +621,7 @@ nsAppShell::LegacyGeckoEvent::Run() break; nsCOMPtr obs; - nsAppShell::gAppShell->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); + nsAppShell::Get()->mBrowserApp->GetUITelemetryObserver(getter_AddRefs(obs)); if (!obs) break; @@ -713,7 +724,7 @@ nsAppShell::LegacyGeckoEvent::Run() case AndroidGeckoEvent::CALL_OBSERVER: { nsCOMPtr observer; - nsAppShell::gAppShell->mObserversHash.Get(curEvent->Characters(), getter_AddRefs(observer)); + nsAppShell::Get()->mObserversHash.Get(curEvent->Characters(), getter_AddRefs(observer)); if (observer) { observer->Observe(nullptr, NS_ConvertUTF16toUTF8(curEvent->CharactersExtra()).get(), @@ -726,11 +737,11 @@ nsAppShell::LegacyGeckoEvent::Run() } case AndroidGeckoEvent::REMOVE_OBSERVER: - nsAppShell::gAppShell->mObserversHash.Remove(curEvent->Characters()); + nsAppShell::Get()->mObserversHash.Remove(curEvent->Characters()); break; case AndroidGeckoEvent::ADD_OBSERVER: - nsAppShell::gAppShell->AddObserver(curEvent->Characters(), curEvent->Observer()); + nsAppShell::Get()->AddObserver(curEvent->Characters(), curEvent->Observer()); break; case AndroidGeckoEvent::LOW_MEMORY: @@ -850,7 +861,7 @@ nsAppShell::LegacyGeckoEvent::PostTo(mozilla::LinkedList& queue) case AndroidGeckoEvent::MOTION_EVENT: case AndroidGeckoEvent::APZ_INPUT_EVENT: - if (nsAppShell::gAppShell->mAllowCoalescingTouches) { + if (sAppShell->mAllowCoalescingTouches) { Event* const event = queue.getLast(); if (event && event->HasSameTypeAs(this) && ae->CanCoalesceWith( static_cast(event)->ae.get())) { @@ -891,18 +902,21 @@ namespace mozilla { bool ProcessNextEvent() { - if (!nsAppShell::gAppShell) { + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { return false; } - return nsAppShell::gAppShell->ProcessNextNativeEvent(true) ? true : false; + return appShell->ProcessNextNativeEvent(true) ? true : false; } void NotifyEvent() { - if (nsAppShell::gAppShell) { - nsAppShell::gAppShell->NotifyNativeEvent(); + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return; } + appShell->NotifyNativeEvent(); } } diff --git a/widget/android/nsAppShell.h b/widget/android/nsAppShell.h index 02377ff9e8f..b7472014ff5 100644 --- a/widget/android/nsAppShell.h +++ b/widget/android/nsAppShell.h @@ -10,6 +10,7 @@ #include "mozilla/LinkedList.h" #include "mozilla/Monitor.h" #include "mozilla/Move.h" +#include "mozilla/StaticMutex.h" #include "mozilla/UniquePtr.h" #include "mozilla/unused.h" #include "mozilla/jni/Natives.h" @@ -69,7 +70,11 @@ public: void Run() override { return lambda(); } }; - static nsAppShell *gAppShell; + static nsAppShell* Get() + { + MOZ_ASSERT(NS_IsMainThread()); + return sAppShell; + } nsAppShell(); @@ -84,26 +89,32 @@ public: // Post a subclass of Event. // e.g. PostEvent(mozilla::MakeUnique()); template - void PostEvent(mozilla::UniquePtr&& event) + static void PostEvent(mozilla::UniquePtr&& event) { - mEventQueue.Post(mozilla::Move(event)); + mozilla::StaticMutexAutoLock lock(sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(mozilla::Move(event)); } // Post a event that will call a lambda // e.g. PostEvent([=] { /* do something */ }); template - void PostEvent(T&& lambda) + static void PostEvent(T&& lambda) { - mEventQueue.Post(mozilla::MakeUnique>( + mozilla::StaticMutexAutoLock lock(sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(mozilla::MakeUnique>( mozilla::Move(lambda))); } - void PostEvent(mozilla::AndroidGeckoEvent* event); + static void PostEvent(mozilla::AndroidGeckoEvent* event); void ResendLastResizeEvent(nsWindow* aDest); - void OnResume() {} - void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) { mBrowserApp = aBrowserApp; } @@ -113,6 +124,9 @@ public: } protected: + static nsAppShell* sAppShell; + static mozilla::StaticMutex sAppShellLock; + virtual ~nsAppShell(); nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver); @@ -190,7 +204,7 @@ public: template static void OnNativeCall(Functor&& call) { - nsAppShell::gAppShell->PostEvent(mozilla::Move(call)); + nsAppShell::PostEvent(mozilla::Move(call)); } }; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 9f3180b6976..a9cdfb1488c 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -230,7 +230,7 @@ public: // can get a head start on opening our window. return aCall(); } - return nsAppShell::gAppShell->PostEvent(mozilla::MakeUnique< + return nsAppShell::PostEvent(mozilla::MakeUnique< WindowEvent>(mozilla::Move(aCall))); } @@ -432,7 +432,7 @@ class nsWindow::GLControllerSupport final finished = true; lock.NotifyAll(); }; - nsAppShell::gAppShell->PostEvent( + nsAppShell::PostEvent( mozilla::MakeUnique( new nsAppShell::LambdaEvent( mozilla::Move(callAndNotify)))); @@ -473,7 +473,7 @@ public: return aCall(); } - nsAppShell::gAppShell->PostEvent( + nsAppShell::PostEvent( mozilla::MakeUnique( new GeckoViewSupport::WindowEvent( mozilla::Move(aCall)))); @@ -491,7 +491,7 @@ public: ~GLControllerSupport() { GLController::GlobalRef glController(mozilla::Move(mGLController)); - nsAppShell::gAppShell->PostEvent([glController] { + nsAppShell::PostEvent([glController] { GLControllerSupport::DisposeNative(GLController::LocalRef( jni::GetGeckoThreadEnv(), glController)); }); @@ -1220,7 +1220,7 @@ nsWindow::BringToFront() } // force a window resize - nsAppShell::gAppShell->ResendLastResizeEvent(newTop); + nsAppShell::Get()->ResendLastResizeEvent(newTop); RedrawAll(); } @@ -2289,7 +2289,7 @@ nsWindow::GeckoViewSupport::PostFlushIMEChanges(FlushChangesFlag aFlags) // Keep a strong reference to the window to keep 'this' alive. RefPtr window(&this->window); - nsAppShell::gAppShell->PostEvent([this, window, aFlags] { + nsAppShell::PostEvent([this, window, aFlags] { if (!window->Destroyed()) { FlushIMEChanges(aFlags); } @@ -2501,7 +2501,7 @@ nsWindow::GeckoViewSupport::SetInputContext(const InputContext& aContext, RefPtr window(&this->window); mIMEUpdatingContext = true; - nsAppShell::gAppShell->PostEvent([this, window] { + nsAppShell::PostEvent([this, window] { mIMEUpdatingContext = false; if (window->Destroyed()) { return;