From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- widget/android/nsAppShell.h | 223 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 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 000000000..42453999d --- /dev/null +++ b/widget/android/nsAppShell.h @@ -0,0 +1,223 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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 "mozilla/HangMonitor.h" +#include "mozilla/LinkedList.h" +#include "mozilla/Monitor.h" +#include "mozilla/Move.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" +#include "mozilla/jni/Natives.h" +#include "nsBaseAppShell.h" +#include "nsCOMPtr.h" +#include "nsTArray.h" +#include "nsInterfaceHashtable.h" +#include "nsIAndroidBridge.h" + +namespace mozilla { +bool ProcessNextEvent(); +void NotifyEvent(); +} + +class nsWindow; + +class nsAppShell : + public nsBaseAppShell +{ +public: + struct Event : mozilla::LinkedListElement + { + typedef mozilla::HangMonitor::ActivityType Type; + + 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 Type ActivityType() const + { + return Type::kGeneralActivity; + } + }; + + template + class LambdaEvent : public Event + { + protected: + T lambda; + + public: + LambdaEvent(T&& l) : lambda(mozilla::Move(l)) {} + void Run() override { return lambda(); } + }; + + class ProxyEvent : public Event + { + protected: + mozilla::UniquePtr baseEvent; + + public: + ProxyEvent(mozilla::UniquePtr&& event) + : baseEvent(mozilla::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(mozilla::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>( + mozilla::Move(lambda))); + } + + // Post a event and wait for it to finish running on the Gecko thread. + static void SyncRunEvent(Event&& event, + mozilla::UniquePtr(*eventFactory)( + mozilla::UniquePtr&&) = nullptr); + + static already_AddRefed ResolveURI(const nsCString& aUriStr); + + void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) { + mBrowserApp = aBrowserApp; + } + + nsIAndroidBrowserApp* GetBrowserApp() { + return mBrowserApp; + } + +protected: + static nsAppShell* sAppShell; + static mozilla::StaticAutoPtr sAppShellLock; + + virtual ~nsAppShell(); + + nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver); + + class NativeCallbackEvent : public Event + { + // Capturing the nsAppShell instance is safe because if the app + // shell is detroyed, this lambda will not be called either. + nsAppShell* const appShell; + + public: + NativeCallbackEvent(nsAppShell* as) : appShell(as) {} + void Run() override { appShell->NativeEventCallback(); } + }; + + void ScheduleNativeEventCallback() override + { + mEventQueue.Post(mozilla::MakeUnique(this)); + } + + class Queue + { + private: + mozilla::Monitor mMonitor; + mozilla::LinkedList mQueue; + + public: + 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()) { + // 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. + return mozilla::UniquePtr(mQueue.popFirst()); + } + + } mEventQueue; + + mozilla::CondVar mSyncRunFinished; + bool mSyncRunQuit; + + bool mAllowCoalescingTouches; + + nsCOMPtr mBrowserApp; + nsInterfaceHashtable mObserversHash; +}; + +#endif // nsAppShell_h__ + -- cgit v1.2.3