diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llappviewer.cpp | 1 | ||||
-rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.cpp | 44 | ||||
-rw-r--r-- | indra/viewer_components/updater/llupdaterservice.cpp | 67 | ||||
-rw-r--r-- | indra/viewer_components/updater/llupdaterservice.h | 20 |
4 files changed, 128 insertions, 4 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6c07974f69..63b2fcefd7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2402,7 +2402,6 @@ namespace { LLNotificationsUtil::add("FailedUpdateInstall"); break; default: - llinfos << "unhandled update event " << evt << llendl; break; } diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index c17a50e242..7b0f960ce4 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -29,6 +29,7 @@ #include <boost/lexical_cast.hpp> #include <curl/curl.h> #include "lldir.h" +#include "llevents.h" #include "llfile.h" #include "llmd5.h" #include "llsd.h" @@ -49,6 +50,7 @@ public: bool isDownloading(void); size_t onHeader(void * header, size_t size); size_t onBody(void * header, size_t size); + int onProgress(double downloadSize, double bytesDownloaded); void resume(void); private: @@ -57,6 +59,7 @@ private: CURL * mCurl; LLSD mDownloadData; llofstream mDownloadStream; + unsigned char mDownloadPercent; std::string mDownloadRecordPath; curl_slist * mHeaderList; @@ -149,6 +152,17 @@ namespace { size_t bytes = blockSize * blocks; return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes); } + + + int progress_callback(void * downloader, + double dowloadTotal, + double downloadNow, + double uploadTotal, + double uploadNow) + { + return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)-> + onProgress(dowloadTotal, downloadNow); + } } @@ -157,6 +171,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & mCancelled(false), mClient(client), mCurl(0), + mDownloadPercent(0), mHeaderList(0) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. @@ -290,6 +305,30 @@ size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) } +int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double bytesDownloaded) +{ + int downloadPercent = static_cast<int>(100. * (bytesDownloaded / downloadSize)); + if(downloadPercent > mDownloadPercent) { + mDownloadPercent = downloadPercent; + + LLSD event; + event["pump"] = LLUpdaterService::pumpName(); + LLSD payload; + payload["type"] = LLSD(LLUpdaterService::PROGRESS); + payload["download_size"] = downloadSize; + payload["bytes_downloaded"] = bytesDownloaded; + event["payload"] = payload; + LLEventPumps::instance().obtain("mainlooprepeater").post(event); + + LL_INFOS("UpdateDownload") << "progress event " << payload << LL_ENDL; + } else { + ; // Keep events to a reasonalbe number. + } + + return 0; +} + + void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); @@ -343,6 +382,11 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u } throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true)); throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str())); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &progress_callback)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, this)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, false)); + + mDownloadPercent = 0; } diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index cc60eaead2..92a0a09137 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -98,6 +98,8 @@ class LLUpdaterServiceImpl : LLUpdaterService::app_exit_callback_t mAppExitCallback; + LLUpdaterService::eUpdaterState mState; + LOG_CLASS(LLUpdaterServiceImpl); public: @@ -115,6 +117,7 @@ public: void startChecking(bool install_if_ready); void stopChecking(); bool isChecking(); + LLUpdaterService::eUpdaterState getState(); void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;} @@ -139,6 +142,7 @@ public: private: void restartTimer(unsigned int seconds); + void setState(LLUpdaterService::eUpdaterState state); void stopTimer(); }; @@ -149,7 +153,8 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsDownloading(false), mCheckPeriod(0), mUpdateChecker(*this), - mUpdateDownloader(*this) + mUpdateDownloader(*this), + mState(LLUpdaterService::INITIAL) { } @@ -201,10 +206,16 @@ void LLUpdaterServiceImpl::startChecking(bool install_if_ready) if(!mIsDownloading) { + setState(LLUpdaterService::CHECKING_FOR_UPDATE); + // Checking can only occur during the mainloop. // reset the timer to 0 so that the next mainloop event // triggers a check; restartTimer(0); + } + else + { + setState(LLUpdaterService::DOWNLOADING); } } } @@ -222,6 +233,8 @@ void LLUpdaterServiceImpl::stopChecking() mUpdateDownloader.cancel(); mIsDownloading = false; } + + setState(LLUpdaterService::TERMINAL); } bool LLUpdaterServiceImpl::isChecking() @@ -229,6 +242,11 @@ bool LLUpdaterServiceImpl::isChecking() return mIsChecking; } +LLUpdaterService::eUpdaterState LLUpdaterServiceImpl::getState() +{ + return mState; +} + bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller) { bool foundInstall = false; // return true if install is found. @@ -266,6 +284,8 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller) { if(launchInstaller) { + setState(LLUpdaterService::INSTALLING); + LLFile::remove(update_marker_path()); int result = ll_install_update(install_script_path(), @@ -335,6 +355,8 @@ void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, stopTimer(); mIsDownloading = true; mUpdateDownloader.download(uri, hash); + + setState(LLUpdaterService::DOWNLOADING); } void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, @@ -344,6 +366,8 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, stopTimer(); mIsDownloading = true; mUpdateDownloader.download(uri, hash); + + setState(LLUpdaterService::DOWNLOADING); } void LLUpdaterServiceImpl::upToDate(void) @@ -352,6 +376,8 @@ void LLUpdaterServiceImpl::upToDate(void) { restartTimer(mCheckPeriod); } + + setState(LLUpdaterService::UP_TO_DATE); } void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) @@ -369,6 +395,8 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE); event["payload"] = payload; LLEventPumps::instance().obtain("mainlooprepeater").post(event); + + setState(LLUpdaterService::TERMINAL); } void LLUpdaterServiceImpl::downloadError(std::string const & message) @@ -390,6 +418,8 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message) payload["message"] = message; event["payload"] = payload; LLEventPumps::instance().obtain("mainlooprepeater").post(event); + + setState(LLUpdaterService::ERROR); } void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) @@ -402,6 +432,28 @@ void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } +void LLUpdaterServiceImpl::setState(LLUpdaterService::eUpdaterState state) +{ + if(state != mState) + { + mState = state; + + LLSD event; + event["pump"] = LLUpdaterService::pumpName(); + LLSD payload; + payload["type"] = LLSD(LLUpdaterService::STATE_CHANGE); + payload["state"] = state; + event["payload"] = payload; + LLEventPumps::instance().obtain("mainlooprepeater").post(event); + + LL_INFOS("UpdaterService") << "setting state to " << state << LL_ENDL; + } + else + { + ; // State unchanged; noop. + } +} + void LLUpdaterServiceImpl::stopTimer() { mTimer.stop(); @@ -425,10 +477,13 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) LLSD event; event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR); LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event); + + setState(LLUpdaterService::TERMINAL); } else { mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); + setState(LLUpdaterService::CHECKING_FOR_UPDATE); } } else @@ -449,6 +504,11 @@ std::string const & LLUpdaterService::pumpName(void) return name; } +bool LLUpdaterService::updateReadyToInstall(void) +{ + return LLFile::isfile(update_marker_path()); +} + LLUpdaterService::LLUpdaterService() { if(gUpdater.expired()) @@ -496,6 +556,11 @@ bool LLUpdaterService::isChecking() return mImpl->isChecking(); } +LLUpdaterService::eUpdaterState LLUpdaterService::getState() +{ + return mImpl->getState(); +} + 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 752a6f834b..3763fbfde0 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -43,12 +43,27 @@ public: // Name of the event pump through which update events will be delivered. static std::string const & pumpName(void); + // Returns true if an update has been completely downloaded and is now ready to install. + static bool updateReadyToInstall(void); + // Type codes for events posted by this service. Stored the event's 'type' element. - enum eUpdateEvent { + enum eUpdaterEvent { INVALID, DOWNLOAD_COMPLETE, DOWNLOAD_ERROR, - INSTALL_ERROR + INSTALL_ERROR, + PROGRESS, + STATE_CHANGE + }; + + enum eUpdaterState { + INITIAL, + CHECKING_FOR_UPDATE, + DOWNLOADING, + INSTALLING, + UP_TO_DATE, + TERMINAL, + ERROR }; LLUpdaterService(); @@ -65,6 +80,7 @@ public: void startChecking(bool install_if_ready = false); void stopChecking(); bool isChecking(); + eUpdaterState getState(); typedef boost::function<void (void)> app_exit_callback_t; template <typename F> |