CHOP-151 Adding startup updater flow to drive update installation and resume.
parent
f42bb00627
commit
b2e84d739b
|
|
@ -2341,7 +2341,7 @@ void LLAppViewer::initUpdater()
|
|||
std::string service_path = gSavedSettings.getString("UpdaterServicePath");
|
||||
U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
|
||||
|
||||
mUpdater->setParams(protocol_version, url, service_path, channel, version);
|
||||
mUpdater->initialize(protocol_version, url, service_path, channel, version);
|
||||
mUpdater->setCheckPeriod(check_period);
|
||||
if(gSavedSettings.getBOOL("UpdaterServiceActive"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue