summaryrefslogtreecommitdiff
path: root/indra/llplugin
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin')
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp34
-rw-r--r--indra/llplugin/llpluginclassmedia.h3
-rw-r--r--indra/llplugin/llpluginclassmediaowner.h4
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp59
-rw-r--r--indra/llplugin/llpluginprocessparent.h5
5 files changed, 83 insertions, 22 deletions
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 7299ede22d..fc58b48a7b 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -133,6 +133,7 @@ void LLPluginClassMedia::reset()
mCurrentTime = 0.0f;
mDuration = 0.0f;
mCurrentRate = 0.0f;
+ mLoadedDuration = 0.0f;
}
void LLPluginClassMedia::idle(void)
@@ -705,6 +706,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
bool time_duration_updated = false;
+ int previous_percent = mProgressPercent;
if(message.hasValue("current_time"))
{
@@ -722,11 +724,32 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mCurrentRate = message.getValueReal("current_rate");
}
+ if(message.hasValue("loaded_duration"))
+ {
+ mLoadedDuration = message.getValueReal("loaded_duration");
+ time_duration_updated = true;
+ }
+ else
+ {
+ // If the message doesn't contain a loaded_duration param, assume it's equal to duration
+ mLoadedDuration = mDuration;
+ }
+
+ // Calculate a percentage based on the loaded duration and total duration.
+ if(mDuration != 0.0f) // Don't divide by zero.
+ {
+ mProgressPercent = (int)((mLoadedDuration * 100.0f)/mDuration);
+ }
+
if(time_duration_updated)
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
}
+ if(previous_percent != mProgressPercent)
+ {
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
+ }
}
else if(message_name == "media_status")
{
@@ -812,6 +835,11 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mCanPaste = message.getValueBoolean("paste");
}
}
+ else if(message_name == "name_text")
+ {
+ mMediaName = message.getValue("name");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED);
+ }
else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@@ -884,6 +912,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
/* virtual */
+void LLPluginClassMedia::pluginLaunchFailed()
+{
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH);
+}
+
+/* virtual */
void LLPluginClassMedia::pluginDied()
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED);
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 331ca5f6dc..697deec353 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -135,6 +135,7 @@ public:
// Inherited from LLPluginProcessParentOwner
/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
+ /* virtual */ void pluginLaunchFailed();
/* virtual */ void pluginDied();
@@ -230,6 +231,7 @@ public:
F64 getCurrentTime(void) const { return mCurrentTime; };
F64 getDuration(void) const { return mDuration; };
F64 getCurrentPlayRate(void) { return mCurrentRate; };
+ F64 getLoadedDuration(void) const { return mLoadedDuration; };
// Initialize the URL history of the plugin by sending
// "init_history" message
@@ -338,6 +340,7 @@ protected:
F64 mCurrentTime;
F64 mDuration;
F64 mCurrentRate;
+ F64 mLoadedDuration;
};
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index df6de0925e..4690f09172 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -52,11 +52,13 @@ public:
MEDIA_EVENT_NAVIGATE_COMPLETE, // browser has finished navigation
MEDIA_EVENT_PROGRESS_UPDATED, // browser has updated loading progress
MEDIA_EVENT_STATUS_TEXT_CHANGED, // browser has updated the status text
+ MEDIA_EVENT_NAME_CHANGED, // browser has updated the name of the media (typically <title> tag)
MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc)
MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are
MEDIA_EVENT_CLICK_LINK_NOFOLLOW,
- MEDIA_EVENT_PLUGIN_FAILED // The plugin failed to launch or died unexpectedly
+ MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
+ MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly
} EMediaEvent;
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 41784a713c..f3b4c6bdc6 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -83,6 +83,14 @@ void LLPluginProcessParent::killSockets(void)
mSocket.reset();
}
+void LLPluginProcessParent::errorState(void)
+{
+ if(mState < STATE_RUNNING)
+ setState(STATE_LAUNCH_FAILURE);
+ else
+ setState(STATE_ERROR);
+}
+
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename)
{
mProcess.setExecutable(launcher_filename);
@@ -132,7 +140,7 @@ bool LLPluginProcessParent::accept()
ll_apr_warn_status(status);
// Some other error.
- setState(STATE_ERROR);
+ errorState();
}
return result;
@@ -150,15 +158,15 @@ void LLPluginProcessParent::idle(void)
if(!mMessagePipe->pump())
{
// LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL;
- setState(STATE_ERROR);
+ errorState();
}
}
- if((mSocketError != APR_SUCCESS) && (mState < STATE_ERROR))
+ if((mSocketError != APR_SUCCESS) && (mState <= STATE_RUNNING))
{
// The socket is in an error state -- the plugin is gone.
LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL;
- setState(STATE_ERROR);
+ errorState();
}
// If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
@@ -191,7 +199,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(status))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
@@ -202,7 +210,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(status))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
@@ -212,7 +220,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket())))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
mBoundPort = bound_addr->port;
@@ -222,7 +230,7 @@ void LLPluginProcessParent::idle(void)
LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
}
@@ -234,7 +242,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(status))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
@@ -242,7 +250,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(status))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
@@ -255,7 +263,7 @@ void LLPluginProcessParent::idle(void)
if(ll_apr_warn_status(status))
{
killSockets();
- setState(STATE_ERROR);
+ errorState();
break;
}
@@ -274,7 +282,7 @@ void LLPluginProcessParent::idle(void)
mProcess.addArgument(stream.str());
if(mProcess.launch() != 0)
{
- setState(STATE_ERROR);
+ errorState();
}
else
{
@@ -290,7 +298,7 @@ void LLPluginProcessParent::idle(void)
// waiting for the plugin to connect
if(pluginLockedUpOrQuit())
{
- setState(STATE_ERROR);
+ errorState();
}
else
{
@@ -309,7 +317,7 @@ void LLPluginProcessParent::idle(void)
if(pluginLockedUpOrQuit())
{
- setState(STATE_ERROR);
+ errorState();
}
break;
@@ -330,14 +338,14 @@ void LLPluginProcessParent::idle(void)
// The load_plugin_response message will kick us from here into STATE_RUNNING
if(pluginLockedUpOrQuit())
{
- setState(STATE_ERROR);
+ errorState();
}
break;
case STATE_RUNNING:
if(pluginLockedUpOrQuit())
{
- setState(STATE_ERROR);
+ errorState();
}
break;
@@ -349,8 +357,16 @@ void LLPluginProcessParent::idle(void)
else if(pluginLockedUp())
{
LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl;
- setState(STATE_ERROR);
+ errorState();
+ }
+ break;
+
+ case STATE_LAUNCH_FAILURE:
+ if(mOwner != NULL)
+ {
+ mOwner->pluginLaunchFailed();
}
+ setState(STATE_CLEANUP);
break;
case STATE_ERROR:
@@ -467,7 +483,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
else
{
LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL;
- setState(STATE_ERROR);
+ errorState();
}
}
@@ -477,6 +493,9 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// Plugin has been loaded.
+ mPluginVersionString = message.getValue("plugin_version");
+ LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL;
+
// Check which message classes/versions the plugin supports.
// TODO: check against current versions
// TODO: kill plugin on major mismatches?
@@ -487,8 +506,6 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;
}
- mPluginVersionString = message.getValue("plugin_version");
-
// Send initial sleep time
setSleepTime(mSleepTime, true);
@@ -497,7 +514,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
else
{
LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL;
- setState(STATE_ERROR);
+ errorState();
}
}
else if(message_name == "heartbeat")
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 0d0b047c88..754ebeb946 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -45,6 +45,7 @@ public:
virtual ~LLPluginProcessParentOwner();
virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
// This will only be called when the plugin has died unexpectedly
+ virtual void pluginLaunchFailed() {};
virtual void pluginDied() {};
};
@@ -68,6 +69,9 @@ public:
bool isDone(void);
void killSockets(void);
+
+ // Go to the proper error state
+ void errorState(void);
void setSleepTime(F64 sleep_time, bool force_send = false);
F64 getSleepTime(void) const { return mSleepTime; };
@@ -110,6 +114,7 @@ private:
STATE_HELLO, // first message from the plugin process has been received
STATE_LOADING, // process has been asked to load the plugin
STATE_RUNNING, //
+ STATE_LAUNCH_FAILURE, // Failure before plugin loaded
STATE_ERROR, // generic bailout state
STATE_CLEANUP, // clean everything up
STATE_EXITING, // Tried to kill process, waiting for it to exit