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 --- indra/viewer_components/CMakeLists.txt | 2 +- indra/viewer_components/updater/CMakeLists.txt | 51 +++++++++++++++++++ .../viewer_components/updater/llupdaterservice.cpp | 58 +++++++++++++++++++++ indra/viewer_components/updater/llupdaterservice.h | 46 +++++++++++++++++ .../updater/tests/llupdaterservice_test.cpp | 59 ++++++++++++++++++++++ 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 indra/viewer_components/updater/CMakeLists.txt create mode 100644 indra/viewer_components/updater/llupdaterservice.cpp create mode 100644 indra/viewer_components/updater/llupdaterservice.h create mode 100644 indra/viewer_components/updater/tests/llupdaterservice_test.cpp diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt index 0993b64b14..74c9b4568d 100644 --- a/indra/viewer_components/CMakeLists.txt +++ b/indra/viewer_components/CMakeLists.txt @@ -1,4 +1,4 @@ # -*- cmake -*- add_subdirectory(login) - +add_subdirectory(updater) diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt new file mode 100644 index 0000000000..4dc5424142 --- /dev/null +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -0,0 +1,51 @@ +# -*- cmake -*- + +project(updater_service) + +include(00-Common) +if(LL_TESTS) + include(LLAddBuildTest) +endif(LL_TESTS) +include(LLCommon) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ) + +set(updater_service_SOURCE_FILES + llupdaterservice.cpp + ) + +set(updater_service_HEADER_FILES + llupdaterservice.h + ) + +set_source_files_properties(${updater_service_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND + updater_service_SOURCE_FILES + ${updater_service_HEADER_FILES} + ) + +add_library(llupdaterservice + ${updater_service_SOURCE_FILES} + ) + +target_link_libraries(llupdaterservice + ${LLCOMMON_LIBRARIES} + ) + +if(LL_TESTS) + SET(llupdater_service_TEST_SOURCE_FILES + llupdaterservice.cpp + ) + +# set_source_files_properties( +# llupdaterservice.cpp +# PROPERTIES +# LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}" +# ) + + LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}") +endif(LL_TESTS) diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp new file mode 100644 index 0000000000..14906bcef8 --- /dev/null +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -0,0 +1,58 @@ +/** + * @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" + +LLUpdaterService::LLUpdaterService() +{ +} + +LLUpdaterService::~LLUpdaterService() +{ +} + +void LLUpdaterService::setURL(const std::string& url) +{ +} + +void LLUpdaterService::setChannel(const std::string& channel) +{ +} + +void LLUpdaterService::setVersion(const std::string& version) +{ +} + +void LLUpdaterService::setUpdateCheckFrequency(unsigned int seconds) +{ +} + +void LLUpdaterService::startChecking() +{ +} + +void LLUpdaterService::stopChecking() +{ +} diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h new file mode 100644 index 0000000000..7836c2cf7f --- /dev/null +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -0,0 +1,46 @@ +/** + * @file llupdaterservice.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_UPDATERSERVICE_H +#define LL_UPDATERSERVICE_H + +class LLUpdaterService +{ + LLUpdaterService(); + ~LLUpdaterService(); + + // 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 setUpdateCheckFrequency(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 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.2.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(-) 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.2.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(-) 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.2.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 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.2.3 From 609f5bd6810ca16a409f209610e6fac972348cba Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 29 Oct 2010 11:20:54 -0700 Subject: added periodic retry to look for updates --- indra/newview/app_settings/settings.xml | 4 +- .../viewer_components/updater/llupdatechecker.cpp | 19 +++++-- indra/viewer_components/updater/llupdatechecker.h | 2 + .../viewer_components/updater/llupdaterservice.cpp | 63 ++++++++++++++++++++-- 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 371326c0f5..5b9bfd0f9c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11011,7 +11011,7 @@ Type U32 Value - 3600 + 10 UpdaterServiceURL @@ -11022,7 +11022,7 @@ Type String Value - http://secondlife.com/app/update + http://localhost/agni UploadBakedTexOld diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index a19b8be607..ca2959a4ac 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -35,6 +35,7 @@ class LLUpdateChecker::Implementation: public: Implementation(Client & client); + ~Implementation(); void check(std::string const & host, std::string channel, std::string version); // Responder: @@ -49,6 +50,7 @@ private: Client & mClient; LLHTTPClient mHttpClient; bool mInProgress; + LLHTTPClient::ResponderPtr mMe; std::string mVersion; LOG_CLASS(LLUpdateChecker::Implementation); @@ -80,21 +82,28 @@ void LLUpdateChecker::check(std::string const & host, std::string channel, std:: LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client): mClient(client), - mInProgress(false) + mInProgress(false), + mMe(this) { ; // No op. } +LLUpdateChecker::Implementation::~Implementation() +{ + mMe.reset(0); +} + + void LLUpdateChecker::Implementation::check(std::string const & host, std::string channel, std::string version) { - llassert(!mInProgress); + // 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); + mHttpClient.get(checkUrl, mMe); } void LLUpdateChecker::Implementation::completed(U32 status, @@ -105,12 +114,16 @@ 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; + mClient.requiredUpdate(content["latest_version"].asString()); } else if(content["latest_version"].asString() != mVersion) { LL_INFOS("UpdateCheck") << "newer version " << content["latest_version"].asString() << " available" << llendl; + mClient.optionalUpdate(content["latest_version"].asString()); } else { LL_INFOS("UpdateCheck") << "up to date" << llendl; + mClient.upToDate(); } } diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index d2ec848e14..b630c4d8a6 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -42,6 +42,7 @@ public: // 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; }; @@ -52,6 +53,7 @@ private: // class LLUpdateChecker::Client { +public: // An error occurred while checking for an update. virtual void error(std::string const & message) = 0; diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index e0f23722dd..2633dbc015 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -25,6 +25,8 @@ #include "linden_common.h" +#include "llevents.h" +#include "lltimer.h" #include "llupdaterservice.h" #include "llupdatechecker.h" @@ -38,6 +40,8 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, public LLUpdateChecker::Client { + static const std::string ListenerName; + std::string mUrl; std::string mChannel; std::string mVersion; @@ -47,10 +51,15 @@ class LLUpdaterServiceImpl : boost::scoped_ptr mPlugin; LLUpdateChecker mUpdateChecker; + LLTimer mTimer; + + void retry(void); + + LOG_CLASS(LLUpdaterServiceImpl); public: LLUpdaterServiceImpl(); - virtual ~LLUpdaterServiceImpl() {} + virtual ~LLUpdaterServiceImpl(); // LLPluginProcessParentOwner interfaces virtual void receivePluginMessage(const LLPluginMessage &message); @@ -74,8 +83,10 @@ public: virtual void requiredUpdate(std::string const & newVersion); virtual void upToDate(void); + bool onMainLoop(LLSD const & event); }; +const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl"; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), @@ -87,6 +98,12 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mPlugin.reset(new LLPluginProcessParent(this)); } +LLUpdaterServiceImpl::~LLUpdaterServiceImpl() +{ + LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL; + LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); +} + // LLPluginProcessParentOwner interfaces void LLUpdaterServiceImpl::receivePluginMessage(const LLPluginMessage &message) { @@ -153,13 +170,49 @@ bool LLUpdaterServiceImpl::isChecking() return mIsChecking; } -void LLUpdaterServiceImpl::error(std::string const & message) {} +void LLUpdaterServiceImpl::error(std::string const & message) +{ + retry(); +} -void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) {} +void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion) +{ + retry(); +} -void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) {} +void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion) +{ + retry(); +} -void LLUpdaterServiceImpl::upToDate(void) {} +void LLUpdaterServiceImpl::upToDate(void) +{ + retry(); +} + +void LLUpdaterServiceImpl::retry(void) +{ + LL_INFOS("UpdaterService") << "will check for update again in " << + mCheckPeriod << " seconds" << LL_ENDL; + mTimer.start(); + mTimer.setTimerExpirySec(mCheckPeriod); + LLEventPumps::instance().obtain("mainloop").listen( + ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); +} + +bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) +{ + if(mTimer.hasExpired()) + { + mTimer.stop(); + LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); + mUpdateChecker.check(mUrl, mChannel, mVersion); + } else { + // Keep on waiting... + } + + return false; +} //----------------------------------------------------------------------- -- cgit v1.2.3 From 064a8d079917ecd91bd6b47f5f7f353989594593 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 29 Oct 2010 11:22:07 -0700 Subject: restore 1hr polling frequency --- indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5b9bfd0f9c..274c7fbeb8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11011,7 +11011,7 @@ Type U32 Value - 10 + 3600 UpdaterServiceURL -- cgit v1.2.3 From a2a9161e1b2d369689d76668dcad2c0ed7752960 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 29 Oct 2010 11:39:07 -0700 Subject: fix quoting of url in version check. --- indra/viewer_components/updater/llupdatechecker.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index ca2959a4ac..941210d35b 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -26,7 +26,9 @@ #include "linden_common.h" #include #include "llhttpclient.h" +#include "llsd.h" #include "llupdatechecker.h" +#include "lluri.h" class LLUpdateChecker::Implementation: @@ -137,8 +139,10 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas 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(); + LLSD path; + path.append("version"); + path.append(channel); + path.append(version); + return LLURI::buildHTTP(host, path).asString(); } -- cgit v1.2.3 From 8bdd99436580772b825a1e99ae5cf37d20163a8c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 29 Oct 2010 15:26:33 -0400 Subject: Fix #endif SYMBOL (breaks Linux build) --- indra/viewer_components/updater/llupdaterservice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 6459ca49f8..313ae8ada3 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -58,4 +58,4 @@ private: boost::shared_ptr mImpl; }; -#endif LL_UPDATERSERVICE_H +#endif // LL_UPDATERSERVICE_H -- cgit v1.2.3 From 36b8b88153180f637c24709dc94739b5f4c4367e Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Mon, 1 Nov 2010 09:33:30 -0700 Subject: changes in respone to review comments. --- indra/viewer_components/updater/llupdatechecker.cpp | 7 ++++++- indra/viewer_components/updater/llupdaterservice.cpp | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 941210d35b..8733bb7ac0 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -52,7 +52,7 @@ private: Client & mClient; LLHTTPClient mHttpClient; bool mInProgress; - LLHTTPClient::ResponderPtr mMe; + LLHTTPClient::ResponderPtr mMe; std::string mVersion; LOG_CLASS(LLUpdateChecker::Implementation); @@ -105,6 +105,11 @@ void LLUpdateChecker::Implementation::check(std::string const & host, std::strin mVersion = version; std::string checkUrl = buildUrl(host, channel, version); LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl; + + // The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the + // passed object to be silently and automatically deleted. We pass a self- + // referential intrusive pointer stored as an attribute of this class to keep + // the client from deletig the update checker implementation instance. mHttpClient.get(checkUrl, mMe); } diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 2633dbc015..62c909e57b 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -40,7 +40,7 @@ class LLUpdaterServiceImpl : public LLPluginProcessParentOwner, public LLUpdateChecker::Client { - static const std::string ListenerName; + static const std::string sListenerName; std::string mUrl; std::string mChannel; @@ -86,7 +86,7 @@ public: bool onMainLoop(LLSD const & event); }; -const std::string LLUpdaterServiceImpl::ListenerName = "LLUpdaterServiceImpl"; +const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; LLUpdaterServiceImpl::LLUpdaterServiceImpl() : mIsChecking(false), @@ -101,7 +101,7 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() : LLUpdaterServiceImpl::~LLUpdaterServiceImpl() { LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL; - LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); + LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); } // LLPluginProcessParentOwner interfaces @@ -197,7 +197,7 @@ void LLUpdaterServiceImpl::retry(void) mTimer.start(); mTimer.setTimerExpirySec(mCheckPeriod); LLEventPumps::instance().obtain("mainloop").listen( - ListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); + sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) @@ -205,7 +205,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) if(mTimer.hasExpired()) { mTimer.stop(); - LLEventPumps::instance().obtain("mainloop").stopListening(ListenerName); + LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); mUpdateChecker.check(mUrl, mChannel, mVersion); } else { // Keep on waiting... -- cgit v1.2.3 From 3e43b0f4ca58aa859de455efe9503a6f6602fe6d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 1 Nov 2010 14:21:56 -0400 Subject: On Mac, require at least CMake 2.6.4 for an important bug fix. 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION): before that version it returns "pathname/SLPlugin", whereas the correct answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin". With 2.6.2, the Mac build breaks in a mysterious way. Changing this version requirement should clarify the solution. --- indra/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 8d4969a49e..d01e1869b6 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -22,7 +22,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(Variables) if (DARWIN) - cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR) + # 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION): + # before that version it returns "pathname/SLPlugin", whereas the correct + # answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin". + cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR) endif (DARWIN) if (NOT CMAKE_BUILD_TYPE) -- cgit v1.2.3 From 2125bc0bbb3a5493b0b96bf68889b1f44b2db011 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 1 Nov 2010 15:49:04 -0400 Subject: On Windows, disable this-used-in-initializer warning. --- indra/viewer_components/updater/llupdatechecker.cpp | 3 +++ indra/viewer_components/updater/llupdaterservice.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 941210d35b..331d0269d4 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -30,6 +30,9 @@ #include "llupdatechecker.h" #include "lluri.h" +#if LL_WINDOWS +#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally +#endif class LLUpdateChecker::Implementation: public LLHTTPClient::Responder diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 2633dbc015..1d0ead3cd4 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -34,6 +34,10 @@ #include #include +#if LL_WINDOWS +#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally +#endif + boost::weak_ptr gUpdater; class LLUpdaterServiceImpl : -- cgit v1.2.3 From 6ab2e44e945ddc085a7b4b5f1524de924419a897 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Mon, 1 Nov 2010 15:18:18 -0700 Subject: VWR-23666 Removed setting VersionChannelName. LLVersionInfo::resetChannel() and unit tests. Reviewed by brad. --- indra/newview/CMakeLists.txt | 1 + indra/newview/app_settings/cmd_line.xml | 3 +- indra/newview/app_settings/settings.xml | 11 --- indra/newview/llappviewer.cpp | 25 +++--- indra/newview/llcurrencyuimanager.cpp | 4 +- indra/newview/llfloaterabout.cpp | 4 +- indra/newview/lllogininstance.cpp | 5 +- indra/newview/llpanellogin.cpp | 4 +- indra/newview/llversioninfo.cpp | 37 ++++++++- indra/newview/llversioninfo.h | 7 ++ indra/newview/llviewercontrol.cpp | 1 - indra/newview/llviewercontrol.h | 2 - indra/newview/llviewermedia.cpp | 2 +- indra/newview/llviewerstats.cpp | 3 +- indra/newview/tests/lllogininstance_test.cpp | 9 ++- indra/newview/tests/llversioninfo_test.cpp | 114 +++++++++++++++++++++++++++ 16 files changed, 189 insertions(+), 43 deletions(-) create mode 100644 indra/newview/tests/llversioninfo_test.cpp diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 63982ba87b..a488fb1069 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1858,6 +1858,7 @@ if (LL_TESTS) llmediadataclient.cpp lllogininstance.cpp llviewerhelputil.cpp + llversioninfo.cpp ) ################################################## diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 00d69f805e..a17da8e344 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -361,8 +361,7 @@ count 1 - map-to - VersionChannelName + loginpage diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 371326c0f5..96d4fb1295 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11344,17 +11344,6 @@ Value 0 - VersionChannelName - - Comment - Versioning Channel Name. - Persist - 0 - Type - String - Value - Second Life Release - VertexShaderEnable Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e6feaae504..b122209af8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -662,11 +662,6 @@ bool LLAppViewer::init() initThreads(); writeSystemInfo(); - // Build a string representing the current version number. - gCurrentVersion = llformat("%s %s", - gSavedSettings.getString("VersionChannelName").c_str(), - LLVersionInfo::getVersion().c_str()); - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -905,7 +900,8 @@ bool LLAppViewer::init() gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); // Save the current version to the prefs file - gSavedSettings.setString("LastRunVersion", gCurrentVersion); + gSavedSettings.setString("LastRunVersion", + LLVersionInfo::getVersionAndChannel()); gSimLastTime = gRenderStartTime.getElapsedTimeF32(); gSimFrames = (F32)gFrameCount; @@ -1941,8 +1937,6 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); - gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel()); - #ifndef LL_RELEASE_FOR_DOWNLOAD // provide developer build only overrides for these control variables that are not // persisted to settings.xml @@ -2074,6 +2068,11 @@ bool LLAppViewer::initConfiguration() } } + if(clp.hasOption("channel")) + { + LLVersionInfo::resetChannel(clp.getOption("channel")[0]); + } + // If we have specified crash on startup, set the global so we'll trigger the crash at the right time if(clp.hasOption("crashonstartup")) @@ -2336,7 +2335,7 @@ void LLAppViewer::initUpdater() // Get Channel // Get Version std::string url = gSavedSettings.getString("UpdaterServiceURL"); - std::string channel = gSavedSettings.getString("VersionChannelName"); + std::string channel = LLVersionInfo::getChannel(); std::string version = LLVersionInfo::getVersion(); U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); @@ -2538,7 +2537,7 @@ void LLAppViewer::writeSystemInfo() { gDebugInfo["SLLog"] = LLError::logFileName(); - gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName"); + gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor(); gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch(); @@ -2636,7 +2635,7 @@ void LLAppViewer::handleViewerCrash() //We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version //to check against no matter what - gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName"); + gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor(); @@ -4363,7 +4362,7 @@ void LLAppViewer::handleLoginComplete() initMainloopTimeout("Mainloop Init"); // Store some data to DebugInfo in case of a freeze. - gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName"); + gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel(); gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor(); gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor(); @@ -4469,7 +4468,7 @@ void LLAppViewer::launchUpdater() // *TODO change userserver to be grid on both viewer and sim, since // userserver no longer exists. query_map["userserver"] = LLGridManager::getInstance()->getGridLabel(); - query_map["channel"] = gSavedSettings.getString("VersionChannelName"); + query_map["channel"] = LLVersionInfo::getChannel(); // *TODO constantize this guy // *NOTE: This URL is also used in win_setup/lldownloader.cpp LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index 2b92b228b3..b4a1457f47 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -166,7 +166,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo() gAgent.getSecureSessionID().asString()); keywordArgs.appendString("language", LLUI::getLanguage()); keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy); - keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName")); + keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel()); keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor()); keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor()); keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch()); @@ -241,7 +241,7 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password) { keywordArgs.appendString("password", password); } - keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName")); + keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel()); keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor()); keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor()); keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch()); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 135137069c..8ae3ccbae3 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -213,7 +213,7 @@ LLSD LLFloaterAbout::getInfo() info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion(); info["BUILD_DATE"] = __DATE__; info["BUILD_TIME"] = __TIME__; - info["CHANNEL"] = gSavedSettings.getString("VersionChannelName"); + info["CHANNEL"] = LLVersionInfo::getChannel(); info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url(); @@ -291,7 +291,7 @@ static std::string get_viewer_release_notes_url() std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL"); if (! LLStringUtil::endsWith(url, "/")) url += "/"; - url += gSavedSettings.getString("VersionChannelName") + "/"; + url += LLVersionInfo::getChannel() + "/"; url += LLVersionInfo::getShortVersion(); return LLWeb::escapeURL(url); } diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 029e700c4c..fe84aca147 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -42,6 +42,7 @@ // newview #include "llviewernetwork.h" #include "llviewercontrol.h" +#include "llversioninfo.h" #include "llslurl.h" #include "llstartup.h" #include "llfloaterreg.h" @@ -181,8 +182,8 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia request_params["read_critical"] = false; // handleTOSResponse request_params["last_exec_event"] = mLastExecEvent; request_params["mac"] = hashed_unique_id_string; - request_params["version"] = gCurrentVersion; // Includes channel name - request_params["channel"] = gSavedSettings.getString("VersionChannelName"); + request_params["version"] = LLVersionInfo::getVersionAndChannel(); // Includes channel name + request_params["channel"] = LLVersionInfo::getChannel(); request_params["id0"] = mSerialNumber; mRequestData.clear(); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 467aefc60f..cf567fb208 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -230,7 +230,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, getChild("login")->setDefaultBtn("connect_btn"); - std::string channel = gSavedSettings.getString("VersionChannelName"); + std::string channel = LLVersionInfo::getChannel(); std::string version = llformat("%s (%d)", LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); @@ -817,7 +817,7 @@ void LLPanelLogin::loadLoginPage() LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - char* curl_channel = curl_escape(gSavedSettings.getString("VersionChannelName").c_str(), 0); + char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); char* curl_version = curl_escape(version.c_str(), 0); oStr << "&channel=" << curl_channel; diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 733d05834a..53994c68f2 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -95,9 +95,42 @@ const std::string &LLVersionInfo::getShortVersion() return version; } +namespace +{ + /// Storage of the channel name the viewer is using. + // The channel name is set by hardcoded constant, + // or by calling LLVersionInfo::resetChannel() + std::string sWorkingChannelName(LL_CHANNEL); + + // Storage for the "version and channel" string. + // This will get reset too. + std::string sVersionChannel(""); +} + +//static +const std::string &LLVersionInfo::getVersionAndChannel() +{ + if (sVersionChannel.empty()) + { + // cache the version string + std::ostringstream stream; + stream << LLVersionInfo::getVersion() + << " " + << LLVersionInfo::getChannel(); + sVersionChannel = stream.str(); + } + + return sVersionChannel; +} + //static const std::string &LLVersionInfo::getChannel() { - static std::string name(LL_CHANNEL); - return name; + return sWorkingChannelName; +} + +void LLVersionInfo::resetChannel(const std::string& channel) +{ + sWorkingChannelName = channel; + sVersionChannel.clear(); // Reset version and channel string til next use. } diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h index e468b6ae4e..36defbcd68 100644 --- a/indra/newview/llversioninfo.h +++ b/indra/newview/llversioninfo.h @@ -58,8 +58,15 @@ public: /// return the viewer version as a string like "2.0.0" static const std::string &getShortVersion(); + /// return the viewer version and channel as a string + /// like "2.0.0.200030 Second Life Release" + static const std::string &getVersionAndChannel(); + /// return the channel name, e.g. "Second Life" static const std::string &getChannel(); + + /// reset the channel name used by the viewer. + static void resetChannel(const std::string& channel); }; #endif diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 522b5a7dfa..ebe9f7e275 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -82,7 +82,6 @@ LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings std::string gLastRunVersion; -std::string gCurrentVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h index 22b48f8906..d7191f5c8d 100644 --- a/indra/newview/llviewercontrol.h +++ b/indra/newview/llviewercontrol.h @@ -57,7 +57,5 @@ extern LLControlGroup gCrashSettings; // Set after settings loaded extern std::string gLastRunVersion; -extern std::string gCurrentVersion; - #endif // LL_LLVIEWERCONTROL_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 48ab122edf..13fbce910b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -492,7 +492,7 @@ std::string LLViewerMedia::getCurrentUserAgent() // Just in case we need to check browser differences in A/B test // builds. - std::string channel = gSavedSettings.getString("VersionChannelName"); + std::string channel = LLVersionInfo::getChannel(); // append our magic version number string to the browser user agent id // See the HTTP 1.0 and 1.1 specifications for allowed formats: diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 42266ad233..3b7e44668d 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -48,6 +48,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "llviewercontrol.h" +#include "llversioninfo.h" #include "llfloatertools.h" #include "lldebugview.h" #include "llfasttimerview.h" @@ -749,7 +750,7 @@ void send_stats() // send fps only for time app spends in foreground agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32(); - agent["version"] = gCurrentVersion; + agent["version"] = LLVersionInfo::getVersionAndChannel(); std::string language = LLUI::getLanguage(); agent["language"] = language; diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index db50b89620..b902c7ab09 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -48,6 +48,9 @@ const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid"); const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno"); +const std::string VIEWERLOGIN_CHANNEL("invalid_channel"); +const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version"); + // Link seams. //----------------------------------------------------------------------------- @@ -160,7 +163,6 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name) //----------------------------------------------------------------------------- #include "../llviewercontrol.h" LLControlGroup gSavedSettings("Global"); -std::string gCurrentVersion = "invalid_version"; LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker(name){} @@ -177,6 +179,10 @@ BOOL LLControlGroup::declareString(const std::string& name, const std::string &i #include "lluicolortable.h" void LLUIColorTable::saveUserSettings(void)const {} +//----------------------------------------------------------------------------- +#include "../llversioninfo.h" +const std::string &LLVersionInfo::getVersionAndChannel() { return VIEWERLOGIN_VERSION_CHANNEL; } +const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; } //----------------------------------------------------------------------------- #include "llnotifications.h" @@ -290,7 +296,6 @@ namespace tut gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE); gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE); gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE); - gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE); gSavedSettings.declareString("NextLoginLocation", "", "", FALSE); gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE); diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp new file mode 100644 index 0000000000..b4f1b0273f --- /dev/null +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -0,0 +1,114 @@ +/** + * @file llversioninfo_test.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 "../test/lltut.h" + +#include "../llversioninfo.h" +#include "llversionviewer.h" + +namespace tut +{ + struct versioninfo + { + versioninfo() + : mResetChannel("Reset Channel") + { + std::ostringstream stream; + stream << LL_VERSION_MAJOR << "." + << LL_VERSION_MINOR << "." + << LL_VERSION_PATCH << "." + << LL_VERSION_BUILD; + mVersion = stream.str(); + stream.str(""); + + stream << LL_VERSION_MAJOR << "." + << LL_VERSION_MINOR << "." + << LL_VERSION_PATCH; + mShortVersion = stream.str(); + stream.str(""); + + stream << mVersion + << " " + << LL_CHANNEL; + mVersionAndChannel = stream.str(); + stream.str(""); + + stream << mVersion + << " " + << mResetChannel; + mResetVersionAndChannel = stream.str(); + } + std::string mResetChannel; + std::string mVersion; + std::string mShortVersion; + std::string mVersionAndChannel; + std::string mResetVersionAndChannel; + }; + + typedef test_group versioninfo_t; + typedef versioninfo_t::object versioninfo_object_t; + tut::versioninfo_t tut_versioninfo("LLVersionInfo"); + + template<> template<> + void versioninfo_object_t::test<1>() + { + ensure_equals("Major version", + LLVersionInfo::getMajor(), + LL_VERSION_MAJOR); + ensure_equals("Minor version", + LLVersionInfo::getMinor(), + LL_VERSION_MINOR); + ensure_equals("Patch version", + LLVersionInfo::getPatch(), + LL_VERSION_PATCH); + ensure_equals("Build version", + LLVersionInfo::getBuild(), + LL_VERSION_BUILD); + ensure_equals("Channel version", + LLVersionInfo::getChannel(), + LL_CHANNEL); + + ensure_equals("Version String", + LLVersionInfo::getVersion(), + mVersion); + ensure_equals("Short Version String", + LLVersionInfo::getShortVersion(), + mShortVersion); + ensure_equals("Version and channel String", + LLVersionInfo::getVersionAndChannel(), + mVersionAndChannel); + + LLVersionInfo::resetChannel(mResetChannel); + ensure_equals("Reset channel version", + LLVersionInfo::getChannel(), + mResetChannel); + + ensure_equals("Reset Version and channel String", + LLVersionInfo::getVersionAndChannel(), + mResetVersionAndChannel); + } +} \ No newline at end of file -- cgit v1.2.3 From 9cc290ef8fccdc585027d84ac9cfb864ed933061 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Mon, 1 Nov 2010 16:49:18 -0700 Subject: Added newline at EOF to satisfy linux gcc --- indra/newview/tests/llversioninfo_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index b4f1b0273f..8855a24ead 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -111,4 +111,4 @@ namespace tut LLVersionInfo::getVersionAndChannel(), mResetVersionAndChannel); } -} \ No newline at end of file +} -- cgit v1.2.3 From be151807222ffa5972256aa9a392e8a319eae5ee Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 2 Nov 2010 15:59:10 -0700 Subject: start of the downloader service. --- indra/viewer_components/updater/CMakeLists.txt | 8 + .../updater/llupdatedownloader.cpp | 168 +++++++++++++++++++++ .../viewer_components/updater/llupdatedownloader.h | 73 +++++++++ 3 files changed, 249 insertions(+) create mode 100644 indra/viewer_components/updater/llupdatedownloader.cpp create mode 100644 indra/viewer_components/updater/llupdatedownloader.h diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 2e77a7140a..64a0f98c2a 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -6,24 +6,30 @@ include(00-Common) if(LL_TESTS) include(LLAddBuildTest) endif(LL_TESTS) +include(CURL) include(LLCommon) include(LLMessage) include(LLPlugin) +include(LLVFS) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} + ${CURL_INCLUDE_DIRS} ) set(updater_service_SOURCE_FILES llupdaterservice.cpp llupdatechecker.cpp + llupdatedownloader.cpp ) set(updater_service_HEADER_FILES llupdaterservice.h llupdatechecker.h + llupdatedownloader.h ) set_source_files_properties(${updater_service_HEADER_FILES} @@ -42,6 +48,8 @@ target_link_libraries(llupdaterservice ${LLCOMMON_LIBRARIES} ${LLMESSAGE_LIBRARIES} ${LLPLUGIN_LIBRARIES} + ${LLVFS_LIBRARIES} + ${CURL_LIBRARIES} ) if(LL_TESTS) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp new file mode 100644 index 0000000000..4adf9c42b1 --- /dev/null +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -0,0 +1,168 @@ +/** + * @file llupdatedownloader.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lldir.h" +#include "llfile.h" +#include "llsd.h" +#include "llsdserialize.h" +#include "llthread.h" +#include "llupdatedownloader.h" + + +class LLUpdateDownloader::Implementation: + public LLThread +{ +public: + Implementation(LLUpdateDownloader::Client & client); + void cancel(void); + void download(LLURI const & uri); + bool isDownloading(void); + +private: + static const char * sSecondLifeUpdateRecord; + + LLUpdateDownloader::Client & mClient; + std::string mDownloadRecordPath; + + void resumeDownloading(LLSD const & downloadData); + void run(void); + bool shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData); + void startDownloading(LLURI const & uri); +}; + + + +// LLUpdateDownloader +//----------------------------------------------------------------------------- + + +LLUpdateDownloader::LLUpdateDownloader(Client & client): + mImplementation(new LLUpdateDownloader::Implementation(client)) +{ + ; // No op. +} + + +void LLUpdateDownloader::cancel(void) +{ + mImplementation->cancel(); +} + + +void LLUpdateDownloader::download(LLURI const & uri) +{ + mImplementation->download(uri); +} + + +bool LLUpdateDownloader::isDownloading(void) +{ + return mImplementation->isDownloading(); +} + + + +// LLUpdateDownloader::Implementation +//----------------------------------------------------------------------------- + + +const char * LLUpdateDownloader::Implementation::sSecondLifeUpdateRecord = + "SecondLifeUpdateDownload.xml"; + + +LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): + LLThread("LLUpdateDownloader"), + mClient(client), + mDownloadRecordPath(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, sSecondLifeUpdateRecord)) +{ + ; // No op. +} + + +void LLUpdateDownloader::Implementation::cancel(void) +{ +} + + +void LLUpdateDownloader::Implementation::download(LLURI const & uri) +{ + LLSD downloadData; + if(shouldResumeOngoingDownload(uri, downloadData)){ + + } else { + + } +} + + +bool LLUpdateDownloader::Implementation::isDownloading(void) +{ + return false; +} + + +void resumeDownloading(LLSD const & downloadData) +{ +} + + +bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData) +{ + if(!LLFile::isfile(mDownloadRecordPath)) return false; + + llifstream dataStream(mDownloadRecordPath); + LLSDSerialize parser; + parser.fromXMLDocument(downloadData, dataStream); + + if(downloadData["url"].asString() != uri.asString()) return false; + + std::string downloadedFilePath = downloadData["path"].asString(); + if(LLFile::isfile(downloadedFilePath)) { + llstat fileStatus; + LLFile::stat(downloadedFilePath, &fileStatus); + downloadData["bytes_downloaded"] = LLSD(LLSD::Integer(fileStatus.st_size)); + return true; + } else { + return false; + } + + return true; +} + + +void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri) +{ + LLSD downloadData; + downloadData["url"] = uri.asString(); + LLSD path = uri.pathArray(); + std::string fileName = path[path.size() - 1].asString(); + std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); + llofstream dataStream(mDownloadRecordPath); + LLSDSerialize parser; + parser.toPrettyXML(downloadData, dataStream); + + llofstream downloadStream(filePath); +} diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h new file mode 100644 index 0000000000..9dc5d789ce --- /dev/null +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -0,0 +1,73 @@ +/** + * @file llupdatedownloader.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_UPDATE_DOWNLOADER_H +#define LL_UPDATE_DOWNLOADER_H + + +#include +#include +#include "lluri.h" + + +// +// An asynchronous download service for fetching updates. +// +class LLUpdateDownloader +{ +public: + class Client; + class Implementation; + + LLUpdateDownloader(Client & client); + + // Cancel any in progress download. + void cancel(void); + + // Start a new download. + void download(LLURI const & uri); + + // Returns true if a download is in progress. + bool isDownloading(void); + +private: + boost::shared_ptr mImplementation; +}; + + +// +// An interface to be implemented by clients initiating a update download. +// +class LLUpdateDownloader::Client { + + // The download has completed successfully. + void downloadComplete(void); + + // The download failed. + void downloadError(std::string const & message); +}; + + +#endif \ No newline at end of file -- cgit v1.2.3 From a26386c53a09d47eff092ad89b5684503ee31b9d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 3 Nov 2010 08:43:31 -0400 Subject: For non-Release Linux build, explain why we don't create tarball. --- indra/newview/viewer_manifest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6861f02bfb..4b98a11091 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -897,6 +897,9 @@ class LinuxManifest(ViewerManifest): 'dir': self.get_build_prefix(), 'inst_name': installer_name, 'inst_path':self.build_path_of(installer_name)}) + else: + print "Skipping %s.tar.bz2 for non-Release build (%s)" % \ + (installer_name, self.args['buildtype']) finally: self.run_command("mv %(inst)s %(dst)s" % { 'dst': self.get_dst_prefix(), -- cgit v1.2.3 From 2f6062e59793c8a5326c1dfac41334bac428faa9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 3 Nov 2010 11:08:04 -0400 Subject: Remove erroneous 'inline' on LLPanelStandStopFlying::getInstance() This is ignored by every compiler except Linux g++ 4.4.3 in Release mode. In that case, it literally does cause getInstance() to be inlined, therefore llmoveview.o contains no such symbol, therefore the Linux viewer link fails in Release mode. But for a method implementation in a .cpp file of a method declared in a .h file, 'inline' is just wrong. Removing it fixes Release build. --- indra/newview/llmoveview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 6658e1d7e8..d38bb5aa4a 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -552,7 +552,7 @@ LLPanelStandStopFlying::LLPanelStandStopFlying() : } // static -inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance() +LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance() { static LLPanelStandStopFlying* panel = getStandStopFlyingPanel(); return panel; -- cgit v1.2.3 From 65997a1f5bb05dd263063606c00e0633af282784 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Wed, 3 Nov 2010 14:39:24 -0700 Subject: Added some logging to viewer_manifest.py to attempt to narrow down the Mac packaging failures a bit. --- indra/newview/viewer_manifest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 4b98a11091..4596938775 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -743,6 +743,11 @@ class DarwinManifest(ViewerManifest): devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip() volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip() + if devfile != '/dev/disk1': + # adding more debugging info based upon nat's hunches to the + # logs to help track down 'SetFile -a V' failures -brad + print "WARNING: 'SetFile -a V' command below is probably gonna fail" + # Copy everything in to the mounted .dmg if self.default_channel() and not self.default_grid(): -- cgit v1.2.3 From d594744d49732fd235694bde41f09cf578fccaf1 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 4 Nov 2010 10:52:21 -0700 Subject: Turned inlining on in windows builds (RelWithDebInfo and Release). This reduces the number of symbols in the viewer binary by about 30%. Also, fixed test errors revealed by inlining being enabled. --- indra/cmake/00-Common.cmake | 4 ++-- indra/newview/tests/llviewerhelputil_test.cpp | 17 +++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index a114d6e778..db2cdb5ff8 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -38,10 +38,10 @@ if (WINDOWS) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP" CACHE STRING "C++ compiler debug options" FORCE) set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP" + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2" CACHE STRING "C++ compiler release-with-debug options" FORCE) set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP" + "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2" CACHE STRING "C++ compiler release options" FORCE) set(CMAKE_CXX_STANDARD_LIBRARIES "") diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp index a0f1d1c3c3..b425b50c8b 100644 --- a/indra/newview/tests/llviewerhelputil_test.cpp +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -72,16 +72,13 @@ static void substitute_string(std::string &input, const std::string &search, con } } -class LLAgent -{ -public: - LLAgent() {} - ~LLAgent() {} -#ifdef __GNUC__ - __attribute__ ((noinline)) -#endif - bool isGodlike() const { return FALSE; } -}; +#include "../llagent.h" +LLAgent::LLAgent() : mAgentAccess(gSavedSettings) { } +LLAgent::~LLAgent() { } +bool LLAgent::isGodlike() const { return FALSE; } +LLAgentAccess::LLAgentAccess(LLControlGroup& settings) : mSavedSettings(settings) { } +LLUIColor::LLUIColor() {} + LLAgent gAgent; std::string LLWeb::expandURLSubstitutions(const std::string &url, -- cgit v1.2.3 From e0c734a7105060740e5597d4439d882bb3f2bff4 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 4 Nov 2010 10:53:11 -0700 Subject: Turned generate_breakpad_symbols target into a noop for non-Release builds. --- indra/newview/CMakeLists.txt | 10 +++++++++- indra/newview/generate_breakpad_symbols.py | 10 +++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a488fb1069..f18107f673 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1831,10 +1831,18 @@ if (PACKAGE) set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) endif (LINUX) + if(CMAKE_CONFIGURATION_TYPES) + # set LLBUILD_CONFIG to be a shell variable evaluated at build time + # reflecting the configuration we are currently building. + set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR}) + else(CMAKE_CONFIGURATION_TYPES) + set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE}) + endif(CMAKE_CONFIGURATION_TYPES) add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" COMMAND "${PYTHON_EXECUTABLE}" ARGS "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py" + "${LLBUILD_CONFIG}" "${VIEWER_DIST_DIR}" "${VIEWER_EXE_GLOBS}" "${VIEWER_LIB_GLOB}" @@ -1843,7 +1851,7 @@ if (PACKAGE) DEPENDS generate_breakpad_symbols.py VERBATIM ) - add_custom_target(generate_breakpad_symbols ALL DEPENDS "${VIEWER_SYMBOL_FILE}") + add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}") add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}") add_dependencies(package generate_breakpad_symbols) endif (PACKAGE) diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py index 8f2dfd2348..0e61bee1ef 100644 --- a/indra/newview/generate_breakpad_symbols.py +++ b/indra/newview/generate_breakpad_symbols.py @@ -45,8 +45,12 @@ class MissingModuleError(Exception): Exception.__init__(self, "Failed to find required modules: %r" % modules) self.modules = modules -def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): - print "generate_breakpad_symbols run with args: %s" % str((viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) +def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): + print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) + + if configuration != "Release": + print "skipping breakpad symbol generation for non-release build." + return 0 # split up list of viewer_exes # "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin'] @@ -122,7 +126,7 @@ def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_fil return 0 if __name__ == "__main__": - if len(sys.argv) != 6: + if len(sys.argv) != 7: usage() sys.exit(1) sys.exit(main(*sys.argv[1:])) -- cgit v1.2.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(-) 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.2.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(-) 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.2.3 From e45ba2957630f6319f8c633a409d78be56c264bd Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 4 Nov 2010 15:09:10 -0700 Subject: Fix for linux eol error. --- indra/viewer_components/updater/llupdatedownloader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 6118c4338e..395d19d6bf 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -76,4 +76,4 @@ public: }; -#endif \ No newline at end of file +#endif -- cgit v1.2.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(-) 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.2.3 From 4d1e45f20f924f070d0f0139878c2c96e698fb07 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 4 Nov 2010 17:14:12 -0700 Subject: added hash validation of downloaded file. --- .../updater/llupdatedownloader.cpp | 41 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 23772e021e..59e929d99f 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -29,6 +29,7 @@ #include #include "lldir.h" #include "llfile.h" +#include "llmd5.h" #include "llsd.h" #include "llsdserialize.h" #include "llthread.h" @@ -58,6 +59,7 @@ private: void run(void); void startDownloading(LLURI const & uri, std::string const & hash); void throwOnCurlError(CURLcode code); + bool validateDownload(void); LOG_CLASS(LLUpdateDownloader::Implementation); }; @@ -130,6 +132,7 @@ namespace { return bytes; } + size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader) { size_t bytes = blockSize * blocks; @@ -219,10 +222,18 @@ void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); if(code == CURLE_OK) { - LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; - mClient.downloadComplete(); + if(validateDownload()) { + LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; + mClient.downloadComplete(); + } else { + LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL; + std::string filePath = mDownloadData["path"].asString(); + if(filePath.size() != 0) LLFile::remove(filePath); + mClient.downloadError("failed hash check"); + } } else { - LL_WARNS("UpdateDownload") << "download failed with error " << code << LL_ENDL; + LL_WARNS("UpdateDownload") << "download failed with error '" << + curl_easy_strerror(code) << "'" << LL_ENDL; mClient.downloadError("curl error"); } } @@ -253,6 +264,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & download { } + /* bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData) { @@ -289,8 +301,9 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); mDownloadData["path"] = filePath; - LL_INFOS("UpdateDownload") << "downloading " << filePath << "\n" - << "from " << uri.asString() << LL_ENDL; + LL_INFOS("UpdateDownload") << "downloading " << filePath + << " from " << uri.asString() << LL_ENDL; + LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL; llofstream dataStream(mDownloadRecordPath); LLSDSerialize parser; @@ -315,3 +328,21 @@ void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code) ; // No op. } } + + +bool LLUpdateDownloader::Implementation::validateDownload(void) +{ + std::string filePath = mDownloadData["path"].asString(); + llifstream fileStream(filePath); + if(!fileStream) return false; + + std::string hash = mDownloadData["hash"].asString(); + if(hash.size() != 0) { + LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL; + char digest[33]; + LLMD5(fileStream).hex_digest(digest); + return hash == digest; + } else { + return true; // No hash check provided. + } +} -- cgit v1.2.3 From 95d39166faecec2c851285775422c3f668641de2 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 4 Nov 2010 19:11:40 -0700 Subject: Fix for windows build breakage in teamcity. --- indra/viewer_components/updater/llupdaterservice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 83b09c4bdd..04adf461b6 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -42,7 +42,7 @@ public: LLUpdaterService(); ~LLUpdaterService(); - void setParams(const std::string& version, + void setParams(const std::string& protocol_version, const std::string& url, const std::string& path, const std::string& channel, -- cgit v1.2.3 From 9d7cdc17e311ba5f1f62112e316c531b68f67046 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 5 Nov 2010 11:12:54 -0700 Subject: resume feature (untested). --- .../updater/llupdatedownloader.cpp | 104 ++++++++++++++------- .../viewer_components/updater/llupdatedownloader.h | 5 +- .../viewer_components/updater/llupdaterservice.cpp | 2 +- 3 files changed, 77 insertions(+), 34 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 59e929d99f..102f2f9eec 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -25,6 +25,7 @@ #include "linden_common.h" #include +#include #include #include #include "lldir.h" @@ -47,6 +48,8 @@ public: bool isDownloading(void); void onHeader(void * header, size_t size); void onBody(void * header, size_t size); + void resume(void); + private: LLUpdateDownloader::Client & mClient; CURL * mCurl; @@ -54,8 +57,8 @@ private: llofstream mDownloadStream; std::string mDownloadRecordPath; - void initializeCurlGet(std::string const & url); - void resumeDownloading(LLSD const & downloadData); + void initializeCurlGet(std::string const & url, bool processHeader); + void resumeDownloading(size_t startByte); void run(void); void startDownloading(LLURI const & uri, std::string const & hash); void throwOnCurlError(CURLcode code); @@ -119,6 +122,12 @@ bool LLUpdateDownloader::isDownloading(void) } +void LLUpdateDownloader::resume(void) +{ + mImplementation->resume(); +} + + // LLUpdateDownloader::Implementation //----------------------------------------------------------------------------- @@ -183,6 +192,45 @@ bool LLUpdateDownloader::Implementation::isDownloading(void) return !isStopped(); } + +void LLUpdateDownloader::Implementation::resume(void) +{ + llifstream dataStream(mDownloadRecordPath); + if(!dataStream) { + mClient.downloadError("no download marker"); + return; + } + + LLSDSerialize parser; + parser.fromXMLDocument(mDownloadData, dataStream); + + if(!mDownloadData.asBoolean()) { + mClient.downloadError("no download information in marker"); + return; + } + + std::string filePath = mDownloadData["path"].asString(); + try { + if(LLFile::isfile(filePath)) { + llstat fileStatus; + LLFile::stat(filePath, &fileStatus); + if(fileStatus.st_size != mDownloadData["size"].asInteger()) { + resumeDownloading(fileStatus.st_size); + } else if(!validateDownload()) { + LLFile::remove(filePath); + download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString()); + } else { + mClient.downloadComplete(mDownloadData); + } + } else { + download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString()); + } + } catch(DownloadError & e) { + mClient.downloadError(e.what()); + } +} + + void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) { char const * headerPtr = reinterpret_cast (buffer); @@ -221,10 +269,11 @@ void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); + LLFile::remove(mDownloadRecordPath); if(code == CURLE_OK) { if(validateDownload()) { LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; - mClient.downloadComplete(); + mClient.downloadComplete(mDownloadData); } else { LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL; std::string filePath = mDownloadData["path"].asString(); @@ -239,7 +288,7 @@ void LLUpdateDownloader::Implementation::run(void) } -void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url) +void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader) { if(mCurl == 0) { mCurl = curl_easy_init(); @@ -253,42 +302,33 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u 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)); + if(processHeader) { + 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())); } -void LLUpdateDownloader::Implementation::resumeDownloading(LLSD const & downloadData) -{ -} - - -/* -bool LLUpdateDownloader::Implementation::shouldResumeOngoingDownload(LLURI const & uri, LLSD & downloadData) +void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte) { - if(!LLFile::isfile(mDownloadRecordPath)) return false; + initializeCurlGet(mDownloadData["url"].asString(), false); - llifstream dataStream(mDownloadRecordPath); - LLSDSerialize parser; - parser.fromXMLDocument(downloadData, dataStream); + // The header 'Range: bytes n-' will request the bytes remaining in the + // source begining with byte n and ending with the last byte. + boost::format rangeHeaderFormat("Range: bytes=%u-"); + rangeHeaderFormat % startByte; + curl_slist * headerList = 0; + headerList = curl_slist_append(headerList, rangeHeaderFormat.str().c_str()); + if(headerList == 0) throw DownloadError("cannot add Range header"); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, headerList)); + curl_slist_free_all(headerList); - if(downloadData["url"].asString() != uri.asString()) return false; - - std::string downloadedFilePath = downloadData["path"].asString(); - if(LLFile::isfile(downloadedFilePath)) { - llstat fileStatus; - LLFile::stat(downloadedFilePath, &fileStatus); - downloadData["bytes_downloaded"] = LLSD(LLSD::Integer(fileStatus.st_size)); - return true; - } else { - return false; - } - - return true; + mDownloadStream.open(mDownloadData["path"].asString(), + std::ios_base::out | std::ios_base::binary | std::ios_base::app); + start(); } - */ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash) @@ -310,7 +350,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std parser.toPrettyXML(mDownloadData, dataStream); mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary); - initializeCurlGet(uri.asString()); + initializeCurlGet(uri.asString(), true); start(); } diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 8754ea329c..7bfb430879 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -56,6 +56,9 @@ public: // Returns true if a download is in progress. bool isDownloading(void); + // Resume a partial download. + void resume(void); + private: boost::shared_ptr mImplementation; }; @@ -68,7 +71,7 @@ class LLUpdateDownloader::Client { public: // The download has completed successfully. - virtual void downloadComplete(void) = 0; + virtual void downloadComplete(LLSD const & data) = 0; // The download failed. 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 1e0c393539..dc48606cbc 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -99,7 +99,7 @@ public: virtual void upToDate(void); // LLUpdateDownloader::Client - void downloadComplete(void) { retry(); } + void downloadComplete(LLSD const & data) { retry(); } void downloadError(std::string const & message) { retry(); } bool onMainLoop(LLSD const & event); -- cgit v1.2.3 From 6f7183cd4422a008554afd854dc631fe575ad8dc Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Fri, 5 Nov 2010 13:56:36 -0700 Subject: Fixed windows build error. --- indra/viewer_components/updater/llupdatedownloader.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 102f2f9eec..75f896cc76 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -201,8 +201,7 @@ void LLUpdateDownloader::Implementation::resume(void) return; } - LLSDSerialize parser; - parser.fromXMLDocument(mDownloadData, dataStream); + LLSDSerialize::fromXMLDocument(mDownloadData, dataStream); if(!mDownloadData.asBoolean()) { mClient.downloadError("no download information in marker"); @@ -248,8 +247,7 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) mDownloadData["size"] = LLSD(LLSD::Integer(size)); llofstream odataStream(mDownloadRecordPath); - LLSDSerialize parser; - parser.toPrettyXML(mDownloadData, odataStream); + LLSDSerialize::toPrettyXML(mDownloadData, odataStream); } catch (std::exception const & e) { LL_WARNS("UpdateDownload") << "unable to read content length (" << e.what() << ")" << LL_ENDL; @@ -346,8 +344,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL; llofstream dataStream(mDownloadRecordPath); - LLSDSerialize parser; - parser.toPrettyXML(mDownloadData, dataStream); + LLSDSerialize::toPrettyXML(mDownloadData, dataStream); mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary); initializeCurlGet(uri.asString(), true); -- cgit v1.2.3 From a13acfc9073b0e29d84e1633fc11ff08e285be8f Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Fri, 5 Nov 2010 15:08:27 -0700 Subject: Fixed build error due to unreferenced local variable. --- indra/viewer_components/updater/llupdatedownloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 75f896cc76..efb55ab83a 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -158,7 +158,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath()) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. - llassert(code = CURLE_OK); // TODO: real error handling here. + llverify(code == CURLE_OK); // TODO: real error handling here. } -- cgit v1.2.3 From 02c362b8ccad08f290ca99a738ca6ad1546c7df6 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 5 Nov 2010 15:56:33 -0700 Subject: implement download cancel (untested). --- .../updater/llupdatedownloader.cpp | 37 +++++++++++++++------- .../viewer_components/updater/llupdatedownloader.h | 3 +- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 102f2f9eec..eaef230a8f 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -46,11 +46,12 @@ public: void cancel(void); 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); + size_t onHeader(void * header, size_t size); + size_t onBody(void * header, size_t size); void resume(void); private: + bool mCancelled; LLUpdateDownloader::Client & mClient; CURL * mCurl; LLSD mDownloadData; @@ -137,28 +138,27 @@ 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; + return reinterpret_cast(downloader)->onBody(data, 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; + return reinterpret_cast(downloader)->onHeader(data, bytes); } } LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): LLThread("LLUpdateDownloader"), + mCancelled(false), mClient(client), mCurl(0), mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath()) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. - llassert(code = CURLE_OK); // TODO: real error handling here. + llassert(code == CURLE_OK); // TODO: real error handling here. } @@ -170,7 +170,7 @@ LLUpdateDownloader::Implementation::~Implementation() void LLUpdateDownloader::Implementation::cancel(void) { - llassert(!"not implemented"); + mCancelled = true; } @@ -231,12 +231,12 @@ void LLUpdateDownloader::Implementation::resume(void) } -void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) +size_t 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(colonPosition == std::string::npos) return size; // HTML response; ignore. if(header.substr(0, colonPosition) == "Content-Length") { try { @@ -257,20 +257,25 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) } else { ; // No op. } + + return size; } -void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) +size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) { + if(mCancelled) return 0; // Forces a write error which will halt curl thread. + mDownloadStream.write(reinterpret_cast(buffer), size); + return size; } void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); - LLFile::remove(mDownloadRecordPath); if(code == CURLE_OK) { + LLFile::remove(mDownloadRecordPath); if(validateDownload()) { LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; mClient.downloadComplete(mDownloadData); @@ -280,9 +285,13 @@ void LLUpdateDownloader::Implementation::run(void) if(filePath.size() != 0) LLFile::remove(filePath); mClient.downloadError("failed hash check"); } + } else if(mCancelled && (code == CURLE_WRITE_ERROR)) { + LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL; + // Do not call back client. } else { LL_WARNS("UpdateDownload") << "download failed with error '" << curl_easy_strerror(code) << "'" << LL_ENDL; + LLFile::remove(mDownloadRecordPath); mClient.downloadError("curl error"); } } @@ -381,6 +390,10 @@ bool LLUpdateDownloader::Implementation::validateDownload(void) LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL; char digest[33]; LLMD5(fileStream).hex_digest(digest); + if(hash != digest) { + LL_WARNS("UpdateDownload") << "download hash mismatch; expeted " << hash << + " but download is " << digest << LL_ENDL; + } return hash == digest; } else { return true; // No hash check provided. diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index dc8ecc378a..491a638f9a 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -47,7 +47,8 @@ public: LLUpdateDownloader(Client & client); - // Cancel any in progress download; a no op if none is in progress. + // Cancel any in progress download; a no op if none is in progress. The + // client will not receive a complete or error callback. void cancel(void); // Start a new download. -- cgit v1.2.3 From 1a711b3fd5912776424012fcfcb472baf6c195af Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Fri, 5 Nov 2010 18:33:25 -0700 Subject: "Fix" for linux link errors due to library ordering problems on the linker command line. --- indra/viewer_components/updater/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 64a0f98c2a..563b64655d 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -49,7 +49,6 @@ target_link_libraries(llupdaterservice ${LLMESSAGE_LIBRARIES} ${LLPLUGIN_LIBRARIES} ${LLVFS_LIBRARIES} - ${CURL_LIBRARIES} ) if(LL_TESTS) -- cgit v1.2.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(-) 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.2.3 From 0836d1b1ae861ee7a226ba342166148a31cc5bdd Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Mon, 8 Nov 2010 15:51:39 -0800 Subject: Fix for linux link errors in teamcity. --- indra/newview/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f18107f673..ff099710f1 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1643,7 +1643,14 @@ if (WINDOWS) endif (PACKAGE) endif (WINDOWS) +# *NOTE - this list is very sensitive to ordering, test carefully on all +# platforms if you change the releative order of the entries here. +# In particular, cmake 2.6.4 (when buidling with linux/makefile generators) +# appears to sometimes de-duplicate redundantly listed dependencies improperly. +# To work around this, higher level modules should be listed before the modules +# that they depend upon. -brad target_link_libraries(${VIEWER_BINARY_NAME} + ${UPDATER_LIBRARIES} ${LLAUDIO_LIBRARIES} ${LLCHARACTER_LIBRARIES} ${LLIMAGE_LIBRARIES} @@ -1680,7 +1687,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} - ${UPDATER_LIBRARIES} ${GOOGLE_PERFTOOLS_LIBRARIES} ) -- cgit v1.2.3 From d681ea89d27e0e37d77c7f57c9bc66fda3f08f4e Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Mon, 8 Nov 2010 16:10:54 -0800 Subject: Get rid of intrusive_ptr member to prevent crash on shutdown. --- indra/viewer_components/updater/llupdatechecker.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index d31244cc9b..c6aa9b0f11 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -70,7 +70,6 @@ private: Client & mClient; LLHTTPClient mHttpClient; bool mInProgress; - LLHTTPClient::ResponderPtr mMe; std::string mVersion; std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, @@ -109,8 +108,7 @@ const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0"; LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client): mClient(client), - mInProgress(false), - mMe(this) + mInProgress(false) { ; // No op. } @@ -118,7 +116,7 @@ LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client LLUpdateChecker::Implementation::~Implementation() { - mMe.reset(0); + ; // No op. } @@ -136,9 +134,11 @@ void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, // The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the // passed object to be silently and automatically deleted. We pass a self- - // referential intrusive pointer stored as an attribute of this class to keep - // the client from deletig the update checker implementation instance. - mHttpClient.get(checkUrl, mMe); + // referential intrusive pointer to which we add a reference to keep the + // client from deleting the update checker implementation instance. + LLHTTPClient::ResponderPtr temporaryPtr(this); + boost::intrusive_ptr_add_ref(temporaryPtr.get()); + mHttpClient.get(checkUrl, temporaryPtr); } void LLUpdateChecker::Implementation::completed(U32 status, -- cgit v1.2.3 From 8cce8827e01dab6bfcd3e94e56b6041f8f487c76 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Mon, 8 Nov 2010 17:12:43 -0800 Subject: Fix for breakpad symbol files failing to be generated on linux. --- indra/newview/CMakeLists.txt | 8 ++++---- indra/newview/generate_breakpad_symbols.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ff099710f1..a9d1fd9064 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1837,13 +1837,13 @@ if (PACKAGE) set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) endif (LINUX) - if(CMAKE_CONFIGURATION_TYPES) + if(CMAKE_CFG_INTDIR STREQUAL ".") + set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE}) + else(CMAKE_CFG_INTDIR STREQUAL ".") # set LLBUILD_CONFIG to be a shell variable evaluated at build time # reflecting the configuration we are currently building. set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR}) - else(CMAKE_CONFIGURATION_TYPES) - set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE}) - endif(CMAKE_CONFIGURATION_TYPES) + endif(CMAKE_CFG_INTDIR STREQUAL ".") add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" COMMAND "${PYTHON_EXECUTABLE}" ARGS diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py index 0e61bee1ef..4fd04d780e 100644 --- a/indra/newview/generate_breakpad_symbols.py +++ b/indra/newview/generate_breakpad_symbols.py @@ -31,6 +31,7 @@ import fnmatch import itertools import operator import os +import re import sys import shlex import subprocess @@ -48,7 +49,7 @@ class MissingModuleError(Exception): def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) - if configuration != "Release": + if not re.match("release", configuration, re.IGNORECASE): print "skipping breakpad symbol generation for non-release build." return 0 -- cgit v1.2.3 From 2cfcdfe2ffd97384324c940447a4197cbf85a38e Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 9 Nov 2010 09:14:50 -0800 Subject: Fix some stream bugs that were affecting windows download and validation. --- indra/viewer_components/updater/llupdatedownloader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index ca1d2d25de..2794f80c47 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -272,6 +272,7 @@ size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); + mDownloadStream.close(); if(code == CURLE_OK) { LLFile::remove(mDownloadRecordPath); if(validateDownload()) { @@ -379,7 +380,7 @@ void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code) bool LLUpdateDownloader::Implementation::validateDownload(void) { std::string filePath = mDownloadData["path"].asString(); - llifstream fileStream(filePath); + llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary); if(!fileStream) return false; std::string hash = mDownloadData["hash"].asString(); -- cgit v1.2.3 From 73b6d4d058107137425cd202e79fb0a2d9c22896 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 9 Nov 2010 11:15:01 -0800 Subject: Fix crash if thread is manually shut down before it is destroyed. --- indra/llcommon/llthread.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index d7b7c3699c..2408be74b9 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -153,10 +153,12 @@ void LLThread::shutdown() } delete mRunCondition; + mRunCondition = 0; - if (mIsLocalPool) + if (mIsLocalPool && mAPRPoolp) { apr_pool_destroy(mAPRPoolp); + mAPRPoolp = 0; } } -- cgit v1.2.3 From 5da253fdde8737361333161517c1173358bd17ff Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 9 Nov 2010 11:16:28 -0800 Subject: Shut down thread if viewer closed while downloading; fix problem of download marker path failing to expand correctly because it was happening too early in start up. --- indra/viewer_components/updater/llupdatedownloader.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 2794f80c47..208cc48c12 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -154,8 +154,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & LLThread("LLUpdateDownloader"), mCancelled(false), mClient(client), - mCurl(0), - mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath()) + mCurl(0) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. llverify(code == CURLE_OK); // TODO: real error handling here. @@ -164,6 +163,12 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & LLUpdateDownloader::Implementation::~Implementation() { + if(isDownloading()) { + cancel(); + shutdown(); + } else { + ; // No op. + } if(mCurl) curl_easy_cleanup(mCurl); } @@ -177,7 +182,8 @@ void LLUpdateDownloader::Implementation::cancel(void) void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash) { if(isDownloading()) mClient.downloadError("download in progress"); - + + mDownloadRecordPath = downloadMarkerPath(); mDownloadData = LLSD(); try { startDownloading(uri, hash); @@ -195,6 +201,9 @@ bool LLUpdateDownloader::Implementation::isDownloading(void) void LLUpdateDownloader::Implementation::resume(void) { + if(isDownloading()) mClient.downloadError("download in progress"); + + mDownloadRecordPath = downloadMarkerPath(); llifstream dataStream(mDownloadRecordPath); if(!dataStream) { mClient.downloadError("no download marker"); -- cgit v1.2.3 From fdf616c59d87219e2d5ad6e12687cf2793cfba1e Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 9 Nov 2010 11:23:32 -0800 Subject: beginnings of the update installer (with simple install script for darwin). --- indra/newview/viewer_manifest.py | 4 +++ indra/viewer_components/updater/CMakeLists.txt | 23 ++++++++---- .../updater/llupdateinstaller.cpp | 38 ++++++++++++++++++++ .../viewer_components/updater/llupdateinstaller.h | 42 ++++++++++++++++++++++ .../updater/scripts/darwin/update_install | 6 ++++ 5 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 indra/viewer_components/updater/llupdateinstaller.cpp create mode 100644 indra/viewer_components/updater/llupdateinstaller.h create mode 100755 indra/viewer_components/updater/scripts/darwin/update_install diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 4596938775..f95697adb6 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -575,6 +575,10 @@ class DarwinManifest(ViewerManifest): # 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/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 563b64655d..c3607dff39 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -6,6 +6,7 @@ include(00-Common) if(LL_TESTS) include(LLAddBuildTest) endif(LL_TESTS) +include(CMakeCopyIfDifferent) include(CURL) include(LLCommon) include(LLMessage) @@ -24,12 +25,14 @@ set(updater_service_SOURCE_FILES llupdaterservice.cpp llupdatechecker.cpp llupdatedownloader.cpp + llupdateinstaller.cpp ) set(updater_service_HEADER_FILES llupdaterservice.h llupdatechecker.h llupdatedownloader.h + llupdateinstaller.h ) set_source_files_properties(${updater_service_HEADER_FILES} @@ -56,12 +59,6 @@ if(LL_TESTS) llupdaterservice.cpp ) -# set_source_files_properties( -# llupdaterservice.cpp -# PROPERTIES -# LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}" -# ) - LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}") endif(LL_TESTS) @@ -74,3 +71,17 @@ set(UPDATER_LIBRARIES llupdaterservice CACHE INTERNAL "" ) + +# Copy install script. +if(DARWIN) + copy_if_different( + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/darwin" + "${CMAKE_CURRENT_BINARY_DIR}" + update_installer_targets + "update_install" + ) +endif() +add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets}) + + + \ No newline at end of file diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp new file mode 100644 index 0000000000..4d7c78d36c --- /dev/null +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -0,0 +1,38 @@ +/** + * @file llupdateinstaller.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 "llprocesslauncher.h" +#include "llupdateinstaller.h" + + +void ll_install_update(std::string const & script, std::string const & updatePath) +{ + LLProcessLauncher launcher; + launcher.setExecutable(script); + launcher.addArgument(updatePath); + launcher.launch(); + launcher.orphan(); +} \ No newline at end of file diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h new file mode 100644 index 0000000000..a6068e9025 --- /dev/null +++ b/indra/viewer_components/updater/llupdateinstaller.h @@ -0,0 +1,42 @@ +/** + * @file llupdateinstaller.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_UPDATE_INSTALLER_H +#define LL_UPDATE_INSTALLER_H + + +#include + + +// +// Launch the installation script. +// +// The updater will overwrite the current installation, so it is highly recommended +// that the current application terminate once this function is called. +// +void ll_install_update(std::string const & script, std::string const & updatePath); + + +#endif \ No newline at end of file diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install new file mode 100755 index 0000000000..24d344ca52 --- /dev/null +++ b/indra/viewer_components/updater/scripts/darwin/update_install @@ -0,0 +1,6 @@ +#! /bin/bash + +hdiutil attach -nobrowse $1 +cp -R /Volumes/Second\ Life\ Installer/Second\ Life\ Viewer\ 2.app /Applications +hdiutil detach /Volumes/Second\ Life\ Installer +open /Applications/Second\ Life\ Viewer\ 2.app \ No newline at end of file -- cgit v1.2.3 From 656b936915d5fd29f213f8eb7cd3873baed19109 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 9 Nov 2010 14:40:32 -0500 Subject: Add name, value info to convert_from_llsd<> specialization LL_ERRS. Prior to this, you could get a viewer crash whose ERROR: message said only: convert_from_llsd: Invalid string value This gave no hint as to *which value* was wrong, or where to go fix it. Ironically, each convert_from_llsd<> specialization already has the control_name and LLSD value in hand; added these to each such LL_ERRS message. --- indra/llxml/llcontrol.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index f9a39826f5..27c694dde9 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -1107,7 +1107,7 @@ bool convert_from_llsd(const LLSD& sd, eControlType type, const std::strin return sd.asBoolean(); else { - CONTROL_ERRS << "Invalid BOOL value" << llendl; + CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << sd << llendl; return FALSE; } } @@ -1119,7 +1119,7 @@ S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return sd.asInteger(); else { - CONTROL_ERRS << "Invalid S32 value" << llendl; + CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << sd << llendl; return 0; } } @@ -1131,7 +1131,7 @@ U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return sd.asInteger(); else { - CONTROL_ERRS << "Invalid U32 value" << llendl; + CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << sd << llendl; return 0; } } @@ -1143,7 +1143,7 @@ F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return (F32) sd.asReal(); else { - CONTROL_ERRS << "Invalid F32 value" << llendl; + CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << sd << llendl; return 0.0f; } } @@ -1155,7 +1155,7 @@ std::string convert_from_llsd(const LLSD& sd, eControlType type, co return sd.asString(); else { - CONTROL_ERRS << "Invalid string value" << llendl; + CONTROL_ERRS << "Invalid string value for " << control_name << ": " << sd << llendl; return LLStringUtil::null; } } @@ -1173,7 +1173,7 @@ LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const return (LLVector3)sd; else { - CONTROL_ERRS << "Invalid LLVector3 value" << llendl; + CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << sd << llendl; return LLVector3::zero; } } @@ -1185,7 +1185,7 @@ LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, cons return (LLVector3d)sd; else { - CONTROL_ERRS << "Invalid LLVector3d value" << llendl; + CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << sd << llendl; return LLVector3d::zero; } } @@ -1197,7 +1197,7 @@ LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::s return LLRect(sd); else { - CONTROL_ERRS << "Invalid rect value" << llendl; + CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << sd << llendl; return LLRect::null; } } @@ -1211,19 +1211,19 @@ LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const st LLColor4 color(sd); if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " red value out of range: " << color << llendl; } else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " green value out of range: " << color << llendl; } else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " blue value out of range: " << color << llendl; } else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl; } return LLColor4(sd); @@ -1242,7 +1242,7 @@ LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const st return sd; else { - CONTROL_ERRS << "Invalid LLColor3 value" << llendl; + CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << sd << llendl; return LLColor3::white; } } -- cgit v1.2.3 From 9ae2891a3afefcbf0c72cadaef203426cb0e5954 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 9 Nov 2010 15:04:44 -0800 Subject: start of a thread safe queue --- indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/llthreadsafequeue.cpp | 109 +++++++++++++++++++ indra/llcommon/llthreadsafequeue.h | 205 +++++++++++++++++++++++++++++++++++ indra/newview/CMakeLists.txt | 2 + indra/newview/llappviewer.cpp | 5 + indra/newview/llmainlooprepeater.cpp | 82 ++++++++++++++ indra/newview/llmainlooprepeater.h | 65 +++++++++++ 7 files changed, 470 insertions(+) create mode 100644 indra/llcommon/llthreadsafequeue.cpp create mode 100644 indra/llcommon/llthreadsafequeue.h create mode 100644 indra/newview/llmainlooprepeater.cpp create mode 100644 indra/newview/llmainlooprepeater.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 7bad780dd8..7d53667f35 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -92,6 +92,7 @@ set(llcommon_SOURCE_FILES llstringtable.cpp llsys.cpp llthread.cpp + llthreadsafequeue.cpp lltimer.cpp lluri.cpp lluuid.cpp @@ -223,6 +224,7 @@ set(llcommon_HEADER_FILES llstringtable.h llsys.h llthread.h + llthreadsafequeue.h lltimer.h lltreeiterators.h lluri.h diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp new file mode 100644 index 0000000000..a7141605ef --- /dev/null +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -0,0 +1,109 @@ +/** + * @file llthread.cpp + * + * $LicenseInfo:firstyear=2004&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 +#include "llthreadsafequeue.h" + + + +// LLThreadSafeQueueImplementation +//----------------------------------------------------------------------------- + + +LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity): + mOwnsPool(pool == 0), + mPool(pool), + mQueue(0) +{ + if(mOwnsPool) { + apr_status_t status = apr_pool_create(&mPool, 0); + if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool"); + } else { + ; // No op. + } + + apr_status_t status = apr_queue_create(&mQueue, capacity, mPool); + if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue"); +} + + +LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation() +{ + if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool); + if(mQueue != 0) { + if(apr_queue_size(mQueue) != 0) llwarns << + "terminating queue which still contains elements;" << + "memory will be leaked" << LL_ENDL; + apr_queue_term(mQueue); + } +} + + +void LLThreadSafeQueueImplementation::pushFront(void * element) +{ + apr_status_t status = apr_queue_push(mQueue, element); + + if(status == APR_EINTR) { + throw LLThreadSafeQueueInterrupt(); + } else if(status != APR_SUCCESS) { + throw LLThreadSafeQueueError("push failed"); + } else { + ; // Success. + } +} + + +bool LLThreadSafeQueueImplementation::tryPushFront(void * element){ + return apr_queue_trypush(mQueue, element) == APR_SUCCESS; +} + + +void * LLThreadSafeQueueImplementation::popBack(void) +{ + void * element; + apr_status_t status = apr_queue_pop(mQueue, &element); + + if(status == APR_EINTR) { + throw LLThreadSafeQueueInterrupt(); + } else if(status != APR_SUCCESS) { + throw LLThreadSafeQueueError("pop failed"); + } else { + return element; + } +} + + +bool LLThreadSafeQueueImplementation::tryPopBack(void *& element) +{ + return apr_queue_trypop(mQueue, &element) == APR_SUCCESS; +} + + +size_t LLThreadSafeQueueImplementation::size() +{ + return apr_queue_size(mQueue); +} diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h new file mode 100644 index 0000000000..46c8b91932 --- /dev/null +++ b/indra/llcommon/llthreadsafequeue.h @@ -0,0 +1,205 @@ +/** + * @file llthreadsafequeue.h + * @brief Base classes for thread, mutex and condition handling. + * + * $LicenseInfo:firstyear=2004&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_LLTHREADSAFEQUEUE_H +#define LL_LLTHREADSAFEQUEUE_H + + +#include +#include + + +struct apr_pool_t; // From apr_pools.h +class LLThreadSafeQueueImplementation; // See below. + + +// +// A general queue exception. +// +class LLThreadSafeQueueError: +public std::runtime_error +{ +public: + LLThreadSafeQueueError(std::string const & message): + std::runtime_error(message) + { + ; // No op. + } +}; + + +// +// An exception raised when blocking operations are interrupted. +// +class LLThreadSafeQueueInterrupt: + public LLThreadSafeQueueError +{ +public: + LLThreadSafeQueueInterrupt(void): + LLThreadSafeQueueError("queue operation interrupted") + { + ; // No op. + } +}; + + +struct apr_queue_t; // From apr_queue.h + + +// +// Implementation details. +// +class LLThreadSafeQueueImplementation +{ +public: + LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity); + ~LLThreadSafeQueueImplementation(); + void pushFront(void * element); + bool tryPushFront(void * element); + void * popBack(void); + bool tryPopBack(void *& element); + size_t size(); + +private: + bool mOwnsPool; + apr_pool_t * mPool; + apr_queue_t * mQueue; +}; + + +// +// Implements a thread safe FIFO. +// +template +class LLThreadSafeQueue +{ +public: + typedef ElementT value_type; + + // If the pool is set to NULL one will be allocated and managed by this + // queue. + LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024); + + // Add an element to the front of queue (will block if the queue has + // reached capacity). + // + // This call will raise an interrupt error if the queue is deleted while + // the caller is blocked. + void pushFront(ElementT const & element); + + // Try to add an element to the front ofqueue without blocking. Returns + // true only if the element was actually added. + bool tryPushFront(ElementT const & element); + + // Pop the element at the end of the queue (will block if the queue is + // empty). + // + // This call will raise an interrupt error if the queue is deleted while + // the caller is blocked. + ElementT popBack(void); + + // Pop an element from the end of the queue if there is one available. + // Returns true only if an element was popped. + bool tryPopBack(ElementT & element); + + // Returns the size of the queue. + size_t size(); + +private: + LLThreadSafeQueueImplementation mImplementation; +}; + + + +// LLThreadSafeQueue +//----------------------------------------------------------------------------- + + +template +LLThreadSafeQueue::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity): + mImplementation(pool, capacity) +{ + ; // No op. +} + + +template +void LLThreadSafeQueue::pushFront(ElementT const & element) +{ + ElementT * elementCopy = new ElementT(element); + try { + mImplementation.pushFront(elementCopy); + } catch (LLThreadSafeQueueInterrupt) { + delete elementCopy; + throw; + } +} + + +template +bool LLThreadSafeQueue::tryPushFront(ElementT const & element) +{ + ElementT * elementCopy = new ElementT(element); + bool result = mImplementation.tryPushFront(elementCopy); + if(!result) delete elementCopy; + return result; +} + + +template +ElementT LLThreadSafeQueue::popBack(void) +{ + ElementT * element = reinterpret_cast (mImplementation.popBack()); + ElementT result(*element); + delete element; + return result; +} + + +template +bool LLThreadSafeQueue::tryPopBack(ElementT & element) +{ + void * storedElement; + bool result = mImplementation.tryPopBack(storedElement); + if(result) { + ElementT * elementPtr = reinterpret_cast(storedElement); + element = *elementPtr; + delete elementPtr; + } else { + ; // No op. + } + return result; +} + + +template +size_t LLThreadSafeQueue::size(void) +{ + return mImplementation.size(); +} + + +#endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a9d1fd9064..36cfa615f0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -283,6 +283,7 @@ set(viewer_SOURCE_FILES llloginhandler.cpp lllogininstance.cpp llmachineid.cpp + llmainlooprepeater.cpp llmanip.cpp llmaniprotate.cpp llmanipscale.cpp @@ -815,6 +816,7 @@ set(viewer_HEADER_FILES llloginhandler.h lllogininstance.h llmachineid.h + llmainlooprepeater.h llmanip.h llmaniprotate.h llmanipscale.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c0ec15f436..438f8668ae 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -197,6 +197,8 @@ #include "llsecapi.h" #include "llmachineid.h" +#include "llmainlooprepeater.h" + // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either // this app, or another 'component' of the viewer. App globals should be @@ -801,6 +803,9 @@ bool LLAppViewer::init() return 1; } + // Initialize the repeater service. + LLMainLoopRepeater::getInstance()->start(); + // // Initialize the window // diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp new file mode 100644 index 0000000000..c2eba97641 --- /dev/null +++ b/indra/newview/llmainlooprepeater.cpp @@ -0,0 +1,82 @@ +/** + * @file llmachineid.cpp + * @brief retrieves unique machine ids + * + * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h" +#include "llapr.h" +#include "llevents.h" +#include "llmainlooprepeater.h" + + + +// LLMainLoopRepeater +//----------------------------------------------------------------------------- + + +LLMainLoopRepeater::LLMainLoopRepeater(void): + mQueue(gAPRPoolp, 1024) +{ + ; // No op. +} + + +void LLMainLoopRepeater::start(void) +{ + mMainLoopConnection = LLEventPumps::instance(). + obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); + mRepeaterConnection = LLEventPumps::instance(). + obtain("mainlooprepeater").listen("other stupid name here", boost::bind(&LLMainLoopRepeater::onMessage, this, _1)); +} + + +void LLMainLoopRepeater::stop(void) +{ + mMainLoopConnection.release(); + mRepeaterConnection.release(); +} + + +bool LLMainLoopRepeater::onMainLoop(LLSD const &) +{ + LLSD message; + while(mQueue.tryPopBack(message)) { + std::string pump = message["pump"].asString(); + if(pump.length() == 0 ) continue; // No pump. + LLEventPumps::instance().obtain(pump).post(message["payload"]); + } + return false; +} + + +bool LLMainLoopRepeater::onMessage(LLSD const & event) +{ + try { + mQueue.pushFront(event); + } catch(LLThreadSafeQueueError & e) { + llwarns << "could not repeat message (" << e.what() << ")" << + event.asString() << LL_ENDL; + } + return false; +} diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h new file mode 100644 index 0000000000..96b83b4916 --- /dev/null +++ b/indra/newview/llmainlooprepeater.h @@ -0,0 +1,65 @@ +/** + * @file llmainlooprepeater.h + * @brief a service for repeating messages on the main loop. + * + * $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_LLMAINLOOPREPEATER_H +#define LL_LLMAINLOOPREPEATER_H + + +#include "llsd.h" +#include "llthreadsafequeue.h" + + +// +// A service which creates the pump 'mainlooprepeater' to which any thread can +// post a message that will be re-posted on the main loop. +// +// The posted message should contain two map elements: pump and payload. The +// pump value is a string naming the pump to which the message should be +// re-posted. The payload value is what will be posted to the designated pump. +// +class LLMainLoopRepeater: + public LLSingleton +{ +public: + LLMainLoopRepeater(void); + + // Start the repeater service. + void start(void); + + // Stop the repeater service. + void stop(void); + +private: + LLTempBoundListener mMainLoopConnection; + LLTempBoundListener mRepeaterConnection; + LLThreadSafeQueue mQueue; + + bool onMainLoop(LLSD const &); + bool onMessage(LLSD const & event); +}; + + +#endif -- cgit v1.2.3 From 3493da8c41a157f2cd52632c2ac69b67e4091644 Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Tue, 9 Nov 2010 17:42:05 -0800 Subject: Fix for linux eol failures. --- indra/viewer_components/updater/llupdateinstaller.cpp | 2 +- indra/viewer_components/updater/llupdateinstaller.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 4d7c78d36c..1bb2101df1 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -35,4 +35,4 @@ void ll_install_update(std::string const & script, std::string const & updatePat launcher.addArgument(updatePath); launcher.launch(); launcher.orphan(); -} \ No newline at end of file +} diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h index a6068e9025..991fe2afe1 100644 --- a/indra/viewer_components/updater/llupdateinstaller.h +++ b/indra/viewer_components/updater/llupdateinstaller.h @@ -39,4 +39,4 @@ void ll_install_update(std::string const & script, std::string const & updatePath); -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From e87b447a0ca7c6e4aeb5f87e6767db918682499c Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Tue, 9 Nov 2010 17:42:13 -0800 Subject: Fix for dll linkage errors. --- indra/llcommon/llthreadsafequeue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 46c8b91932..58cac38769 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -39,7 +39,7 @@ class LLThreadSafeQueueImplementation; // See below. // // A general queue exception. // -class LLThreadSafeQueueError: +class LL_COMMON_API LLThreadSafeQueueError: public std::runtime_error { public: @@ -54,7 +54,7 @@ public: // // An exception raised when blocking operations are interrupted. // -class LLThreadSafeQueueInterrupt: +class LL_COMMON_API LLThreadSafeQueueInterrupt: public LLThreadSafeQueueError { public: @@ -72,7 +72,7 @@ struct apr_queue_t; // From apr_queue.h // // Implementation details. // -class LLThreadSafeQueueImplementation +class LL_COMMON_API LLThreadSafeQueueImplementation { public: LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity); -- cgit v1.2.3 From deaaad5e3350a57153d7eaf8635e492ab1062c27 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Wed, 10 Nov 2010 10:03:37 -0800 Subject: Add dependency to fix viewer manifest exception in build modes other than all. --- indra/viewer_components/updater/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index c3607dff39..7657dd4517 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -82,6 +82,7 @@ if(DARWIN) ) endif() add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets}) +add_dependencies(llupdaterservice copy_update_install) \ No newline at end of file -- cgit v1.2.3 From f42bb00627f756b277496ec203d567cac31b3438 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 10 Nov 2010 14:25:03 -0800 Subject: CHOP-151 Imported patch from server-trunk to support preprocessor at unit tests. Rev. by Brad --- indra/cmake/LLAddBuildTest.cmake | 538 ++++++++++++++++++++------------------- 1 file changed, 273 insertions(+), 265 deletions(-) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 79c3bb7da2..29e2492551 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -1,265 +1,273 @@ -# -*- cmake -*- -include(LLTestCommand) -include(GoogleMock) - -MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) - # Given a project name and a list of sourcefiles (with optional properties on each), - # add targets to build and run the tests specified. - # ASSUMPTIONS: - # * this macro is being executed in the project file that is passed in - # * current working SOURCE dir is that project dir - # * there is a subfolder tests/ with test code corresponding to the filenames passed in - # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT) - # - # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code - # - # WARNING: do NOT modify this code without working with poppy - - # there is another branch that will conflict heavily with any changes here. -INCLUDE(GoogleMock) - - - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") - ENDIF(LL_TEST_VERBOSE) - - # Start with the header and project-wide setup before making targets - #project(UNITTEST_PROJECT_${project}) - # Setup includes, paths, etc - SET(alltest_SOURCE_FILES - ${CMAKE_SOURCE_DIR}/test/test.cpp - ${CMAKE_SOURCE_DIR}/test/lltut.cpp - ) - SET(alltest_DEP_TARGETS - # needed by the test harness itself - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - llcommon - ) - IF(NOT "${project}" STREQUAL "llmath") - # add llmath as a dep unless the tested module *is* llmath! - LIST(APPEND alltest_DEP_TARGETS - llmath - ) - ENDIF(NOT "${project}" STREQUAL "llmath") - SET(alltest_INCLUDE_DIRS - ${LLMATH_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LIBS_OPEN_DIR}/test - ${GOOGLEMOCK_INCLUDE_DIRS} - ) - SET(alltest_LIBRARIES - ${GOOGLEMOCK_LIBRARIES} - ${PTHREAD_LIBRARY} - ${WINDOWS_LIBRARIES} - ) - # Headers, for convenience in targets. - SET(alltest_HEADER_FILES - ${CMAKE_SOURCE_DIR}/test/test.h - ) - - # Use the default flags - if (LINUX) - SET(CMAKE_EXE_LINKER_FLAGS "") - endif (LINUX) - - # start the source test executable definitions - SET(${project}_TEST_OUTPUT "") - FOREACH (source ${sources}) - STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} ) - STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})") - ENDIF(LL_TEST_VERBOSE) - - # - # Per-codefile additional / external source, header, and include dir property extraction - # - # Source - GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES) - IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) - SET(${name}_test_additional_SOURCE_FILES "") - ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) - SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") - ENDIF(LL_TEST_VERBOSE) - # Headers - GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES) - IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) - SET(${name}_test_additional_HEADER_FILES "") - ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) - SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) - set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) - LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES}) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}") - ENDIF(LL_TEST_VERBOSE) - # Include dirs - GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS) - IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) - SET(${name}_test_additional_INCLUDE_DIRS "") - ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) - INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}") - ENDIF(LL_TEST_VERBOSE) - - - # Setup target - ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) - SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") - - # - # Per-codefile additional / external project dep and lib dep property extraction - # - # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19 - # Projects - GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS) - IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) - SET(${name}_test_additional_PROJECTS "") - ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) - # Libraries - GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES) - IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) - SET(${name}_test_additional_LIBRARIES "") - ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}") - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}") - ENDIF(LL_TEST_VERBOSE) - # Add to project - TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} ) - - # - # Setup test targets - # - GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION) - SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt) - SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) - - # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19 - IF(LL_TEST_VERBOSE) - MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}") - ENDIF(LL_TEST_VERBOSE) - - SET_TEST_PATH(LD_LIBRARY_PATH) - LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD}) - IF(LL_TEST_VERBOSE) - MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}") - ENDIF(LL_TEST_VERBOSE) - # Add test - ADD_CUSTOM_COMMAND( - OUTPUT ${TEST_OUTPUT} - COMMAND ${TEST_SCRIPT_CMD} - DEPENDS PROJECT_${project}_TEST_${name} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - # Why not add custom target and add POST_BUILD command? - # Slightly less uncertain behavior - # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19 - # > I did not use a post build step as I could not make it notify of a - # > failure after the first time you build and fail a test. - daveh 2009-04-20 - LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT}) - ENDFOREACH (source) - - # Add the test runner target per-project - # (replaces old _test_ok targets all over the place) - ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) - ADD_DEPENDENCIES(${project} ${project}_tests) -ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) - -FUNCTION(LL_ADD_INTEGRATION_TEST - testname - additional_source_files - library_dependencies -# variable args - ) - if(TEST_DEBUG) - message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on") - endif(TEST_DEBUG) - - SET(source_files - tests/${testname}_test.cpp - ${CMAKE_SOURCE_DIR}/test/test.cpp - ${CMAKE_SOURCE_DIR}/test/lltut.cpp - ${additional_source_files} - ) - - SET(libraries - ${library_dependencies} - ${GOOGLEMOCK_LIBRARIES} - ${PTHREAD_LIBRARY} - ) - - # Add test executable build target - if(TEST_DEBUG) - message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") - endif(TEST_DEBUG) - ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) - SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") - - # Add link deps to the executable - if(TEST_DEBUG) - message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})") - endif(TEST_DEBUG) - TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries}) - - # Create the test running command - SET(test_command ${ARGN}) - GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION) - LIST(FIND test_command "{}" test_exe_pos) - IF(test_exe_pos LESS 0) - # The {} marker means "the full pathname of the test executable." - # test_exe_pos -1 means we didn't find it -- so append the test executable - # name to $ARGN, the variable part of the arg list. This is convenient - # shorthand for both straightforward execution of the test program (empty - # $ARGN) and for running a "wrapper" program of some kind accepting the - # pathname of the test program as the last of its args. You need specify - # {} only if the test program's pathname isn't the last argument in the - # desired command line. - LIST(APPEND test_command "${TEST_EXE}") - ELSE (test_exe_pos LESS 0) - # Found {} marker at test_exe_pos. Remove the {}... - LIST(REMOVE_AT test_command test_exe_pos) - # ...and replace it with the actual name of the test executable. - LIST(INSERT test_command test_exe_pos "${TEST_EXE}") - ENDIF (test_exe_pos LESS 0) - - SET_TEST_PATH(LD_LIBRARY_PATH) - LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command}) - - if(TEST_DEBUG) - message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}") - endif(TEST_DEBUG) - - ADD_CUSTOM_COMMAND( - TARGET INTEGRATION_TEST_${testname} - POST_BUILD - COMMAND ${TEST_SCRIPT_CMD} - ) - - # Use CTEST? Not sure how to yet... - # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD}) - -ENDFUNCTION(LL_ADD_INTEGRATION_TEST) - -MACRO(SET_TEST_PATH LISTVAR) - IF(WINDOWS) - # We typically build/package only Release variants of third-party - # libraries, so append the Release staging dir in case the library being - # sought doesn't have a debug variant. - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release) - ELSEIF(DARWIN) - # We typically build/package only Release variants of third-party - # libraries, so append the Release staging dir in case the library being - # sought doesn't have a debug variant. - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) - ELSE(WINDOWS) - # Linux uses a single staging directory anyway. - IF (STANDALONE) - set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib) - ELSE (STANDALONE) - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) - ENDIF (STANDALONE) - ENDIF(WINDOWS) -ENDMACRO(SET_TEST_PATH) +# -*- cmake -*- +include(LLTestCommand) +include(GoogleMock) + +MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) + # Given a project name and a list of sourcefiles (with optional properties on each), + # add targets to build and run the tests specified. + # ASSUMPTIONS: + # * this macro is being executed in the project file that is passed in + # * current working SOURCE dir is that project dir + # * there is a subfolder tests/ with test code corresponding to the filenames passed in + # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT) + # + # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code + # + # WARNING: do NOT modify this code without working with poppy - + # there is another branch that will conflict heavily with any changes here. +INCLUDE(GoogleMock) + + + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") + ENDIF(LL_TEST_VERBOSE) + + # Start with the header and project-wide setup before making targets + #project(UNITTEST_PROJECT_${project}) + # Setup includes, paths, etc + SET(alltest_SOURCE_FILES + ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ) + SET(alltest_DEP_TARGETS + # needed by the test harness itself + ${APRUTIL_LIBRARIES} + ${APR_LIBRARIES} + llcommon + ) + IF(NOT "${project}" STREQUAL "llmath") + # add llmath as a dep unless the tested module *is* llmath! + LIST(APPEND alltest_DEP_TARGETS + llmath + ) + ENDIF(NOT "${project}" STREQUAL "llmath") + SET(alltest_INCLUDE_DIRS + ${LLMATH_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LIBS_OPEN_DIR}/test + ${GOOGLEMOCK_INCLUDE_DIRS} + ) + SET(alltest_LIBRARIES + ${GOOGLEMOCK_LIBRARIES} + ${PTHREAD_LIBRARY} + ${WINDOWS_LIBRARIES} + ) + # Headers, for convenience in targets. + SET(alltest_HEADER_FILES + ${CMAKE_SOURCE_DIR}/test/test.h + ) + + # Use the default flags + if (LINUX) + SET(CMAKE_EXE_LINKER_FLAGS "") + endif (LINUX) + + # start the source test executable definitions + SET(${project}_TEST_OUTPUT "") + FOREACH (source ${sources}) + STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} ) + STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} ) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})") + ENDIF(LL_TEST_VERBOSE) + + # + # Per-codefile additional / external source, header, and include dir property extraction + # + # Source + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES) + IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) + SET(${name}_test_additional_SOURCE_FILES "") + ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND) + SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} ) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") + ENDIF(LL_TEST_VERBOSE) + # Headers + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES) + IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) + SET(${name}_test_additional_HEADER_FILES "") + ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND) + SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) + set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) + LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES}) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}") + ENDIF(LL_TEST_VERBOSE) + # Include dirs + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS) + IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) + SET(${name}_test_additional_INCLUDE_DIRS "") + ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) + INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS ) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}") + ENDIF(LL_TEST_VERBOSE) + + + # Setup target + ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) + SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + + # + # Per-codefile additional / external project dep and lib dep property extraction + # + # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19 + # Projects + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS) + IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) + SET(${name}_test_additional_PROJECTS "") + ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND) + # Libraries + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES) + IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) + SET(${name}_test_additional_LIBRARIES "") + ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}") + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}") + ENDIF(LL_TEST_VERBOSE) + # Add to project + TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} ) + # Compile-time Definitions + GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS) + IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND) + SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} ) + IF(LL_TEST_VERBOSE) + MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}") + ENDIF(LL_TEST_VERBOSE) + ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND) + + # + # Setup test targets + # + GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION) + SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt) + SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + + # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19 + IF(LL_TEST_VERBOSE) + MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}") + ENDIF(LL_TEST_VERBOSE) + + SET_TEST_PATH(LD_LIBRARY_PATH) + LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD}) + IF(LL_TEST_VERBOSE) + MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}") + ENDIF(LL_TEST_VERBOSE) + # Add test + ADD_CUSTOM_COMMAND( + OUTPUT ${TEST_OUTPUT} + COMMAND ${TEST_SCRIPT_CMD} + DEPENDS PROJECT_${project}_TEST_${name} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + # Why not add custom target and add POST_BUILD command? + # Slightly less uncertain behavior + # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19 + # > I did not use a post build step as I could not make it notify of a + # > failure after the first time you build and fail a test. - daveh 2009-04-20 + LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT}) + ENDFOREACH (source) + + # Add the test runner target per-project + # (replaces old _test_ok targets all over the place) + ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) + ADD_DEPENDENCIES(${project} ${project}_tests) +ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) + +FUNCTION(LL_ADD_INTEGRATION_TEST + testname + additional_source_files + library_dependencies +# variable args + ) + if(TEST_DEBUG) + message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on") + endif(TEST_DEBUG) + + SET(source_files + tests/${testname}_test.cpp + ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ${additional_source_files} + ) + + SET(libraries + ${library_dependencies} + ${GOOGLEMOCK_LIBRARIES} + ${PTHREAD_LIBRARY} + ) + + # Add test executable build target + if(TEST_DEBUG) + message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") + endif(TEST_DEBUG) + ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) + SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + + # Add link deps to the executable + if(TEST_DEBUG) + message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})") + endif(TEST_DEBUG) + TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries}) + + # Create the test running command + SET(test_command ${ARGN}) + GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION) + LIST(FIND test_command "{}" test_exe_pos) + IF(test_exe_pos LESS 0) + # The {} marker means "the full pathname of the test executable." + # test_exe_pos -1 means we didn't find it -- so append the test executable + # name to $ARGN, the variable part of the arg list. This is convenient + # shorthand for both straightforward execution of the test program (empty + # $ARGN) and for running a "wrapper" program of some kind accepting the + # pathname of the test program as the last of its args. You need specify + # {} only if the test program's pathname isn't the last argument in the + # desired command line. + LIST(APPEND test_command "${TEST_EXE}") + ELSE (test_exe_pos LESS 0) + # Found {} marker at test_exe_pos. Remove the {}... + LIST(REMOVE_AT test_command test_exe_pos) + # ...and replace it with the actual name of the test executable. + LIST(INSERT test_command test_exe_pos "${TEST_EXE}") + ENDIF (test_exe_pos LESS 0) + + SET_TEST_PATH(LD_LIBRARY_PATH) + LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command}) + + if(TEST_DEBUG) + message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}") + endif(TEST_DEBUG) + + ADD_CUSTOM_COMMAND( + TARGET INTEGRATION_TEST_${testname} + POST_BUILD + COMMAND ${TEST_SCRIPT_CMD} + ) + + # Use CTEST? Not sure how to yet... + # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD}) + +ENDFUNCTION(LL_ADD_INTEGRATION_TEST) + +MACRO(SET_TEST_PATH LISTVAR) + IF(WINDOWS) + # We typically build/package only Release variants of third-party + # libraries, so append the Release staging dir in case the library being + # sought doesn't have a debug variant. + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release) + ELSEIF(DARWIN) + # We typically build/package only Release variants of third-party + # libraries, so append the Release staging dir in case the library being + # sought doesn't have a debug variant. + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) + ELSE(WINDOWS) + # Linux uses a single staging directory anyway. + IF (STANDALONE) + set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib) + ELSE (STANDALONE) + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) + ENDIF (STANDALONE) + ENDIF(WINDOWS) +ENDMACRO(SET_TEST_PATH) -- cgit v1.2.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(-) 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.2.3 From 41ec2e01ddf12c7d9fc57a115b1e6047560c7e5e Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Wed, 10 Nov 2010 14:30:11 -0800 Subject: copy script to temp if needed before installing. --- .../updater/llupdateinstaller.cpp | 44 ++++++++++++++++++++-- .../viewer_components/updater/llupdateinstaller.h | 10 ++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 1bb2101df1..52744b0479 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -24,15 +24,53 @@ */ #include "linden_common.h" +#include +#include "llapr.h" #include "llprocesslauncher.h" #include "llupdateinstaller.h" +#include "lldir.h" -void ll_install_update(std::string const & script, std::string const & updatePath) +namespace { + class RelocateError {}; + + + std::string copy_to_temp(std::string const & path) + { + std::string scriptFile = gDirUtilp->getBaseFileName(path); + std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile); + apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp); + if(status != APR_SUCCESS) throw RelocateError(); + + return newPath; + } +} + + +int ll_install_update(std::string const & script, std::string const & updatePath, LLInstallScriptMode mode) { + std::string finalPath; + switch(mode) { + case LL_COPY_INSTALL_SCRIPT_TO_TEMP: + try { + finalPath = copy_to_temp(updatePath); + } + catch (RelocateError &) { + return -1; + } + break; + case LL_RUN_INSTALL_SCRIPT_IN_PLACE: + finalPath = updatePath; + break; + default: + llassert(!"unpossible copy mode"); + } + LLProcessLauncher launcher; launcher.setExecutable(script); - launcher.addArgument(updatePath); - launcher.launch(); + launcher.addArgument(finalPath); + int result = launcher.launch(); launcher.orphan(); + + return result; } diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h index 991fe2afe1..310bfe4348 100644 --- a/indra/viewer_components/updater/llupdateinstaller.h +++ b/indra/viewer_components/updater/llupdateinstaller.h @@ -30,13 +30,21 @@ #include +enum LLInstallScriptMode { + LL_RUN_INSTALL_SCRIPT_IN_PLACE, + LL_COPY_INSTALL_SCRIPT_TO_TEMP +}; + // // Launch the installation script. // // The updater will overwrite the current installation, so it is highly recommended // that the current application terminate once this function is called. // -void ll_install_update(std::string const & script, std::string const & updatePath); +int ll_install_update( + std::string const & script, // Script to execute. + std::string const & updatePath, // Path to update file. + LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp? #endif -- cgit v1.2.3 From dcf4ddacd81e3864525c44f145514911116daebd Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Wed, 10 Nov 2010 15:15:25 -0800 Subject: fix race between resume and download check. --- indra/viewer_components/updater/llupdaterservice.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 4eb317e668..28d9075efa 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -137,9 +137,9 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl() void LLUpdaterServiceImpl::initialize(const std::string& protocol_version, const std::string& url, - const std::string& path, - const std::string& channel, - const std::string& version) + const std::string& path, + const std::string& channel, + const std::string& version) { if(mIsChecking) { @@ -226,6 +226,7 @@ bool LLUpdaterServiceImpl::checkForResume() llstat stat_info; if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info)) { + mIsChecking = true; mUpdateDownloader.resume(); result = true; } -- cgit v1.2.3 From 94942671fa81ad0da3682af31b715ca49f8e3bef Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Wed, 10 Nov 2010 15:23:26 -0800 Subject: fix resume crash. --- .../viewer_components/updater/llupdatedownloader.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 208cc48c12..21555dc3ff 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -57,6 +57,7 @@ private: LLSD mDownloadData; llofstream mDownloadStream; std::string mDownloadRecordPath; + curl_slist * mHeaderList; void initializeCurlGet(std::string const & url, bool processHeader); void resumeDownloading(size_t startByte); @@ -154,7 +155,8 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & LLThread("LLUpdateDownloader"), mCancelled(false), mClient(client), - mCurl(0) + mCurl(0), + mHeaderList(0) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. llverify(code == CURLE_OK); // TODO: real error handling here. @@ -302,6 +304,11 @@ void LLUpdateDownloader::Implementation::run(void) LLFile::remove(mDownloadRecordPath); mClient.downloadError("curl error"); } + + if(mHeaderList) { + curl_slist_free_all(mHeaderList); + mHeaderList = 0; + } } @@ -330,17 +337,18 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte) { + LL_INFOS("UpdateDownload") << "resuming download from " << mDownloadData["url"].asString() + << " at byte " << startByte << LL_ENDL; + initializeCurlGet(mDownloadData["url"].asString(), false); // The header 'Range: bytes n-' will request the bytes remaining in the // source begining with byte n and ending with the last byte. boost::format rangeHeaderFormat("Range: bytes=%u-"); rangeHeaderFormat % startByte; - curl_slist * headerList = 0; - headerList = curl_slist_append(headerList, rangeHeaderFormat.str().c_str()); - if(headerList == 0) throw DownloadError("cannot add Range header"); - throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, headerList)); - curl_slist_free_all(headerList); + mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str()); + if(mHeaderList == 0) throw DownloadError("cannot add Range header"); + throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList)); mDownloadStream.open(mDownloadData["path"].asString(), std::ios_base::out | std::ios_base::binary | std::ios_base::app); -- cgit v1.2.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(-) 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.2.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(-) 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.2.3 From 4e22d63352dd65085cfbba9c22070271ecdd4bcf Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 11 Nov 2010 11:05:46 -0800 Subject: Add very basic windows install script. --- indra/newview/viewer_manifest.py | 4 ++++ indra/viewer_components/updater/CMakeLists.txt | 7 +++++++ indra/viewer_components/updater/scripts/windows/update_install.bat | 1 + 3 files changed, 12 insertions(+) create mode 100644 indra/viewer_components/updater/scripts/windows/update_install.bat diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 0073641ed4..55d64fd3a6 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -251,6 +251,10 @@ class WindowsManifest(ViewerManifest): if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): + if self.prefix(src="../../viewer_components/updater", dst=""): + self.path("update_install.bat") + self.end_prefix() + self.enable_crt_manifest_check() # Get kdu dll, continue if missing. diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index c5ccfbf66a..469c0cf05e 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -89,6 +89,13 @@ if(DARWIN) update_installer_targets "update_install" ) +elseif(WINDOWS) + copy_if_different( + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/windows" + "${CMAKE_CURRENT_BINARY_DIR}" + update_installer_targets + "update_install.bat" + ) endif() add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets}) add_dependencies(llupdaterservice copy_update_install) diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat new file mode 100644 index 0000000000..def33c1346 --- /dev/null +++ b/indra/viewer_components/updater/scripts/windows/update_install.bat @@ -0,0 +1 @@ +start /WAIT %1 \ No newline at end of file -- cgit v1.2.3 From 7a7f89db6d9c5e6b2c6c89ea39c0302907a0442b Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 11 Nov 2010 11:46:24 -0800 Subject: fix termination issues with thread safe queue in main loop repeater service. --- indra/llcommon/llthreadsafequeue.cpp | 6 +++--- indra/newview/llappviewer.cpp | 4 +++- indra/newview/llmainlooprepeater.cpp | 12 +++++++++--- indra/newview/llmainlooprepeater.h | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index a7141605ef..8a73e632a9 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -53,13 +53,13 @@ LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * po LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation() { - if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool); if(mQueue != 0) { if(apr_queue_size(mQueue) != 0) llwarns << - "terminating queue which still contains elements;" << - "memory will be leaked" << LL_ENDL; + "terminating queue which still contains " << apr_queue_size(mQueue) << + " elements;" << "memory will be leaked" << LL_ENDL; apr_queue_term(mQueue); } + if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool); } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c06f0c18e8..76d518b610 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -812,7 +812,7 @@ bool LLAppViewer::init() } // Initialize the repeater service. - LLMainLoopRepeater::getInstance()->start(); + LLMainLoopRepeater::instance().start(); // // Initialize the window @@ -1737,6 +1737,8 @@ bool LLAppViewer::cleanup() llinfos << "File launched." << llendflush; } + LLMainLoopRepeater::instance().stop(); + ll_close_fail_log(); llinfos << "Goodbye!" << llendflush; diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index c2eba97641..ddc925a73b 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -36,7 +36,7 @@ LLMainLoopRepeater::LLMainLoopRepeater(void): - mQueue(gAPRPoolp, 1024) + mQueue(0) { ; // No op. } @@ -44,6 +44,9 @@ LLMainLoopRepeater::LLMainLoopRepeater(void): void LLMainLoopRepeater::start(void) { + if(mQueue != 0) return; + + mQueue = new LLThreadSafeQueue(gAPRPoolp, 1024); mMainLoopConnection = LLEventPumps::instance(). obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). @@ -55,13 +58,16 @@ void LLMainLoopRepeater::stop(void) { mMainLoopConnection.release(); mRepeaterConnection.release(); + + delete mQueue; + mQueue = 0; } bool LLMainLoopRepeater::onMainLoop(LLSD const &) { LLSD message; - while(mQueue.tryPopBack(message)) { + while(mQueue->tryPopBack(message)) { std::string pump = message["pump"].asString(); if(pump.length() == 0 ) continue; // No pump. LLEventPumps::instance().obtain(pump).post(message["payload"]); @@ -73,7 +79,7 @@ bool LLMainLoopRepeater::onMainLoop(LLSD const &) bool LLMainLoopRepeater::onMessage(LLSD const & event) { try { - mQueue.pushFront(event); + mQueue->pushFront(event); } catch(LLThreadSafeQueueError & e) { llwarns << "could not repeat message (" << e.what() << ")" << event.asString() << LL_ENDL; diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h index 96b83b4916..f84c0ca94c 100644 --- a/indra/newview/llmainlooprepeater.h +++ b/indra/newview/llmainlooprepeater.h @@ -55,7 +55,7 @@ public: private: LLTempBoundListener mMainLoopConnection; LLTempBoundListener mRepeaterConnection; - LLThreadSafeQueue mQueue; + LLThreadSafeQueue * mQueue; bool onMainLoop(LLSD const &); bool onMessage(LLSD const & event); -- cgit v1.2.3 From 830afa5b27092668517b2f5670e892143de3cf66 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 11 Nov 2010 16:45:38 -0800 Subject: hacking mac updater to install from local dmg --- indra/llcommon/llthread.cpp | 2 + indra/mac_updater/mac_updater.cpp | 48 ++++++++++++++++++++-- .../updater/scripts/darwin/update_install | 5 +-- 3 files changed, 47 insertions(+), 8 deletions(-) mode change 100644 => 100755 indra/viewer_components/updater/scripts/darwin/update_install diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 2408be74b9..148aaf8aed 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -147,6 +147,8 @@ void LLThread::shutdown() { // This thread just wouldn't stop, even though we gave it time llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; + // Put a stake in its heart. + apr_thread_exit(mAPRThreadp, -1); return; } mAPRThreadp = NULL; diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 23980ffac2..5f6ea4d33b 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -26,6 +26,9 @@ #include "linden_common.h" +#include + +#include #include #include #include @@ -62,6 +65,7 @@ Boolean gCancelled = false; const char *gUpdateURL; const char *gProductName; const char *gBundleID; +const char *gDmgFile; void *updatethreadproc(void*); @@ -334,6 +338,10 @@ int parse_args(int argc, char **argv) { gBundleID = argv[j]; } + else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) + { + gDmgFile = argv[j]; + } } return 0; @@ -361,10 +369,11 @@ int main(int argc, char **argv) gUpdateURL = NULL; gProductName = NULL; gBundleID = NULL; + gDmgFile = NULL; parse_args(argc, argv); - if (!gUpdateURL) + if ((gUpdateURL == NULL) && (gDmgFile == NULL)) { - llinfos << "Usage: mac_updater -url [-name ] [-program ]" << llendl; + llinfos << "Usage: mac_updater -url | -dmg [-name ] [-program ]" << llendl; exit(1); } else @@ -700,10 +709,14 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) // Looks promising. Check to see if it has the right bundle identifier. if(isFSRefViewerBundle(&ref)) { + llinfos << name << " is the one" << llendl; // This is the one. Return it. *app = ref; found = true; + } else { + llinfos << name << " is not the bundle we are looking for; move along" << llendl; } + } } } @@ -921,6 +934,22 @@ void *updatethreadproc(void*) #endif // 0 *HACK for DEV-11935 + // Skip downloading the file if the dmg was passed on the command line. + std::string dmgName; + if(gDmgFile != NULL) { + dmgName = basename((char *)gDmgFile); + char * dmgDir = dirname((char *)gDmgFile); + strncpy(tempDir, dmgDir, sizeof(tempDir)); + err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); + if(err != noErr) throw 0; + chdir(tempDir); + goto begin_install; + } else { + // Continue on to download file. + dmgName = "SecondLife.dmg"; + } + + strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); if(mkdtemp(temp) == NULL) { @@ -979,14 +1008,17 @@ void *updatethreadproc(void*) fclose(downloadFile); downloadFile = NULL; } - + + begin_install: sendProgress(0, 0, CFSTR("Mounting image...")); LLFile::mkdir("mnt", 0700); // NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder, // but if our cleanup fails, this makes it much harder for the user to unmount the image. std::string mountOutput; - FILE* mounter = popen("hdiutil attach SecondLife.dmg -mountpoint mnt", "r"); /* Flawfinder: ignore */ + boost::format cmdFormat("hdiutil attach %s -mountpoint mnt"); + cmdFormat % dmgName; + FILE* mounter = popen(cmdFormat.str().c_str(), "r"); /* Flawfinder: ignore */ if(mounter == NULL) { @@ -1077,7 +1109,11 @@ void *updatethreadproc(void*) // Move aside old version (into work directory) err = FSMoveObject(&targetRef, &tempDirRef, &asideRef); if(err != noErr) + { + llwarns << "failed to move aside old version (error code " << + err << ")" << llendl; throw 0; + } // Grab the path for later use. err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside)); @@ -1175,6 +1211,10 @@ void *updatethreadproc(void*) llinfos << "Moving work directory to the trash." << llendl; err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL); + if(err != noErr) { + llwarns << "failed to move files to trash, (error code " << + err << ")" << llendl; + } // snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir); // printf("%s\n", temp); 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 24d344ca52..c061d2818f --- a/indra/viewer_components/updater/scripts/darwin/update_install +++ b/indra/viewer_components/updater/scripts/darwin/update_install @@ -1,6 +1,3 @@ #! /bin/bash -hdiutil attach -nobrowse $1 -cp -R /Volumes/Second\ Life\ Installer/Second\ Life\ Viewer\ 2.app /Applications -hdiutil detach /Volumes/Second\ Life\ Installer -open /Applications/Second\ Life\ Viewer\ 2.app \ No newline at end of file +open ../Resources/mac-updater.app --args -dmg "$1" -name "Second Life Viewer 2" -- cgit v1.2.3 From bfa393f933ccf11105daf5258f373efc764b736f Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Thu, 11 Nov 2010 19:05:05 -0800 Subject: CHOP-178 Add a non-interactive moe to the windows installer. Rev by Brad --- .../installers/windows/installer_template.nsi | 55 +++++++++++++++------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index d5712f80cf..4e8ed807ee 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -85,6 +85,8 @@ AutoCloseWindow true ; after all files install, close window InstallDir "$PROGRAMFILES\${INSTNAME}" InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "" DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) +Page directory dirPre +Page instfiles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Variables @@ -95,6 +97,8 @@ Var INSTFLAGS Var INSTSHORTCUT Var COMMANDLINE ; command line passed to this installer, set in .onInit Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer +Var SKIP_DIALOGS ; set from command line in .onInit. autoinstall + ; GUI and the defaults. ;;; Function definitions should go before file includes, because calls to ;;; DLLs like LangDLL trigger an implicit file include, so if that call is at @@ -110,6 +114,9 @@ Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function .onInstSuccess Push $R0 # Option value, unused + + StrCmp $SKIP_DIALOGS "true" label_launch + ${GetOptions} $COMMANDLINE "/AUTOSTART" $R0 # If parameter was there (no error) just launch # Otherwise ask @@ -128,6 +135,13 @@ label_no_launch: Pop $R0 FunctionEnd +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Pre-directory page callback +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function dirPre + StrCmp $SKIP_DIALOGS "true" 0 +2 + Abort +FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Make sure we're not on Windows 98 / ME @@ -145,7 +159,8 @@ Function CheckWindowsVersion StrCmp $R0 "NT" win_ver_bad Return win_ver_bad: - MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort + StrCmp $SKIP_DIALOGS "true" +2 ; If skip_dialogs is set just install + MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort Return win_ver_abort: Quit @@ -184,13 +199,13 @@ FunctionEnd ; If it has, allow user to bail out of install process. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CheckIfAlreadyCurrent - Push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" - StrCmp $0 ${VERSION_LONG} 0 DONE - MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE + Push $0 + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" + StrCmp $0 ${VERSION_LONG} 0 continue_install + StrCmp $SKIP_DIALOGS "true" continue_install + MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK continue_install Quit - - DONE: +continue_install: Pop $0 Return FunctionEnd @@ -203,7 +218,9 @@ Function CloseSecondLife Push $0 FindWindow $0 "Second Life" "" IntCmp $0 0 DONE - MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL + + StrCmp $SKIP_DIALOGS "true" CLOSE + MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL CANCEL_INSTALL: Quit @@ -659,23 +676,29 @@ FunctionEnd Function .onInit Push $0 ${GetParameters} $COMMANDLINE ; get our command line + + ${GetOptions} $COMMANDLINE "/SKIP_DIALOGS" $0 + IfErrors +2 0 ; If error jump past setting SKIP_DIALOGS + StrCpy $SKIP_DIALOGS "true" + ${GetOptions} $COMMANDLINE "/LANGID=" $0 ; /LANGID=1033 implies US English ; If no language (error), then proceed - IfErrors lbl_check_silent + IfErrors lbl_configure_default_lang ; No error means we got a language, so use it StrCpy $LANGUAGE $0 Goto lbl_return -lbl_check_silent: - ; For silent installs, no language prompt, use default - IfSilent lbl_return - - ; If we currently have a version of SL installed, default to the language of that install +lbl_configure_default_lang: + ; If we currently have a version of SL installed, default to the language of that install ; Otherwise don't change $LANGUAGE and it will default to the OS UI language. - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" - IfErrors lbl_build_menu + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" + IfErrors +2 0 ; If error skip the copy instruction StrCpy $LANGUAGE $0 + ; For silent installs, no language prompt, use default + IfSilent lbl_return + StrCmp $SKIP_DIALOGS "true" lbl_return + lbl_build_menu: Push "" # Use separate file so labels can be UTF-16 but we can still merge changes -- cgit v1.2.3 From 1368a94f014884588b343802eef5fd2c7888390a Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 12 Nov 2010 12:23:30 -0800 Subject: do not resume or install if current viewer version doesn't match the recorded version which started the process. --- .../updater/llupdatedownloader.cpp | 2 + .../viewer_components/updater/llupdaterservice.cpp | 71 +++++++++++++++++++--- indra/viewer_components/updater/llupdaterservice.h | 3 + 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 21555dc3ff..ab441aa747 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -35,6 +35,7 @@ #include "llsdserialize.h" #include "llthread.h" #include "llupdatedownloader.h" +#include "llupdaterservice.h" class LLUpdateDownloader::Implementation: @@ -360,6 +361,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std { mDownloadData["url"] = uri.asString(); mDownloadData["hash"] = hash; + mDownloadData["current_version"] = ll_get_version(); LLSD path = uri.pathArray(); if(path.size() == 0) throw DownloadError("no file path"); std::string fileName = path[path.size() - 1].asString(); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 43551d6cea..6cc872f2ca 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -31,6 +31,7 @@ #include "llupdaterservice.h" #include "llupdatechecker.h" #include "llupdateinstaller.h" +#include "llversionviewer.h" #include #include @@ -237,7 +238,23 @@ bool LLUpdaterServiceImpl::checkForInstall() // Get the path to the installer file. LLSD path = update_info.get("path"); - if(path.isDefined() && !path.asString().empty()) + if(update_info["current_version"].asString() != ll_get_version()) + { + // This viewer is not the same version as the one that downloaded + // the update. Do not install this update. + if(!path.asString().empty()) + { + llinfos << "ignoring update dowloaded by different client version" << llendl; + LLFile::remove(path.asString()); + } + else + { + ; // Nothing to clean up. + } + + result = false; + } + else if(path.isDefined() && !path.asString().empty()) { int result = ll_install_update(install_script_path(), update_info["path"].asString(), @@ -251,9 +268,9 @@ bool LLUpdaterServiceImpl::checkForInstall() } else { ; // No op. } + + result = true; } - - result = true; } return result; } @@ -261,14 +278,33 @@ bool LLUpdaterServiceImpl::checkForInstall() bool LLUpdaterServiceImpl::checkForResume() { bool result = false; - llstat stat_info; - if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info)) + std::string download_marker_path = mUpdateDownloader.downloadMarkerPath(); + if(LLFile::isfile(download_marker_path)) { - mIsDownloading = true; - mUpdateDownloader.resume(); - result = true; + llifstream download_marker_stream(download_marker_path, + std::ios::in | std::ios::binary); + if(download_marker_stream.is_open()) + { + LLSD download_info; + LLSDSerialize::fromXMLDocument(download_info, download_marker_stream); + download_marker_stream.close(); + if(download_info["current_version"].asString() == ll_get_version()) + { + mIsDownloading = true; + mUpdateDownloader.resume(); + result = true; + } + else + { + // The viewer that started this download is not the same as this viewer; ignore. + llinfos << "ignoring partial download from different viewer version" << llendl; + std::string path = download_info["path"].asString(); + if(!path.empty()) LLFile::remove(path); + LLFile::remove(download_marker_path); + } + } } - return false; + return result; } void LLUpdaterServiceImpl::error(std::string const & message) @@ -406,3 +442,20 @@ void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callbac { return mImpl->setAppExitCallback(aecb); } + + +std::string const & ll_get_version(void) { + static std::string version(""); + + if (version.empty()) { + std::ostringstream stream; + stream << LL_VERSION_MAJOR << "." + << LL_VERSION_MINOR << "." + << LL_VERSION_PATCH << "." + << LL_VERSION_BUILD; + version = stream.str(); + } + + return version; +} + diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 42ec3a2cab..ec20dc6e05 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -68,4 +68,7 @@ private: void setImplAppExitCallback(app_exit_callback_t aecb); }; +// Returns the full version as a string. +std::string const & ll_get_version(void); + #endif // LL_UPDATERSERVICE_H -- cgit v1.2.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 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.2.3 From a89024fb372bb293d24d860fb70156b5cf48d6f3 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Mon, 15 Nov 2010 09:57:00 -0800 Subject: write marker on windows installer fail. --- indra/viewer_components/updater/scripts/windows/update_install.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat index def33c1346..9cdc51847a 100644 --- a/indra/viewer_components/updater/scripts/windows/update_install.bat +++ b/indra/viewer_components/updater/scripts/windows/update_install.bat @@ -1 +1,2 @@ -start /WAIT %1 \ No newline at end of file +start /WAIT %1 +IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2 -- cgit v1.2.3 From f47c42bb10cd3291ce966be7b209b422646dff19 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Mon, 15 Nov 2010 14:26:45 -0800 Subject: create marker on error; use /SKIP_DIALOGS option in installer to run without user input. --- indra/viewer_components/updater/scripts/windows/update_install.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat index 9cdc51847a..44ccef010b 100644 --- a/indra/viewer_components/updater/scripts/windows/update_install.bat +++ b/indra/viewer_components/updater/scripts/windows/update_install.bat @@ -1,2 +1,2 @@ -start /WAIT %1 +start /WAIT %1 /SKIP_DIALOGS IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2 -- cgit v1.2.3 From 35fc90e8aaebc10a5a01c58247c29c8103220578 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Mon, 15 Nov 2010 14:37:32 -0800 Subject: CHOP-179 Added --file option to linux-updater for local install --- indra/linux_updater/linux_updater.cpp | 149 +++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 67 deletions(-) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index be4d810860..16660de6bb 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -49,6 +49,7 @@ const guint ROTATE_IMAGE_TIMEOUT = 8000; typedef struct _updater_app_state { std::string app_name; std::string url; + std::string file; std::string image_dir; std::string dest_dir; std::string strings_dirs; @@ -266,85 +267,95 @@ gpointer worker_thread_cb(gpointer data) CURLcode result; FILE *package_file; GError *error = NULL; - char *tmp_filename = NULL; int fd; //g_return_val_if_fail (data != NULL, NULL); app_state = (UpdaterAppState *) data; try { - // create temporary file to store the package. - fd = g_file_open_tmp - ("secondlife-update-XXXXXX", &tmp_filename, &error); - if (error != NULL) - { - llerrs << "Unable to create temporary file: " - << error->message - << llendl; - g_error_free(error); - throw 0; - } - - package_file = fdopen(fd, "wb"); - if (package_file == NULL) + if(!app_state->url.empty()) { - llerrs << "Failed to create temporary file: " - << tmp_filename - << llendl; + char* tmp_local_filename = NULL; + // create temporary file to store the package. + fd = g_file_open_tmp + ("secondlife-update-XXXXXX", &tmp_local_filename, &error); + if (error != NULL) + { + llerrs << "Unable to create temporary file: " + << error->message + << llendl; - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } + g_error_free(error); + throw 0; + } + + if(tmp_local_filename != NULL) + { + app_state->file = tmp_local_filename; + g_free(tmp_local_filename); + } - // initialize curl and start downloading the package - llinfos << "Downloading package: " << app_state->url << llendl; + package_file = fdopen(fd, "wb"); + if (package_file == NULL) + { + llerrs << "Failed to create temporary file: " + << app_state->file.c_str() + << llendl; + + gdk_threads_enter(); + display_error(app_state->window, + LLTrans::getString("UpdaterFailDownloadTitle"), + LLTrans::getString("UpdaterFailUpdateDescriptive")); + gdk_threads_leave(); + throw 0; + } - curl = curl_easy_init(); - if (curl == NULL) - { - llerrs << "Failed to initialize libcurl" << llendl; + // initialize curl and start downloading the package + llinfos << "Downloading package: " << app_state->url << llendl; - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); - throw 0; - } + curl = curl_easy_init(); + if (curl == NULL) + { + llerrs << "Failed to initialize libcurl" << llendl; + + gdk_threads_enter(); + display_error(app_state->window, + LLTrans::getString("UpdaterFailDownloadTitle"), + LLTrans::getString("UpdaterFailUpdateDescriptive")); + gdk_threads_leave(); + throw 0; + } - curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, - &download_progress_cb); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state); + curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str()); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, + &download_progress_cb); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state); - result = curl_easy_perform(curl); - fclose(package_file); - curl_easy_cleanup(curl); + result = curl_easy_perform(curl); + fclose(package_file); + curl_easy_cleanup(curl); - if (result) - { - llerrs << "Failed to download update: " - << app_state->url - << llendl; + if (result) + { + llerrs << "Failed to download update: " + << app_state->url + << llendl; - gdk_threads_enter(); - display_error(app_state->window, - LLTrans::getString("UpdaterFailDownloadTitle"), - LLTrans::getString("UpdaterFailUpdateDescriptive")); - gdk_threads_leave(); + gdk_threads_enter(); + display_error(app_state->window, + LLTrans::getString("UpdaterFailDownloadTitle"), + LLTrans::getString("UpdaterFailUpdateDescriptive")); + gdk_threads_leave(); - throw 0; + throw 0; + } } - + // now pulse the progres bar back and forth while the package is // being unpacked gdk_threads_enter(); @@ -357,7 +368,7 @@ gpointer worker_thread_cb(gpointer data) // *TODO: if the destination is not writable, terminate this // thread and show file chooser? - if (!install_package(tmp_filename, app_state->dest_dir)) + if (!install_package(app_state->file.c_str(), app_state->dest_dir)) { llwarns << "Failed to install package to destination: " << app_state->dest_dir @@ -393,11 +404,11 @@ gpointer worker_thread_cb(gpointer data) } // FIXME: delete package file also if delete-event is raised on window - if (tmp_filename != NULL) + if(!app_state->url.empty() && !app_state->file.empty()) { - if (gDirUtilp->fileExists(tmp_filename)) + if (gDirUtilp->fileExists(app_state->file)) { - LLFile::remove(tmp_filename); + LLFile::remove(app_state->file); } } @@ -712,7 +723,7 @@ BOOL spawn_viewer(UpdaterAppState *app_state) void show_usage_and_exit() { - std::cout << "Usage: linux-updater --url URL --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE" + std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE" << "[--image-dir PATH]" << std::endl; exit(1); @@ -728,6 +739,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) { app_state->url = argv[i]; } + else if ((!strcmp(argv[i], "--file")) && (++i < argc)) + { + app_state->file = argv[i]; + } else if ((!strcmp(argv[i], "--name")) && (++i < argc)) { app_state->app_name = argv[i]; @@ -756,7 +771,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) } if (app_state->app_name.empty() - || app_state->url.empty() + || (app_state->url.empty() && app_state->file.empty()) || app_state->dest_dir.empty()) { show_usage_and_exit(); -- cgit v1.2.3 From 64876ea9459ed0e0f1673c5ec9ae67abea2280e2 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 16 Nov 2010 09:43:23 -0800 Subject: better error checking when writing downloaded file. --- indra/viewer_components/updater/llupdatedownloader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index ab441aa747..eccc25aeee 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -275,9 +275,14 @@ size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) { if(mCancelled) return 0; // Forces a write error which will halt curl thread. + if((size == 0) || (buffer == 0)) return 0; mDownloadStream.write(reinterpret_cast(buffer), size); - return size; + if(mDownloadStream.bad()) { + return 0; + } else { + return size; + } } -- cgit v1.2.3 From ad354324ca444d1fc71653e2ade799053a8d6f01 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 16 Nov 2010 15:21:35 -0800 Subject: clean up installer file after install. --- indra/viewer_components/updater/scripts/windows/update_install.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat index 44ccef010b..42e148a707 100644 --- a/indra/viewer_components/updater/scripts/windows/update_install.bat +++ b/indra/viewer_components/updater/scripts/windows/update_install.bat @@ -1,2 +1,3 @@ start /WAIT %1 /SKIP_DIALOGS -IF ERRORLEVEL 1 ECHO ERRORLEVEL > %2 +IF ERRORLEVEL 1 ECHO %ERRORLEVEL% > %2 +DEL %1 -- cgit v1.2.3 From 13b77e3622de18ac8d06fdfffceb08990eb908f9 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Tue, 16 Nov 2010 16:21:17 -0800 Subject: CHOP-179 Linux install uses linux-updater. Rev. by Alain --- indra/newview/viewer_manifest.py | 13 +++++-------- indra/viewer_components/updater/CMakeLists.txt | 22 ---------------------- .../viewer_components/updater/llupdaterservice.cpp | 6 ++++-- .../updater/scripts/linux/update_install | 5 +++++ 4 files changed, 14 insertions(+), 32 deletions(-) create mode 100755 indra/viewer_components/updater/scripts/linux/update_install diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 55d64fd3a6..5d35778e3e 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -247,13 +247,12 @@ class WindowsManifest(ViewerManifest): self.disable_manifest_check() + self.path("../viewer_components/updater/scripts/windows/update_install.bat") + # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): - if self.prefix(src="../../viewer_components/updater", dst=""): - self.path("update_install.bat") - self.end_prefix() self.enable_crt_manifest_check() @@ -575,12 +574,8 @@ 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() + self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install") # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): @@ -857,6 +852,8 @@ class LinuxManifest(ViewerManifest): # recurse self.end_prefix("res-sdl") + self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install") + # plugins if self.prefix(src="", dst="bin/llplugin"): self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 469c0cf05e..0e288bb496 100644 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -80,25 +80,3 @@ set(UPDATER_LIBRARIES llupdaterservice CACHE INTERNAL "" ) - -# Copy install script. -if(DARWIN) - copy_if_different( - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/darwin" - "${CMAKE_CURRENT_BINARY_DIR}" - update_installer_targets - "update_install" - ) -elseif(WINDOWS) - copy_if_different( - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/windows" - "${CMAKE_CURRENT_BINARY_DIR}" - update_installer_targets - "update_install.bat" - ) -endif() -add_custom_target(copy_update_install ALL DEPENDS ${update_installer_targets}) -add_dependencies(llupdaterservice copy_update_install) - - - \ No newline at end of file diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index a1ad3e3381..976e639098 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -353,9 +353,11 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) void LLUpdaterServiceImpl::downloadError(std::string const & message) { + LL_INFOS("UpdaterService") << "Error downloading: " << message << LL_ENDL; + mIsDownloading = false; - // Restart the + // Restart the timer on error if(mIsChecking) { restartTimer(mCheckPeriod); @@ -365,7 +367,7 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message) void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) { LL_INFOS("UpdaterService") << "will check for update again in " << - mCheckPeriod << " seconds" << LL_ENDL; + seconds << " seconds" << LL_ENDL; mTimer.start(); mTimer.setTimerExpirySec(seconds); LLEventPumps::instance().obtain("mainloop").listen( diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install new file mode 100755 index 0000000000..acedaad25c --- /dev/null +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -0,0 +1,5 @@ +#! /bin/bash +INSTALL_DIR=$(cd "$(dirname $0)/.." ; pwd) +export LD_LIBRARY_PATH=$INSTALL_DIR/lib +bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer 2" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml" + -- cgit v1.2.3 From 74a60346b2f04157862786d31d7181885092b766 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 16 Nov 2010 16:22:37 -0800 Subject: remove downloaded file on error. --- indra/viewer_components/updater/llupdatedownloader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index eccc25aeee..4820f1f452 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -308,6 +308,7 @@ void LLUpdateDownloader::Implementation::run(void) LL_WARNS("UpdateDownload") << "download failed with error '" << curl_easy_strerror(code) << "'" << LL_ENDL; LLFile::remove(mDownloadRecordPath); + if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString()); mClient.downloadError("curl error"); } -- cgit v1.2.3 From dd6213abf4f70cfb9d221572f9dc4d597d8fa0dc Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Tue, 16 Nov 2010 18:34:58 -0800 Subject: CHOP-209 Added marker creation, fixed updater crash bug --- indra/linux_updater/linux_updater.cpp | 17 ++++++++++------- .../updater/scripts/linux/update_install | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index 16660de6bb..a7f886b389 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -114,7 +114,7 @@ BOOL install_package(std::string package_file, std::string destination); BOOL spawn_viewer(UpdaterAppState *app_state); extern "C" { - void on_window_closed(GtkWidget *sender, gpointer state); + void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state); gpointer worker_thread_cb(gpointer *data); int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow); gboolean rotate_image_cb(gpointer data); @@ -221,7 +221,7 @@ std::string next_image_filename(std::string& image_path) return image_path + "/" + image_filename; } -void on_window_closed(GtkWidget *sender, gpointer data) +void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data) { UpdaterAppState *app_state; @@ -786,10 +786,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state) int main(int argc, char **argv) { - UpdaterAppState app_state; + UpdaterAppState* app_state = new UpdaterAppState; GThread *worker_thread; - parse_args_and_init(argc, argv, &app_state); + parse_args_and_init(argc, argv, app_state); // Initialize logger, and rename old log file gDirUtilp->initAppDirs("SecondLife"); @@ -812,17 +812,20 @@ int main(int argc, char **argv) gtk_init(&argc, &argv); // create UI - updater_app_ui_init(&app_state); + updater_app_ui_init(app_state); //llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl; // create download thread worker_thread = g_thread_create - (GThreadFunc(worker_thread_cb), &app_state, FALSE, NULL); + (GThreadFunc(worker_thread_cb), app_state, FALSE, NULL); gdk_threads_enter(); gtk_main(); gdk_threads_leave(); - return (app_state.failure == FALSE) ? 0 : 1; + bool success = app_state->failure != FALSE; + delete app_state; + return success ? 0 : 1; } + diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index acedaad25c..7d8a27607c 100755 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -3,3 +3,6 @@ INSTALL_DIR=$(cd "$(dirname $0)/.." ; pwd) export LD_LIBRARY_PATH=$INSTALL_DIR/lib bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer 2" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml" +if [ $? -ne 0 ] + then touch $2 +fi \ No newline at end of file -- cgit v1.2.3 From c61d89f61d0b696e6e73105ed7be7580bf1b3437 Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 17 Nov 2010 12:24:37 -0800 Subject: CHOP-203 Fixed linux release bug - exclude update_install from symbol strippage --- indra/newview/viewer_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 5d35778e3e..4e5d6271df 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -882,7 +882,7 @@ class LinuxManifest(ViewerManifest): if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command("find %(d)r/bin %(d)r/lib -type f | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure # Fix access permissions self.run_command(""" -- cgit v1.2.3 From 8e0e5e0bd9fd3e699a36b6babfacab3c0f61935b Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 17 Nov 2010 15:20:53 -0800 Subject: CHOP-203 Deleting the update file after installer run. --- indra/linux_updater/linux_updater.cpp | 18 +++++++++--------- .../updater/scripts/linux/update_install | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index a7f886b389..cbdb3ddfe0 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -403,15 +403,6 @@ gpointer worker_thread_cb(gpointer data) app_state->failure = TRUE; } - // FIXME: delete package file also if delete-event is raised on window - if(!app_state->url.empty() && !app_state->file.empty()) - { - if (gDirUtilp->fileExists(app_state->file)) - { - LLFile::remove(app_state->file); - } - } - gdk_threads_enter(); updater_app_quit(app_state); gdk_threads_leave(); @@ -824,6 +815,15 @@ int main(int argc, char **argv) gtk_main(); gdk_threads_leave(); + // Delete the file only if created from url download. + if(!app_state->url.empty() && !app_state->file.empty()) + { + if (gDirUtilp->fileExists(app_state->file)) + { + LLFile::remove(app_state->file); + } + } + bool success = app_state->failure != FALSE; delete app_state; return success ? 0 : 1; diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 7d8a27607c..fef5ef7d09 100755 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -5,4 +5,6 @@ bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life View if [ $? -ne 0 ] then touch $2 -fi \ No newline at end of file +fi + +rm -f $1 -- cgit v1.2.3 From c212695cd96f94248b0da2085aeb23c54a5ca76b Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Wed, 17 Nov 2010 16:27:50 -0800 Subject: post events for dowload success and error. --- .../viewer_components/updater/llupdaterservice.cpp | 24 +++++++++++++++++++++- indra/viewer_components/updater/llupdaterservice.h | 10 +++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 976e639098..6a40246497 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -135,7 +135,7 @@ public: void downloadComplete(LLSD const & data); void downloadError(std::string const & message); - bool onMainLoop(LLSD const & event); + bool onMainLoop(LLSD const & event); private: void restartTimer(unsigned int seconds); @@ -349,6 +349,13 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) // marker file. llofstream update_marker(update_marker_path()); LLSDSerialize::toPrettyXML(data, update_marker); + + LLSD event; + event["pump"] = LLUpdaterService::pumpName(); + LLSD payload; + payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE); + event["payload"] = payload; + LLEventPumps::instance().obtain("mainlooprepeater").post(event); } void LLUpdaterServiceImpl::downloadError(std::string const & message) @@ -362,6 +369,14 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message) { restartTimer(mCheckPeriod); } + + LLSD event; + event["pump"] = LLUpdaterService::pumpName(); + LLSD payload; + payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_ERROR); + payload["message"] = message; + event["payload"] = payload; + LLEventPumps::instance().obtain("mainlooprepeater").post(event); } void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) @@ -405,6 +420,13 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) //----------------------------------------------------------------------- // Facade interface + +std::string const & LLUpdaterService::pumpName(void) +{ + static std::string name("updater_service"); + return name; +} + LLUpdaterService::LLUpdaterService() { if(gUpdater.expired()) diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index ec20dc6e05..8d0b95be86 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -39,6 +39,16 @@ public: public: UsageError(const std::string& msg) : std::runtime_error(msg) {} }; + + // Name of the event pump through which update events will be delivered. + static std::string const & pumpName(void); + + // Type codes for events posted by this service. Stored the event's 'type' element. + enum UpdateEvent { + INVALID, + DOWNLOAD_COMPLETE, + DOWNLOAD_ERROR + }; LLUpdaterService(); ~LLUpdaterService(); -- cgit v1.2.3 From 5c35547ade48123cb571714de42ffe42b232480d Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Wed, 17 Nov 2010 16:50:38 -0800 Subject: CHOP-135 Added Pref UI to Setup panel. Rev. by Brad --- .../default/xui/en/panel_preferences_setup.xml | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 140d16e37f..79013e7e27 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -29,7 +29,7 @@ layout="topleft" left_delta="50" name=" Mouse Sensitivity" - top_pad="10" + top_pad="5" width="150"> Mouse sensitivity @@ -76,7 +76,7 @@ left_delta="50" name="Maximum bandwidth" mouse_opaque="false" - top_pad="10" + top_pad="5" width="200"> Maximum bandwidth @@ -115,7 +115,7 @@ layout="topleft" left="77" name="connection_port_enabled" - top_pad="20" + top_pad="10" width="256"> Cache size @@ -239,7 +239,7 @@ layout="topleft" left="30" name="Web:" - top_pad="5" + top_pad="10" width="300"> Web: @@ -386,4 +386,20 @@ name="web_proxy_port" top_delta="0" width="145" /> + + + -- cgit v1.2.3 From 098fa21c4f812b94348c0631c29babff68968d3d Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Wed, 17 Nov 2010 17:06:21 -0800 Subject: Work on CHOP-135: Hooking up setting UpdaterServiceActive to functionality. Paired with Mani. Toggling the setting now calls LLUpdaterService::startChecking() and LLUpdaterService::stopChecking(), which enable and disable the service. --- indra/newview/llviewercontrol.cpp | 14 ++++++++++++++ indra/viewer_components/updater/llupdaterservice.cpp | 17 +++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index f579c433e1..f65811598f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -70,6 +70,7 @@ #include "llpaneloutfitsinventory.h" #include "llpanellogin.h" #include "llpaneltopinfobar.h" +#include "llupdaterservice.h" #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; @@ -488,6 +489,18 @@ bool toggle_show_object_render_cost(const LLSD& newvalue) return true; } +void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_value) +{ + if(new_value.asBoolean()) + { + LLUpdaterService().startChecking(); + } + else + { + LLUpdaterService().stopChecking(); + } +} + //////////////////////////////////////////////////////////////////////////// void settings_setup_listeners() @@ -635,6 +648,7 @@ void settings_setup_listeners() gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2)); gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2)); gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2)); + gSavedSettings.getControl("UpdaterServiceActive")->getSignal()->connect(&toggle_updater_service_active); gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); } diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index 6a40246497..58f2c7da76 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -175,12 +175,6 @@ void LLUpdaterServiceImpl::initialize(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) @@ -198,6 +192,12 @@ void LLUpdaterServiceImpl::startChecking() mIsChecking = true; + // Check to see if an install is ready. + if(!checkForInstall()) + { + checkForResume(); + } + if(!mIsDownloading) { // Checking can only occur during the mainloop. @@ -214,6 +214,11 @@ void LLUpdaterServiceImpl::stopChecking() mIsChecking = false; mTimer.stop(); } + + if(mIsDownloading) + { + this->mUpdateDownloader.cancel(); + } } bool LLUpdaterServiceImpl::isChecking() -- cgit v1.2.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(+) 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.2.3 From cf3ded4491751231056b220525970e125d813e6a Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 18 Nov 2010 12:15:49 -0800 Subject: First draft of CHOP-106 downloaded update ready notification. Reviewed by mani. --- indra/newview/llappviewer.cpp | 14 ++++++++++++++ indra/newview/llmainlooprepeater.cpp | 4 ++-- indra/newview/skins/default/xui/en/notifications.xml | 8 ++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 76d518b610..0c6c77566f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2385,6 +2385,17 @@ bool LLAppViewer::initConfiguration() return true; // Config was successful. } +namespace { + // *TODO - decide if there's a better place for this function. + // do we need a file llupdaterui.cpp or something? -brad + bool notify_update(LLSD const & evt) + { + LLNotificationsUtil::add("DownloadBackground"); + // let others also handle this event by default + return false; + } +}; + void LLAppViewer::initUpdater() { // Initialize the updater service. @@ -2409,6 +2420,9 @@ void LLAppViewer::initUpdater() { mUpdater->startChecking(); } + + LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()); + updater_pump.listen("notify_update", notify_update); } void LLAppViewer::checkForCrash(void) diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index ddc925a73b..5c020e6d98 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -48,9 +48,9 @@ void LLMainLoopRepeater::start(void) mQueue = new LLThreadSafeQueue(gAPRPoolp, 1024); mMainLoopConnection = LLEventPumps::instance(). - obtain("mainloop").listen("stupid name here", boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); + obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). - obtain("mainlooprepeater").listen("other stupid name here", boost::bind(&LLMainLoopRepeater::onMessage, this, _1)); + obtain("mainlooprepeater").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMessage, this, _1)); } diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 1f747ab997..40d5f75de2 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2869,6 +2869,14 @@ Download to your Applications folder? yestext="Download"/> + +An updated version of [APP_NAME] has been downloaded. +It will be applied the next time you restart [APP_NAME] + + Date: Thu, 18 Nov 2010 13:25:44 -0800 Subject: inform user on failed install--needs proper user dialog ;-) --- indra/newview/llappviewer.cpp | 16 ++++++++++++++-- indra/newview/skins/default/xui/en/notifications.xml | 10 ++++++++++ indra/viewer_components/updater/llupdaterservice.cpp | 4 ++++ indra/viewer_components/updater/llupdaterservice.h | 3 ++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0c6c77566f..93fd75f74b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2390,8 +2390,20 @@ namespace { // do we need a file llupdaterui.cpp or something? -brad bool notify_update(LLSD const & evt) { - LLNotificationsUtil::add("DownloadBackground"); - // let others also handle this event by default + switch (evt["type"].asInteger()) + { + case LLUpdaterService::DOWNLOAD_COMPLETE: + LLNotificationsUtil::add("DownloadBackground"); + break; + case LLUpdaterService::INSTALL_ERROR: + LLNotificationsUtil::add("FailedUpdateInstall"); + break; + default: + llinfos << "unhandled update event " << evt << llendl; + break; + } + + // let others also handle this event by default return false; } }; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 40d5f75de2..a342db8442 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2869,6 +2869,16 @@ Download to your Applications folder? yestext="Download"/> + +Gadzooks, I failed to install the latest update. +Get thee to the interwebs and install it thyself. + + Date: Thu, 18 Nov 2010 14:49:03 -0800 Subject: CHOP-187 Fixed linux updater return code to return 0 on success --- indra/linux_updater/linux_updater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index cbdb3ddfe0..8aabb5ca60 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -824,7 +824,7 @@ int main(int argc, char **argv) } } - bool success = app_state->failure != FALSE; + bool success = !app_state->failure; delete app_state; return success ? 0 : 1; } -- cgit v1.2.3 From 0e52564f0a36365c2ce5f5263d15778394741fde Mon Sep 17 00:00:00 2001 From: brad kittenbrink Date: Thu, 18 Nov 2010 15:11:42 -0800 Subject: Fix for mac build error. --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0c6c77566f..548bebcfa9 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2422,7 +2422,7 @@ void LLAppViewer::initUpdater() } LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()); - updater_pump.listen("notify_update", notify_update); + updater_pump.listen("notify_update", ¬ify_update); } void LLAppViewer::checkForCrash(void) -- cgit v1.2.3 From 86e84a1313f9fcb78b3e6b490dcf1604829ef175 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Thu, 18 Nov 2010 15:40:21 -0800 Subject: conform to coding standard. --- indra/viewer_components/updater/llupdaterservice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 3655136f3c..55824af188 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -44,7 +44,7 @@ public: static std::string const & pumpName(void); // Type codes for events posted by this service. Stored the event's 'type' element. - enum UpdateEvent { + enum eUpdateEvent { INVALID, DOWNLOAD_COMPLETE, DOWNLOAD_ERROR, -- cgit v1.2.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(-) 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.2.3 From 8c2026d6b71f133deafa6b0e19baf69632a2510a Mon Sep 17 00:00:00 2001 From: "Mark Palange (Mani)" Date: Thu, 18 Nov 2010 21:57:27 -0800 Subject: CHOP-135 Bug fixes. --- indra/llcommon/llfile.cpp | 5 ++ indra/newview/llappviewer.cpp | 3 +- indra/newview/llchiclet.cpp | 8 +- indra/newview/lltransientfloatermgr.cpp | 5 +- .../updater/llupdatedownloader.cpp | 6 +- .../viewer_components/updater/llupdaterservice.cpp | 85 +++++++++++++--------- indra/viewer_components/updater/llupdaterservice.h | 2 +- 7 files changed, 71 insertions(+), 43 deletions(-) diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 289ce0bc2c..8f02391e75 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -318,7 +318,12 @@ void llofstream::close() if(is_open()) { if (_Filebuffer->close() == 0) + { _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/ + } + delete _Filebuffer; + _Filebuffer = NULL; + _ShouldClose = false; } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1fd8b02530..b6f52e3e15 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2433,7 +2433,8 @@ void LLAppViewer::initUpdater() mUpdater->setCheckPeriod(check_period); if(gSavedSettings.getBOOL("UpdaterServiceActive")) { - mUpdater->startChecking(); + bool install_if_ready = true; + mUpdater->startChecking(install_if_ready); } LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 8f385160e9..885d553524 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1092,9 +1092,11 @@ LLChicletPanel::LLChicletPanel(const Params&p) LLChicletPanel::~LLChicletPanel() { - LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton); - LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton); - + if(LLTransientFloaterMgr::instanceExists()) + { + LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton); + LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton); + } } void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp index 78dd602f39..6deab96b45 100644 --- a/indra/newview/lltransientfloatermgr.cpp +++ b/indra/newview/lltransientfloatermgr.cpp @@ -36,8 +36,11 @@ LLTransientFloaterMgr::LLTransientFloaterMgr() { - gViewerWindow->getRootView()->addMouseDownCallback(boost::bind( + if(gViewerWindow) + { + gViewerWindow->getRootView()->addMouseDownCallback(boost::bind( &LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3)); + } mGroupControls.insert(std::pair >(GLOBAL, std::set())); mGroupControls.insert(std::pair >(DOCKED, std::set())); diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 4820f1f452..c17a50e242 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -204,7 +204,11 @@ bool LLUpdateDownloader::Implementation::isDownloading(void) void LLUpdateDownloader::Implementation::resume(void) { - if(isDownloading()) mClient.downloadError("download in progress"); + mCancelled = false; + + if(isDownloading()) { + mClient.downloadError("download in progress"); + } mDownloadRecordPath = downloadMarkerPath(); llifstream dataStream(mDownloadRecordPath); diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index b49f6d04b0..cc60eaead2 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -112,13 +112,13 @@ public: void setCheckPeriod(unsigned int seconds); - void startChecking(); + void startChecking(bool install_if_ready); void stopChecking(); bool isChecking(); void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;} - bool checkForInstall(); // Test if a local install is ready. + bool checkForInstall(bool launchInstaller); // Test if a local install is ready. bool checkForResume(); // Test for resumeable d/l. // LLUpdateChecker::Client: @@ -139,6 +139,7 @@ public: private: void restartTimer(unsigned int seconds); + void stopTimer(); }; const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; @@ -182,7 +183,7 @@ void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds) mCheckPeriod = seconds; } -void LLUpdaterServiceImpl::startChecking() +void LLUpdaterServiceImpl::startChecking(bool install_if_ready) { if(mUrl.empty() || mChannel.empty() || mVersion.empty()) { @@ -193,17 +194,18 @@ void LLUpdaterServiceImpl::startChecking() mIsChecking = true; // Check to see if an install is ready. - if(!checkForInstall()) + bool has_install = checkForInstall(install_if_ready); + if(!has_install) { - checkForResume(); - } + checkForResume(); // will set mIsDownloading to true if resuming - 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); + 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); + } } } @@ -212,12 +214,13 @@ void LLUpdaterServiceImpl::stopChecking() if(mIsChecking) { mIsChecking = false; - mTimer.stop(); + stopTimer(); } if(mIsDownloading) { - this->mUpdateDownloader.cancel(); + mUpdateDownloader.cancel(); + mIsDownloading = false; } } @@ -226,9 +229,9 @@ bool LLUpdaterServiceImpl::isChecking() return mIsChecking; } -bool LLUpdaterServiceImpl::checkForInstall() +bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller) { - bool result = false; // return true if install is found. + bool foundInstall = false; // return true if install is found. llifstream update_marker(update_marker_path(), std::ios::in | std::ios::binary); @@ -239,7 +242,6 @@ bool LLUpdaterServiceImpl::checkForInstall() 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"); @@ -251,33 +253,39 @@ bool LLUpdaterServiceImpl::checkForInstall() { llinfos << "ignoring update dowloaded by different client version" << llendl; LLFile::remove(path.asString()); + LLFile::remove(update_marker_path()); } else { ; // Nothing to clean up. } - result = false; + foundInstall = false; } else if(path.isDefined() && !path.asString().empty()) { - int result = ll_install_update(install_script_path(), - update_info["path"].asString(), - install_script_mode()); - - if((result == 0) && mAppExitCallback) + if(launchInstaller) { - mAppExitCallback(); - } else if(result != 0) { - llwarns << "failed to run update install script" << LL_ENDL; - } else { - ; // No op. + LLFile::remove(update_marker_path()); + + 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. + } } - result = true; + foundInstall = true; } } - return result; + return foundInstall; } bool LLUpdaterServiceImpl::checkForResume() @@ -324,7 +332,7 @@ void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, LLURI const & uri, std::string const & hash) { - mTimer.stop(); + stopTimer(); mIsDownloading = true; mUpdateDownloader.download(uri, hash); } @@ -333,7 +341,7 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, LLURI const & uri, std::string const & hash) { - mTimer.stop(); + stopTimer(); mIsDownloading = true; mUpdateDownloader.download(uri, hash); } @@ -394,12 +402,17 @@ void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); } +void LLUpdaterServiceImpl::stopTimer() +{ + mTimer.stop(); + LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); +} + bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) { if(mTimer.getStarted() && mTimer.hasExpired()) { - mTimer.stop(); - LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); + stopTimer(); // Check for failed install. if(LLFile::isfile(ll_install_failed_marker_path())) @@ -468,9 +481,9 @@ void LLUpdaterService::setCheckPeriod(unsigned int seconds) mImpl->setCheckPeriod(seconds); } -void LLUpdaterService::startChecking() +void LLUpdaterService::startChecking(bool install_if_ready) { - mImpl->startChecking(); + mImpl->startChecking(install_if_ready); } void LLUpdaterService::stopChecking() diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 55824af188..752a6f834b 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -62,7 +62,7 @@ public: void setCheckPeriod(unsigned int seconds); - void startChecking(); + void startChecking(bool install_if_ready = false); void stopChecking(); bool isChecking(); -- cgit v1.2.3 From 8d21105a8c2b6bff98b4f3b91a614a4710d4b7ea Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 19 Nov 2010 12:04:01 -0800 Subject: dull boring notification message. --- indra/newview/skins/default/xui/en/notifications.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 0663583543..9536bf2cf7 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2873,8 +2873,9 @@ Download to your Applications folder? icon="alertmodal.tga" name="FailedUpdateInstall" type="alertmodal"> -Gadzooks, I failed to install the latest update. -Get thee to the interwebs and install it thyself. +An error occurred installing the viewer update. +Please download and install the latest viewer from +http://secondlife.com/download. -- cgit v1.2.3