This checkin enables the StartDocumentLoadEvent. Now adding the rest of

the DocumentLoadListener events will be trivial.

Next step: flesh out the rest of the DocumentLoadListener events.
Modify NavigationTest so that it does its selection checking inside the
listeners.  This will probably require creating a Thread, managed by
EventRegistrationImpl, that is used to process callbacks from mozilla
into Java, so that we don't get deadlock.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java

- remove all dependencies on NativeEventThread

- introduce dependency on BrowserControlCanvas (needed for future
  MouseListener) work.

- {add,remove}DocumentLoadListener() now just a matter of
  adding/removing to List.

- add nativeEventOccurred() method, called from native code

M classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java

- remove dependency on BrowserControlCanvas

- removed nativeEventOccurred

M src_moz/EmbedProgress.cpp

- delete the global ref in the dtor.

- create the global ref in SetEventRegistration().

- call back to Java on startDocumentLoad.

M src_moz/NativeBrowserControl.cpp

- initialize our string constants.

M src_share/jni_util.cpp
M src_share/jni_util.h

- alter the signature of util_SendEventToJava

-void util_SendEventToJava(JNIEnv *yourEnv, jobject nativeEventThread,
-                          jobject webclientEventListener,
+void util_SendEventToJava(JNIEnv *yourEnv, jobject eventRegistrationImpl,
                           jstring eventListenerClassName,
                           jlong eventType, jobject eventData)

M test/automated/src/classes/org/mozilla/webclient/NavigationTest.java

- show that the DocumentLoadListener gets called.
This commit is contained in:
edburns%acm.org 2004-06-12 05:46:48 +00:00
Родитель 40f1f802ce
Коммит 21c5637b7d
8 изменённых файлов: 126 добавлений и 156 удалений

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/*
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@ -27,7 +27,12 @@ import org.mozilla.util.Assert;
import org.mozilla.util.Log;
import org.mozilla.util.ParameterCheck;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.EventRegistration2;
import org.mozilla.webclient.impl.WrapperFactory;
import org.mozilla.webclient.DocumentLoadEvent;
@ -57,19 +62,9 @@ public class EventRegistrationImpl extends ImplObjectNative implements EventRegi
// Relationship Instance Variables
/**
private BrowserControlCanvas browserControlCanvas = null;
* the Java thread for processing events, owned by WrapperFactoryImpl
*/
// PENDING: Currently we rely on NativeEventThread logic to maintain the
// list of listeners to add and to add them in a threadsafe manner. In
// webclient 2.0, we're going to maintain the list of listeners ourself,
// in this class, and use the Runnable trick to make sure they get added
// on the right thread.
private NativeEventThread nativeEventThread = null;
private List documentLoadListeners;
//
// Constructors and Initializers
@ -80,14 +75,19 @@ public EventRegistrationImpl(WrapperFactory yourFactory,
{
super(yourFactory, yourBrowserControl);
// pull out the NativeEventThread from the WrapperFactory
nativeEventThread = NativeEventThread.instance;
try {
browserControlCanvas = (BrowserControlCanvas)
yourBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
}
catch (ClassNotFoundException e) {
throw new RuntimeException("EventRegistrationImpl: Can't obtain reference to BrowserControlCanvas");
}
documentLoadListeners = new ArrayList();
}
public void delete()
{
nativeEventThread = null;
super.delete();
}
@ -103,31 +103,13 @@ public void delete()
// Methods from EventRegistration
//
/**
* We create a WCEventListenerWrapper containing the user passed
* DocumentLoadListener, and the string obtained from
* DocumentLoadListener.class.getName();
*/
public void addDocumentLoadListener(DocumentLoadListener listener)
{
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
WCEventListenerWrapper listenerWrapper =
new WCEventListenerWrapper(listener,
DocumentLoadListener.class.getName());
if (null == listenerWrapper) {
throw new NullPointerException("Can't instantiate WCEventListenerWrapper, out of memory.");
}
synchronized(getBrowserControl()) {
// PENDING nativeEventThread.addListener(listenerWrapper);
synchronized(documentLoadListeners) {
documentLoadListeners.add(listener);
}
}
@ -135,19 +117,9 @@ public void removeDocumentLoadListener(DocumentLoadListener listener)
{
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
WCEventListenerWrapper listenerWrapper =
new WCEventListenerWrapper(listener,
DocumentLoadListener.class.getName());
if (null == listenerWrapper) {
throw new NullPointerException("Can't instantiate WCEventListenerWrapper, out of memory.");
}
synchronized(getBrowserControl()) {
// PENDING nativeEventThread.removeListener(listenerWrapper);
synchronized(documentLoadListeners) {
documentLoadListeners.remove(listener);
}
}
@ -156,7 +128,6 @@ public void addMouseListener(MouseListener listener)
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
// We have to wrap the user provided java.awt.event.MouseListener
@ -189,7 +160,6 @@ public void removeMouseListener(MouseListener listener)
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
WCMouseListenerImpl mouseListenerWrapper =
@ -217,7 +187,6 @@ public void addNewWindowListener(NewWindowListener listener)
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
WCEventListenerWrapper listenerWrapper =
@ -237,7 +206,6 @@ public void removeNewWindowListener(NewWindowListener listener)
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
Assert.assert_it(-1 != getNativeBrowserControl());
Assert.assert_it(null != nativeEventThread);
ParameterCheck.nonNull(listener);
WCEventListenerWrapper listenerWrapper =
@ -252,36 +220,51 @@ public void removeNewWindowListener(NewWindowListener listener)
}
}
/**
// ----VERTIGO_TEST_START
* This method is called from native code when an event occurrs. This
* method relies on the fact that all events types that the client can
* observe descend from WebclientEventListener. I use instanceOf to
* determine what kind of WebclientEvent subclass to create.
//
// Test methods
//
*/
public static void main(String [] args)
void nativeEventOccurred(String targetClassName, long eventType,
Object eventData)
{
Assert.setEnabled(true);
ParameterCheck.nonNull(targetClassName);
Log.setApplicationName("EventRegistrationImpl");
Log.setApplicationVersion("0.0");
Log.setApplicationVersionDate("$Id: EventRegistrationImpl.java,v 1.5 2004-04-17 21:25:11 edburns%acm.org Exp $");
WebclientEvent event = null;
WebclientEventListener curListener = null;
List listeners = null;
try {
org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]);
org.mozilla.webclient.BrowserControl control =
org.mozilla.webclient.BrowserControlFactory.newBrowserControl();
Assert.assert_it(control != null);
EventRegistration2 wc = (EventRegistration2)
control.queryInterface(org.mozilla.webclient.BrowserControl.WINDOW_CONTROL_NAME);
Assert.assert_it(wc != null);
if (DocumentLoadListener.class.getName().equals(targetClassName)) {
event = new DocumentLoadEvent(this, eventType, eventData);
listeners = documentLoadListeners;
}
catch (Exception e) {
System.out.println("got exception: " + e.getMessage());
else if (MouseListener.class.getName().equals(targetClassName)) {
// We create a plain vanilla WebclientEvent, which the
// WCMouseListenerImpl target knows how to deal with.
// Also, the source happens to be the browserControlCanvas
// to satisfy the java.awt.event.MouseEvent's requirement
// that the source be a java.awt.Component subclass.
event = new WebclientEvent(browserControlCanvas, eventType, eventData);
}
else if (NewWindowListener.class.getName().equals(targetClassName)) {
event = new NewWindowEvent(this, eventType, eventData);
}
// else...
if (null != event && null != listeners) {
Iterator iter = listeners.iterator();
while (iter.hasNext()) {
curListener = (WebclientEventListener) iter.next();
curListener.eventDispatched(event);
}
}
}
// ----VERTIGO_TEST_END
} // end of class EventRegistrationImpl

Просмотреть файл

@ -33,14 +33,6 @@ import java.util.Enumeration;
import java.util.Stack;
import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.DocumentLoadEvent;
import org.mozilla.webclient.DocumentLoadListener;
import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.NewWindowListener;
import java.awt.event.MouseListener;
import org.mozilla.webclient.WebclientEvent;
import org.mozilla.webclient.WebclientEventListener;
import org.mozilla.webclient.UnimplementedException;
import org.mozilla.webclient.impl.WrapperFactory;
@ -74,8 +66,6 @@ public class NativeEventThread extends Thread {
private WrapperFactory wrapperFactory;
private int nativeWrapperFactory;
private BrowserControlCanvas browserControlCanvas;
private Stack blockingRunnables;
private Stack runnables;
@ -260,51 +250,6 @@ public void run()
return result;
}
/**
* This method is called from native code when an event occurrs. This
* method relies on the fact that all events types that the client can
* observe descend from WebclientEventListener. I use instanceOf to
* determine what kind of WebclientEvent subclass to create.
*/
void nativeEventOccurred(WebclientEventListener target,
String targetClassName, long eventType,
Object eventData)
{
ParameterCheck.nonNull(target);
ParameterCheck.nonNull(targetClassName);
Assert.assert_it(-1 != nativeWrapperFactory);
WebclientEvent event = null;
if (DocumentLoadListener.class.getName().equals(targetClassName)) {
event = new DocumentLoadEvent(this, eventType, eventData);
}
else if (MouseListener.class.getName().equals(targetClassName)) {
Assert.assert_it(target instanceof WCMouseListenerImpl);
// We create a plain vanilla WebclientEvent, which the
// WCMouseListenerImpl target knows how to deal with.
// Also, the source happens to be the browserControlCanvas
// to satisfy the java.awt.event.MouseEvent's requirement
// that the source be a java.awt.Component subclass.
event = new WebclientEvent(browserControlCanvas, eventType, eventData);
}
else if (NewWindowListener.class.getName().equals(targetClassName)) {
event = new NewWindowEvent(this, eventType, eventData);
}
// else...
// PENDING(edburns): maybe we need to put this in some sort of
// event queue?
target.eventDispatched(event);
}
//
// Native methods
//

Просмотреть файл

@ -36,10 +36,17 @@
EmbedProgress::EmbedProgress(void)
{
mOwner = nsnull;
mEventRegistration = nsnull;
}
EmbedProgress::~EmbedProgress()
{
if (nsnull != mEventRegistration) {
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
::util_DeleteGlobalRef(env, mEventRegistration);
mEventRegistration = nsnull;
}
}
NS_IMPL_ISUPPORTS2(EmbedProgress,
@ -63,8 +70,16 @@ EmbedProgress::Init(NativeBrowserControl *aOwner)
nsresult
EmbedProgress::SetEventRegistration(jobject yourEventRegistration)
{
mEventRegistration = yourEventRegistration;
return NS_OK;
nsresult rv = NS_OK;
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
mEventRegistration = ::util_NewGlobalRef(env, yourEventRegistration);
if (nsnull == mEventRegistration) {
::util_ThrowExceptionToJava(env, "Exception: EmbedProgress->SetEventRegistration(): can't create NewGlobalRef\n\tfor eventRegistration");
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
@ -73,18 +88,20 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
PRUint32 aStateFlags,
nsresult aStatus)
{
// get the uri for this request
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
nsString tmpString;
tmpString.AssignWithConversion(uriString);
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: URI: %s\n",
(const char *) uriString));
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
jstring uriJstr = ::util_NewStringUTF(env, (const char *) uriString);
nsString tmpString;
tmpString.AssignWithConversion(uriString);
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: URI: %s\n",
(const char *) uriString));
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, ("debug: edburns: EmbedProgress::OnStateChange: interpreting flags\n"));
if (aStateFlags & STATE_IS_REQUEST) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, ("debug: edburns: EmbedProgress::OnStateChange: STATE_IS_REQUEST\n"));
}
@ -97,7 +114,7 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
if (aStateFlags & STATE_IS_WINDOW) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, ("debug: edburns: EmbedProgress::OnStateChange: STATE_IS_WINDOW\n"));
}
if (aStateFlags & STATE_START) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, ("debug: edburns: EmbedProgress::OnStateChange: STATE_START\n"));
}
@ -122,6 +139,12 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
if ((aStateFlags & STATE_IS_NETWORK) &&
(aStateFlags & STATE_START))
{
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[START_DOCUMENT_LOAD_EVENT_MASK],
uriJstr);
// gtk_signal_emit(GTK_OBJECT(mOwner->mOwningWidget),
// moz_embed_signals[NET_START]);
}
@ -152,6 +175,8 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
*********/
}
::util_DeleteStringUTF(env, uriJstr);
return NS_OK;
}

