mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1479034 - Make GeckoView's SessionAccessibility a JNIObject associated with a nsWindow. r=jchen
This commit is contained in:
parent
537fb3b46c
commit
0206ea9620
36
accessible/android/SessionAccessibility.cpp
Normal file
36
accessible/android/SessionAccessibility.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* 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/. */
|
||||
|
||||
#include "SessionAccessibility.h"
|
||||
#include "AndroidUiThread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <android/log.h>
|
||||
#define AALOG(args...) \
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoAccessibilityNative", ##args)
|
||||
#else
|
||||
#define AALOG(args...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
template<>
|
||||
const char nsWindow::NativePtr<mozilla::a11y::SessionAccessibility>::sName[] =
|
||||
"SessionAccessibility";
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
void
|
||||
SessionAccessibility::SetAttached(bool aAttached)
|
||||
{
|
||||
if (RefPtr<nsThread> uiThread = GetAndroidUiThread()) {
|
||||
uiThread->Dispatch(NS_NewRunnableFunction(
|
||||
"SessionAccessibility::Attach",
|
||||
[aAttached,
|
||||
sa = java::SessionAccessibility::NativeProvider::GlobalRef(
|
||||
mSessionAccessibility)] { sa->SetAttached(aAttached); }));
|
||||
}
|
||||
}
|
51
accessible/android/SessionAccessibility.h
Normal file
51
accessible/android/SessionAccessibility.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 mozilla_a11y_SessionAccessibility_h_
|
||||
#define mozilla_a11y_SessionAccessibility_h_
|
||||
|
||||
#include "GeneratedJNINatives.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class SessionAccessibility final
|
||||
: public java::SessionAccessibility::NativeProvider::Natives<SessionAccessibility>
|
||||
{
|
||||
public:
|
||||
typedef java::SessionAccessibility::NativeProvider::Natives<SessionAccessibility> Base;
|
||||
|
||||
SessionAccessibility(
|
||||
nsWindow::NativePtr<SessionAccessibility>* aPtr,
|
||||
nsWindow* aWindow,
|
||||
java::SessionAccessibility::NativeProvider::Param aSessionAccessibility)
|
||||
: mWindow(aPtr, aWindow)
|
||||
, mSessionAccessibility(aSessionAccessibility)
|
||||
{
|
||||
SetAttached(true);
|
||||
}
|
||||
|
||||
void OnDetach() { SetAttached(false); }
|
||||
|
||||
// Native implementations
|
||||
using Base::AttachNative;
|
||||
using Base::DisposeNative;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(SessionAccessibility)
|
||||
|
||||
private:
|
||||
~SessionAccessibility() {}
|
||||
|
||||
void SetAttached(bool aAttached);
|
||||
|
||||
nsWindow::WindowPtr<SessionAccessibility> mWindow; // Parent only
|
||||
java::SessionAccessibility::NativeProvider::GlobalRef mSessionAccessibility;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -6,11 +6,13 @@
|
||||
|
||||
EXPORTS.mozilla.a11y += ['AccessibleWrap.h',
|
||||
'HyperTextAccessibleWrap.h',
|
||||
'SessionAccessibility.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'AccessibleWrap.cpp',
|
||||
'Platform.cpp',
|
||||
'SessionAccessibility.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
@ -708,6 +708,7 @@ public final class GeckoSession extends LayerSession
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
public static native void open(Window instance, NativeQueue queue,
|
||||
Compositor compositor, EventDispatcher dispatcher,
|
||||
SessionAccessibility.NativeProvider sessionAccessibility,
|
||||
GeckoBundle initData, String id, String chromeUri,
|
||||
int screenId, boolean privateMode);
|
||||
|
||||
@ -756,6 +757,7 @@ public final class GeckoSession extends LayerSession
|
||||
public synchronized void transfer(final NativeQueue queue,
|
||||
final Compositor compositor,
|
||||
final EventDispatcher dispatcher,
|
||||
final SessionAccessibility.NativeProvider sessionAccessibility,
|
||||
final GeckoBundle initData) {
|
||||
if (mNativeQueue == null) {
|
||||
// Already closed.
|
||||
@ -763,13 +765,14 @@ public final class GeckoSession extends LayerSession
|
||||
}
|
||||
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
nativeTransfer(queue, compositor, dispatcher, initData);
|
||||
nativeTransfer(queue, compositor, dispatcher, sessionAccessibility, initData);
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
this, "nativeTransfer",
|
||||
NativeQueue.class, queue,
|
||||
Compositor.class, compositor,
|
||||
EventDispatcher.class, dispatcher,
|
||||
SessionAccessibility.NativeProvider.class, sessionAccessibility,
|
||||
GeckoBundle.class, initData);
|
||||
}
|
||||
|
||||
@ -783,12 +786,17 @@ public final class GeckoSession extends LayerSession
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy", stubName = "Transfer")
|
||||
private native void nativeTransfer(NativeQueue queue, Compositor compositor,
|
||||
EventDispatcher dispatcher, GeckoBundle initData);
|
||||
EventDispatcher dispatcher,
|
||||
SessionAccessibility.NativeProvider sessionAccessibility,
|
||||
GeckoBundle initData);
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
public native void attachEditable(IGeckoEditableParent parent,
|
||||
GeckoEditableChild child);
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
public native void attachAccessibility(SessionAccessibility.NativeProvider sessionAccessibility);
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
private synchronized void onReady(final @Nullable NativeQueue queue) {
|
||||
// onReady is called the first time the Gecko window is ready, with a null queue
|
||||
@ -876,7 +884,8 @@ public final class GeckoSession extends LayerSession
|
||||
|
||||
if (mWindow != null) {
|
||||
mWindow.transfer(mNativeQueue, mCompositor,
|
||||
mEventDispatcher, createInitData());
|
||||
mEventDispatcher, mAccessibility != null ? mAccessibility.nativeProvider : null,
|
||||
createInitData());
|
||||
|
||||
onWindowChanged(WINDOW_TRANSFER_IN, /* inProgress */ false);
|
||||
}
|
||||
@ -1003,6 +1012,7 @@ public final class GeckoSession extends LayerSession
|
||||
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
Window.open(mWindow, mNativeQueue, mCompositor, mEventDispatcher,
|
||||
mAccessibility != null ? mAccessibility.nativeProvider : null,
|
||||
createInitData(), mId, chromeUri, screenId, isPrivate);
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(
|
||||
@ -1012,6 +1022,8 @@ public final class GeckoSession extends LayerSession
|
||||
NativeQueue.class, mNativeQueue,
|
||||
Compositor.class, mCompositor,
|
||||
EventDispatcher.class, mEventDispatcher,
|
||||
SessionAccessibility.NativeProvider.class,
|
||||
mAccessibility != null ? mAccessibility.nativeProvider : null,
|
||||
GeckoBundle.class, createInitData(),
|
||||
String.class, mId,
|
||||
String.class, chromeUri,
|
||||
@ -1076,8 +1088,18 @@ public final class GeckoSession extends LayerSession
|
||||
* @return SessionAccessibility instance.
|
||||
*/
|
||||
public @NonNull SessionAccessibility getAccessibility() {
|
||||
if (mAccessibility == null) {
|
||||
mAccessibility = new SessionAccessibility(this);
|
||||
ThreadUtils.assertOnUiThread();
|
||||
if (mAccessibility != null) { return mAccessibility; }
|
||||
|
||||
mAccessibility = new SessionAccessibility(this);
|
||||
if (mWindow != null) {
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
mWindow.attachAccessibility(mAccessibility.nativeProvider);
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
mWindow, "attachAccessibility",
|
||||
SessionAccessibility.NativeProvider.class, mAccessibility.nativeProvider);
|
||||
}
|
||||
}
|
||||
return mAccessibility;
|
||||
}
|
||||
|
@ -5,12 +5,14 @@
|
||||
|
||||
package org.mozilla.geckoview;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.PrefsHelper;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.mozglue.JNIObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
@ -232,6 +234,8 @@ public class SessionAccessibility {
|
||||
/* package */ final GeckoSession mSession;
|
||||
// This is the view that delegates accessibility to us. We also sends event through it.
|
||||
private View mView;
|
||||
// The native portion of the node provider.
|
||||
/* package */ final NativeProvider nativeProvider = new NativeProvider();
|
||||
// Have we reached the last item in content?
|
||||
private boolean mLastItem;
|
||||
// Used to store the JSON message and populate the event later in the code path.
|
||||
@ -241,6 +245,8 @@ public class SessionAccessibility {
|
||||
private SparseArray<EventCallback> mAutoFillRoots;
|
||||
private int mAutoFillFocusedId = View.NO_ID;
|
||||
|
||||
private boolean mAttached = false;
|
||||
|
||||
/* package */ SessionAccessibility(final GeckoSession session) {
|
||||
mSession = session;
|
||||
|
||||
@ -803,4 +809,20 @@ public class SessionAccessibility {
|
||||
((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ final class NativeProvider extends JNIObject {
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void setAttached(final boolean attached) {
|
||||
if (attached) {
|
||||
mAttached = true;
|
||||
} else if (mAttached) {
|
||||
mAttached = false;
|
||||
disposeNative();
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
@Override
|
||||
protected native void disposeNative();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/WheelHandlingHelper.h" // for WheelDeltaAdjustmentStrategy
|
||||
|
||||
#include "mozilla/a11y/SessionAccessibility.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
@ -285,6 +286,7 @@ public:
|
||||
jni::Object::Param aQueue,
|
||||
jni::Object::Param aCompositor,
|
||||
jni::Object::Param aDispatcher,
|
||||
jni::Object::Param aSessionAccessibility,
|
||||
jni::Object::Param aInitData,
|
||||
jni::String::Param aId,
|
||||
jni::String::Param aChromeURI,
|
||||
@ -299,12 +301,16 @@ public:
|
||||
jni::Object::Param aQueue,
|
||||
jni::Object::Param aCompositor,
|
||||
jni::Object::Param aDispatcher,
|
||||
jni::Object::Param aSessionAccessibility,
|
||||
jni::Object::Param aInitData);
|
||||
|
||||
void AttachEditable(const GeckoSession::Window::LocalRef& inst,
|
||||
jni::Object::Param aEditableParent,
|
||||
jni::Object::Param aEditableChild);
|
||||
|
||||
void AttachAccessibility(const GeckoSession::Window::LocalRef& inst,
|
||||
jni::Object::Param aSessionAccessibility);
|
||||
|
||||
void OnReady(jni::Object::Param aQueue = nullptr);
|
||||
};
|
||||
|
||||
@ -1135,6 +1141,10 @@ nsWindow::GeckoViewSupport::~GeckoViewSupport()
|
||||
if (window.mLayerViewSupport) {
|
||||
window.mLayerViewSupport.Detach();
|
||||
}
|
||||
|
||||
if (window.mSessionAccessibility) {
|
||||
window.mSessionAccessibility.Detach();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@ -1143,6 +1153,7 @@ nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
|
||||
jni::Object::Param aQueue,
|
||||
jni::Object::Param aCompositor,
|
||||
jni::Object::Param aDispatcher,
|
||||
jni::Object::Param aSessionAccessibility,
|
||||
jni::Object::Param aInitData,
|
||||
jni::String::Param aId,
|
||||
jni::String::Param aChromeURI,
|
||||
@ -1198,7 +1209,7 @@ nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
|
||||
|
||||
// Attach other session support objects.
|
||||
window->mGeckoViewSupport->Transfer(
|
||||
sessionWindow, aQueue, aCompositor, aDispatcher, aInitData);
|
||||
sessionWindow, aQueue, aCompositor, aDispatcher, aSessionAccessibility, aInitData);
|
||||
|
||||
if (window->mWidgetListener) {
|
||||
nsCOMPtr<nsIXULWindow> xulWindow(
|
||||
@ -1232,6 +1243,7 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
|
||||
jni::Object::Param aQueue,
|
||||
jni::Object::Param aCompositor,
|
||||
jni::Object::Param aDispatcher,
|
||||
jni::Object::Param aSessionAccessibility,
|
||||
jni::Object::Param aInitData)
|
||||
{
|
||||
if (window.mNPZCSupport) {
|
||||
@ -1253,6 +1265,13 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
|
||||
window.mAndroidView->mEventDispatcher->Attach(
|
||||
java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
|
||||
|
||||
if (window.mSessionAccessibility) {
|
||||
window.mSessionAccessibility.Detach();
|
||||
}
|
||||
if (aSessionAccessibility) {
|
||||
AttachAccessibility(inst, aSessionAccessibility);
|
||||
}
|
||||
|
||||
if (mIsReady) {
|
||||
// We're in a transfer; update init-data and notify JS code.
|
||||
window.mAndroidView->mInitData =
|
||||
@ -1285,6 +1304,24 @@ nsWindow::GeckoViewSupport::AttachEditable(const GeckoSession::Window::LocalRef&
|
||||
window.mEditableParent = aEditableParent;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::GeckoViewSupport::AttachAccessibility(const GeckoSession::Window::LocalRef& inst,
|
||||
jni::Object::Param aSessionAccessibility)
|
||||
{
|
||||
MOZ_ASSERT(!window.mSessionAccessibility);
|
||||
java::SessionAccessibility::NativeProvider::LocalRef sessionAccessibility(
|
||||
inst.Env());
|
||||
sessionAccessibility = java::SessionAccessibility::NativeProvider::Ref::From(
|
||||
aSessionAccessibility);
|
||||
|
||||
if (window.mSessionAccessibility) {
|
||||
window.mSessionAccessibility.Detach();
|
||||
}
|
||||
|
||||
window.mSessionAccessibility.Attach(
|
||||
sessionAccessibility, &window, sessionAccessibility);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::InitNatives()
|
||||
{
|
||||
@ -1293,6 +1330,7 @@ nsWindow::InitNatives()
|
||||
nsWindow::NPZCSupport::Init();
|
||||
|
||||
GeckoEditableSupport::Init();
|
||||
a11y::SessionAccessibility::Init();
|
||||
}
|
||||
|
||||
nsWindow*
|
||||
@ -2342,4 +2380,3 @@ nsIWidget::CreateChildWindow()
|
||||
nsCOMPtr<nsIWidget> window = new nsWindow();
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,10 @@ namespace mozilla {
|
||||
namespace ipc {
|
||||
class Shmem;
|
||||
} // namespace ipc
|
||||
|
||||
namespace a11y {
|
||||
class SessionAccessibility;
|
||||
}
|
||||
}
|
||||
|
||||
class nsWindow final : public nsBaseWidget
|
||||
@ -186,6 +190,10 @@ private:
|
||||
NativePtr<mozilla::widget::GeckoEditableSupport> mEditableSupport;
|
||||
mozilla::jni::Object::GlobalRef mEditableParent;
|
||||
|
||||
// Object that implements native SessionAccessibility calls.
|
||||
// Strong referenced by the Java instance.
|
||||
NativePtr<mozilla::a11y::SessionAccessibility> mSessionAccessibility;
|
||||
|
||||
class GeckoViewSupport;
|
||||
// Object that implements native GeckoView calls and associated states.
|
||||
// nullptr for nsWindows that were not opened from GeckoView.
|
||||
@ -306,6 +314,8 @@ public:
|
||||
|
||||
mozilla::jni::Object::Ref& GetEditableParent() { return mEditableParent; }
|
||||
|
||||
mozilla::a11y::SessionAccessibility* GetSessionAccessibility() { return mSessionAccessibility; }
|
||||
|
||||
void RecvToolbarAnimatorMessageFromCompositor(int32_t aMessage) override;
|
||||
void UpdateRootFrameMetrics(const ScreenPoint& aScrollOffset, const CSSToScreenScale& aZoom) override;
|
||||
void RecvScreenPixels(mozilla::ipc::Shmem&& aMem, const ScreenIntSize& aSize) override;
|
||||
@ -353,6 +363,7 @@ private:
|
||||
// Explicit template declarations to make clang be quiet.
|
||||
template<> const char nsWindow::NativePtr<nsWindow::LayerViewSupport>::sName[];
|
||||
template<> const char nsWindow::NativePtr<mozilla::widget::GeckoEditableSupport>::sName[];
|
||||
template<> const char nsWindow::NativePtr<mozilla::a11y::SessionAccessibility>::sName[];
|
||||
template<> const char nsWindow::NativePtr<nsWindow::NPZCSupport>::sName[];
|
||||
|
||||
template<class Impl>
|
||||
|
Loading…
Reference in New Issue
Block a user