diff options
| -rw-r--r-- | indra/newview/llappviewer.cpp | 74 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 28 | ||||
| -rwxr-xr-x | indra/newview/llviewerwindow.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 66 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatechecker.cpp | 23 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatechecker.h | 14 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.cpp | 135 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.h | 2 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdaterservice.cpp | 107 | ||||
| -rw-r--r-- | indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 2 | 
10 files changed, 315 insertions, 149 deletions
| diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6ec6f5489c..18314904a7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -121,6 +121,7 @@  #include <boost/bind.hpp>  #include <boost/foreach.hpp>  #include <boost/algorithm/string.hpp> +#include <boost/regex.hpp>  #if LL_WINDOWS @@ -2831,25 +2832,46 @@ namespace {  		std::string notification_name;  		void (*apply_callback)(LLSD const &, LLSD const &) = NULL; +		/* Build up the notification name... +		 * it can be any of these, which are included here for the sake of grep: +		 *   RequiredUpdateDownloadedDialog +		 *   RequiredUpdateDownloadedVerboseDialog +		 *   OtherChannelRequiredUpdateDownloadedDialog +		 *   OtherChannelRequiredUpdateDownloadedVerbose +		 *   DownloadBackgroundTip +		 *   DownloadBackgroundDialog +		 *   OtherChannelDownloadBackgroundTip +		 *   OtherChannelDownloadBackgroundDialog +		 */ +		{ +			LL_DEBUGS("UpdaterService") << "data = "; +			std::ostringstream data_dump; +			LLSDSerialize::toNotation(data, data_dump); +			LL_CONT << data_dump.str() << LL_ENDL; +		} +		if(data["channel"].asString() != LLVersionInfo::getChannel()) +		{ +			notification_name.append("OtherChannel"); +		}  		if(data["required"].asBoolean())  		{  			if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)  			{  				// The user never saw the progress bar.  				apply_callback = &apply_update_ok_callback; -				notification_name = "RequiredUpdateDownloadedVerboseDialog"; +				notification_name += "RequiredUpdateDownloadedVerboseDialog";  			}  			else if(LLStartUp::getStartupState() < STATE_WORLD_INIT)  			{  				// The user is logging in but blocked.  				apply_callback = &apply_update_ok_callback; -				notification_name = "RequiredUpdateDownloadedDialog"; +				notification_name += "RequiredUpdateDownloadedDialog";  			}  			else  			{  				// The user is already logged in; treat like an optional update.  				apply_callback = &apply_update_callback; -				notification_name = "DownloadBackgroundTip"; +				notification_name += "DownloadBackgroundTip";  			}  		}  		else @@ -2859,36 +2881,47 @@ namespace {  			{  				// CHOP-262 we need to use a different notification  				// method prior to login. -				notification_name = "DownloadBackgroundDialog"; +				notification_name += "DownloadBackgroundDialog";  			}  			else  			{ -				notification_name = "DownloadBackgroundTip"; +				notification_name += "DownloadBackgroundTip";  			}  		}  		LLSD substitutions;  		substitutions["VERSION"] = data["version"]; - -		// truncate version at the rightmost '.'  -		std::string version_short(data["version"]); -		size_t short_length = version_short.rfind('.'); -		if (short_length != std::string::npos) +		std::string new_channel = data["channel"].asString(); +		substitutions["NEW_CHANNEL"] = new_channel; +		std::string info_url    = data["info_url"].asString(); +		if ( !info_url.empty() )  		{ -			version_short.resize(short_length); +			substitutions["INFO_URL"] = info_url;  		} +		else +		{ +			LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL; -		LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); -		relnotes_url.setArg("[VERSION_SHORT]", version_short); +			// truncate version at the rightmost '.'  +			std::string version_short(data["version"]); +			size_t short_length = version_short.rfind('.'); +			if (short_length != std::string::npos) +			{ +				version_short.resize(short_length); +			} -		// *TODO thread the update service's response through to this point -		std::string const & channel = LLVersionInfo::getChannel(); -		boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); +			LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); +			relnotes_url.setArg("[VERSION_SHORT]", version_short); -		relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); -		relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); -		substitutions["RELEASE_NOTES_FULL_URL"] = relnotes_url.getString(); +			// *TODO thread the update service's response through to this point +			std::string const & channel = LLVersionInfo::getChannel(); +			boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); +			relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); +			relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); +			substitutions["INFO_URL"] = relnotes_url.getString(); +		} +		  		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);  	} @@ -2940,7 +2973,8 @@ void LLAppViewer::initUpdater()  	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");  	bool willing_to_test;  	LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL; -	if (channel.find("Test") != std::string::npos) // TBD - should be a regex +	static const boost::regex is_test_channel("\\bTest$"); +	if (boost::regex_search(channel, is_test_channel))   	{  		LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL;  		willing_to_test = false; diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 12796ca262..b27a566c23 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -777,20 +777,20 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)  	LLSD payload;  	payload["mandatory"] = mandatory; -/* - We're constructing one of the following 9 strings here: -	 "DownloadWindowsMandatory" -	 "DownloadWindowsReleaseForDownload" -	 "DownloadWindows" -	 "DownloadMacMandatory" -	 "DownloadMacReleaseForDownload" -	 "DownloadMac" -	 "DownloadLinuxMandatory" -	 "DownloadLinuxReleaseForDownload" -	 "DownloadLinux" -  - I've called them out explicitly in this comment so that they can be grepped for. - */ +	/* +	 * We're constructing one of the following 9 strings here: +	 *   "DownloadWindowsMandatory" +	 *	 "DownloadWindowsReleaseForDownload" +	 *	 "DownloadWindows" +	 *	 "DownloadMacMandatory" +	 *	 "DownloadMacReleaseForDownload" +	 *	 "DownloadMac" +	 *	 "DownloadLinuxMandatory" +	 *	 "DownloadLinuxReleaseForDownload" +	 *	 "DownloadLinux" + 	 * +	 * I've called them out explicitly in this comment so that they can be grepped for. +	 */  	std::string notification_name = "Download";  #if LL_WINDOWS diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8c72421888..2d9c127b87 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -34,6 +34,7 @@  #include <fstream>  #include <algorithm>  #include <boost/lambda/core.hpp> +#include <boost/regex.hpp>  #include "llagent.h"  #include "llagentcamera.h" @@ -2235,9 +2236,9 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)  	// no l10n problem because channel is always an english string  	std::string channel = LLVersionInfo::getChannel(); -	bool isProject = (channel.find("Project") != std::string::npos); // TBD - should be a regex -	bool isBeta = (channel.find("Beta") != std::string::npos); // TBD - should be a regex -	bool isTest = (channel.find("Test") != std::string::npos); // TBD - should be a regex +	static const boost::regex is_beta_channel("\\bBeta\\b"); +	static const boost::regex is_project_channel("\\bProject\\b"); +	static const boost::regex is_test_channel("\\bTest$");  	// god more important than project, proj more important than grid      if ( god_mode )  @@ -2251,15 +2252,15 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)  			new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );  		}      } -	else if (isBeta) +	else if (boost::regex_search(channel, is_beta_channel))  	{  		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" );  	} -	else if (isProject) +	else if (boost::regex_search(channel, is_project_channel))  	{  		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" );  	} -	else if (isTest) +	else if (boost::regex_search(channel, is_test_channel))  	{  		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" );  	} diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c8f5cbb2b0..2319729339 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3452,7 +3452,7 @@ or you can install it now.     name="DownloadBackgroundTip"     type="notify">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] +Version [VERSION] [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3465,7 +3465,7 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]   name="DownloadBackgroundDialog"   type="alertmodal">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] +Version [VERSION] [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3478,7 +3478,7 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]   name="RequiredUpdateDownloadedVerboseDialog"   type="alertmodal">  We have downloaded a required software update. -Version [VERSION] +Version [VERSION] [[INFO_URL] Information about this update]  We must restart [APP_NAME] to install the update.      <tag>confirm</tag> @@ -3492,6 +3492,66 @@ We must restart [APP_NAME] to install the update.   name="RequiredUpdateDownloadedDialog"   type="alertmodal">  We must restart [APP_NAME] to install the update. +[[INFO_URL] Information about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification +   icon="notify.tga" +   name="OtherChannelDownloadBackgroundTip" +   type="notify"> +We have downloaded an update to your [APP_NAME] installation. +Version [VERSION]  +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] for details about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Later..." +     yestext="Install now and restart [APP_NAME]"/> +  </notification> + +  <notification + icon="alertmodal.tga" + name="OtherChannelDownloadBackgroundDialog" + type="alertmodal"> +We have downloaded an update to your [APP_NAME] installation. +Version [VERSION] +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update] +    <tag>confirm</tag> +    <usetemplate +     name="okcancelbuttons" +     notext="Later..." +     yestext="Install now and restart [APP_NAME]"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedVerboseDialog" + type="alertmodal"> +We have downloaded a required software update. +Version [VERSION] +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update] + +We must restart [APP_NAME] to install the update. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedDialog" + type="alertmodal"> +We must restart [APP_NAME] to install the update. +This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; +see [[INFO_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okbutton" diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 6d0758b226..734747c811 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -143,8 +143,8 @@ void LLUpdateChecker::Implementation::completed(U32 status,  				LL_WARNS("UpdaterService")  					<< "update response using " << sProtocolVersion -					<< " was 404... retry at " << retryUrl -					<< " with legacy protocol" +					<< " was 404... retry with legacy protocol" << mProtocol +					<< "\n at " << retryUrl  					<< LL_ENDL;  				mHttpClient.get(retryUrl, this); @@ -164,22 +164,9 @@ void LLUpdateChecker::Implementation::completed(U32 status,  			mClient.error(reason);  		}  	} -	else if(!content.asBoolean()) -	{ -		LL_INFOS("UpdaterService") << "up to date" << LL_ENDL; -		mClient.upToDate(); -	} -	else if(content["required"].asBoolean()) -	{ -		LL_INFOS("UpdaterService") << "version invalid" << LL_ENDL; -		LLURI uri(content["url"].asString()); -		mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString()); -	}  	else  	{ -		LL_INFOS("UpdaterService") << "newer version " << content["version"].asString() << " available" << LL_ENDL; -		LLURI uri(content["url"].asString()); -		mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString()); +		mClient.response(content);  	}  } @@ -215,8 +202,10 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr      {          platform = "mac";      } -#else +#elif LL_LINUX  	static const char * platform = "lnx"; +#else +#   error "unsupported platform"  #endif  	LLSD path; diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index b60f21549e..55806137d7 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -117,18 +117,8 @@ public:  	// 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, -								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, -								std::string const & hash) = 0; -	 -	// The checked version is up to date; no newer version exists. -	virtual void upToDate(void) = 0; +	// A successful response was received from the viewer version manager +	virtual void response(LLSD const & content) = 0;  }; diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 001dd5ed16..c28ad76c77 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -50,7 +50,9 @@ public:  	void cancel(void);  	void download(LLURI const & uri,  				  std::string const & hash, +				  std::string const & updateChannel,  				  std::string const & updateVersion, +				  std::string const & info_url,  				  bool required);  	bool isDownloading(void);  	size_t onHeader(void * header, size_t size); @@ -125,10 +127,12 @@ void LLUpdateDownloader::cancel(void)  void LLUpdateDownloader::download(LLURI const & uri,  								  std::string const & hash, +								  std::string const & updateChannel,  								  std::string const & updateVersion, +								  std::string const & info_url,  								  bool required)  { -	mImplementation->download(uri, hash, updateVersion, required); +	mImplementation->download(uri, hash, updateChannel, updateVersion, info_url, required);  } @@ -222,18 +226,28 @@ void LLUpdateDownloader::Implementation::cancel(void)  void LLUpdateDownloader::Implementation::download(LLURI const & uri,  												  std::string const & hash, +												  std::string const & updateChannel,  												  std::string const & updateVersion, +												  std::string const & info_url,  												  bool required) -{ +{   	if(isDownloading()) mClient.downloadError("download in progress");  	mDownloadRecordPath = downloadMarkerPath();  	mDownloadData = LLSD();  	mDownloadData["required"] = required; +	mDownloadData["update_channel"] = updateChannel;  	mDownloadData["update_version"] = updateVersion; -	try { +	if (!info_url.empty()) +	{ +		mDownloadData["info_url"] = info_url; +	} +	try +	{  		startDownloading(uri, hash); -	} catch(DownloadError const & e) { +	} +	catch(DownloadError const & e) +	{  		mClient.downloadError(e.what());  	}  } @@ -249,47 +263,65 @@ void LLUpdateDownloader::Implementation::resume(void)  {  	mCancelled = false; -	if(isDownloading()) { +	if(isDownloading()) +	{  		mClient.downloadError("download in progress");  	}  	mDownloadRecordPath = downloadMarkerPath();  	llifstream dataStream(mDownloadRecordPath); -	if(!dataStream) { +	if(!dataStream) +	{  		mClient.downloadError("no download marker");  		return;  	}  	LLSDSerialize::fromXMLDocument(mDownloadData, dataStream); -	if(!mDownloadData.asBoolean()) { +	if(!mDownloadData.asBoolean()) +	{  		mClient.downloadError("no download information in marker");  		return;  	}  	std::string filePath = mDownloadData["path"].asString(); -	try { -		if(LLFile::isfile(filePath)) { +	try +	{ +		if(LLFile::isfile(filePath)) +		{  			llstat fileStatus;  			LLFile::stat(filePath, &fileStatus); -			if(fileStatus.st_size != mDownloadData["size"].asInteger()) { +			if(fileStatus.st_size != mDownloadData["size"].asInteger()) +			{  				resumeDownloading(fileStatus.st_size); -			} else if(!validateDownload()) { +			} +			else if(!validateDownload()) +			{  				LLFile::remove(filePath);  				download(LLURI(mDownloadData["url"].asString()),  						 mDownloadData["hash"].asString(), +						 mDownloadData["update_channel"].asString(),  						 mDownloadData["update_version"].asString(), +						 mDownloadData["info_url"].asString(),  						 mDownloadData["required"].asBoolean()); -			} else { +			} +			else +			{  				mClient.downloadComplete(mDownloadData);  			} -		} else { +		} +		else +		{  			download(LLURI(mDownloadData["url"].asString()),  					 mDownloadData["hash"].asString(), +					 mDownloadData["update_channel"].asString(),  					 mDownloadData["update_version"].asString(), +					 mDownloadData["info_url"].asString(),  					 mDownloadData["required"].asBoolean());  		} -	} catch(DownloadError & e) { +	} +	catch(DownloadError & e) +	{  		mClient.downloadError(e.what());  	}  } @@ -297,13 +329,18 @@ void LLUpdateDownloader::Implementation::resume(void)  void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)  { -	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) { +	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) +	{  		llassert(mCurl != 0);  		mBandwidthLimit = bytesPerSecond;  		CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit); -		if(code != CURLE_OK) LL_WARNS("UpdaterService") << -			"unable to change dowload bandwidth" << LL_ENDL; -	} else { +		if(code != CURLE_OK) +		{ +			LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL; +		} +	} +	else +	{  		mBandwidthLimit = bytesPerSecond;  	}  } @@ -381,29 +418,44 @@ void LLUpdateDownloader::Implementation::run(void)  {  	CURLcode code = curl_easy_perform(mCurl);  	mDownloadStream.close(); -	if(code == CURLE_OK) { +	if(code == CURLE_OK) +	{  		LLFile::remove(mDownloadRecordPath); -		if(validateDownload()) { +		if(validateDownload()) +		{  			LL_INFOS("UpdaterService") << "download successful" << LL_ENDL;  			mClient.downloadComplete(mDownloadData); -		} else { +		} +		else +		{  			LL_INFOS("UpdaterService") << "download failed hash check" << LL_ENDL;  			std::string filePath = mDownloadData["path"].asString(); -			if(filePath.size() != 0) LLFile::remove(filePath); +			if(filePath.size() != 0) +			{ +				LLFile::remove(filePath); +			}  			mClient.downloadError("failed hash check");  		} -	} else if(mCancelled && (code == CURLE_WRITE_ERROR)) { +	} +	else if(mCancelled && (code == CURLE_WRITE_ERROR)) +	{  		LL_INFOS("UpdaterService") << "download canceled by user" << LL_ENDL;  		// Do not call back client. -	} else { +	} +	else +	{  		LL_WARNS("UpdaterService") << "download failed with error '" <<  			curl_easy_strerror(code) << "'" << LL_ENDL;  		LLFile::remove(mDownloadRecordPath); -		if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString()); +		if(mDownloadData.has("path")) +		{ +			LLFile::remove(mDownloadData["path"].asString()); +		}  		mClient.downloadError("curl error");  	} -	if(mHeaderList) { +	if(mHeaderList) +	{  		curl_slist_free_all(mHeaderList);  		mHeaderList = 0;  	} @@ -421,13 +473,16 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u  		curl_easy_reset(mCurl);  	} -	if(mCurl == 0) throw DownloadError("failed to initialize curl"); - +	if(mCurl == 0) +	{ +		throw DownloadError("failed to initialize curl"); +	}  	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)); -	if(processHeader) { +	if(processHeader) +	{  	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));  	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));  	} @@ -456,7 +511,10 @@ void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)  	boost::format rangeHeaderFormat("Range: bytes=%u-");  	rangeHeaderFormat % startByte;  	mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str()); -	if(mHeaderList == 0) throw DownloadError("cannot add Range header"); +	if(mHeaderList == 0) +	{ +		throw DownloadError("cannot add Range header"); +	}  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));  	mDownloadStream.open(mDownloadData["path"].asString(), @@ -508,19 +566,26 @@ bool LLUpdateDownloader::Implementation::validateDownload(void)  {  	std::string filePath = mDownloadData["path"].asString();  	llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary); -	if(!fileStream) return false; +	if(!fileStream) +	{ +		return false; +	}  	std::string hash = mDownloadData["hash"].asString(); -	if(hash.size() != 0) { +	if(hash.size() != 0) +	{  		LL_INFOS("UpdaterService") << "checking hash..." << LL_ENDL;  		char digest[33];  		LLMD5(fileStream).hex_digest(digest); -		if(hash != digest) { -			LL_WARNS("UpdaterService") << "download hash mismatch; expeted " << hash << +		if(hash != digest) +		{ +			LL_WARNS("UpdaterService") << "download hash mismatch; expected " << hash <<  				" but download is " << digest << LL_ENDL;  		}  		return hash == digest; -	} else { +	} +	else +	{  		return true; // No hash check provided.  	}  } diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 0d635640cf..f759988f12 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -54,7 +54,9 @@ public:  	// Start a new download.  	void download(LLURI const & uri,  				  std::string const & hash,  +				  std::string const & updateChannel,  				  std::string const & updateVersion, +				  std::string const & info_url,  				  bool required=false);  	// Returns true if a download is in progress. diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index c6c89655d3..324b051b21 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -140,13 +140,9 @@ public:  	// LLUpdateChecker::Client:  	virtual void error(std::string const & message); -	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); +	 +	// A successful response was received from the viewer version manager +	virtual void response(LLSD const & content);  	// LLUpdateDownloader::Client  	void downloadComplete(LLSD const & data); @@ -155,6 +151,7 @@ public:  	bool onMainLoop(LLSD const & event);  private: +	std::string mNewChannel;  	std::string mNewVersion;  	void restartTimer(unsigned int seconds); @@ -334,9 +331,13 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)  				if((result == 0) && mAppExitCallback)  				{  					mAppExitCallback(); -				} else if(result != 0) { +				} +				else if(result != 0) +				{  					LL_WARNS("UpdaterService") << "failed to run update install script" << LL_ENDL; -				} else { +				} +				else +				{  					; // No op.  				}  			} @@ -364,6 +365,7 @@ bool LLUpdaterServiceImpl::checkForResume()  			{  				mIsDownloading = true;  				mNewVersion = download_info["update_version"].asString(); +				mNewChannel = download_info["update_channel"].asString();  				mUpdateDownloader.resume();  				result = true;  			} @@ -372,7 +374,10 @@ bool LLUpdaterServiceImpl::checkForResume()  				// The viewer that started this download is not the same as this viewer; ignore.  				LL_INFOS("UpdaterService") << "ignoring partial download from different viewer version" << LL_ENDL;;  				std::string path = download_info["path"].asString(); -				if(!path.empty()) LLFile::remove(path); +				if(!path.empty()) +				{ +					LLFile::remove(path); +				}  				LLFile::remove(download_marker_path);  			}  		}  @@ -389,36 +394,43 @@ void LLUpdaterServiceImpl::error(std::string const & message)  	}  } -void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, -										  LLURI const & uri, -										  std::string const & hash) -{ -	stopTimer(); -	mNewVersion = newVersion; -	mIsDownloading = true; -	setState(LLUpdaterService::DOWNLOADING); -	mUpdateDownloader.download(uri, hash, newVersion, false); -} - -void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, -										  LLURI const & uri, -										  std::string const & hash) -{ -	stopTimer(); -	mNewVersion = newVersion; -	mIsDownloading = true; -	setState(LLUpdaterService::DOWNLOADING); -	mUpdateDownloader.download(uri, hash, newVersion, true); -} - -void LLUpdaterServiceImpl::upToDate(void) +// A successful response was received from the viewer version manager +void LLUpdaterServiceImpl::response(LLSD const & content)  { -	if(mIsChecking) +	if(!content.asBoolean()) // an empty response means "no update"  	{ -		restartTimer(mCheckPeriod); -	} +		LL_INFOS("UpdaterService") << "up to date" << LL_ENDL; +		if(mIsChecking) +		{ +			restartTimer(mCheckPeriod); +		} -	setState(LLUpdaterService::UP_TO_DATE); +		setState(LLUpdaterService::UP_TO_DATE); +	} +	else +	{ +		// there is an update available... +		stopTimer(); +		mNewChannel = content["channel"].asString(); +		if (mNewChannel.empty()) +		{ +			LL_INFOS("UpdaterService") << "no channel supplied, assuming current channel" << LL_ENDL; +			mNewChannel = mChannel; +		} +		mNewVersion = content["version"].asString(); +		mIsDownloading = true; +		setState(LLUpdaterService::DOWNLOADING); +		BOOL required = content["required"].asBoolean(); +		LLURI url(content["url"].asString()); +		std::string more_info = content["more_info"].asString(); +		LL_DEBUGS("UpdaterService") +			<< "Starting download of " +			<< ( required ? "required" : "optional" ) << " update " +			<< "to channel '" << mNewChannel << "' version " << mNewVersion +			<< "more info '" << more_info << "'" +			<< LL_ENDL; +		mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required); +	}  }  void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  @@ -436,9 +448,19 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);  	payload["required"] = data["required"];  	payload["version"] = mNewVersion; +	payload["channel"] = mNewChannel; +	payload["info_url"] = data["info_url"];  	event["payload"] = payload; +	LL_DEBUGS("UpdaterService") +		<< "Download complete " +		<< ( data["required"].asBoolean() ? "required" : "optional" ) +		<< "channel " << mNewChannel +		<< "version " << mNewVersion +		<< "info " << data["info_url"].asString() +		<< LL_ENDL; +  	LLEventPumps::instance().obtain("mainlooprepeater").post(event); -	 +  	setState(LLUpdaterService::TERMINAL);  } @@ -512,15 +534,18 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)  		// Check for failed install.  		if(LLFile::isfile(ll_install_failed_marker_path()))  		{ +			LL_DEBUGS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;;  			int requiredValue = 0;   			{  				llifstream stream(ll_install_failed_marker_path());  				stream >> requiredValue; -				if(stream.fail()) requiredValue = 0; +				if(stream.fail()) +				{ +					requiredValue = 0; +				}  			}  			// TODO: notify the user. -			LL_INFOS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;; -			LL_INFOS("UpdaterService") << "last install attempt failed" << LL_ENDL;; +			LL_WARNS("UpdaterService") << "last install attempt failed" << LL_ENDL;;  			LLFile::remove(ll_install_failed_marker_path());  			LLSD event; diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index ddaaccc051..51b63dcb7b 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -53,7 +53,7 @@ void LLUpdateChecker::checkVersion(std::string const & hostUrl,  								   bool                willing_to_test)  {}  LLUpdateDownloader::LLUpdateDownloader(Client & ) {} -void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){} +void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, std::string const &, std::string const &, bool){}  class LLDir_Mock : public LLDir  { | 
