diff options
5 files changed, 260 insertions, 6 deletions
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 2e77a7140a..64a0f98c2a 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -6,24 +6,30 @@ include(00-Common) if(LL_TESTS) include(LLAddBuildTest) endif(LL_TESTS) +include(CURL) include(LLCommon) include(LLMessage) include(LLPlugin) +include(LLVFS) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} + ${CURL_INCLUDE_DIRS} ) set(updater_service_SOURCE_FILES llupdaterservice.cpp llupdatechecker.cpp + llupdatedownloader.cpp ) set(updater_service_HEADER_FILES llupdaterservice.h llupdatechecker.h + llupdatedownloader.h ) set_source_files_properties(${updater_service_HEADER_FILES} @@ -42,6 +48,8 @@ target_link_libraries(llupdaterservice ${LLCOMMON_LIBRARIES} ${LLMESSAGE_LIBRARIES} ${LLPLUGIN_LIBRARIES} + ${LLVFS_LIBRARIES} + ${CURL_LIBRARIES} ) if(LL_TESTS) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 331d0269d4..9cfa919b39 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -55,7 +55,7 @@ private: Client & mClient; LLHTTPClient mHttpClient; bool mInProgress; - LLHTTPClient::ResponderPtr mMe; + LLHTTPClient::ResponderPtr mMe; std::string mVersion; LOG_CLASS(LLUpdateChecker::Implementation); @@ -108,6 +108,11 @@ void LLUpdateChecker::Implementation::check(std::string const & host, std::strin mVersion = version; std::string checkUrl = buildUrl(host, channel, version); LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl; + + // The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the + // passed object to be silently and automatically deleted. We pass a self- + // referential intrusive pointer stored as an attribute of this class to keep + // the client from deletig the update checker implementation instance. mHttpClient.get(checkUrl, mMe); } diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp new file mode 100644 index 0000000000..4adf9c42b1 --- /dev/null +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -0,0 +1,168 @@ +/** + * @file llupdatedownloader.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 "lldir.h" +#include "llfile.h" +#include "llsd.h" +#include "llsdserialize.h" +#include "llthread.h" +#include "llupdatedownloader.h" + + +class LLUpdateDownloader::Implementation: + public LLThread +{ +public: + Implementation(LLUpdateDownloader::Client & client); + void cancel(void); + void download(LLURI const & uri); + bool isDownloading(void); + +private: + static const char * sSecondLifeUpdateRecord; + + LLUpdateDownloader::Client & mClient; + std::string mDownloadRecordPath; + + void resumeDownloading(LLSD const & downloadData); + void run(void); + bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData); + void startDownloading(LLURI const & uri); +}; + + + +// LLUpdateDownloader +//----------------------------------------------------------------------------- + + +LLUpdateDownloader::LLUpdateDownloader(Client & client): + mImplementation(new LLUpdateDownloader::Implementation(client)) +{ + ; // No op. +} + + +void LLUpdateDownloader::cancel(void) +{ + mImplementation->cancel(); +} + + +void LLUpdateDownloader::download(LLURI const & uri) +{ + mImplementation->download(uri); +} + + +bool LLUpdateDownloader::isDownloading(void) +{ + return mImplementation->isDownloading(); +} + + + +// LLUpdateDownloader::Implementation +//----------------------------------------------------------------------------- + + +const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord = + "SecondLifeUpdateDownload.xml"; + + +LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): + LLThread("LLUpdateDownloader"), + mClient(client), + mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord)) +{ + ; // No op. +} + + +void LLUpdateDownloader::Implementation::cancel(void) +{ +} + + +void LLUpdateDownloader::Implementation::download(LLURI const & uri) +{ + LLSD downloadData; + if(shouldResumeOngoingDownload(uri, downloadData)){ + + } else { + + } +} + + +bool LLUpdateDownloader::Implementation::isDownloading(void) +{ + return false; +} + + +void resumeDownloading(LLSD const & downloadData) +{ +} + + +bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData) +{ + if(!LLFile::isfile(mDownloadRecordPath)) return false; + + llifstream dataStream(mDownloadRecordPath); + LLSDSerialize parser; + parser.fromXMLDocument(downloadData, dataStream); + + if(downloadData["url"].asString() != uri.asString()) return false; + + std::string downloadedFilePath = downloadData["path"].asString(); + if(LLFile::isfile(downloadedFilePath)) { + llstat fileStatus; + LLFile::stat(downloadedFilePath, &fileStatus); + downloadData["bytes_downloaded"] = LLSD(LLSD::Integer(fileStatus.st_size)); + return true; + } else { + return false; + } + + return true; +} + + +void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri) +{ + LLSD downloadData; + downloadData["url"] = uri.asString(); + LLSD path = uri.pathArray(); + std::string fileName = path[path.size() - 1].asString(); + std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); + llofstream dataStream(mDownloadRecordPath); + LLSDSerialize parser; + parser.toPrettyXML(downloadData, dataStream); + + llofstream downloadStream(filePath); +} diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h new file mode 100644 index 0000000000..9dc5d789ce --- /dev/null +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -0,0 +1,73 @@ +/** + * @file llupdatedownloader.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_UPDATE_DOWNLOADER_H +#define LL_UPDATE_DOWNLOADER_H + + +#include <string> +#include <boost/shared_ptr.hpp> +#include "lluri.h" + + +// +// An asynchronous download service for fetching updates. +// +class LLUpdateDownloader +{ +public: + class Client; + class Implementation; + + LLUpdateDownloader(Client & client); + + // Cancel any in progress download. + void cancel(void); + + // Start a new download. + void download(LLURI const & uri); + + // Returns true if a download is in progress. + bool isDownloading(void); + +private: + boost::shared_ptr<Implementation> mImplementation; +}; + + +// +// An interface to be implemented by clients initiating a update download. +// +class LLUpdateDownloader::Client { + + // The download has completed successfully. + void downloadComplete(void); + + // The download failed. + void downloadError(std::string const & message); +}; + + +#endif
\ No newline at end of file diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 1d0ead3cd4..e339c69724 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -44,7 +44,7 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, public LLUpdateChecker::Client { - static const std::string ListenerName; + static const std::string sListenerName; std::string mUrl; std::string mChannel; @@ -90,7 +90,7 @@ public: bool onMainLoop(LLSD const & event); }; -const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl"; +const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), @@ -105,7 +105,7 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() : LLUpdaterServiceImpl::~LLUpdaterServiceImpl() { LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL; - LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); + LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); } // LLPluginProcessParentOwner interfaces @@ -201,7 +201,7 @@ void LLUpdaterServiceImpl::retry(void) mTimer.start(); mTimer.setTimerExpirySec(mCheckPeriod); LLEventPumps::instance().obtain("mainloop").listen( - ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); + sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) @@ -209,7 +209,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) if(mTimer.hasExpired()) { mTimer.stop(); - LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); + LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); mUpdateChecker.check(mUrl, mChannel, mVersion); } else { // Keep on waiting... |