From 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:47:29 +0200 Subject: Adding upstream version 115.8.0esr. Signed-off-by: Daniel Baumann --- widget/android/nsAppShell.h | 217 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 widget/android/nsAppShell.h (limited to 'widget/android/nsAppShell.h') diff --git a/widget/android/nsAppShell.h b/widget/android/nsAppShell.h new file mode 100644 index 0000000000..9b1dc5ca14 --- /dev/null +++ b/widget/android/nsAppShell.h @@ -0,0 +1,217 @@ +/* -*- Mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* 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/. */ + +#ifndef nsAppShell_h__ +#define nsAppShell_h__ + +#include + +#include +#include + +#include "mozilla/BackgroundHangMonitor.h" +#include "mozilla/LinkedList.h" +#include "mozilla/Monitor.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/TimeStamp.h" // for mozilla::TimeDuration +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" +#include "mozilla/jni/Natives.h" +#include "nsBaseAppShell.h" +#include "nsCOMPtr.h" +#include "nsIAndroidBridge.h" +#include "nsInterfaceHashtable.h" +#include "nsTArray.h" + +namespace mozilla { +bool ProcessNextEvent(); +void NotifyEvent(); +} // namespace mozilla + +class nsWindow; + +class nsAppShell : public nsBaseAppShell { + public: + struct Event : mozilla::LinkedListElement { + static uint64_t GetTime() { + timespec time; + if (clock_gettime(CLOCK_MONOTONIC, &time)) { + return 0ull; + } + return uint64_t(time.tv_sec) * 1000000000ull + time.tv_nsec; + } + + uint64_t mPostTime{0}; + + bool HasSameTypeAs(const Event* other) const { + // Compare vtable addresses to determine same type. + return *reinterpret_cast(this) == + *reinterpret_cast(other); + } + + virtual ~Event() {} + virtual void Run() = 0; + + virtual void PostTo(mozilla::LinkedList& queue) { + queue.insertBack(this); + } + + virtual bool IsUIEvent() const { return false; } + }; + + template + class LambdaEvent : public Event { + protected: + T lambda; + + public: + explicit LambdaEvent(T&& l) : lambda(std::move(l)) {} + void Run() override { lambda(); } + }; + + class ProxyEvent : public Event { + protected: + mozilla::UniquePtr baseEvent; + + public: + explicit ProxyEvent(mozilla::UniquePtr&& event) + : baseEvent(std::move(event)) {} + + void PostTo(mozilla::LinkedList& queue) override { + baseEvent->PostTo(queue); + } + + void Run() override { baseEvent->Run(); } + }; + + static nsAppShell* Get() { + MOZ_ASSERT(NS_IsMainThread()); + return sAppShell; + } + + nsAppShell(); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIOBSERVER + + nsresult Init(); + + void NotifyNativeEvent(); + bool ProcessNextNativeEvent(bool mayWait) override; + + // Post a subclass of Event. + // e.g. PostEvent(mozilla::MakeUnique()); + template + static void PostEvent(mozilla::UniquePtr&& event) { + mozilla::MutexAutoLock lock(*sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(std::move(event)); + } + + // Post a event that will call a lambda + // e.g. PostEvent([=] { /* do something */ }); + template + static void PostEvent(T&& lambda) { + mozilla::MutexAutoLock lock(*sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post( + mozilla::MakeUnique>(std::move(lambda))); + } + + // Post a event and wait for it to finish running on the Gecko thread. + static bool SyncRunEvent( + Event&& event, + mozilla::UniquePtr (*eventFactory)(mozilla::UniquePtr&&) = + nullptr, + const mozilla::TimeDuration timeout = mozilla::TimeDuration::Forever()); + + template + static std::enable_if_t::value, void> SyncRunEvent( + T&& lambda) { + SyncRunEvent(LambdaEvent(std::forward(lambda))); + } + + static already_AddRefed ResolveURI(const nsCString& aUriStr); + + protected: + static nsAppShell* sAppShell; + static mozilla::StaticAutoPtr sAppShellLock; + + virtual ~nsAppShell(); + + NS_IMETHOD Exit() override; + nsresult AddObserver(const nsAString& aObserverKey, nsIObserver* aObserver); + + class NativeCallbackEvent : public Event { + // Capturing the nsAppShell instance is safe because if the app + // shell is destroyed, this lambda will not be called either. + nsAppShell* const appShell; + + public: + explicit NativeCallbackEvent(nsAppShell* as) : appShell(as) {} + void Run() override { appShell->NativeEventCallback(); } + }; + + void ScheduleNativeEventCallback() override { + mEventQueue.Post(mozilla::MakeUnique(this)); + } + + class Queue { + private: + mozilla::Monitor mMonitor MOZ_UNANNOTATED; + mozilla::LinkedList mQueue; + + public: + enum { LATENCY_UI, LATENCY_OTHER, LATENCY_COUNT }; + Queue() : mMonitor("nsAppShell.Queue") {} + + void Signal() { + mozilla::MonitorAutoLock lock(mMonitor); + lock.NotifyAll(); + } + + void Post(mozilla::UniquePtr&& event) { + MOZ_ASSERT(event && !event->isInList()); + + mozilla::MonitorAutoLock lock(mMonitor); + event->PostTo(mQueue); + if (event->isInList()) { + event->mPostTime = Event::GetTime(); + // Ownership of event object transfers to the queue. + mozilla::Unused << event.release(); + } + lock.NotifyAll(); + } + + mozilla::UniquePtr Pop(bool mayWait) { + mozilla::MonitorAutoLock lock(mMonitor); + + if (mayWait && mQueue.isEmpty()) { + lock.Wait(); + } + + // Ownership of event object transfers to the return value. + mozilla::UniquePtr event(mQueue.popFirst()); + if (!event || !event->mPostTime) { + return event; + } + + return event; + } + + } mEventQueue; + + private: + mozilla::CondVar mSyncRunFinished; + bool mSyncRunQuit; + + nsInterfaceHashtable mObserversHash; +}; + +#endif // nsAppShell_h__ -- cgit v1.2.3