Просмотреть файл

@ -62,6 +62,10 @@ nsresult
NativeBrowserControl::Init()
{
if (!util_StringConstantsAreInitialized()) {
util_InitStringConstants();
}
// Create our embed window, and create an owning reference to it and
// initialize it. It is assumed that this window will be destroyed
// when we go out of scope.

Просмотреть файл

@ -338,15 +338,14 @@ void util_ThrowExceptionToJava (JNIEnv * env, const char * message)
}
} // ThrowExceptionToJava()
void util_SendEventToJava(JNIEnv *yourEnv, jobject nativeEventThread,
jobject webclientEventListener,
void util_SendEventToJava(JNIEnv *yourEnv, jobject eventRegistrationImpl,
jstring eventListenerClassName,
jlong eventType, jobject eventData)
{
#ifdef BAL_INTERFACE
if (nsnull != externalEventOccurred) {
externalEventOccurred(yourEnv, nativeEventThread,
webclientEventListener, eventType, eventData);
externalEventOccurred(yourEnv, eventRegistrationImpl,
eventType, eventData);
}
#else
if (nsnull == gVm) {
@ -365,11 +364,11 @@ void util_SendEventToJava(JNIEnv *yourEnv, jobject nativeEventThread,
env->ExceptionDescribe();
}
jclass clazz = env->GetObjectClass(nativeEventThread);
jclass clazz = env->GetObjectClass(eventRegistrationImpl);
jmethodID mid = env->GetMethodID(clazz, "nativeEventOccurred",
"(Lorg/mozilla/webclient/WebclientEventListener;Ljava/lang/String;JLjava/lang/Object;)V");
"(Ljava/lang/String;JLjava/lang/Object;)V");
if ( mid != nsnull) {
env->CallVoidMethod(nativeEventThread, mid, webclientEventListener,
env->CallVoidMethod(eventRegistrationImpl, mid,
eventListenerClassName,
eventType, eventData);
} else {

Просмотреть файл

@ -241,7 +241,6 @@ void util_ThrowExceptionToJava (JNIEnv * env, const char * message);
*/
void util_SendEventToJava(JNIEnv *env, jobject eventRegistrationImpl,
jobject webclientEventListener,
jstring eventListenerClassName,
jlong eventType,
jobject eventData);

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: NavigationTest.java,v 1.9 2004-06-10 16:30:00 edburns%acm.org Exp $
* $Id: NavigationTest.java,v 1.10 2004-06-12 05:46:48 edburns%acm.org Exp $
*/
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
@ -65,6 +65,9 @@ public class NavigationTest extends WebclientTestCase {
assertNotNull(firstBrowserControl);
BrowserControlCanvas canvas = (BrowserControlCanvas)
firstBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
final EventRegistration2 eventRegistration = (EventRegistration2)
firstBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
assertNotNull(canvas);
Frame frame = new Frame();
frame.setUndecorated(true);
@ -76,7 +79,7 @@ public class NavigationTest extends WebclientTestCase {
Navigation2 nav = (Navigation2)
firstBrowserControl.queryInterface(BrowserControl.NAVIGATION_NAME);
assertNotNull(nav);
CurrentPage2 currentPage = (CurrentPage2)
final CurrentPage2 currentPage = (CurrentPage2)
firstBrowserControl.queryInterface(BrowserControl.CURRENT_PAGE_NAME);
assertNotNull(currentPage);
@ -88,6 +91,18 @@ public class NavigationTest extends WebclientTestCase {
// try loading a file: url
//
System.out.println("Loading url: " + testPage.toURL().toString());
eventRegistration.addDocumentLoadListener(new DocumentLoadListener() {
public void eventDispatched(WebclientEvent event) {
if (event instanceof DocumentLoadEvent) {
switch ((int) event.getType()) {
case ((int) DocumentLoadEvent.START_DOCUMENT_LOAD_EVENT_MASK):
System.out.println("Start Document Load Event:" +
event.getEventData());
break;
}
}
}
});
nav.loadURL(testPage.toURL().toString());
Thread.currentThread().sleep(1000);