Split plugin classes and derive AIFilePicker from BasicPluginBase (part 4).

Add back fixes that were in Singularity (in indra/media_plugins) but not
in imprudence.

Also:

Add "shutdown" plugin message and terminate file picker plugins cleanly.

The DSO (libbasic_plugin_filepicker.so) now tells the child process /
plugin loader (SLPlugin) to terminate (using the 'shutdown' message),
and AIFilePicker::finish_impl destroys the plugin object on the viewer
side when it's ... finished thus.

Also added a large comment that gives an overview of all classes
involved on the viewer side.

Additional fixes for filepicker.

Plugin refactor bug fix: mDeleteMe was uninitialized in AIPluginFilePicker.
This commit is contained in:
Aleric Inglewood
2011-05-06 16:29:43 +02:00
parent 16cd4c5c4b
commit c46c86ca4b
21 changed files with 129 additions and 55 deletions

View File

@@ -46,10 +46,9 @@
///
/// @param[in] send_message_function Function for sending messages from plugin to plugin loader shell
/// @param[in] plugin_instance Message data for messages from plugin to plugin loader shell
BasicPluginBase::BasicPluginBase(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance)
BasicPluginBase::BasicPluginBase(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance) :
mPluginInstance(plugin_instance), mSendMessageFunction(send_message_function), mDeleteMe(false)
{
mSendMessageFunction = send_message_function;
mPluginInstance = plugin_instance;
}
/**
@@ -79,6 +78,12 @@ void BasicPluginBase::staticReceiveMessage(char const* message_string, BasicPlug
// This is the loaded DSO.
//
// Call this function to send 'message' to the viewer.
// Note: mSendMessageFunction points to LLPluginInstance::staticReceiveMessage, so indirectly this
// just calls LLPluginInstance::receiveMessage (mPluginInstance->receiveMessage) where
// mPluginInstance is the LLPluginInstance created in LLPluginProcessChild::idle during
// state STATE_PLUGIN_LOADING. That function then immediately calls mOwner->receivePluginMessage
// which is implemented as LLPluginProcessChild::receivePluginMessage, the same
// LLPluginProcessChild object that created the LLPluginInstance.
/**
* Send message to plugin loader shell.
*
@@ -91,6 +96,17 @@ void BasicPluginBase::sendMessage(const LLPluginMessage &message)
mSendMessageFunction(output.c_str(), &mPluginInstance);
}
/**
* Send shutdown message to the plugin loader shell.
*
* This will cause the SLPlugin process that loaded this DSO to be terminated.
*/
void BasicPluginBase::sendShutdownMessage(void)
{
LLPluginMessage shutdownmessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shutdown");
sendMessage(shutdownmessage);
}
#if LL_WINDOWS
# define LLSYMEXPORT __declspec(dllexport)
#elif LL_LINUX

View File

@@ -57,6 +57,9 @@ public:
// This function is actually called and then calls the member function above.
static void staticReceiveMessage(char const* message_string, BasicPluginBase** self_ptr);
// Shoot down the whole process.
void sendShutdownMessage(void);
protected:
void sendMessage(LLPluginMessage const& message);

View File

@@ -49,7 +49,6 @@
MediaPluginBase::MediaPluginBase(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance)
: BasicPluginBase(send_message_function, plugin_instance)
{
mDeleteMe = false;
mPixels = 0;
mWidth = 0;
mHeight = 0;

View File

@@ -17,13 +17,13 @@ include_directories(
### basic_plugin_example
if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif(WINDOWS)
endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
endif (NOT WORD_SIZE EQUAL 32)
set(basic_plugin_example_SOURCE_FILES
basic_plugin_example.cpp

View File

@@ -28,13 +28,13 @@ include_directories(
### media_plugin_example
if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif(WINDOWS)
endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
endif (NOT WORD_SIZE EQUAL 32)
set(media_plugin_example_SOURCE_FILES
media_plugin_example.cpp

View File

@@ -19,13 +19,13 @@ include_directories(
### basic_plugin_filepicker
if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
if(NOT WORD_SIZE EQUAL 32)
if(WINDOWS)
add_definitions(/FIXED:NO)
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
add_definitions(-fPIC)
endif(WINDOWS)
endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4)
endif (NOT WORD_SIZE EQUAL 32)
set(basic_plugin_filepicker_SOURCE_FILES
basic_plugin_filepicker.cpp

View File

@@ -150,6 +150,10 @@ void FilepickerPlugin::receiveMessage(char const* message_string)
message.setValue("plugin_version", plugin_version);
sendMessage(message);
}
else if (message_name == "cleanup")
{
// We have no resources that need care. Just do nothing.
}
else if (message_name == "idle")
{
// This whole message should not have existed imho -- Aleric
@@ -213,6 +217,8 @@ void FilepickerPlugin::receiveMessage(char const* message_string)
message.setValueLLSD("filenames", filenames);
sendMessage(message);
}
// We're done. Exit the whole application.
sendShutdownMessage();
}
else
{

View File

@@ -1048,7 +1048,7 @@ void LLFilePickerBase::chooser_responder(GtkWidget *widget, gint response, gpoin
if (response == GTK_RESPONSE_ACCEPT)
{
GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data);
g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, picker);
g_slist_foreach(file_list, (GFunc)g_free, NULL);
g_slist_free (file_list);
}

View File

@@ -652,7 +652,7 @@ bool
MediaPluginGStreamer010::getTimePos(double &sec_out)
{
bool got_position = false;
if (mPlaybin)
if (mDoneInit && mPlaybin)
{
gint64 pos;
GstFormat timefmt = GST_FORMAT_TIME;

View File

@@ -40,6 +40,10 @@
#if defined(LL_DARWIN)
#include <QuickTime/QuickTime.h>
#elif defined(LL_WINDOWS)
#undef __STDC_CONSTANT_MACROS //Needed, as boost/unordered_map.hpp already defines INT32_C, etc.
#if defined(_MSC_VER) && _MSC_VER >= 1600
#define _STDINT_H //Visual Studio 2010 includes its own stdint header already
#endif
#include "MacTypes.h"
#include "QTML.h"
#include "Movies.h"

View File

@@ -51,9 +51,9 @@ set(media_plugin_webkit_LINK_LIBRARIES
# Select which VolumeCatcher implementation to use
if (LINUX)
if (PULSEAUDIO)
if (PULSEAUDIO_FOUND)
list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
endif (PULSEAUDIO)
endif (PULSEAUDIO_FOUND)
list(APPEND media_plugin_webkit_LINK_LIBRARIES
${UI_LIBRARIES} # for glib/GTK
)

View File

@@ -42,9 +42,8 @@
5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call
*/
# include <set> //imprudence
#include "linden_common.h"
# include <set>
#include "volume_catcher.h"

View File

@@ -79,20 +79,6 @@ extern "C" {
}
#endif
#ifdef LL_STANDALONE
#include <qglobal.h>
#elif defined(LL_LINUX)
// We don't provide Qt headers for non-standalone, therefore define this here.
// Our prebuilt is built with QT_NAMESPACE undefined.
#define QT_MANGLE_NAMESPACE(name) name
#define Q_INIT_RESOURCE(name) \
do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \
QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0)
#else
// Apparently this symbol doesn't exist in the windows and Mac tar balls provided by LL.
#define Q_INIT_RESOURCE(name) /*nothing*/
#endif
////////////////////////////////////////////////////////////////////////////////
//
class MediaPluginWebKit :
@@ -138,6 +124,7 @@ private:
F32 mBackgroundR;
F32 mBackgroundG;
F32 mBackgroundB;
std::string mTarget;
VolumeCatcher mVolumeCatcher;
@@ -326,11 +313,7 @@ private:
LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
// create single browser window
#if LLQTWEBKIT_API_VERSION >= 2
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow(mWidth, mHeight /*, mTarget*/ ); // We don't have mTarget yet.
#else
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight );
#endif
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow(mWidth, mHeight, mTarget);
// tell LLQtWebKit about the size of the browser window
LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
@@ -537,16 +520,9 @@ private:
void onClickLinkHref(const EventType& event)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
#if LLQTWEBKIT_API_VERSION >= 2
message.setValue("uri", event.getEventUri());
message.setValue("target", event.getStringValue());
message.setValue("uuid", event.getStringValue2());
#else
// This will work as long as we don't need "uuid", which will be needed for MoaP.
message.setValue("uri", event.getStringValue());
message.setValue("target", event.getStringValue2());
message.setValueU32("target_type", event.getLinkType());
#endif
sendMessage(message);
}
@@ -555,11 +531,7 @@ private:
void onClickLinkNoFollow(const EventType& event)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
#if LLQTWEBKIT_API_VERSION >= 2
message.setValue("uri", event.getEventUri());
#else
message.setValue("uri", event.getStringValue());
#endif
sendMessage(message);
}
@@ -744,9 +716,6 @@ MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction send_
mJavascriptEnabled = true; // default to on
mPluginsEnabled = true; // default to on
mUserAgent = "LLPluginMedia Web Browser";
// Initialize WebCore resource.
Q_INIT_RESOURCE(WebCore);
}
MediaPluginWebKit::~MediaPluginWebKit()
@@ -773,6 +742,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
{
if(message_name == "init")
{
mTarget = message_in.getValue("target");
LLPluginMessage message("base", "init_response");
LLSD versions = LLSD::emptyMap();
versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
@@ -1082,7 +1053,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
else
{
// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
};
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
{