summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/CMakeLists.txt5
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/llappviewer.cpp8
-rw-r--r--indra/newview/lltranslate.cpp2
-rw-r--r--indra/viewer_components/updater/CMakeLists.txt2
-rw-r--r--indra/viewer_components/updater/llupdatechecker.cpp151
-rw-r--r--indra/viewer_components/updater/llupdatechecker.h71
-rw-r--r--indra/viewer_components/updater/llupdaterservice.cpp88
-rw-r--r--indra/viewer_components/updater/llupdaterservice.h2
-rw-r--r--indra/viewer_components/updater/tests/llupdaterservice_test.cpp6
10 files changed, 326 insertions, 11 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 8d4969a49e..d01e1869b6 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -22,7 +22,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
if (DARWIN)
- cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
+ # 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION):
+ # before that version it returns "pathname/SLPlugin", whereas the correct
+ # answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin".
+ cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
endif (DARWIN)
if (NOT CMAKE_BUILD_TYPE)
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7f3d4bc4e2..8f5cb7c709 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11022,7 +11022,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://secondlife.com/app/update</string>
+ <string>http://localhost/agni</string>
</map>
<key>UploadBakedTexOld</key>
<map>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b122209af8..3a48bc25f1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -632,9 +632,6 @@ bool LLAppViewer::init()
if (!initConfiguration())
return false;
- // Initialize updater service
- initUpdater();
-
// write Google Breakpad minidump files to our log directory
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
logdir += gDirUtilp->getDirDelimiter();
@@ -976,7 +973,10 @@ bool LLAppViewer::mainLoop()
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
-
+
+ // Initialize updater service (now that we have an io pump)
+ initUpdater();
+
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
LLVoiceChannel::initClass();
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 21467a2ab8..8ccfdb071b 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -64,7 +64,7 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std
getTranslateUrl(url, from_lang, to_lang, mesg);
std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel(),
+ LLVersionInfo::getChannel().c_str(),
LLVersionInfo::getMajor(),
LLVersionInfo::getMinor(),
LLVersionInfo::getPatch(),
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index a8a1d685f7..2e77a7140a 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -18,10 +18,12 @@ include_directories(
set(updater_service_SOURCE_FILES
llupdaterservice.cpp
+ llupdatechecker.cpp
)
set(updater_service_HEADER_FILES
llupdaterservice.h
+ llupdatechecker.h
)
set_source_files_properties(${updater_service_HEADER_FILES}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
new file mode 100644
index 0000000000..331d0269d4
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -0,0 +1,151 @@
+/**
+ * @file llupdaterservice.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include <boost/format.hpp>
+#include "llhttpclient.h"
+#include "llsd.h"
+#include "llupdatechecker.h"
+#include "lluri.h"
+
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+class LLUpdateChecker::Implementation:
+ public LLHTTPClient::Responder
+{
+public:
+
+ Implementation(Client & client);
+ ~Implementation();
+ void check(std::string const & host, std::string channel, std::string version);
+
+ // Responder:
+ virtual void completed(U32 status,
+ const std::string & reason,
+ const LLSD& content);
+ virtual void error(U32 status, const std::string & reason);
+
+private:
+ std::string buildUrl(std::string const & host, std::string channel, std::string version);
+
+ Client & mClient;
+ LLHTTPClient mHttpClient;
+ bool mInProgress;
+ LLHTTPClient::ResponderPtr mMe;
+ std::string mVersion;
+
+ LOG_CLASS(LLUpdateChecker::Implementation);
+};
+
+
+
+// LLUpdateChecker
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
+ mImplementation(new LLUpdateChecker::Implementation(client))
+{
+ ; // No op.
+}
+
+
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version)
+{
+ mImplementation->check(host, channel, version);
+}
+
+
+
+// LLUpdateChecker::Implementation
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
+ mClient(client),
+ mInProgress(false),
+ mMe(this)
+{
+ ; // No op.
+}
+
+
+LLUpdateChecker::Implementation::~Implementation()
+{
+ mMe.reset(0);
+}
+
+
+void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version)
+{
+ // llassert(!mInProgress);
+
+ mInProgress = true;
+ mVersion = version;
+ std::string checkUrl = buildUrl(host, channel, version);
+ LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+ mHttpClient.get(checkUrl, mMe);
+}
+
+void LLUpdateChecker::Implementation::completed(U32 status,
+ const std::string & reason,
+ const LLSD & content)
+{
+ mInProgress = false;
+
+ if(status != 200) {
+ LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+ mClient.error(reason);
+ } else if(!content["valid"].asBoolean()) {
+ LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+ mClient.requiredUpdate(content["latest_version"].asString());
+ } else if(content["latest_version"].asString() != mVersion) {
+ LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl;
+ mClient.optionalUpdate(content["latest_version"].asString());
+ } else {
+ LL_INFOS("UpdateCheck") << "up to date" << llendl;
+ mClient.upToDate();
+ }
+}
+
+
+void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
+{
+ mInProgress = false;
+ LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+}
+
+
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version)
+{
+ LLSD path;
+ path.append("version");
+ path.append(channel);
+ path.append(version);
+ return LLURI::buildHTTP(host, path).asString();
+}
+
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
new file mode 100644
index 0000000000..b630c4d8a6
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -0,0 +1,71 @@
+/**
+ * @file llupdatechecker.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_UPDATERCHECKER_H
+#define LL_UPDATERCHECKER_H
+
+
+#include <boost/shared_ptr.hpp>
+
+
+//
+// Implements asynchronous checking for updates.
+//
+class LLUpdateChecker {
+public:
+ class Client;
+ class Implementation;
+
+ LLUpdateChecker(Client & client);
+
+ // Check status of current app on the given host for the channel and version provided.
+ void check(std::string const & hostUrl, std::string channel, std::string version);
+
+private:
+ boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+//
+// The client interface implemented by a requestor checking for an update.
+//
+class LLUpdateChecker::Client
+{
+public:
+ // An error occurred while checking for an update.
+ virtual void error(std::string const & message) = 0;
+
+ // A newer version is available, but the current version may still be used.
+ virtual void optionalUpdate(std::string const & newVersion) = 0;
+
+ // A newer version is available, and the current version is no longer valid.
+ virtual void requiredUpdate(std::string const & newVersion) = 0;
+
+ // The checked version is up to date; no newer version exists.
+ virtual void upToDate(void) = 0;
+};
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 28c942b5f2..1d0ead3cd4 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -25,16 +25,27 @@
#include "linden_common.h"
+#include "llevents.h"
+#include "lltimer.h"
#include "llupdaterservice.h"
+#include "llupdatechecker.h"
#include "llpluginprocessparent.h"
#include <boost/scoped_ptr.hpp>
#include <boost/weak_ptr.hpp>
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
-class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
+class LLUpdaterServiceImpl :
+ public LLPluginProcessParentOwner,
+ public LLUpdateChecker::Client
{
+ static const std::string ListenerName;
+
std::string mUrl;
std::string mChannel;
std::string mVersion;
@@ -42,10 +53,17 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner
unsigned int mCheckPeriod;
bool mIsChecking;
boost::scoped_ptr<LLPluginProcessParent> mPlugin;
+
+ LLUpdateChecker mUpdateChecker;
+ LLTimer mTimer;
+ void retry(void);
+
+ LOG_CLASS(LLUpdaterServiceImpl);
+
public:
LLUpdaterServiceImpl();
- virtual ~LLUpdaterServiceImpl() {}
+ virtual ~LLUpdaterServiceImpl();
// LLPluginProcessParentOwner interfaces
virtual void receivePluginMessage(const LLPluginMessage &message);
@@ -62,17 +80,34 @@ public:
void startChecking();
void stopChecking();
bool isChecking();
+
+ // LLUpdateChecker::Client:
+ virtual void error(std::string const & message);
+ virtual void optionalUpdate(std::string const & newVersion);
+ virtual void requiredUpdate(std::string const & newVersion);
+ virtual void upToDate(void);
+
+ bool onMainLoop(LLSD const & event);
};
+const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl";
+
LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
mIsChecking(false),
mCheckPeriod(0),
- mPlugin(0)
+ mPlugin(0),
+ mUpdateChecker(*this)
{
// Create the plugin parent, this is the owner.
mPlugin.reset(new LLPluginProcessParent(this));
}
+LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
+{
+ LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL;
+ LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+}
+
// LLPluginProcessParentOwner interfaces
void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message)
{
@@ -121,6 +156,8 @@ void LLUpdaterServiceImpl::startChecking()
"LLUpdaterService::startCheck().");
}
mIsChecking = true;
+
+ mUpdateChecker.check(mUrl, mChannel, mVersion);
}
}
@@ -137,6 +174,51 @@ bool LLUpdaterServiceImpl::isChecking()
return mIsChecking;
}
+void LLUpdaterServiceImpl::error(std::string const & message)
+{
+ retry();
+}
+
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion)
+{
+ retry();
+}
+
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion)
+{
+ retry();
+}
+
+void LLUpdaterServiceImpl::upToDate(void)
+{
+ retry();
+}
+
+void LLUpdaterServiceImpl::retry(void)
+{
+ LL_INFOS("UpdaterService") << "will check for update again in " <<
+ mCheckPeriod << " seconds" << LL_ENDL;
+ mTimer.start();
+ mTimer.setTimerExpirySec(mCheckPeriod);
+ LLEventPumps::instance().obtain("mainloop").listen(
+ ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
+}
+
+bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
+{
+ if(mTimer.hasExpired())
+ {
+ mTimer.stop();
+ LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName);
+ mUpdateChecker.check(mUrl, mChannel, mVersion);
+ } else {
+ // Keep on waiting...
+ }
+
+ return false;
+}
+
+
//-----------------------------------------------------------------------
// Facade interface
LLUpdaterService::LLUpdaterService()
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 6459ca49f8..313ae8ada3 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -58,4 +58,4 @@ private:
boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
};
-#endif LL_UPDATERSERVICE_H
+#endif // LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 73cf6ea6eb..d93a85cf7d 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
// associated header
#include "../llupdaterservice.h"
+#include "../llupdatechecker.h"
#include "../../../test/lltut.h"
//#define DEBUG_ON
@@ -54,6 +55,11 @@ int LLPluginMessagePipeOwner::socketError(int) { return 0; }
void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {}
void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {}
LLPluginMessage::~LLPluginMessage() {}
+LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {}
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
+{}
+void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){}
/*****************************************************************************
* TUT