From 374deb8da13c63f80dc1b245488eb254eb86f5d2 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Mon, 5 Oct 2009 15:48:00 -0700 Subject: Fixes for a different class of plugin failures (where loading the plugin dll fails) causing an error message loop: Made LLPluginProcessParent differentiate between failures launching/loading the plugin and failures after the plugin has been loaded. This allows us to handle launch failures differently, since retrying is unlikely to fix them. Added new media event MEDIA_EVENT_PLUGIN_FAILED_LAUNCH to indicate a launch failure. Added a case for the new event to LLViewerMediaImpl::handleMediaEvent() that sets the "failed init" flag to prevent retries. --- indra/llplugin/llpluginclassmedia.cpp | 6 ++++ indra/llplugin/llpluginclassmedia.h | 1 + indra/llplugin/llpluginclassmediaowner.h | 3 +- indra/llplugin/llpluginprocessparent.cpp | 54 +++++++++++++++++++++----------- indra/llplugin/llpluginprocessparent.h | 5 +++ 5 files changed, 49 insertions(+), 20 deletions(-) (limited to 'indra/llplugin') diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 7299ede22d..e019cdcf21 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -883,6 +883,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) } +/* virtual */ +void LLPluginClassMedia::pluginLaunchFailed() +{ + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH); +} + /* virtual */ void LLPluginClassMedia::pluginDied() { diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 331ca5f6dc..97f2a11ef2 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(); diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index df6de0925e..cfee847080 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -56,7 +56,8 @@ public: 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..c925d4b760 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,10 +357,18 @@ 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: if(mOwner != NULL) { @@ -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(); } } @@ -497,7 +513,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 -- cgit v1.2.3 From bf82ec22647736333e1b14766e3c7d5cfb1a739a Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 8 Oct 2009 18:42:16 -0700 Subject: Log the plugin version string when a plugin is loaded. --- indra/llplugin/llpluginprocessparent.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llplugin') diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index c925d4b760..f3b4c6bdc6 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -493,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? @@ -503,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); -- cgit v1.2.3 From d02906b12ee335676e11ac883981e75f4df2cacc Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Mon, 12 Oct 2009 17:21:26 -0700 Subject: Added an optional "loaded_duration" parameter to the 'updated' message. This is the duration through which the time-based media has loaded, and should be between zero and the value of the "duration" parameter. If the parameter is not supplied, it will be implicitly set to the same value as the "duration" parameter, so the movie will appear fully loaded. This can be queried with LLPluginClassMedia::getLoadedDuration(). Made the "loaded_duration" parameter also implicitly set the progress percentage and send out MEDIA_EVENT_PROGRESS_UPDATED messages when it changes. Made the quicktime plugin set the "loaded_duration" parameter in its update messages. --- indra/llplugin/llpluginclassmedia.cpp | 23 +++++++++++++++++++++++ indra/llplugin/llpluginclassmedia.h | 2 ++ 2 files changed, 25 insertions(+) (limited to 'indra/llplugin') diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index e019cdcf21..2a343fd0c9 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") { diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 97f2a11ef2..697deec353 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -231,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 @@ -339,6 +340,7 @@ protected: F64 mCurrentTime; F64 mDuration; F64 mCurrentRate; + F64 mLoadedDuration; }; -- cgit v1.2.3 From 434709680326aa634805afdcf900b7445ef4aac4 Mon Sep 17 00:00:00 2001 From: callum Date: Thu, 15 Oct 2009 11:26:52 -0700 Subject: https://jira.lindenlab.com/jira/browse/DEV-40711 Implement name fetching capabilities for Webkit and Quicktime plugins Adds support for new PluginAPI message (MEDIA_EVENT_NAME_CHANGED) that updates the "title" of the media. In WebKit plugin this is the contents of the tag. In The QuickTime plugin it is the "display name" from the movie meta data --- indra/llplugin/llpluginclassmedia.cpp | 5 +++++ indra/llplugin/llpluginclassmediaowner.h | 1 + 2 files changed, 6 insertions(+) (limited to 'indra/llplugin') diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 2a343fd0c9..fc58b48a7b 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -835,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; diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index cfee847080..4690f09172 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -52,6 +52,7 @@ 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, -- cgit v1.2.3