From 0b9cd83642f297687989b0813a9dca83cc78cc15 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Mon, 25 Oct 2010 14:53:58 -0700 Subject: CHOP-122 Adding stub background updater files to the build. Rev. by brad --- .../updater/tests/llupdaterservice_test.cpp | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 indra/viewer_components/updater/tests/llupdaterservice_test.cpp (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp new file mode 100644 index 0000000000..37d1c8243e --- /dev/null +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -0,0 +1,59 @@ +/** + * @file llupdaterservice_test.cpp + * @brief Tests of 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$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "../llupdaterservice.h" + +#include "../../../test/lltut.h" +//#define DEBUG_ON +#include "../../../test/debug.h" + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llupdaterservice_data + { + llupdaterservice_data() : + pumps(LLEventPumps::instance()) + {} + LLEventPumps& pumps; + }; + + typedef test_group llupdaterservice_group; + typedef llviewerlogin_group::object llupdaterservice_object; + llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); + + template<> template<> + void llupdateservice_object::test<1>() + { + DEBUG; + ensure_equals("Dummy", "true", "true"); + } +} -- cgit v1.3 From 34db27c26f9a5627b733cc8a04265afed68d199c Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Tue, 26 Oct 2010 15:00:34 -0700 Subject: CHOP-122 Mowr work on the llupdater facade... Added LLPluginProcessParent, including mockery for unit tests. Re. by Jenn --- indra/viewer_components/updater/CMakeLists.txt | 6 ++ .../viewer_components/updater/llupdaterservice.cpp | 120 ++++++++++++++++++++- indra/viewer_components/updater/llupdaterservice.h | 10 +- .../updater/tests/llupdaterservice_test.cpp | 28 ++++- 4 files changed, 158 insertions(+), 6 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 4dc5424142..df9404474c 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -7,9 +7,13 @@ if(LL_TESTS) include(LLAddBuildTest) endif(LL_TESTS) include(LLCommon) +include(LLMessage) +include(LLPlugin) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLPLUGIN_INCLUDE_DIRS} ) set(updater_service_SOURCE_FILES @@ -34,6 +38,8 @@ add_library(llupdaterservice target_link_libraries(llupdaterservice ${LLCOMMON_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLPLUGIN_LIBRARIES} ) if(LL_TESTS) diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 14906bcef8..6c7619a2b9 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -25,6 +25,118 @@ #include "linden_common.h" +#include "llupdaterservice.h" + +#include "llsingleton.h" +#include "llpluginprocessparent.h" +#include + +class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, + public LLSingleton +{ + std::string mUrl; + std::string mChannel; + std::string mVersion; + + unsigned int mUpdateCheckPeriod; + bool mIsChecking; + boost::scoped_ptr mPlugin; + +public: + LLUpdaterServiceImpl(); + virtual ~LLUpdaterServiceImpl() {} + + // LLPluginProcessParentOwner interfaces + virtual void receivePluginMessage(const LLPluginMessage &message); + virtual bool receivePluginMessageEarly(const LLPluginMessage &message); + virtual void pluginLaunchFailed(); + virtual void pluginDied(); + + void setURL(const std::string& url); + void setChannel(const std::string& channel); + void setVersion(const std::string& version); + void setUpdateCheckPeriod(unsigned int seconds); + void startChecking(); + void stopChecking(); +}; + +LLUpdaterServiceImpl::LLUpdaterServiceImpl() : + mIsChecking(false), + mUpdateCheckPeriod(0), + mPlugin(0) +{ + // Create the plugin parent, this is the owner. + mPlugin.reset(new LLPluginProcessParent(this)); +} + +// LLPluginProcessParentOwner interfaces +void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message) +{ +} + +bool LLUpdaterServiceImpl::receivePluginMessageEarly(const LLPluginMessage &message) +{ + return false; +}; + +void LLUpdaterServiceImpl::pluginLaunchFailed() +{ +}; + +void LLUpdaterServiceImpl::pluginDied() +{ +}; + +void LLUpdaterServiceImpl::setURL(const std::string& url) +{ + if(mUrl != url) + { + mUrl = url; + } +} + +void LLUpdaterServiceImpl::setChannel(const std::string& channel) +{ + if(mChannel != channel) + { + mChannel = channel; + } +} + +void LLUpdaterServiceImpl::setVersion(const std::string& version) +{ + if(mVersion != version) + { + mVersion = version; + } +} + +void LLUpdaterServiceImpl::setUpdateCheckPeriod(unsigned int seconds) +{ + if(mUpdateCheckPeriod != seconds) + { + mUpdateCheckPeriod = seconds; + } +} + +void LLUpdaterServiceImpl::startChecking() +{ + if(!mIsChecking) + { + mIsChecking = true; + } +} + +void LLUpdaterServiceImpl::stopChecking() +{ + if(mIsChecking) + { + mIsChecking = false; + } +} + +//----------------------------------------------------------------------- +// Facade interface LLUpdaterService::LLUpdaterService() { } @@ -35,24 +147,30 @@ LLUpdaterService::~LLUpdaterService() void LLUpdaterService::setURL(const std::string& url) { + LLUpdaterServiceImpl::getInstance()->setURL(url); } void LLUpdaterService::setChannel(const std::string& channel) { + LLUpdaterServiceImpl::getInstance()->setChannel(channel); } void LLUpdaterService::setVersion(const std::string& version) { + LLUpdaterServiceImpl::getInstance()->setVersion(version); } -void LLUpdaterService::setUpdateCheckFrequency(unsigned int seconds) +void LLUpdaterService::setUpdateCheckPeriod(unsigned int seconds) { + LLUpdaterServiceImpl::getInstance()->setUpdateCheckPeriod(seconds); } void LLUpdaterService::startChecking() { + LLUpdaterServiceImpl::getInstance()->startChecking(); } void LLUpdaterService::stopChecking() { + LLUpdaterServiceImpl::getInstance()->stopChecking(); } diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 7836c2cf7f..33d0dc0816 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -28,6 +28,12 @@ class LLUpdaterService { +public: + class UsageError: public std::runtime_error + { + UsageError(const std::string& msg) : std::runtime_error(msg) {} + }; + LLUpdaterService(); ~LLUpdaterService(); @@ -37,10 +43,10 @@ class LLUpdaterService void setChannel(const std::string& channel); void setVersion(const std::string& version); - void setUpdateCheckFrequency(unsigned int seconds); + void setUpdateCheckPeriod(unsigned int seconds); void startChecking(); void stopChecking(); -} +}; #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 37d1c8243e..9edf15ba11 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -33,6 +33,28 @@ //#define DEBUG_ON #include "../../../test/debug.h" +#include "llevents.h" +#include "llpluginprocessparent.h" + +/***************************************************************************** +* MOCK'd +*****************************************************************************/ +LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {} +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) +: mOwner(owner), + mIncomingQueueMutex(NULL) +{ +} + +LLPluginProcessParent::~LLPluginProcessParent() {} +LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){} +LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){} +void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {} +int LLPluginMessagePipeOwner::socketError(int) { return 0; } +void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {} +void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {} +LLPluginMessage::~LLPluginMessage() {} + /***************************************************************************** * TUT *****************************************************************************/ @@ -47,13 +69,13 @@ namespace tut }; typedef test_group llupdaterservice_group; - typedef llviewerlogin_group::object llupdaterservice_object; + typedef llupdaterservice_group::object llupdaterservice_object; llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); template<> template<> - void llupdateservice_object::test<1>() + void llupdaterservice_object::test<1>() { DEBUG; - ensure_equals("Dummy", "true", "true"); + ensure_equals("Dummy", 0, 0); } } -- cgit v1.3 From be8c9fc21758bcbc1d9f3d565b221310344231bd Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 27 Oct 2010 17:07:31 -0700 Subject: CHOP-122 Initializing Facade service in the viewer. Rev. by Brad. --- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 35 +++- indra/newview/llappviewer.cpp | 25 ++- indra/newview/llappviewer.h | 11 +- indra/newview/lltranslate.cpp | 12 +- indra/viewer_components/updater/CMakeLists.txt | 10 ++ .../viewer_components/updater/llupdaterservice.cpp | 107 +++++------ indra/viewer_components/updater/llupdaterservice.h | 19 +- .../updater/tests/llupdaterservice_test.cpp | 195 +++++++++++++-------- 9 files changed, 278 insertions(+), 138 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bf885e5934..63982ba87b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ${LSCRIPT_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS}/lscript_compile ${LLLOGIN_INCLUDE_DIRS} + ${UPDATER_INCLUDE_DIRS} ) set(viewer_SOURCE_FILES @@ -1679,6 +1680,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} + ${UPDATER_LIBRARIES} ${GOOGLE_PERFTOOLS_LIBRARIES} ) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 086d73bc00..371326c0f5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10991,7 +10991,40 @@ Value 15 - UploadBakedTexOld + UpdaterServiceActive + + Comment + Enable or disable the updater service. + Persist + 1 + Type + Boolean + Value + 1 + + UpdaterServiceCheckPeriod + + Comment + Default period between update checking. + Persist + 1 + Type + U32 + Value + 3600 + + UpdaterServiceURL + + Comment + Default location for the updater service. + Persist + 0 + Type + String + Value + http://secondlife.com/app/update + + UploadBakedTexOld Comment Forces the baked texture pipeline to upload using the old method. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 931b9fd2f3..e6feaae504 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -83,6 +83,7 @@ #include "llweb.h" #include "llsecondlifeurls.h" +#include "llupdaterservice.h" // Linden library includes #include "llavatarnamecache.h" @@ -581,7 +582,8 @@ LLAppViewer::LLAppViewer() : mAgentRegionLastAlive(false), mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", FALSE)), mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), - mFastTimerLogThread(NULL) + mFastTimerLogThread(NULL), + mUpdater(new LLUpdaterService()) { if(NULL != sInstance) { @@ -630,6 +632,9 @@ 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(); @@ -2324,6 +2329,24 @@ bool LLAppViewer::initConfiguration() return true; // Config was successful. } +void LLAppViewer::initUpdater() +{ + // Initialize the updater service. + // Generate URL to the udpater service + // Get Channel + // Get Version + std::string url = gSavedSettings.getString("UpdaterServiceURL"); + std::string channel = gSavedSettings.getString("VersionChannelName"); + std::string version = LLVersionInfo::getVersion(); + U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); + + mUpdater->setParams(url, channel, version); + mUpdater->setCheckPeriod(check_period); + if(gSavedSettings.getBOOL("UpdaterServiceActive")) + { + mUpdater->startChecking(); + } +} void LLAppViewer::checkForCrash(void) { diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index fdc3b9ef9e..ea44ade8c6 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -39,7 +39,7 @@ class LLTextureCache; class LLImageDecodeThread; class LLTextureFetch; class LLWatchdogTimeout; -class LLCommandLineParser; +class LLUpdaterService; struct apr_dso_handle_t; @@ -186,7 +186,7 @@ private: bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. - + void initUpdater(); // Initialize the updater service. bool initCache(); // Initialize local client cache. @@ -260,7 +260,13 @@ private: std::set mPlugins; + boost::scoped_ptr mUpdater; + + //--------------------------------------------- + //*NOTE: Mani - legacy updater stuff + // Still useable? public: + //some information for updater typedef struct { @@ -270,6 +276,7 @@ public: static LLUpdaterInfo *sUpdaterInfo ; void launchUpdater(); + //--------------------------------------------- }; // consts from viewer.h diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 050e34ade9..21467a2ab8 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -36,7 +36,7 @@ #include "llbufferstream.h" #include "llui.h" -#include "llversionviewer.h" +#include "llversioninfo.h" #include "llviewercontrol.h" #include "jsoncpp/reader.h" @@ -64,11 +64,11 @@ 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)", - LL_CHANNEL, - LL_VERSION_MAJOR, - LL_VERSION_MINOR, - LL_VERSION_PATCH, - LL_VERSION_BUILD ); + LLVersionInfo::getChannel(), + LLVersionInfo::getMajor(), + LLVersionInfo::getMinor(), + LLVersionInfo::getPatch(), + LLVersionInfo::getBuild()); if (!m_Header.size()) { diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index df9404474c..a8a1d685f7 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -55,3 +55,13 @@ if(LL_TESTS) LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}") endif(LL_TESTS) + +set(UPDATER_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/viewer_components/updater + CACHE INTERNAL "" +) + +set(UPDATER_LIBRARIES + llupdaterservice + CACHE INTERNAL "" +) diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 6c7619a2b9..28c942b5f2 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -27,18 +27,19 @@ #include "llupdaterservice.h" -#include "llsingleton.h" #include "llpluginprocessparent.h" #include +#include -class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, - public LLSingleton +boost::weak_ptr gUpdater; + +class LLUpdaterServiceImpl : public LLPluginProcessParentOwner { std::string mUrl; std::string mChannel; std::string mVersion; - unsigned int mUpdateCheckPeriod; + unsigned int mCheckPeriod; bool mIsChecking; boost::scoped_ptr mPlugin; @@ -52,17 +53,20 @@ public: virtual void pluginLaunchFailed(); virtual void pluginDied(); - void setURL(const std::string& url); - void setChannel(const std::string& channel); - void setVersion(const std::string& version); - void setUpdateCheckPeriod(unsigned int seconds); + void setParams(const std::string& url, + const std::string& channel, + const std::string& version); + + void setCheckPeriod(unsigned int seconds); + void startChecking(); void stopChecking(); + bool isChecking(); }; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), - mUpdateCheckPeriod(0), + mCheckPeriod(0), mPlugin(0) { // Create the plugin parent, this is the owner. @@ -87,42 +91,35 @@ void LLUpdaterServiceImpl::pluginDied() { }; -void LLUpdaterServiceImpl::setURL(const std::string& url) -{ - if(mUrl != url) - { - mUrl = url; - } -} - -void LLUpdaterServiceImpl::setChannel(const std::string& channel) +void LLUpdaterServiceImpl::setParams(const std::string& url, + const std::string& channel, + const std::string& version) { - if(mChannel != channel) - { - mChannel = channel; - } -} - -void LLUpdaterServiceImpl::setVersion(const std::string& version) -{ - if(mVersion != version) + if(mIsChecking) { - mVersion = version; + throw LLUpdaterService::UsageError("Call LLUpdaterService::stopCheck()" + " before setting params."); } + + mUrl = url; + mChannel = channel; + mVersion = version; } -void LLUpdaterServiceImpl::setUpdateCheckPeriod(unsigned int seconds) +void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds) { - if(mUpdateCheckPeriod != seconds) - { - mUpdateCheckPeriod = seconds; - } + mCheckPeriod = seconds; } void LLUpdaterServiceImpl::startChecking() { if(!mIsChecking) { + if(mUrl.empty() || mChannel.empty() || mVersion.empty()) + { + throw LLUpdaterService::UsageError("Set params before call to " + "LLUpdaterService::startCheck()."); + } mIsChecking = true; } } @@ -135,42 +132,54 @@ void LLUpdaterServiceImpl::stopChecking() } } +bool LLUpdaterServiceImpl::isChecking() +{ + return mIsChecking; +} + //----------------------------------------------------------------------- // Facade interface LLUpdaterService::LLUpdaterService() { + if(gUpdater.expired()) + { + mImpl = + boost::shared_ptr(new LLUpdaterServiceImpl()); + gUpdater = mImpl; + } + else + { + mImpl = gUpdater.lock(); + } } LLUpdaterService::~LLUpdaterService() { } -void LLUpdaterService::setURL(const std::string& url) -{ - LLUpdaterServiceImpl::getInstance()->setURL(url); -} - -void LLUpdaterService::setChannel(const std::string& channel) +void LLUpdaterService::setParams(const std::string& url, + const std::string& chan, + const std::string& vers) { - LLUpdaterServiceImpl::getInstance()->setChannel(channel); + mImpl->setParams(url, chan, vers); } -void LLUpdaterService::setVersion(const std::string& version) -{ - LLUpdaterServiceImpl::getInstance()->setVersion(version); -} - -void LLUpdaterService::setUpdateCheckPeriod(unsigned int seconds) +void LLUpdaterService::setCheckPeriod(unsigned int seconds) { - LLUpdaterServiceImpl::getInstance()->setUpdateCheckPeriod(seconds); + mImpl->setCheckPeriod(seconds); } void LLUpdaterService::startChecking() { - LLUpdaterServiceImpl::getInstance()->startChecking(); + mImpl->startChecking(); } void LLUpdaterService::stopChecking() { - LLUpdaterServiceImpl::getInstance()->stopChecking(); + mImpl->stopChecking(); +} + +bool LLUpdaterService::isChecking() +{ + return mImpl->isChecking(); } diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 33d0dc0816..6459ca49f8 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -26,11 +26,16 @@ #ifndef LL_UPDATERSERVICE_H #define LL_UPDATERSERVICE_H +#include + +class LLUpdaterServiceImpl; + class LLUpdaterService { public: class UsageError: public std::runtime_error { + public: UsageError(const std::string& msg) : std::runtime_error(msg) {} }; @@ -39,14 +44,18 @@ public: // The base URL. // *NOTE:Mani The grid, if any, would be embedded in the base URL. - void setURL(const std::string& url); - void setChannel(const std::string& channel); - void setVersion(const std::string& version); - - void setUpdateCheckPeriod(unsigned int seconds); + void setParams(const std::string& url, + const std::string& channel, + const std::string& version); + + void setCheckPeriod(unsigned int seconds); void startChecking(); void stopChecking(); + bool isChecking(); + +private: + boost::shared_ptr mImpl; }; #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 9edf15ba11..73cf6ea6eb 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -1,50 +1,50 @@ -/** - * @file llupdaterservice_test.cpp - * @brief Tests of 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$ - */ - -// Precompiled header -#include "linden_common.h" -// associated header -#include "../llupdaterservice.h" - -#include "../../../test/lltut.h" -//#define DEBUG_ON -#include "../../../test/debug.h" - -#include "llevents.h" -#include "llpluginprocessparent.h" - -/***************************************************************************** -* MOCK'd -*****************************************************************************/ -LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {} -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) -: mOwner(owner), - mIncomingQueueMutex(NULL) -{ -} +/** + * @file llupdaterservice_test.cpp + * @brief Tests of 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$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "../llupdaterservice.h" + +#include "../../../test/lltut.h" +//#define DEBUG_ON +#include "../../../test/debug.h" + +#include "llevents.h" +#include "llpluginprocessparent.h" + +/***************************************************************************** +* MOCK'd +*****************************************************************************/ +LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {} +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) +: mOwner(owner), + mIncomingQueueMutex(gAPRPoolp) +{ +} LLPluginProcessParent::~LLPluginProcessParent() {} LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){} @@ -52,30 +52,77 @@ LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){} void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {} int LLPluginMessagePipeOwner::socketError(int) { return 0; } void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) {} -void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {} -LLPluginMessage::~LLPluginMessage() {} - -/***************************************************************************** -* TUT -*****************************************************************************/ -namespace tut -{ - struct llupdaterservice_data - { - llupdaterservice_data() : - pumps(LLEventPumps::instance()) - {} - LLEventPumps& pumps; - }; - - typedef test_group llupdaterservice_group; - typedef llupdaterservice_group::object llupdaterservice_object; - llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); - - template<> template<> - void llupdaterservice_object::test<1>() - { - DEBUG; - ensure_equals("Dummy", 0, 0); - } -} +void LLPluginMessagePipeOwner::setMessagePipe(class LLPluginMessagePipe *) {} +LLPluginMessage::~LLPluginMessage() {} + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct llupdaterservice_data + { + llupdaterservice_data() : + pumps(LLEventPumps::instance()), + test_url("dummy_url"), + test_channel("dummy_channel"), + test_version("dummy_version") + {} + LLEventPumps& pumps; + std::string test_url; + std::string test_channel; + std::string test_version; + }; + + typedef test_group llupdaterservice_group; + typedef llupdaterservice_group::object llupdaterservice_object; + llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); + + template<> template<> + void llupdaterservice_object::test<1>() + { + DEBUG; + LLUpdaterService updater; + bool got_usage_error = false; + try + { + updater.startChecking(); + } + catch(LLUpdaterService::UsageError) + { + got_usage_error = true; + } + ensure("Caught start before params", got_usage_error); + } + + template<> template<> + void llupdaterservice_object::test<2>() + { + DEBUG; + LLUpdaterService updater; + bool got_usage_error = false; + try + { + updater.setParams(test_url, test_channel, test_version); + updater.startChecking(); + updater.setParams("other_url", test_channel, test_version); + } + catch(LLUpdaterService::UsageError) + { + got_usage_error = true; + } + ensure("Caught params while running", got_usage_error); + } + + template<> template<> + void llupdaterservice_object::test<3>() + { + DEBUG; + LLUpdaterService updater; + updater.setParams(test_url, test_channel, test_version); + updater.startChecking(); + ensure(updater.isChecking()); + updater.stopChecking(); + ensure(!updater.isChecking()); + } +} -- cgit v1.3 From ca9594af28ce2e1cc8bb333a0fa7384dae718a9a Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 28 Oct 2010 16:47:05 -0700 Subject: shell of the update checker; it will just print a message to the log depending on the result of the check one time. --- indra/newview/llappviewer.cpp | 8 +- indra/newview/lltranslate.cpp | 2 +- indra/viewer_components/updater/CMakeLists.txt | 2 + .../viewer_components/updater/llupdatechecker.cpp | 131 +++++++++++++++++++++ indra/viewer_components/updater/llupdatechecker.h | 69 +++++++++++ .../viewer_components/updater/llupdaterservice.cpp | 31 ++++- .../updater/tests/llupdaterservice_test.cpp | 6 + 7 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 indra/viewer_components/updater/llupdatechecker.cpp create mode 100644 indra/viewer_components/updater/llupdatechecker.h (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e6feaae504..06300141be 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(); @@ -980,7 +977,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..a19b8be607 --- /dev/null +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -0,0 +1,131 @@ +/** + * @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 +#include "llhttpclient.h" +#include "llupdatechecker.h" + + +class LLUpdateChecker::Implementation: + public LLHTTPClient::Responder +{ +public: + + Implementation(Client & client); + 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; + 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) +{ + ; // No op. +} + + +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, this); +} + +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; + } else if(!content["valid"].asBoolean()) { + LL_INFOS("UpdateCheck") << "version invalid" << llendl; + } else if(content["latest_version"].asString() != mVersion) { + LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl; + } else { + LL_INFOS("UpdateCheck") << "up to date" << llendl; + } +} + + +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) +{ + static boost::format urlFormat("%s/version/%s/%s"); + urlFormat % host % channel % version; + return urlFormat.str(); +} + diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h new file mode 100644 index 0000000000..d2ec848e14 --- /dev/null +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -0,0 +1,69 @@ +/** + * @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 + + +// +// 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 mImplementation; +}; + + +// +// The client interface implemented by a requestor checking for an update. +// +class LLUpdateChecker::Client +{ + // 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..e0f23722dd 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -26,6 +26,7 @@ #include "linden_common.h" #include "llupdaterservice.h" +#include "llupdatechecker.h" #include "llpluginprocessparent.h" #include @@ -33,7 +34,9 @@ boost::weak_ptr gUpdater; -class LLUpdaterServiceImpl : public LLPluginProcessParentOwner +class LLUpdaterServiceImpl : + public LLPluginProcessParentOwner, + public LLUpdateChecker::Client { std::string mUrl; std::string mChannel; @@ -42,7 +45,9 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner unsigned int mCheckPeriod; bool mIsChecking; boost::scoped_ptr mPlugin; - + + LLUpdateChecker mUpdateChecker; + public: LLUpdaterServiceImpl(); virtual ~LLUpdaterServiceImpl() {} @@ -62,12 +67,21 @@ 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); + }; + 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)); @@ -121,6 +135,8 @@ void LLUpdaterServiceImpl::startChecking() "LLUpdaterService::startCheck()."); } mIsChecking = true; + + mUpdateChecker.check(mUrl, mChannel, mVersion); } } @@ -137,6 +153,15 @@ bool LLUpdaterServiceImpl::isChecking() return mIsChecking; } +void LLUpdaterServiceImpl::error(std::string const & message) {} + +void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) {} + +void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) {} + +void LLUpdaterServiceImpl::upToDate(void) {} + + //----------------------------------------------------------------------- // Facade interface LLUpdaterService::LLUpdaterService() 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 -- cgit v1.3 From 7622ab9249506539894d0e33d4c2a8fd9fb3e3ac Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 4 Nov 2010 11:33:02 -0700 Subject: just barely working udate downloading service; missing little nicities like error checking and sill stuff like that. --- .../viewer_components/updater/llupdatechecker.cpp | 9 +- indra/viewer_components/updater/llupdatechecker.h | 7 +- .../updater/llupdatedownloader.cpp | 128 +++++++++++++++++++-- .../viewer_components/updater/llupdatedownloader.h | 12 +- .../viewer_components/updater/llupdaterservice.cpp | 24 ++-- .../updater/tests/llupdaterservice_test.cpp | 4 + 6 files changed, 159 insertions(+), 25 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 9cfa919b39..596b122a25 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -120,17 +120,19 @@ void LLUpdateChecker::Implementation::completed(U32 status, const std::string & reason, const LLSD & content) { - mInProgress = false; + 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()); + LLURI uri(content["download_url"].asString()); + mClient.requiredUpdate(content["latest_version"].asString(), uri); } else if(content["latest_version"].asString() != mVersion) { LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl; - mClient.optionalUpdate(content["latest_version"].asString()); + LLURI uri(content["download_url"].asString()); + mClient.optionalUpdate(content["latest_version"].asString(), uri); } else { LL_INFOS("UpdateCheck") << "up to date" << llendl; mClient.upToDate(); @@ -153,4 +155,3 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, 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 index b630c4d8a6..1f8c6d8a91 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -48,6 +48,9 @@ private: }; +class LLURI; // From lluri.h + + // // The client interface implemented by a requestor checking for an update. // @@ -58,10 +61,10 @@ public: 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; + virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri) = 0; // A newer version is available, and the current version is no longer valid. - virtual void requiredUpdate(std::string const & newVersion) = 0; + virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri) = 0; // The checked version is up to date; no newer version exists. virtual void upToDate(void) = 0; diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 4adf9c42b1..21e4ce94cc 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -24,6 +24,8 @@ */ #include "linden_common.h" +#include +#include #include "lldir.h" #include "llfile.h" #include "llsd.h" @@ -37,20 +39,27 @@ class LLUpdateDownloader::Implementation: { public: Implementation(LLUpdateDownloader::Client & client); + ~Implementation(); void cancel(void); void download(LLURI const & uri); bool isDownloading(void); - + void onHeader(void * header, size_t size); + void onBody(void * header, size_t size); private: static const char * sSecondLifeUpdateRecord; LLUpdateDownloader::Client & mClient; + CURL * mCurl; + llofstream mDownloadStream; std::string mDownloadRecordPath; + void initializeCurlGet(std::string const & url); void resumeDownloading(LLSD const & downloadData); void run(void); bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData); void startDownloading(LLURI const & uri); + + LOG_CLASS(LLUpdateDownloader::Implementation); }; @@ -89,6 +98,23 @@ bool LLUpdateDownloader::isDownloading(void) //----------------------------------------------------------------------------- +namespace { + size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader) + { + size_t bytes = blockSize * blocks; + reinterpret_cast(downloader)->onBody(data, bytes); + return bytes; + } + + size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader) + { + size_t bytes = blockSize * blocks; + reinterpret_cast(downloader)->onHeader(data, bytes); + return bytes; + } +} + + const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml"; @@ -96,35 +122,116 @@ const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord = LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): LLThread("LLUpdateDownloader"), mClient(client), + mCurl(0), mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord)) { - ; // No op. + CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. + llassert(code = CURLE_OK); // TODO: real error handling here. } -void LLUpdateDownloader::Implementation::cancel(void) +LLUpdateDownloader::Implementation::~Implementation() { + if(mCurl) curl_easy_cleanup(mCurl); } +void LLUpdateDownloader::Implementation::cancel(void) +{ + llassert(!"not implemented"); +} + + void LLUpdateDownloader::Implementation::download(LLURI const & uri) { LLSD downloadData; if(shouldResumeOngoingDownload(uri, downloadData)){ - + startDownloading(uri); // TODO: Implement resume. } else { - + startDownloading(uri); } } bool LLUpdateDownloader::Implementation::isDownloading(void) { - return false; + return !isStopped(); +} + +void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) +{ + char const * headerPtr = reinterpret_cast (buffer); + std::string header(headerPtr, headerPtr + size); + size_t colonPosition = header.find(':'); + if(colonPosition == std::string::npos) return; // HTML response; ignore. + + if(header.substr(0, colonPosition) == "Content-Length") { + try { + size_t firstDigitPos = header.find_first_of("0123456789", colonPosition); + size_t lastDigitPos = header.find_last_of("0123456789"); + std::string contentLength = header.substr(firstDigitPos, lastDigitPos - firstDigitPos + 1); + size_t size = boost::lexical_cast(contentLength); + LL_INFOS("UpdateDownload") << "download size is " << size << LL_ENDL; + + LLSD downloadData; + llifstream idataStream(mDownloadRecordPath); + LLSDSerialize parser; + parser.fromXMLDocument(downloadData, idataStream); + idataStream.close(); + downloadData["size"] = LLSD(LLSD::Integer(size)); + llofstream odataStream(mDownloadRecordPath); + parser.toPrettyXML(downloadData, odataStream); + } catch (std::exception const & e) { + LL_WARNS("UpdateDownload") << "unable to read content length (" + << e.what() << ")" << LL_ENDL; + } + } else { + ; // No op. + } +} + + +void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) +{ + mDownloadStream.write(reinterpret_cast(buffer), size); +} + + +void LLUpdateDownloader::Implementation::run(void) +{ + CURLcode code = curl_easy_perform(mCurl); + if(code == CURLE_OK) { + LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; + mClient.downloadComplete(); + } else { + LL_WARNS("UpdateDownload") << "download failed with error " << code << LL_ENDL; + mClient.downloadError("curl error"); + } +} + + +void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url) +{ + if(mCurl == 0) { + mCurl = curl_easy_init(); + } else { + curl_easy_reset(mCurl); + } + + llassert(mCurl != 0); // TODO: real error handling here. + + CURLcode code; + code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true); + code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function); + code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this); + code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function); + code = curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this); + code = curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true); + code = curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()); } -void resumeDownloading(LLSD const & downloadData) +void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & downloadData) { } @@ -160,9 +267,14 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri) LLSD path = uri.pathArray(); std::string fileName = path[path.size() - 1].asString(); std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); + LL_INFOS("UpdateDownload") << "downloading " << filePath << LL_ENDL; + LL_INFOS("UpdateDownload") << "from " << uri.asString() << LL_ENDL; + downloadData["path"] = filePath; llofstream dataStream(mDownloadRecordPath); LLSDSerialize parser; parser.toPrettyXML(downloadData, dataStream); - llofstream downloadStream(filePath); + mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary); + initializeCurlGet(uri.asString()); + start(); } diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 9dc5d789ce..6118c4338e 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -27,6 +27,7 @@ #define LL_UPDATE_DOWNLOADER_H +#include #include #include #include "lluri.h" @@ -38,15 +39,19 @@ class LLUpdateDownloader { public: + class BusyError; class Client; class Implementation; LLUpdateDownloader(Client & client); - // Cancel any in progress download. + // Cancel any in progress download; a no op if none is in progress. void cancel(void); // Start a new download. + // + // This method will throw a BusyException instance if a download is already + // in progress. void download(LLURI const & uri); // Returns true if a download is in progress. @@ -61,12 +66,13 @@ private: // An interface to be implemented by clients initiating a update download. // class LLUpdateDownloader::Client { +public: // The download has completed successfully. - void downloadComplete(void); + virtual void downloadComplete(void) = 0; // The download failed. - void downloadError(std::string const & message); + virtual void downloadError(std::string const & message) = 0; }; diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index e339c69724..a1b6de38e5 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -25,6 +25,7 @@ #include "linden_common.h" +#include "llupdatedownloader.h" #include "llevents.h" #include "lltimer.h" #include "llupdaterservice.h" @@ -42,7 +43,8 @@ boost::weak_ptr gUpdater; class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, - public LLUpdateChecker::Client + public LLUpdateChecker::Client, + public LLUpdateDownloader::Client { static const std::string sListenerName; @@ -55,6 +57,7 @@ class LLUpdaterServiceImpl : boost::scoped_ptr mPlugin; LLUpdateChecker mUpdateChecker; + LLUpdateDownloader mUpdateDownloader; LLTimer mTimer; void retry(void); @@ -83,10 +86,14 @@ public: // 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 optionalUpdate(std::string const & newVersion, LLURI const & uri); + virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri); virtual void upToDate(void); + // LLUpdateDownloader::Client + void downloadComplete(void) { retry(); } + void downloadError(std::string const & message) { retry(); } + bool onMainLoop(LLSD const & event); }; @@ -96,7 +103,8 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), mCheckPeriod(0), mPlugin(0), - mUpdateChecker(*this) + mUpdateChecker(*this), + mUpdateDownloader(*this) { // Create the plugin parent, this is the owner. mPlugin.reset(new LLPluginProcessParent(this)); @@ -179,14 +187,14 @@ void LLUpdaterServiceImpl::error(std::string const & message) retry(); } -void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) +void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri) { - retry(); + mUpdateDownloader.download(uri); } -void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) +void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri) { - retry(); + mUpdateDownloader.download(uri); } void LLUpdaterServiceImpl::upToDate(void) diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index d93a85cf7d..0ffc1f2c70 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -29,6 +29,7 @@ // associated header #include "../llupdaterservice.h" #include "../llupdatechecker.h" +#include "../llupdatedownloader.h" #include "../../../test/lltut.h" //#define DEBUG_ON @@ -60,6 +61,9 @@ LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {} LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client) {} void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){} +LLUpdateDownloader::LLUpdateDownloader(LLUpdateDownloader::Client & client) +{} +void LLUpdateDownloader::download(LLURI const & ){} /***************************************************************************** * TUT -- cgit v1.3 From dfeb7abe5f690bbd3a908c84c53bbea20a5adb7c Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 4 Nov 2010 14:08:14 -0700 Subject: checker working with v1.0 update protocol. --- indra/newview/app_settings/settings.xml | 24 +++++++++- indra/newview/llappviewer.cpp | 4 +- .../viewer_components/updater/llupdatechecker.cpp | 52 ++++++++++++++-------- indra/viewer_components/updater/llupdatechecker.h | 3 +- .../updater/llupdatedownloader.cpp | 1 + .../viewer_components/updater/llupdaterservice.cpp | 28 ++++++++---- indra/viewer_components/updater/llupdaterservice.h | 6 +-- .../updater/tests/llupdaterservice_test.cpp | 11 ++--- 8 files changed, 91 insertions(+), 38 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8f5cb7c709..cc0e0a78db 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11022,7 +11022,29 @@ Type String Value - http://localhost/agni + http://update.secondlife.com + + UpdaterServicePath + + Comment + Path on the update server host. + Persist + 0 + Type + String + Value + update + + UpdaterServiceProtocolVersion + + Comment + The update protocol version to use. + Persist + 0 + Type + String + Value + v1.0 UploadBakedTexOld diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3a48bc25f1..6bb25969a6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2337,9 +2337,11 @@ void LLAppViewer::initUpdater() std::string url = gSavedSettings.getString("UpdaterServiceURL"); std::string channel = LLVersionInfo::getChannel(); std::string version = LLVersionInfo::getVersion(); + std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion"); + std::string service_path = gSavedSettings.getString("UpdaterServicePath"); U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); - mUpdater->setParams(url, channel, version); + mUpdater->setParams(protocol_version, url, service_path, channel, version); mUpdater->setCheckPeriod(check_period); if(gSavedSettings.getBOOL("UpdaterServiceActive")) { diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 596b122a25..2c60636122 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -41,7 +41,8 @@ public: Implementation(Client & client); ~Implementation(); - void check(std::string const & host, std::string channel, std::string version); + void check(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); // Responder: virtual void completed(U32 status, @@ -50,7 +51,8 @@ public: virtual void error(U32 status, const std::string & reason); private: - std::string buildUrl(std::string const & host, std::string channel, std::string version); + std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); Client & mClient; LLHTTPClient mHttpClient; @@ -74,9 +76,10 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client): } -void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version) +void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version) { - mImplementation->check(host, channel, version); + mImplementation->check(protocolVersion, hostUrl, servicePath, channel, version); } @@ -100,13 +103,14 @@ LLUpdateChecker::Implementation::~Implementation() } -void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version) +void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version) { // llassert(!mInProgress); mInProgress = true; mVersion = version; - std::string checkUrl = buildUrl(host, channel, version); + std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, 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 @@ -125,17 +129,17 @@ void LLUpdateChecker::Implementation::completed(U32 status, 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; - LLURI uri(content["download_url"].asString()); - mClient.requiredUpdate(content["latest_version"].asString(), uri); - } else if(content["latest_version"].asString() != mVersion) { - LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl; - LLURI uri(content["download_url"].asString()); - mClient.optionalUpdate(content["latest_version"].asString(), uri); - } else { + } else if(!content.asBoolean()) { LL_INFOS("UpdateCheck") << "up to date" << llendl; mClient.upToDate(); + } else if(content["required"].asBoolean()) { + LL_INFOS("UpdateCheck") << "version invalid" << llendl; + LLURI uri(content["url"].asString()); + mClient.requiredUpdate(content["version"].asString(), uri); + } else { + LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl; + LLURI uri(content["url"].asString()); + mClient.optionalUpdate(content["version"].asString(), uri); } } @@ -144,14 +148,26 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas { mInProgress = false; LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl; + mClient.error(reason); } -std::string LLUpdateChecker::Implementation::buildUrl(std::string const & host, std::string channel, std::string version) +std::string LLUpdateChecker::Implementation::buildUrl(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version) { +#ifdef LL_WINDOWS + static const char * platform = "win"; +#elif LL_DARWIN + static const char * platform = "mac"; +#else + static const char * platform = "lnx"; +#endif + LLSD path; - path.append("version"); + path.append(servicePath); + path.append(protocolVersion); path.append(channel); path.append(version); - return LLURI::buildHTTP(host, path).asString(); + path.append(platform); + return LLURI::buildHTTP(hostUrl, path).asString(); } diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index 1f8c6d8a91..58aaee4e3d 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -41,7 +41,8 @@ public: 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); + void check(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); private: boost::shared_ptr mImplementation; diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 21e4ce94cc..087d79f804 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -222,6 +222,7 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u CURLcode code; code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true); + code = curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true); code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function); code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this); code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index a1b6de38e5..e865552fb3 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -48,7 +48,9 @@ class LLUpdaterServiceImpl : { static const std::string sListenerName; + std::string mProtocolVersion; std::string mUrl; + std::string mPath; std::string mChannel; std::string mVersion; @@ -74,10 +76,12 @@ public: virtual void pluginLaunchFailed(); virtual void pluginDied(); - void setParams(const std::string& url, + void setParams(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); void startChecking(); @@ -134,7 +138,9 @@ void LLUpdaterServiceImpl::pluginDied() { }; -void LLUpdaterServiceImpl::setParams(const std::string& url, +void LLUpdaterServiceImpl::setParams(const std::string& protocol_version, + const std::string& url, + const std::string& path, const std::string& channel, const std::string& version) { @@ -144,7 +150,9 @@ void LLUpdaterServiceImpl::setParams(const std::string& url, " before setting params."); } + mProtocolVersion = protocol_version; mUrl = url; + mPath = path; mChannel = channel; mVersion = version; } @@ -165,7 +173,7 @@ void LLUpdaterServiceImpl::startChecking() } mIsChecking = true; - mUpdateChecker.check(mUrl, mChannel, mVersion); + mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); } } @@ -218,7 +226,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) { mTimer.stop(); LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); - mUpdateChecker.check(mUrl, mChannel, mVersion); + mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); } else { // Keep on waiting... } @@ -247,11 +255,13 @@ LLUpdaterService::~LLUpdaterService() { } -void LLUpdaterService::setParams(const std::string& url, - const std::string& chan, - const std::string& vers) +void LLUpdaterService::setParams(const std::string& protocol_version, + const std::string& url, + const std::string& path, + const std::string& channel, + const std::string& version) { - mImpl->setParams(url, chan, vers); + mImpl->setParams(protocol_version, url, path, channel, version); } void LLUpdaterService::setCheckPeriod(unsigned int seconds) diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 313ae8ada3..83b09c4bdd 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -42,9 +42,9 @@ public: LLUpdaterService(); ~LLUpdaterService(); - // The base URL. - // *NOTE:Mani The grid, if any, would be embedded in the base URL. - void setParams(const std::string& url, + void setParams(const std::string& version, + const std::string& url, + const std::string& path, const std::string& channel, const std::string& version); diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 0ffc1f2c70..958526e35b 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -60,9 +60,10 @@ LLPluginMessage::LLPluginMessage(LLPluginMessage const&) {} LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client) {} -void LLUpdateChecker::check(std::string const & host, std::string channel, std::string version){} -LLUpdateDownloader::LLUpdateDownloader(LLUpdateDownloader::Client & client) +void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version) {} +LLUpdateDownloader::LLUpdateDownloader(Client & ) {} void LLUpdateDownloader::download(LLURI const & ){} /***************************************************************************** @@ -113,9 +114,9 @@ namespace tut bool got_usage_error = false; try { - updater.setParams(test_url, test_channel, test_version); + updater.setParams("1.0",test_url, "update" ,test_channel, test_version); updater.startChecking(); - updater.setParams("other_url", test_channel, test_version); + updater.setParams("1.0", "other_url", "update", test_channel, test_version); } catch(LLUpdaterService::UsageError) { @@ -129,7 +130,7 @@ namespace tut { DEBUG; LLUpdaterService updater; - updater.setParams(test_url, test_channel, test_version); + updater.setParams("1.0", test_url, "update", test_channel, test_version); updater.startChecking(); ensure(updater.isChecking()); updater.stopChecking(); -- cgit v1.3 From 191e164a503b72c7feae0a46ad0422740b365556 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 4 Nov 2010 15:49:19 -0700 Subject: some better error handling. --- .../viewer_components/updater/llupdatechecker.cpp | 35 ++++-- indra/viewer_components/updater/llupdatechecker.h | 11 +- .../updater/llupdatedownloader.cpp | 122 +++++++++++++-------- .../viewer_components/updater/llupdatedownloader.h | 11 +- .../viewer_components/updater/llupdaterservice.cpp | 20 +++- .../updater/tests/llupdaterservice_test.cpp | 2 +- 6 files changed, 136 insertions(+), 65 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 2c60636122..d31244cc9b 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -24,21 +24,35 @@ */ #include "linden_common.h" +#include #include #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::CheckError: + public std::runtime_error +{ +public: + CheckError(const char * message): + std::runtime_error(message) + { + ; // No op. + } +}; + + class LLUpdateChecker::Implementation: public LLHTTPClient::Responder { public: - Implementation(Client & client); ~Implementation(); void check(std::string const & protocolVersion, std::string const & hostUrl, @@ -50,9 +64,8 @@ public: const LLSD& content); virtual void error(U32 status, const std::string & reason); -private: - std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, - std::string const & servicePath, std::string channel, std::string version); +private: + static const char * sProtocolVersion; Client & mClient; LLHTTPClient mHttpClient; @@ -60,6 +73,9 @@ private: LLHTTPClient::ResponderPtr mMe; std::string mVersion; + std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); + LOG_CLASS(LLUpdateChecker::Implementation); }; @@ -88,6 +104,9 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con //----------------------------------------------------------------------------- +const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0"; + + LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client): mClient(client), mInProgress(false), @@ -106,7 +125,9 @@ LLUpdateChecker::Implementation::~Implementation() void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl, std::string const & servicePath, std::string channel, std::string version) { - // llassert(!mInProgress); + llassert(!mInProgress); + + if(protocolVersion != sProtocolVersion) throw CheckError("unsupported protocol"); mInProgress = true; mVersion = version; @@ -135,11 +156,11 @@ void LLUpdateChecker::Implementation::completed(U32 status, } else if(content["required"].asBoolean()) { LL_INFOS("UpdateCheck") << "version invalid" << llendl; LLURI uri(content["url"].asString()); - mClient.requiredUpdate(content["version"].asString(), uri); + mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString()); } else { LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl; LLURI uri(content["url"].asString()); - mClient.optionalUpdate(content["version"].asString(), uri); + mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString()); } } diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index 58aaee4e3d..cea1f13647 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -38,6 +38,9 @@ public: class Client; class Implementation; + // An exception that may be raised on check errors. + class CheckError; + LLUpdateChecker(Client & client); // Check status of current app on the given host for the channel and version provided. @@ -62,10 +65,14 @@ public: 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, LLURI const & uri) = 0; + virtual void optionalUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash) = 0; // A newer version is available, and the current version is no longer valid. - virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri) = 0; + virtual void requiredUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash) = 0; // The checked version is up to date; no newer version exists. virtual void upToDate(void) = 0; diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 087d79f804..23772e021e 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -24,6 +24,7 @@ */ #include "linden_common.h" +#include #include #include #include "lldir.h" @@ -41,33 +42,56 @@ public: Implementation(LLUpdateDownloader::Client & client); ~Implementation(); void cancel(void); - void download(LLURI const & uri); + void download(LLURI const & uri, std::string const & hash); bool isDownloading(void); void onHeader(void * header, size_t size); void onBody(void * header, size_t size); private: - static const char * sSecondLifeUpdateRecord; - LLUpdateDownloader::Client & mClient; CURL * mCurl; + LLSD mDownloadData; llofstream mDownloadStream; std::string mDownloadRecordPath; void initializeCurlGet(std::string const & url); void resumeDownloading(LLSD const & downloadData); void run(void); - bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData); - void startDownloading(LLURI const & uri); + void startDownloading(LLURI const & uri, std::string const & hash); + void throwOnCurlError(CURLcode code); LOG_CLASS(LLUpdateDownloader::Implementation); }; +namespace { + class DownloadError: + public std::runtime_error + { + public: + DownloadError(const char * message): + std::runtime_error(message) + { + ; // No op. + } + }; + + + const char * gSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml"; +}; + + // LLUpdateDownloader //----------------------------------------------------------------------------- + +std::string LLUpdateDownloader::downloadMarkerPath(void) +{ + return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, gSecondLifeUpdateRecord); +} + + LLUpdateDownloader::LLUpdateDownloader(Client & client): mImplementation(new LLUpdateDownloader::Implementation(client)) { @@ -81,9 +105,9 @@ void LLUpdateDownloader::cancel(void) } -void LLUpdateDownloader::download(LLURI const & uri) +void LLUpdateDownloader::download(LLURI const & uri, std::string const & hash) { - mImplementation->download(uri); + mImplementation->download(uri, hash); } @@ -115,15 +139,11 @@ namespace { } -const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord = - "SecondLifeUpdateDownload.xml"; - - LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): LLThread("LLUpdateDownloader"), mClient(client), mCurl(0), - mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord)) + mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath()) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. llassert(code = CURLE_OK); // TODO: real error handling here. @@ -142,13 +162,15 @@ void LLUpdateDownloader::Implementation::cancel(void) } -void LLUpdateDownloader::Implementation::download(LLURI const & uri) +void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash) { - LLSD downloadData; - if(shouldResumeOngoingDownload(uri, downloadData)){ - startDownloading(uri); // TODO: Implement resume. - } else { - startDownloading(uri); + if(isDownloading()) mClient.downloadError("download in progress"); + + mDownloadData = LLSD(); + try { + startDownloading(uri, hash); + } catch(DownloadError const & e) { + mClient.downloadError(e.what()); } } @@ -173,14 +195,10 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) size_t size = boost::lexical_cast(contentLength); LL_INFOS("UpdateDownload") << "download size is " << size << LL_ENDL; - LLSD downloadData; - llifstream idataStream(mDownloadRecordPath); - LLSDSerialize parser; - parser.fromXMLDocument(downloadData, idataStream); - idataStream.close(); - downloadData["size"] = LLSD(LLSD::Integer(size)); + mDownloadData["size"] = LLSD(LLSD::Integer(size)); llofstream odataStream(mDownloadRecordPath); - parser.toPrettyXML(downloadData, odataStream); + LLSDSerialize parser; + parser.toPrettyXML(mDownloadData, odataStream); } catch (std::exception const & e) { LL_WARNS("UpdateDownload") << "unable to read content length (" << e.what() << ")" << LL_ENDL; @@ -218,17 +236,16 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u curl_easy_reset(mCurl); } - llassert(mCurl != 0); // TODO: real error handling here. + if(mCurl == 0) throw DownloadError("failed to initialize curl"); - CURLcode code; - code = curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true); - code = curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true); - code = curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function); - code = curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this); - code = curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function); - code = curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this); - code = curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true); - code = curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true)); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str())); } @@ -236,7 +253,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & download { } - +/* bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData) { if(!LLFile::isfile(mDownloadRecordPath)) return false; @@ -259,23 +276,42 @@ bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const return true; } + */ -void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri) +void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash) { - LLSD downloadData; - downloadData["url"] = uri.asString(); + mDownloadData["url"] = uri.asString(); + mDownloadData["hash"] = hash; LLSD path = uri.pathArray(); + if(path.size() == 0) throw DownloadError("no file path"); std::string fileName = path[path.size() - 1].asString(); std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); - LL_INFOS("UpdateDownload") << "downloading " << filePath << LL_ENDL; - LL_INFOS("UpdateDownload") << "from " << uri.asString() << LL_ENDL; - downloadData["path"] = filePath; + mDownloadData["path"] = filePath; + + LL_INFOS("UpdateDownload") << "downloading " << filePath << "\n" + << "from " << uri.asString() << LL_ENDL; + llofstream dataStream(mDownloadRecordPath); LLSDSerialize parser; - parser.toPrettyXML(downloadData, dataStream); + parser.toPrettyXML(mDownloadData, dataStream); mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary); initializeCurlGet(uri.asString()); start(); } + + +void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code) +{ + if(code != CURLE_OK) { + const char * errorString = curl_easy_strerror(code); + if(errorString != 0) { + throw DownloadError(curl_easy_strerror(code)); + } else { + throw DownloadError("unknown curl error"); + } + } else { + ; // No op. + } +} diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 6118c4338e..8754ea329c 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -27,7 +27,6 @@ #define LL_UPDATE_DOWNLOADER_H -#include #include #include #include "lluri.h" @@ -39,20 +38,20 @@ class LLUpdateDownloader { public: - class BusyError; class Client; class Implementation; + // Returns the path to the download marker file containing details of the + // latest download. + static std::string downloadMarkerPath(void); + LLUpdateDownloader(Client & client); // Cancel any in progress download; a no op if none is in progress. void cancel(void); // Start a new download. - // - // This method will throw a BusyException instance if a download is already - // in progress. - void download(LLURI const & uri); + void download(LLURI const & uri, std::string const & hash); // Returns true if a download is in progress. bool isDownloading(void); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index e865552fb3..1e0c393539 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -90,8 +90,12 @@ public: // LLUpdateChecker::Client: virtual void error(std::string const & message); - virtual void optionalUpdate(std::string const & newVersion, LLURI const & uri); - virtual void requiredUpdate(std::string const & newVersion, LLURI const & uri); + virtual void optionalUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash); + virtual void requiredUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash); virtual void upToDate(void); // LLUpdateDownloader::Client @@ -195,14 +199,18 @@ void LLUpdaterServiceImpl::error(std::string const & message) retry(); } -void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri) +void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash) { - mUpdateDownloader.download(uri); + mUpdateDownloader.download(uri, hash); } -void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri) +void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, + LLURI const & uri, + std::string const & hash) { - mUpdateDownloader.download(uri); + mUpdateDownloader.download(uri, hash); } void LLUpdaterServiceImpl::upToDate(void) diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 958526e35b..20d0f8fa09 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -64,7 +64,7 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con std::string const & servicePath, std::string channel, std::string version) {} LLUpdateDownloader::LLUpdateDownloader(Client & ) {} -void LLUpdateDownloader::download(LLURI const & ){} +void LLUpdateDownloader::download(LLURI const & , std::string const &){} /***************************************************************************** * TUT -- cgit v1.3 From e1016b5bc7cda03fed98b10f1ee5615245495e00 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Mon, 8 Nov 2010 09:49:38 -0800 Subject: Removed refrences to SLPlugin from LLUpdaterService and test. --- .../viewer_components/updater/llupdaterservice.cpp | 30 ---------------------- .../updater/tests/llupdaterservice_test.cpp | 18 ------------- 2 files changed, 48 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index dc48606cbc..4292da1528 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -31,7 +31,6 @@ #include "llupdaterservice.h" #include "llupdatechecker.h" -#include "llpluginprocessparent.h" #include #include @@ -42,7 +41,6 @@ boost::weak_ptr gUpdater; class LLUpdaterServiceImpl : - public LLPluginProcessParentOwner, public LLUpdateChecker::Client, public LLUpdateDownloader::Client { @@ -56,7 +54,6 @@ class LLUpdaterServiceImpl : unsigned int mCheckPeriod; bool mIsChecking; - boost::scoped_ptr mPlugin; LLUpdateChecker mUpdateChecker; LLUpdateDownloader mUpdateDownloader; @@ -70,12 +67,6 @@ public: LLUpdaterServiceImpl(); virtual ~LLUpdaterServiceImpl(); - // LLPluginProcessParentOwner interfaces - virtual void receivePluginMessage(const LLPluginMessage &message); - virtual bool receivePluginMessageEarly(const LLPluginMessage &message); - virtual void pluginLaunchFailed(); - virtual void pluginDied(); - void setParams(const std::string& protocol_version, const std::string& url, const std::string& path, @@ -110,12 +101,9 @@ const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), mCheckPeriod(0), - mPlugin(0), mUpdateChecker(*this), mUpdateDownloader(*this) { - // Create the plugin parent, this is the owner. - mPlugin.reset(new LLPluginProcessParent(this)); } LLUpdaterServiceImpl::~LLUpdaterServiceImpl() @@ -124,24 +112,6 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl() LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); } -// LLPluginProcessParentOwner interfaces -void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message) -{ -} - -bool LLUpdaterServiceImpl::receivePluginMessageEarly(const LLPluginMessage &message) -{ - return false; -}; - -void LLUpdaterServiceImpl::pluginLaunchFailed() -{ -}; - -void LLUpdaterServiceImpl::pluginDied() -{ -}; - void LLUpdaterServiceImpl::setParams(const std::string& protocol_version, const std::string& url, const std::string& path, diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 20d0f8fa09..7f45ae51fb 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -36,28 +36,10 @@ #include "../../../test/debug.h" #include "llevents.h" -#include "llpluginprocessparent.h" /***************************************************************************** * MOCK'd *****************************************************************************/ -LLPluginProcessParentOwner::~LLPluginProcessParentOwner() {} -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) -: mOwner(owner), - mIncomingQueueMutex(gAPRPoolp) -{ -} - -LLPluginProcessParent::~LLPluginProcessParent() {} -LLPluginMessagePipeOwner::LLPluginMessagePipeOwner(){} -LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner(){} -void LLPluginProcessParent::receiveMessageRaw(const std::string &message) {} -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 & protocolVersion, std::string const & hostUrl, -- cgit v1.3 From b2e84d739b4f5c00b497e57e892fc10d78af8b76 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 10 Nov 2010 14:26:14 -0800 Subject: CHOP-151 Adding startup updater flow to drive update installation and resume. --- indra/newview/llappviewer.cpp | 2 +- indra/viewer_components/updater/CMakeLists.txt | 7 +- .../viewer_components/updater/llupdatedownloader.h | 5 + .../viewer_components/updater/llupdaterservice.cpp | 111 +++++++++++++++++++-- indra/viewer_components/updater/llupdaterservice.h | 20 +++- .../updater/tests/llupdaterservice_test.cpp | 71 ++++++++++++- 6 files changed, 195 insertions(+), 21 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6bb25969a6..335998767c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -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")) { 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 #include +#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 gUpdater; + +namespace +{ + boost::weak_ptr 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 +#include 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 app_exit_callback_t; + template + void setAppExitCallback(F const &callable) + { + app_exit_callback_t aecb = callable; + setImplAppExitCallback(aecb); + } + private: boost::shared_ptr 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 >(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(); -- cgit v1.3 From 41517715844c986aab169502c94f39a9f507eb55 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 10 Nov 2010 19:21:03 -0800 Subject: CHOP-151 Hooked up app exit callback, cleaned up early exit. Rev. by Brad --- indra/llui/llui.cpp | 5 +- indra/newview/llappviewer.cpp | 66 +++++++++++------ .../viewer_components/updater/llupdaterservice.cpp | 86 ++++++++++++++-------- .../updater/tests/llupdaterservice_test.cpp | 12 +-- 4 files changed, 111 insertions(+), 58 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index ff9af21e54..19c42bf61a 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1620,7 +1620,10 @@ void LLUI::initClass(const settings_map_t& settings, void LLUI::cleanupClass() { - sImageProvider->cleanUp(); + if(sImageProvider) + { + sImageProvider->cleanUp(); + } } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 10c03954bc..c06f0c18e8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -661,6 +661,14 @@ bool LLAppViewer::init() initThreads(); writeSystemInfo(); + // Initialize updater service (now that we have an io pump) + initUpdater(); + if(isQuitting()) + { + // Early out here because updater set the quitting flag. + return true; + } + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -979,9 +987,6 @@ bool LLAppViewer::mainLoop() 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(); @@ -1364,11 +1369,14 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning Up" << llendflush; // Must clean up texture references before viewer window is destroyed. - LLHUDManager::getInstance()->updateEffects(); - LLHUDObject::updateAll(); - LLHUDManager::getInstance()->cleanupEffects(); - LLHUDObject::cleanupHUDObjects(); - llinfos << "HUD Objects cleaned up" << llendflush; + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->updateEffects(); + LLHUDObject::updateAll(); + LLHUDManager::getInstance()->cleanupEffects(); + LLHUDObject::cleanupHUDObjects(); + llinfos << "HUD Objects cleaned up" << llendflush; + } LLKeyframeDataCache::clear(); @@ -1380,8 +1388,10 @@ bool LLAppViewer::cleanup() // Note: this is where gWorldMap used to be deleted. // Note: this is where gHUDManager used to be deleted. - LLHUDManager::getInstance()->shutdownClass(); - + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->shutdownClass(); + } delete gAssetStorage; gAssetStorage = NULL; @@ -1683,7 +1693,10 @@ bool LLAppViewer::cleanup() #ifndef LL_RELEASE_FOR_DOWNLOAD llinfos << "Auditing VFS" << llendl; - gVFS->audit(); + if(gVFS) + { + gVFS->audit(); + } #endif llinfos << "Misc Cleanup" << llendflush; @@ -2383,8 +2396,13 @@ void LLAppViewer::initUpdater() std::string service_path = gSavedSettings.getString("UpdaterServicePath"); U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); - mUpdater->initialize(protocol_version, url, service_path, channel, version); - mUpdater->setCheckPeriod(check_period); + mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this)); + mUpdater->initialize(protocol_version, + url, + service_path, + channel, + version); + mUpdater->setCheckPeriod(check_period); if(gSavedSettings.getBOOL("UpdaterServiceActive")) { mUpdater->startChecking(); @@ -2550,15 +2568,18 @@ void LLAppViewer::cleanupSavedSettings() // save window position if not maximized // as we don't track it in callbacks - BOOL maximized = gViewerWindow->mWindow->getMaximized(); - if (!maximized) + if(NULL != gViewerWindow) { - LLCoordScreen window_pos; - - if (gViewerWindow->mWindow->getPosition(&window_pos)) + BOOL maximized = gViewerWindow->mWindow->getMaximized(); + if (!maximized) { - gSavedSettings.setS32("WindowX", window_pos.mX); - gSavedSettings.setS32("WindowY", window_pos.mY); + LLCoordScreen window_pos; + + if (gViewerWindow->mWindow->getPosition(&window_pos)) + { + gSavedSettings.setS32("WindowX", window_pos.mX); + gSavedSettings.setS32("WindowY", window_pos.mY); + } } } @@ -4297,7 +4318,10 @@ void LLAppViewer::disconnectViewer() // This is where we used to call gObjectList.destroy() and then delete gWorldp. // Now we just ask the LLWorld singleton to cleanly shut down. - LLWorld::getInstance()->destroyClass(); + if(LLWorld::instanceExists()) + { + LLWorld::getInstance()->destroyClass(); + } // call all self-registered classes LLDestroyClassList::instance().fireCallbacks(); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 28d9075efa..466b27f6fe 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -68,6 +68,7 @@ class LLUpdaterServiceImpl : unsigned int mCheckPeriod; bool mIsChecking; + bool mIsDownloading; LLUpdateChecker mUpdateChecker; LLUpdateDownloader mUpdateDownloader; @@ -115,14 +116,14 @@ public: bool onMainLoop(LLSD const & event); private: - void retry(void); - + void restartTimer(unsigned int seconds); }; const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), + mIsDownloading(false), mCheckPeriod(0), mUpdateChecker(*this), mUpdateDownloader(*this) @@ -141,10 +142,10 @@ void LLUpdaterServiceImpl::initialize(const std::string& protocol_version, const std::string& channel, const std::string& version) { - if(mIsChecking) + if(mIsChecking || mIsDownloading) { - throw LLUpdaterService::UsageError("Call LLUpdaterService::stopCheck()" - " before setting params."); + throw LLUpdaterService::UsageError("LLUpdaterService::initialize call " + "while updater is running."); } mProtocolVersion = protocol_version; @@ -167,16 +168,20 @@ void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds) void LLUpdaterServiceImpl::startChecking() { - if(!mIsChecking) + if(mUrl.empty() || mChannel.empty() || mVersion.empty()) { - if(mUrl.empty() || mChannel.empty() || mVersion.empty()) - { - throw LLUpdaterService::UsageError("Set params before call to " - "LLUpdaterService::startCheck()."); - } - mIsChecking = true; - - mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); + throw LLUpdaterService::UsageError("Set params before call to " + "LLUpdaterService::startCheck()."); + } + + mIsChecking = true; + + if(!mIsDownloading) + { + // Checking can only occur during the mainloop. + // reset the timer to 0 so that the next mainloop event + // triggers a check; + restartTimer(0); } } @@ -185,6 +190,7 @@ void LLUpdaterServiceImpl::stopChecking() if(mIsChecking) { mIsChecking = false; + mTimer.stop(); } } @@ -205,16 +211,21 @@ bool LLUpdaterServiceImpl::checkForInstall() // Found an update info - now lets see if its valid. LLSD update_info; LLSDSerialize::fromXMLDocument(update_info, update_marker); + update_marker.close(); + LLFile::remove(update_marker_path()); // Get the path to the installer file. LLSD path = update_info.get("path"); if(path.isDefined() && !path.asString().empty()) { // install! + + if(mAppExitCallback) + { + mAppExitCallback(); + } } - update_marker.close(); - LLFile::remove(update_marker_path()); result = true; } return result; @@ -226,7 +237,7 @@ bool LLUpdaterServiceImpl::checkForResume() llstat stat_info; if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info)) { - mIsChecking = true; + mIsDownloading = true; mUpdateDownloader.resume(); result = true; } @@ -235,13 +246,18 @@ bool LLUpdaterServiceImpl::checkForResume() void LLUpdaterServiceImpl::error(std::string const & message) { - retry(); + if(mIsChecking) + { + restartTimer(mCheckPeriod); + } } void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri, std::string const & hash) { + mTimer.stop(); + mIsDownloading = true; mUpdateDownloader.download(uri, hash); } @@ -249,50 +265,60 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri, std::string const & hash) { + mTimer.stop(); + mIsDownloading = true; mUpdateDownloader.download(uri, hash); } void LLUpdaterServiceImpl::upToDate(void) { - retry(); + if(mIsChecking) + { + restartTimer(mCheckPeriod); + } } void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) { + mIsDownloading = false; + // Save out the download data to the SecondLifeUpdateReady - // marker file. + // 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(); + mIsDownloading = false; + + // Restart the + if(mIsChecking) + { + restartTimer(mCheckPeriod); + } } -void LLUpdaterServiceImpl::retry(void) +void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) { LL_INFOS("UpdaterService") << "will check for update again in " << mCheckPeriod << " seconds" << LL_ENDL; mTimer.start(); - mTimer.setTimerExpirySec(mCheckPeriod); + mTimer.setTimerExpirySec(seconds); LLEventPumps::instance().obtain("mainloop").listen( sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) { - if(mTimer.hasExpired()) + if(mTimer.getStarted() && mTimer.hasExpired()) { mTimer.stop(); LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); - } else { + } + else + { // Keep on waiting... } diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 57732ad0a5..aa30fa717d 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -102,12 +102,12 @@ 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 >(NULL,true) -{} - +llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, + ios_base::openmode _Mode, + int _Prot) : + std::basic_istream >(NULL,true) +{} + llus_mock_llifstream::~llus_mock_llifstream() {} bool llus_mock_llifstream::is_open() const {return true;} void llus_mock_llifstream::close() {} -- cgit v1.3 From 6e15957d909787ba612004903f04335a593b5348 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 11 Nov 2010 09:40:30 -0800 Subject: run install script on successful download --- indra/newview/viewer_manifest.py | 10 ++++--- .../updater/llupdateinstaller.cpp | 13 +++++---- .../viewer_components/updater/llupdaterservice.cpp | 33 ++++++++++++++++++++-- .../updater/tests/llupdaterservice_test.cpp | 6 ++++ 4 files changed, 50 insertions(+), 12 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f95697adb6..0073641ed4 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -571,14 +571,16 @@ class DarwinManifest(ViewerManifest): # copy additional libs in /Contents/MacOS/ self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib") + + + if self.prefix(src="../viewer_components/updater", dst="MacOS"): + self.path("update_install") + self.end_prefix() + # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): super(DarwinManifest, self).construct() - - if self.prefix(src="../viewer_components/updater", dst=""): - self.path("update_install") - self.end_prefix() if self.prefix("cursors_mac"): self.path("*.tif") diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 52744b0479..10d5edc6a0 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -49,26 +49,29 @@ namespace { int ll_install_update(std::string const & script, std::string const & updatePath, LLInstallScriptMode mode) { - std::string finalPath; + std::string actualScriptPath; switch(mode) { case LL_COPY_INSTALL_SCRIPT_TO_TEMP: try { - finalPath = copy_to_temp(updatePath); + actualScriptPath = copy_to_temp(script); } catch (RelocateError &) { return -1; } break; case LL_RUN_INSTALL_SCRIPT_IN_PLACE: - finalPath = updatePath; + actualScriptPath = script; break; default: llassert(!"unpossible copy mode"); } + llinfos << "UpdateInstaller: installing " << updatePath << " using " << + actualScriptPath << LL_ENDL; + LLProcessLauncher launcher; - launcher.setExecutable(script); - launcher.addArgument(finalPath); + launcher.setExecutable(actualScriptPath); + launcher.addArgument(updatePath); int result = launcher.launch(); launcher.orphan(); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 466b27f6fe..43551d6cea 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -30,6 +30,7 @@ #include "lltimer.h" #include "llupdaterservice.h" #include "llupdatechecker.h" +#include "llupdateinstaller.h" #include #include @@ -52,6 +53,26 @@ namespace return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, UPDATE_MARKER_FILENAME); } + + std::string install_script_path(void) + { +#ifdef LL_WINDOWS + std::string scriptFile = "update_install.bat"; +#else + std::string scriptFile = "update_install"; +#endif + return gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, scriptFile); + } + + LLInstallScriptMode install_script_mode(void) + { +#ifdef LL_WINDOWS + return LL_COPY_INSTALL_SCRIPT_TO_TEMP; +#else + return LL_RUN_INSTALL_SCRIPT_IN_PLACE; +#endif + }; + } class LLUpdaterServiceImpl : @@ -218,11 +239,17 @@ bool LLUpdaterServiceImpl::checkForInstall() LLSD path = update_info.get("path"); if(path.isDefined() && !path.asString().empty()) { - // install! - - if(mAppExitCallback) + int result = ll_install_update(install_script_path(), + update_info["path"].asString(), + install_script_mode()); + + if((result == 0) && mAppExitCallback) { mAppExitCallback(); + } else if(result != 0) { + llwarns << "failed to run update install script" << LL_ENDL; + } else { + ; // No op. } } diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index aa30fa717d..9b56a04ff6 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -30,6 +30,7 @@ #include "../llupdaterservice.h" #include "../llupdatechecker.h" #include "../llupdatedownloader.h" +#include "../llupdateinstaller.h" #include "../../../test/lltut.h" //#define DEBUG_ON @@ -100,6 +101,11 @@ std::string LLUpdateDownloader::downloadMarkerPath(void) void LLUpdateDownloader::resume(void) {} +int ll_install_update(std::string const &, std::string const &, LLInstallScriptMode) +{ + return 0; +} + /* #pragma warning(disable: 4273) llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, -- cgit v1.3 From ec7d36f6cfbed53a30d918415dfa3e429a645ce1 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Mon, 15 Nov 2010 09:38:20 -0800 Subject: added mechanism for install scripts to indicate a failed install and for update service to note the failure; modified mac installer to write marker on error. --- indra/mac_updater/mac_updater.cpp | 35 ++++++++++++++++++---- .../updater/llupdateinstaller.cpp | 11 +++++++ .../viewer_components/updater/llupdateinstaller.h | 7 +++++ .../viewer_components/updater/llupdaterservice.cpp | 14 ++++++++- .../updater/scripts/darwin/update_install | 8 ++++- .../updater/tests/llupdaterservice_test.cpp | 6 ++++ 6 files changed, 74 insertions(+), 7 deletions(-) mode change 100644 => 100755 indra/viewer_components/updater/scripts/darwin/update_install (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 5f6ea4d33b..5d19e8a889 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -66,6 +66,7 @@ const char *gUpdateURL; const char *gProductName; const char *gBundleID; const char *gDmgFile; +const char *gMarkerPath; void *updatethreadproc(void*); @@ -342,6 +343,10 @@ int parse_args(int argc, char **argv) { gDmgFile = argv[j]; } + else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) + { + gMarkerPath = argv[j];; + } } return 0; @@ -370,6 +375,7 @@ int main(int argc, char **argv) gProductName = NULL; gBundleID = NULL; gDmgFile = NULL; + gMarkerPath = NULL; parse_args(argc, argv); if ((gUpdateURL == NULL) && (gDmgFile == NULL)) { @@ -497,11 +503,18 @@ int main(int argc, char **argv) NULL, &retval_mac); } - + + if(gMarkerPath != 0) + { + // Create a install fail marker that can be used by the viewer to + // detect install problems. + std::ofstream stream(gMarkerPath); + if(stream) stream << -1; + } + exit(-1); + } else { + exit(0); } - - // Don't dispose of things, just exit. This keeps the update thread from potentially getting hosed. - exit(0); if(gWindow != NULL) { @@ -713,6 +726,7 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) // This is the one. Return it. *app = ref; found = true; + break; } else { llinfos << name << " is not the bundle we are looking for; move along" << llendl; } @@ -721,9 +735,13 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) } } } - while(!err && !found); + while(!err); + + llinfos << "closing the iterator" << llendl; FSCloseIterator(iterator); + + llinfos << "closed" << llendl; } if(!err && !found) @@ -1084,12 +1102,19 @@ void *updatethreadproc(void*) throw 0; } + sendProgress(0, 0, CFSTR("Searching for the app bundle...")); err = findAppBundleOnDiskImage(&mountRef, &sourceRef); if(err != noErr) { llinfos << "Couldn't find application bundle on mounted disk image." << llendl; throw 0; } + else + { + llinfos << "found the bundle." << llendl; + } + + sendProgress(0, 0, CFSTR("Preparing to copy files...")); FSRef asideRef; char aside[MAX_PATH]; /* Flawfinder: ignore */ diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 10d5edc6a0..6e69bcf28b 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -72,8 +72,19 @@ int ll_install_update(std::string const & script, std::string const & updatePath LLProcessLauncher launcher; launcher.setExecutable(actualScriptPath); launcher.addArgument(updatePath); + launcher.addArgument(ll_install_failed_marker_path().c_str()); int result = launcher.launch(); launcher.orphan(); return result; } + + +std::string const & ll_install_failed_marker_path(void) +{ + static std::string path; + if(path.empty()) { + path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeInstallFailed.marker"); + } + return path; +} diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h index 310bfe4348..6ce08ce6fa 100644 --- a/indra/viewer_components/updater/llupdateinstaller.h +++ b/indra/viewer_components/updater/llupdateinstaller.h @@ -47,4 +47,11 @@ int ll_install_update( LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp? +// +// Returns the path which points to the failed install marker file, should it +// exist. +// +std::string const & ll_install_failed_marker_path(void); + + #endif diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 6cc872f2ca..a1ad3e3381 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -378,7 +378,19 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) { mTimer.stop(); LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); - mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); + + // Check for failed install. + if(LLFile::isfile(ll_install_failed_marker_path())) + { + // TODO: notify the user. + llinfos << "found marker " << ll_install_failed_marker_path() << llendl; + llinfos << "last install attempt failed" << llendl; + LLFile::remove(ll_install_failed_marker_path()); + } + else + { + mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); + } } else { diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install old mode 100644 new mode 100755 index c061d2818f..b174b3570a --- a/indra/viewer_components/updater/scripts/darwin/update_install +++ b/indra/viewer_components/updater/scripts/darwin/update_install @@ -1,3 +1,9 @@ #! /bin/bash -open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2" +# +# The first argument contains the path to the installer app. The second a path +# to a marker file which should be created if the installer fails.q +# + +open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2" -marker "$2" +exit 0 diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 9b56a04ff6..25fd1b034d 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -106,6 +106,12 @@ int ll_install_update(std::string const &, std::string const &, LLInstallScriptM return 0; } +std::string const & ll_install_failed_marker_path() +{ + static std::string wubba; + return wubba; +} + /* #pragma warning(disable: 4273) llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, -- cgit v1.3 From 0018762228c627b27ccc0d98528cfe745ca5d53e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Nov 2010 12:12:44 -0500 Subject: Dummy out LLUpdateDownloader::cancel() too for testing. --- indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 25fd1b034d..390879352c 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -100,6 +100,7 @@ std::string LLUpdateDownloader::downloadMarkerPath(void) } void LLUpdateDownloader::resume(void) {} +void LLUpdateDownloader::cancel(void) {} int ll_install_update(std::string const &, std::string const &, LLInstallScriptMode) { -- cgit v1.3 From c893c55d8a1328a134c956b70e6fef7fd7053d47 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Thu, 18 Nov 2010 17:03:01 -0800 Subject: Fixing bugs discovered in merge with viewer development --- indra/newview/llspeakbutton.cpp | 7 +++++-- indra/newview/llspeakingindicatormanager.cpp | 5 ++++- indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/viewer_components/updater/tests/llupdaterservice_test.cpp') diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp index 3dce66f394..c76ecae4a2 100644 --- a/indra/newview/llspeakbutton.cpp +++ b/indra/newview/llspeakbutton.cpp @@ -134,8 +134,11 @@ LLSpeakButton::LLSpeakButton(const Params& p) LLSpeakButton::~LLSpeakButton() { - LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn); - LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn); + if(LLTransientFloaterMgr::instanceExists()) + { + LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn); + LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn); + } } void LLSpeakButton::setSpeakToolTip(const std::string& msg) diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index ede1d6bebe..9b38bf22ff 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -308,7 +308,10 @@ void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) { - SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator); + if(SpeakingIndicatorManager::instanceExists()) + { + SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator); + } } // EOF diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 390879352c..04ed4e6364 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -61,7 +61,7 @@ class LLDir_Mock : public LLDir BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, - std::string &fname, BOOL wrap) + std::string &fname) { return false; } -- cgit v1.3