diff options
author | Mark Palange (Mani) <palange@lindenlab.com> | 2010-11-10 14:26:14 -0800 |
---|---|---|
committer | Mark Palange (Mani) <palange@lindenlab.com> | 2010-11-10 14:26:14 -0800 |
commit | b2e84d739b4f5c00b497e57e892fc10d78af8b76 (patch) | |
tree | f035b0be5134c0286f4af7d4f5835ea533ec2e3f /indra/viewer_components | |
parent | f42bb00627f756b277496ec203d567cac31b3438 (diff) |
CHOP-151 Adding startup updater flow to drive update installation and resume.
Diffstat (limited to 'indra/viewer_components')
5 files changed, 194 insertions, 20 deletions
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 64a0f98c2a..980599dd48 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -57,10 +57,13 @@ if(LL_TESTS) llupdaterservice.cpp ) -# set_source_files_properties( +# *NOTE:Mani - I was trying to use the preprocessor seam to mock out +# llifstream (and other) llcommon classes. I didn't work +# because of the windows declspec(dllimport)attribute. +#set_source_files_properties( # llupdaterservice.cpp # PROPERTIES -# LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}" +# LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream" # ) LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}") diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index dc8ecc378a..fb628c99eb 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -71,6 +71,11 @@ class LLUpdateDownloader::Client { public: // The download has completed successfully. + // data is a map containing the following items: + // url - source (remote) location + // hash - the md5 sum that should match the installer file. + // path - destination (local) location + // size - the size of the installer in bytes virtual void downloadComplete(LLSD const & data) = 0; // The download failed. diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 4292da1528..4eb317e668 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -33,12 +33,26 @@ #include <boost/scoped_ptr.hpp> #include <boost/weak_ptr.hpp> +#include "lldir.h" +#include "llsdserialize.h" +#include "llfile.h" #if LL_WINDOWS #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif -boost::weak_ptr<LLUpdaterServiceImpl> gUpdater; + +namespace +{ + boost::weak_ptr<LLUpdaterServiceImpl> gUpdater; + + const std::string UPDATE_MARKER_FILENAME("SecondLifeUpdateReady.xml"); + std::string update_marker_path() + { + return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + UPDATE_MARKER_FILENAME); + } +} class LLUpdaterServiceImpl : public LLUpdateChecker::Client, @@ -59,7 +73,7 @@ class LLUpdaterServiceImpl : LLUpdateDownloader mUpdateDownloader; LLTimer mTimer; - void retry(void); + LLUpdaterService::app_exit_callback_t mAppExitCallback; LOG_CLASS(LLUpdaterServiceImpl); @@ -67,7 +81,7 @@ public: LLUpdaterServiceImpl(); virtual ~LLUpdaterServiceImpl(); - void setParams(const std::string& protocol_version, + void initialize(const std::string& protocol_version, const std::string& url, const std::string& path, const std::string& channel, @@ -79,6 +93,11 @@ public: void stopChecking(); bool isChecking(); + void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;} + + bool checkForInstall(); // Test if a local install is ready. + bool checkForResume(); // Test for resumeable d/l. + // LLUpdateChecker::Client: virtual void error(std::string const & message); virtual void optionalUpdate(std::string const & newVersion, @@ -90,10 +109,14 @@ public: virtual void upToDate(void); // LLUpdateDownloader::Client - void downloadComplete(LLSD const & data) { retry(); } - void downloadError(std::string const & message) { retry(); } + void downloadComplete(LLSD const & data); + void downloadError(std::string const & message); bool onMainLoop(LLSD const & event); + +private: + void retry(void); + }; const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; @@ -112,8 +135,8 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl() LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); } -void LLUpdaterServiceImpl::setParams(const std::string& protocol_version, - const std::string& url, +void LLUpdaterServiceImpl::initialize(const std::string& protocol_version, + const std::string& url, const std::string& path, const std::string& channel, const std::string& version) @@ -129,6 +152,12 @@ void LLUpdaterServiceImpl::setParams(const std::string& protocol_version, mPath = path; mChannel = channel; mVersion = version; + + // Check to see if an install is ready. + if(!checkForInstall()) + { + checkForResume(); + } } void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds) @@ -146,7 +175,7 @@ void LLUpdaterServiceImpl::startChecking() "LLUpdaterService::startCheck()."); } mIsChecking = true; - + mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); } } @@ -164,6 +193,45 @@ bool LLUpdaterServiceImpl::isChecking() return mIsChecking; } +bool LLUpdaterServiceImpl::checkForInstall() +{ + bool result = false; // return true if install is found. + + llifstream update_marker(update_marker_path(), + std::ios::in | std::ios::binary); + + if(update_marker.is_open()) + { + // Found an update info - now lets see if its valid. + LLSD update_info; + LLSDSerialize::fromXMLDocument(update_info, update_marker); + + // Get the path to the installer file. + LLSD path = update_info.get("path"); + if(path.isDefined() && !path.asString().empty()) + { + // install! + } + + update_marker.close(); + LLFile::remove(update_marker_path()); + result = true; + } + return result; +} + +bool LLUpdaterServiceImpl::checkForResume() +{ + bool result = false; + llstat stat_info; + if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info)) + { + mUpdateDownloader.resume(); + result = true; + } + return false; +} + void LLUpdaterServiceImpl::error(std::string const & message) { retry(); @@ -188,6 +256,24 @@ void LLUpdaterServiceImpl::upToDate(void) retry(); } +void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) +{ + // Save out the download data to the SecondLifeUpdateReady + // marker file. + llofstream update_marker(update_marker_path()); + LLSDSerialize::toPrettyXML(data, update_marker); + + // Stop checking. + stopChecking(); + + // Wait for restart...? +} + +void LLUpdaterServiceImpl::downloadError(std::string const & message) +{ + retry(); +} + void LLUpdaterServiceImpl::retry(void) { LL_INFOS("UpdaterService") << "will check for update again in " << @@ -233,13 +319,13 @@ LLUpdaterService::~LLUpdaterService() { } -void LLUpdaterService::setParams(const std::string& protocol_version, +void LLUpdaterService::initialize(const std::string& protocol_version, const std::string& url, const std::string& path, const std::string& channel, const std::string& version) { - mImpl->setParams(protocol_version, url, path, channel, version); + mImpl->initialize(protocol_version, url, path, channel, version); } void LLUpdaterService::setCheckPeriod(unsigned int seconds) @@ -261,3 +347,8 @@ bool LLUpdaterService::isChecking() { return mImpl->isChecking(); } + +void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) +{ + return mImpl->setAppExitCallback(aecb); +} diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 04adf461b6..42ec3a2cab 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -27,6 +27,7 @@ #define LL_UPDATERSERVICE_H #include <boost/shared_ptr.hpp> +#include <boost/function.hpp> class LLUpdaterServiceImpl; @@ -42,11 +43,11 @@ public: LLUpdaterService(); ~LLUpdaterService(); - void setParams(const std::string& protocol_version, - const std::string& url, - const std::string& path, - const std::string& channel, - const std::string& version); + void initialize(const std::string& protocol_version, + const std::string& url, + const std::string& path, + const std::string& channel, + const std::string& version); void setCheckPeriod(unsigned int seconds); @@ -54,8 +55,17 @@ public: void stopChecking(); bool isChecking(); + typedef boost::function<void (void)> app_exit_callback_t; + template <typename F> + void setAppExitCallback(F const &callable) + { + app_exit_callback_t aecb = callable; + setImplAppExitCallback(aecb); + } + private: boost::shared_ptr<LLUpdaterServiceImpl> mImpl; + void setImplAppExitCallback(app_exit_callback_t aecb); }; #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 7f45ae51fb..57732ad0a5 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -36,6 +36,7 @@ #include "../../../test/debug.h"
#include "llevents.h"
+#include "lldir.h"
/*****************************************************************************
* MOCK'd
@@ -48,6 +49,70 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
void LLUpdateDownloader::download(LLURI const & , std::string const &){}
+class LLDir_Mock : public LLDir
+{
+ void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir = "") {}
+ U32 countFilesInDir(const std::string &dirname, const std::string &mask)
+ {
+ return 0;
+ }
+
+ BOOL getNextFileInDir(const std::string &dirname,
+ const std::string &mask,
+ std::string &fname, BOOL wrap)
+ {
+ return false;
+ }
+ void getRandomFileInDir(const std::string &dirname,
+ const std::string &mask,
+ std::string &fname) {}
+ std::string getCurPath() { return ""; }
+ BOOL fileExists(const std::string &filename) const { return false; }
+ std::string getLLPluginLauncher() { return ""; }
+ std::string getLLPluginFilename(std::string base_name) { return ""; }
+
+} gDirUtil;
+LLDir* gDirUtilp = &gDirUtil;
+LLDir::LLDir() {}
+LLDir::~LLDir() {}
+S32 LLDir::deleteFilesInDir(const std::string &dirname,
+ const std::string &mask)
+{ return 0; }
+
+void LLDir::setChatLogsDir(const std::string &path){}
+void LLDir::setPerAccountChatLogsDir(const std::string &username){}
+void LLDir::setLindenUserDir(const std::string &username){}
+void LLDir::setSkinFolder(const std::string &skin_folder){}
+bool LLDir::setCacheDir(const std::string &path){ return true; }
+void LLDir::dumpCurrentDirectories() {}
+
+std::string LLDir::getExpandedFilename(ELLPath location,
+ const std::string &filename) const
+{
+ return "";
+}
+
+std::string LLUpdateDownloader::downloadMarkerPath(void)
+{
+ return "";
+}
+
+void LLUpdateDownloader::resume(void) {}
+
+/*
+#pragma warning(disable: 4273)
+llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, + ios_base::openmode _Mode, + int _Prot) : + std::basic_istream<char,std::char_traits< char > >(NULL,true) +{} + +llus_mock_llifstream::~llus_mock_llifstream() {}
+bool llus_mock_llifstream::is_open() const {return true;}
+void llus_mock_llifstream::close() {}
+*/
+
/*****************************************************************************
* TUT
*****************************************************************************/
@@ -96,9 +161,9 @@ namespace tut bool got_usage_error = false;
try
{
- updater.setParams("1.0",test_url, "update" ,test_channel, test_version);
+ updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
updater.startChecking();
- updater.setParams("1.0", "other_url", "update", test_channel, test_version);
+ updater.initialize("1.0", "other_url", "update", test_channel, test_version);
}
catch(LLUpdaterService::UsageError)
{
@@ -112,7 +177,7 @@ namespace tut {
DEBUG;
LLUpdaterService updater;
- updater.setParams("1.0", test_url, "update", test_channel, test_version);
+ updater.initialize("1.0", test_url, "update", test_channel, test_version);
updater.startChecking();
ensure(updater.isChecking());
updater.stopChecking();
|