diff options
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 19 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 85 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 415 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.h | 6 | ||||
| -rw-r--r-- | indra/newview/llprogressview.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llviewercontrol.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 64 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_setup.xml | 53 | ||||
| -rw-r--r-- | indra/newview/tests/lllogininstance_test.cpp | 47 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.cpp | 89 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.h | 6 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdaterservice.cpp | 102 | ||||
| -rw-r--r-- | indra/viewer_components/updater/llupdaterservice.h | 26 | ||||
| -rw-r--r-- | indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 3 | 
14 files changed, 873 insertions, 50 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ed67a87024..ae66f5ec39 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9990,6 +9990,17 @@        <key>Value</key>        <real>500.0</real>      </map> +    <key>UpdaterMaximumBandwidth</key> +    <map> +      <key>Comment</key> +      <string>Maximum allowable downstream bandwidth for updater service (kilo bits per second)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>500.0</real> +    </map>      <key>ToolTipDelay</key>      <map>        <key>Comment</key> @@ -11090,16 +11101,16 @@        <key>Value</key>        <integer>15</integer>      </map> -    <key>UpdaterServiceActive</key> +    <key>UpdaterServiceSetting</key>      <map>        <key>Comment</key> -      <string>Enable or disable the updater service.</string> +      <string>Configure updater service.</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> -      <string>Boolean</string> +      <string>U32</string>        <key>Value</key> -      <integer>1</integer> +      <integer>3</integer>      </map>      <key>UpdaterServiceCheckPeriod</key>      <map> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6c07974f69..41be4eb065 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -80,6 +80,7 @@  #include "llfeaturemanager.h"  #include "llurlmatch.h"  #include "lltextutil.h" +#include "lllogininstance.h"  #include "llweb.h"  #include "llsecondlifeurls.h" @@ -590,10 +591,14 @@ LLAppViewer::LLAppViewer() :  	setupErrorHandling();  	sInstance = this;  	gLoggedInTime.stop(); +	 +	LLLoginInstance::instance().setUpdaterService(mUpdater.get());  }  LLAppViewer::~LLAppViewer()  { +	LLLoginInstance::instance().setUpdaterService(0); +	  	destroyMainloopTimeout();  	// If we got to this destructor somehow, the app didn't hang. @@ -2389,26 +2394,95 @@ bool LLAppViewer::initConfiguration()  }  namespace { -    // *TODO - decide if there's a better place for this function. +    // *TODO - decide if there's a better place for these functions.      // do we need a file llupdaterui.cpp or something? -brad + +	void apply_update_callback(LLSD const & notification, LLSD const & response) +	{ +		lldebugs << "LLUpdate user response: " << response << llendl; +		if(response["OK_okcancelbuttons"].asBoolean()) +		{ +			llinfos << "LLUpdate restarting viewer" << llendl; +			static const bool install_if_ready = true; +			// *HACK - this lets us launch the installer immediately for now +			LLUpdaterService().startChecking(install_if_ready); +		} +	} +	 +	void apply_update_ok_callback(LLSD const & notification, LLSD const & response) +	{ +		llinfos << "LLUpdate restarting viewer" << llendl; +		static const bool install_if_ready = true; +		// *HACK - this lets us launch the installer immediately for now +		LLUpdaterService().startChecking(install_if_ready); +	} +	 +	void on_required_update_downloaded(LLSD const & data) +	{ +		std::string notification_name; +		if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT) +		{ +			// The user never saw the progress bar. +			notification_name = "RequiredUpdateDownloadedVerboseDialog"; +		} +		else +		{ +			notification_name = "RequiredUpdateDownloadedDialog"; +		} +		LLSD substitutions; +		substitutions["VERSION"] = data["version"]; +		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), &apply_update_ok_callback); +	} +	 +	void on_optional_update_downloaded(LLSD const & data) +	{ +		std::string notification_name; +		if(LLStartUp::getStartupState() < STATE_STARTED) +		{ +			// CHOP-262 we need to use a different notification +			// method prior to login. +			notification_name = "DownloadBackgroundDialog"; +		} +		else +		{ +			notification_name = "DownloadBackgroundTip"; +		} +		LLSD substitutions; +		substitutions["VERSION"] = data["version"]; +		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_update_callback); +	} +      bool notify_update(LLSD const & evt)      { +		std::string notification_name;  		switch (evt["type"].asInteger())  		{  			case LLUpdaterService::DOWNLOAD_COMPLETE: -				LLNotificationsUtil::add("DownloadBackground"); +				if(evt["required"].asBoolean()) +				{ +					on_required_update_downloaded(evt); +				} +				else +				{ +					on_optional_update_downloaded(evt); +				}  				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;      } +	 +	bool on_bandwidth_throttle(LLUpdaterService * updater, LLSD const & evt) +	{ +		updater->setBandwidthLimit(evt.asInteger() * (1024/8)); +		return false; // Let others receive this event. +	};  };  void LLAppViewer::initUpdater() @@ -2431,7 +2505,10 @@ void LLAppViewer::initUpdater()  						 channel,   						 version);   	mUpdater->setCheckPeriod(check_period); -	if(gSavedSettings.getBOOL("UpdaterServiceActive")) +	mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8)); +	gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()-> +		connect(boost::bind(&on_bandwidth_throttle, mUpdater.get(), _2)); +	if(gSavedSettings.getU32("UpdaterServiceSetting"))  	{  		bool install_if_ready = true;  		mUpdater->startChecking(install_if_ready); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 52ce932241..8d9d7298f8 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -49,18 +49,421 @@  #include "llnotifications.h"  #include "llwindow.h"  #include "llviewerwindow.h" +#include "llprogressview.h"  #if LL_LINUX || LL_SOLARIS  #include "lltrans.h"  #endif  #include "llsecapi.h"  #include "llstartup.h"  #include "llmachineid.h" +#include "llupdaterservice.h" +#include "llevents.h" +#include "llnotificationsutil.h" +#include "llappviewer.h" + +#include <boost/scoped_ptr.hpp> +#include <sstream> + +class LLLoginInstance::Disposable { +public: +	virtual ~Disposable() {} +}; + +namespace { +	class MandatoryUpdateMachine: +		public LLLoginInstance::Disposable +	{ +	public: +		MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService); +		 +		void start(void); +		 +	private: +		class State; +		class CheckingForUpdate; +		class Error; +		class ReadyToInstall;  +		class StartingUpdaterService; +		class WaitingForDownload; +		 +		LLLoginInstance & mLoginInstance; +		boost::scoped_ptr<State> mState; +		LLUpdaterService & mUpdaterService; +		 +		void setCurrentState(State * newState); +	}; + +	 +	class MandatoryUpdateMachine::State { +	public: +		virtual ~State() {} +		virtual void enter(void) {} +		virtual void exit(void) {} +	}; +	 +	 +	class MandatoryUpdateMachine::CheckingForUpdate: +	public MandatoryUpdateMachine::State +	{ +	public: +		CheckingForUpdate(MandatoryUpdateMachine & machine); +		 +		virtual void enter(void); +		virtual void exit(void); +		 +	private: +		LLTempBoundListener mConnection; +		MandatoryUpdateMachine & mMachine; +		LLProgressView * mProgressView; +		 +		bool onEvent(LLSD const & event); +	}; +	 +	 +	class MandatoryUpdateMachine::Error: +	public MandatoryUpdateMachine::State +	{ +	public: +		Error(MandatoryUpdateMachine & machine); +		 +		virtual void enter(void); +		virtual void exit(void); +		void onButtonClicked(const LLSD &, const LLSD &); +		 +	private: +		MandatoryUpdateMachine & mMachine; +	}; +	 +	 +	class MandatoryUpdateMachine::ReadyToInstall: +	public MandatoryUpdateMachine::State +	{ +	public: +		ReadyToInstall(MandatoryUpdateMachine & machine); +		 +		virtual void enter(void); +		virtual void exit(void); +		 +	private: +		MandatoryUpdateMachine & mMachine; +	}; +	 +	 +	class MandatoryUpdateMachine::StartingUpdaterService: +	public MandatoryUpdateMachine::State +	{ +	public: +		StartingUpdaterService(MandatoryUpdateMachine & machine); +		 +		virtual void enter(void); +		virtual void exit(void); +		void onButtonClicked(const LLSD & uiform, const LLSD & result); +	private: +		MandatoryUpdateMachine & mMachine; +	}; +	 +	 +	class MandatoryUpdateMachine::WaitingForDownload: +		public MandatoryUpdateMachine::State +	{ +	public: +		WaitingForDownload(MandatoryUpdateMachine & machine); +		 +		virtual void enter(void); +		virtual void exit(void); +		 +	private: +		LLTempBoundListener mConnection; +		MandatoryUpdateMachine & mMachine; +		LLProgressView * mProgressView; +		 +		bool onEvent(LLSD const & event); +	}; +}  static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";  static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";  std::string construct_start_string(); + + +// MandatoryUpdateMachine +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService): +	mLoginInstance(loginInstance), +	mUpdaterService(updaterService) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::start(void) +{ +	llinfos << "starting manditory update machine" << llendl; +	 +	if(mUpdaterService.isChecking()) { +		switch(mUpdaterService.getState()) { +			case LLUpdaterService::UP_TO_DATE: +				mUpdaterService.stopChecking(); +				mUpdaterService.startChecking(); +				// Fall through. +			case LLUpdaterService::INITIAL: +			case LLUpdaterService::CHECKING_FOR_UPDATE: +				setCurrentState(new CheckingForUpdate(*this)); +				break; +			case LLUpdaterService::DOWNLOADING: +				setCurrentState(new WaitingForDownload(*this)); +				break; +			case LLUpdaterService::TERMINAL: +				if(LLUpdaterService::updateReadyToInstall()) { +					setCurrentState(new ReadyToInstall(*this)); +				} else { +					setCurrentState(new Error(*this)); +				} +				break; +			case LLUpdaterService::FAILURE: +				setCurrentState(new Error(*this)); +				break; +			default: +				llassert(!"unpossible case"); +				break; +		} +	} else { +		setCurrentState(new StartingUpdaterService(*this)); +	} +} + + +void MandatoryUpdateMachine::setCurrentState(State * newStatePointer) +{ +	{ +		boost::scoped_ptr<State> newState(newStatePointer); +		if(mState != 0) mState->exit(); +		mState.swap(newState); +		 +		// Old state will be deleted on exit from this block before the new state +		// is entered. +	} +	if(mState != 0) mState->enter(); +} + + + +// MandatoryUpdateMachine::CheckingForUpdate +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::CheckingForUpdate::CheckingForUpdate(MandatoryUpdateMachine & machine): +	mMachine(machine) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::CheckingForUpdate::enter(void) +{ +	llinfos << "entering checking for update" << llendl; +	 +	mProgressView = gViewerWindow->getProgressView(); +	mProgressView->setMessage("Looking for update..."); +	mProgressView->setText("There is a required update for your Second Life installation."); +	mProgressView->setPercent(0); +	mProgressView->setVisible(true); +	mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()). +		listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::CheckingForUpdate::onEvent, this, _1)); +} + + +void MandatoryUpdateMachine::CheckingForUpdate::exit(void) +{ +} + + +bool MandatoryUpdateMachine::CheckingForUpdate::onEvent(LLSD const & event) +{ +	if(event["type"].asInteger() == LLUpdaterService::STATE_CHANGE) { +		switch(event["state"].asInteger()) { +			case LLUpdaterService::DOWNLOADING: +				mMachine.setCurrentState(new WaitingForDownload(mMachine)); +				break; +			case LLUpdaterService::UP_TO_DATE: +			case LLUpdaterService::TERMINAL: +			case LLUpdaterService::FAILURE: +				mProgressView->setVisible(false); +				mMachine.setCurrentState(new Error(mMachine)); +				break; +			case LLUpdaterService::INSTALLING: +				llassert(!"can't possibly be installing"); +				break; +			default: +				break; +		} +	} else { +		; // Ignore. +	} +	 +	return false; +} + + + +// MandatoryUpdateMachine::Error +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::Error::Error(MandatoryUpdateMachine & machine): +	mMachine(machine) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::Error::enter(void) +{ +	llinfos << "entering error" << llendl; +	LLNotificationsUtil::add("FailedUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2)); +} + + +void MandatoryUpdateMachine::Error::exit(void) +{ +	LLAppViewer::instance()->forceQuit(); +} + + +void MandatoryUpdateMachine::Error::onButtonClicked(const LLSD &, const LLSD &) +{ +	mMachine.setCurrentState(0); +} + + + +// MandatoryUpdateMachine::ReadyToInstall +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::ReadyToInstall::ReadyToInstall(MandatoryUpdateMachine & machine): +	mMachine(machine) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::ReadyToInstall::enter(void) +{ +	llinfos << "entering ready to install" << llendl; +	// Open update ready dialog. +} + + +void MandatoryUpdateMachine::ReadyToInstall::exit(void) +{ +	// Restart viewer. +} + + + +// MandatoryUpdateMachine::StartingUpdaterService +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::StartingUpdaterService::StartingUpdaterService(MandatoryUpdateMachine & machine): +	mMachine(machine) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::StartingUpdaterService::enter(void) +{ +	llinfos << "entering start update service" << llendl; +	LLNotificationsUtil::add("UpdaterServiceNotRunning", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked, this, _1, _2)); +} + + +void MandatoryUpdateMachine::StartingUpdaterService::exit(void) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked(const LLSD & uiform, const LLSD & result) +{ +	if(result["OK_okcancelbuttons"].asBoolean()) { +		mMachine.mUpdaterService.startChecking(false); +		mMachine.setCurrentState(new CheckingForUpdate(mMachine)); +	} else { +		LLAppViewer::instance()->forceQuit(); +	} +} + + + +// MandatoryUpdateMachine::WaitingForDownload +//----------------------------------------------------------------------------- + + +MandatoryUpdateMachine::WaitingForDownload::WaitingForDownload(MandatoryUpdateMachine & machine): +	mMachine(machine), +	mProgressView(0) +{ +	; // No op. +} + + +void MandatoryUpdateMachine::WaitingForDownload::enter(void) +{ +	llinfos << "entering waiting for download" << llendl; +	mProgressView = gViewerWindow->getProgressView(); +	mProgressView->setMessage("Downloading update..."); +	std::ostringstream stream; +	stream << "There is a required update for your Second Life installation." << std::endl << +		"Version " << mMachine.mUpdaterService.updatedVersion(); +	mProgressView->setText(stream.str()); +	mProgressView->setPercent(0); +	mProgressView->setVisible(true); +	mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()). +		listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::WaitingForDownload::onEvent, this, _1)); +} + + +void MandatoryUpdateMachine::WaitingForDownload::exit(void) +{ +	mProgressView->setVisible(false); +} + + +bool MandatoryUpdateMachine::WaitingForDownload::onEvent(LLSD const & event) +{ +	switch(event["type"].asInteger()) { +		case LLUpdaterService::DOWNLOAD_COMPLETE: +			mMachine.setCurrentState(new ReadyToInstall(mMachine)); +			break; +		case LLUpdaterService::DOWNLOAD_ERROR: +			mMachine.setCurrentState(new Error(mMachine)); +			break; +		case LLUpdaterService::PROGRESS: { +			double downloadSize = event["download_size"].asReal(); +			double bytesDownloaded = event["bytes_downloaded"].asReal(); +			mProgressView->setPercent(100. * bytesDownloaded / downloadSize); +			break; +		} +		default: +			break; +	} + +	return false; +} + + + +// LLLoginInstance +//----------------------------------------------------------------------------- + +  LLLoginInstance::LLLoginInstance() :  	mLoginModule(new LLLogin()),  	mNotifications(NULL), @@ -69,7 +472,8 @@ LLLoginInstance::LLLoginInstance() :  	mSkipOptionalUpdate(false),  	mAttemptComplete(false),  	mTransferRate(0.0f), -	mDispatcher("LLLoginInstance", "change") +	mDispatcher("LLLoginInstance", "change"), +	mUpdaterService(0)  {  	mLoginModule->getEventPump().listen("lllogininstance",   		boost::bind(&LLLoginInstance::handleLoginEvent, this, _1)); @@ -353,6 +757,15 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)  void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)  { +	if(mandatory) +	{ +		gViewerWindow->setShowProgress(false); +		MandatoryUpdateMachine * machine = new MandatoryUpdateMachine(*this, *mUpdaterService); +		mUpdateStateMachine.reset(machine); +		machine->start(); +		return; +	} +	  	// store off config state, as we might quit soon  	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	  	LLUIColorTable::instance().saveUserSettings(); diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 159e05046c..b872d7d1b1 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -34,12 +34,15 @@  class LLLogin;  class LLEventStream;  class LLNotificationsInterface; +class LLUpdaterService;  // This class hosts the login module and is used to   // negotiate user authentication attempts.  class LLLoginInstance : public LLSingleton<LLLoginInstance>  {  public: +	class Disposable; +  	LLLoginInstance();  	~LLLoginInstance(); @@ -75,6 +78,7 @@ public:  	typedef boost::function<void()> UpdaterLauncherCallback;  	void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; } +	void setUpdaterService(LLUpdaterService * updaterService) { mUpdaterService = updaterService; }  private:  	void constructAuthParams(LLPointer<LLCredential> user_credentials);  	void updateApp(bool mandatory, const std::string& message); @@ -104,6 +108,8 @@ private:  	int mLastExecEvent;  	UpdaterLauncherCallback mUpdaterLauncher;  	LLEventDispatcher mDispatcher; +	LLUpdaterService * mUpdaterService;	 +	boost::scoped_ptr<Disposable> mUpdateStateMachine;  };  #endif diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index e9504cbba0..250dfc5713 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -133,13 +133,13 @@ void LLProgressView::setVisible(BOOL visible)  		mFadeTimer.start();  	}  	// showing progress view -	else if (!getVisible() && visible) +	else if (visible && (!getVisible() || mFadeTimer.getStarted()))  	{  		setFocus(TRUE);  		mFadeTimer.stop();  		mProgressTimer.start();  		LLPanel::setVisible(TRUE); -	} +	}   } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 622d09c600..2c75551285 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -504,7 +504,7 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)  void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_value)  { -    if(new_value.asBoolean()) +    if(new_value.asInteger())      {          LLUpdaterService().startChecking();      } @@ -661,7 +661,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("UpdaterServiceSetting")->getSignal()->connect(&toggle_updater_service_active);  	gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));  	gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));  } diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 60b876d163..eecbeeb8dc 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2887,12 +2887,66 @@ http://secondlife.com/download.       name="okbutton"       yestext="OK"/>    </notification> +    <notification -   icon="notifytip.tga" -   name="DownloadBackground" -   type="notifytip"> -An updated version of [APP_NAME] has been downloaded. -It will be applied the next time you restart [APP_NAME] +   icon="alertmodal.tga" +   name="UpdaterServiceNotRunning" +   type="alertmodal"> +There is a required update for your Second Life Installation. + +You may download this update from http://www.secondlife.com/downloads +or you can install it now. +    <usetemplate +     name="okcancelbuttons" +     notext="Quit Second Life" +     yestext="Download and install now"/> +  </notification> + +  <notification +   icon="notify.tga" +   name="DownloadBackgroundTip" +   type="notify"> +We have downloaded and update to your [APP_NAME] installation. +Version [VERSION] +    <usetemplate +     name="okcancelbuttons" +     notext="Wait" +     yestext="Restart Now"/> +  </notification> + +  <notification + icon="alertmodal.tga" + name="DownloadBackgroundDialog" + type="alertmodal"> +We have downloaded and update to your [APP_NAME] installation. +Version [VERSION] +    <usetemplate +     name="okcancelbuttons" +     notext="Later..." +     yestext="Install now and restart [APP_NAME]"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="RequiredUpdateDownloadedVerboseDialog" + type="alertmodal"> +We have downloaded a required software update. +Version [VERSION] + +We must restart [APP_NAME] to install the update. +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="RequiredUpdateDownloadedDialog" + type="alertmodal"> +We must restart [APP_NAME] to install the update. +    <usetemplate +     name="okbutton" +     yestext="OK"/>    </notification>    <notification 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 584bd1ea9d..542b6bcf6b 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -142,7 +142,7 @@     layout="topleft"     left="80"     name="Cache location" -   top_delta="40" +   top_delta="20"     width="300">      Cache location:    </text> @@ -341,20 +341,39 @@     name="web_proxy_port"     top_delta="0"     width="145" /> - -  <check_box -    top_delta="2" -    enabled="true" -    follows="left|top" -    height="18" -    initial_value="true" -    control_name="UpdaterServiceActive" -    label="Automatically download and install [APP_NAME] updates" -    left="30" -    mouse_opaque="true" -    name="updater_service_active" -    radio_style="false" -    width="400" -    top_pad="10"/> - +  <text +     type="string" +     length="1" +     follows="left|top" +     height="10" +     layout="topleft" +     left="30" +     name="Software updates:" +     mouse_opaque="false" +     top_pad="5" +     width="300"> +    Software updates: +  </text> +  <combo_box +     control_name="UpdaterServiceSetting" +     follows="left|top" +     height="23" +     layout="topleft" +     left_delta="50" +	 top_pad="5" +     name="updater_service_combobox" +     width="300"> +        <combo_box.item +         label="Install automatically" +         name="Install_automatically" +         value="3" /> +        <combo_box.item +         label="Ask before installing" +         name="Install_ask" +         value="1" /> +        <combo_box.item +         label="Download and install updates manually" +         name="Install_manual" +         value="0" /> +  </combo_box>  </panel> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 309e9e9ee3..9e321db889 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -40,6 +40,7 @@  #if defined(LL_WINDOWS)  #pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr +#pragma warning(disable: 4702)      // disable 'unreachable code' so we can safely use skip().  #endif  // Constants @@ -68,6 +69,7 @@ static bool gDisconnectCalled = false;  #include "../llviewerwindow.h"  void LLViewerWindow::setShowProgress(BOOL show) {} +LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }  LLViewerWindow* gViewerWindow; @@ -185,6 +187,41 @@ const std::string &LLVersionInfo::getChannelAndVersion() { return VIEWERLOGIN_VE  const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }  //----------------------------------------------------------------------------- +#include "../llappviewer.h" +void LLAppViewer::forceQuit(void) {} +LLAppViewer * LLAppViewer::sInstance = 0; + +//----------------------------------------------------------------------------- +#include "llnotificationsutil.h" +LLNotificationPtr LLNotificationsUtil::add(const std::string& name,  +					  const LLSD& substitutions,  +					  const LLSD& payload,  +					  boost::function<void (const LLSD&, const LLSD&)> functor) { return LLNotificationPtr((LLNotification*)0); } + + +//----------------------------------------------------------------------------- +#include "llupdaterservice.h" + +std::string const & LLUpdaterService::pumpName(void) +{ +	static std::string wakka = "wakka wakka wakka"; +	return wakka; +} +bool LLUpdaterService::updateReadyToInstall(void) { return false; } +void LLUpdaterService::initialize(const std::string& protocol_version, +				const std::string& url,  +				const std::string& path, +				const std::string& channel, +								  const std::string& version) {} + +void LLUpdaterService::setCheckPeriod(unsigned int seconds) {} +void LLUpdaterService::startChecking(bool install_if_ready) {} +void LLUpdaterService::stopChecking() {} +bool LLUpdaterService::isChecking() { return false; } +LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; } +std::string LLUpdaterService::updatedVersion() { return ""; } + +//-----------------------------------------------------------------------------  #include "llnotifications.h"  #include "llfloaterreg.h"  static std::string gTOSType; @@ -198,6 +235,12 @@ LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key,  	return NULL;  } +//---------------------------------------------------------------------------- +#include "../llprogressview.h" +void LLProgressView::setText(std::string const &){} +void LLProgressView::setPercent(float){} +void LLProgressView::setMessage(std::string const &){} +  //-----------------------------------------------------------------------------  // LLNotifications  class MockNotifications : public LLNotificationsInterface @@ -435,6 +478,8 @@ namespace tut      template<> template<>      void lllogininstance_object::test<3>()      { +		skip(); +		  		set_test_name("Test Mandatory Update User Accepts");  		// Part 1 - Mandatory Update, with User accepts response. @@ -462,6 +507,8 @@ namespace tut  	template<> template<>      void lllogininstance_object::test<4>()      { +		skip(); +		  		set_test_name("Test Mandatory Update User Decline");  		// Test connect with update needed. diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index c17a50e242..2dd0084fdc 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -24,17 +24,20 @@   */  #include "linden_common.h" + +#include "llupdatedownloader.h" +  #include <stdexcept>  #include <boost/format.hpp>  #include <boost/lexical_cast.hpp>  #include <curl/curl.h>  #include "lldir.h" +#include "llevents.h"  #include "llfile.h"  #include "llmd5.h"  #include "llsd.h"  #include "llsdserialize.h"  #include "llthread.h" -#include "llupdatedownloader.h"  #include "llupdaterservice.h" @@ -45,18 +48,22 @@ public:  	Implementation(LLUpdateDownloader::Client & client);  	~Implementation();  	void cancel(void); -	void download(LLURI const & uri, std::string const & hash); +	void download(LLURI const & uri, std::string const & hash, bool required);  	bool isDownloading(void);  	size_t onHeader(void * header, size_t size);  	size_t onBody(void * header, size_t size); +	int onProgress(double downloadSize, double bytesDownloaded);  	void resume(void); +	void setBandwidthLimit(U64 bytesPerSecond);  private: +	curl_off_t mBandwidthLimit;  	bool mCancelled;  	LLUpdateDownloader::Client & mClient;  	CURL * mCurl;  	LLSD mDownloadData;  	llofstream mDownloadStream; +	unsigned char mDownloadPercent;  	std::string mDownloadRecordPath;  	curl_slist * mHeaderList; @@ -113,9 +120,9 @@ void LLUpdateDownloader::cancel(void)  } -void LLUpdateDownloader::download(LLURI const & uri, std::string const & hash) +void LLUpdateDownloader::download(LLURI const & uri, std::string const & hash, bool required)  { -	mImplementation->download(uri, hash); +	mImplementation->download(uri, hash, required);  } @@ -131,6 +138,12 @@ void LLUpdateDownloader::resume(void)  } +void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) +{ +	mImplementation->setBandwidthLimit(bytesPerSecond); +} + +  // LLUpdateDownloader::Implementation  //----------------------------------------------------------------------------- @@ -149,14 +162,27 @@ namespace {  		size_t bytes = blockSize * blocks;  		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes);  	} + + +	int progress_callback(void * downloader, +						  double dowloadTotal, +						  double downloadNow, +						  double uploadTotal, +						  double uploadNow) +	{ +		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)-> +			onProgress(dowloadTotal, downloadNow); +	}  }  LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):  	LLThread("LLUpdateDownloader"), +	mBandwidthLimit(0),  	mCancelled(false),  	mClient(client),  	mCurl(0), +	mDownloadPercent(0),  	mHeaderList(0)  {  	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. @@ -182,12 +208,13 @@ void LLUpdateDownloader::Implementation::cancel(void)  } -void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash) +void LLUpdateDownloader::Implementation::download(LLURI const & uri, std::string const & hash, bool required)  {  	if(isDownloading()) mClient.downloadError("download in progress");  	mDownloadRecordPath = downloadMarkerPath();  	mDownloadData = LLSD(); +	mDownloadData["required"] = required;  	try {  		startDownloading(uri, hash);  	} catch(DownloadError const & e) { @@ -233,12 +260,12 @@ void LLUpdateDownloader::Implementation::resume(void)  				resumeDownloading(fileStatus.st_size);  			} else if(!validateDownload()) {  				LLFile::remove(filePath); -				download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString()); +				download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString(), mDownloadData["required"].asBoolean());  			} else {  				mClient.downloadComplete(mDownloadData);  			}  		} else { -			download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString()); +			download(LLURI(mDownloadData["url"].asString()), mDownloadData["hash"].asString(), mDownloadData["required"].asBoolean());  		}  	} catch(DownloadError & e) {  		mClient.downloadError(e.what()); @@ -246,6 +273,20 @@ void LLUpdateDownloader::Implementation::resume(void)  } +void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond) +{ +	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("UpdateDownload") <<  +			"unable to change dowload bandwidth" << LL_ENDL; +	} else { +		mBandwidthLimit = bytesPerSecond; +	} +} + +  size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)  {  	char const * headerPtr = reinterpret_cast<const char *> (buffer); @@ -290,6 +331,30 @@ size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)  } +int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double bytesDownloaded) +{ +	int downloadPercent = static_cast<int>(100. * (bytesDownloaded / downloadSize)); +	if(downloadPercent > mDownloadPercent) { +		mDownloadPercent = downloadPercent; +		 +		LLSD event; +		event["pump"] = LLUpdaterService::pumpName(); +		LLSD payload; +		payload["type"] = LLSD(LLUpdaterService::PROGRESS); +		payload["download_size"] = downloadSize; +		payload["bytes_downloaded"] = bytesDownloaded; +		event["payload"] = payload; +		LLEventPumps::instance().obtain("mainlooprepeater").post(event); +		 +		LL_INFOS("UpdateDownload") << "progress event " << payload << LL_ENDL; +	} else { +		; // Keep events to a reasonalbe number. +	} +	 +	return 0; +} + +  void LLUpdateDownloader::Implementation::run(void)  {  	CURLcode code = curl_easy_perform(mCurl); @@ -343,6 +408,16 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u  	}  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true));  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str())); +	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &progress_callback)); +	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, this)); +	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, false)); +	if((mBandwidthLimit != 0) && !mDownloadData["required"].asBoolean()) { +		throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, mBandwidthLimit)); +	} else { +		throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, -1)); +	} +	 +	mDownloadPercent = 0;  } diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 1b3d7480fd..4e20b307b8 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -52,7 +52,7 @@ public:  	void cancel(void);  	// Start a new download. -	void download(LLURI const & uri, std::string const & hash); +	void download(LLURI const & uri, std::string const & hash, bool required=false);  	// Returns true if a download is in progress.  	bool isDownloading(void); @@ -60,6 +60,9 @@ public:  	// Resume a partial download.  	void resume(void); +	// Set a limit on the dowload rate. +	void setBandwidthLimit(U64 bytesPerSecond); +	  private:  	boost::shared_ptr<Implementation> mImplementation;  }; @@ -76,6 +79,7 @@ public:  	// url - source (remote) location  	// hash - the md5 sum that should match the installer file.  	// path - destination (local) location +	// required - boolean indicating if this is a required update.  	// size - the size of the installer in bytes  	virtual void downloadComplete(LLSD const & data) = 0; diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index cc60eaead2..78f768facf 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -25,10 +25,11 @@  #include "linden_common.h" +#include "llupdaterservice.h" +  #include "llupdatedownloader.h"  #include "llevents.h"  #include "lltimer.h" -#include "llupdaterservice.h"  #include "llupdatechecker.h"  #include "llupdateinstaller.h"  #include "llversionviewer.h" @@ -98,6 +99,8 @@ class LLUpdaterServiceImpl :  	LLUpdaterService::app_exit_callback_t mAppExitCallback; +	LLUpdaterService::eUpdaterState mState; +	  	LOG_CLASS(LLUpdaterServiceImpl);  public: @@ -111,12 +114,15 @@ public:  				   const std::string& version);  	void setCheckPeriod(unsigned int seconds); +	void setBandwidthLimit(U64 bytesPerSecond);  	void startChecking(bool install_if_ready);  	void stopChecking();  	bool isChecking(); +	LLUpdaterService::eUpdaterState getState();  	void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;} +	std::string updatedVersion(void);  	bool checkForInstall(bool launchInstaller); // Test if a local install is ready.  	bool checkForResume(); // Test for resumeable d/l. @@ -138,7 +144,10 @@ public:  	bool onMainLoop(LLSD const & event);  private: +	std::string mNewVersion; +	  	void restartTimer(unsigned int seconds); +	void setState(LLUpdaterService::eUpdaterState state);  	void stopTimer();  }; @@ -149,7 +158,8 @@ LLUpdaterServiceImpl::LLUpdaterServiceImpl() :  	mIsDownloading(false),  	mCheckPeriod(0),  	mUpdateChecker(*this), -	mUpdateDownloader(*this) +	mUpdateDownloader(*this), +	mState(LLUpdaterService::INITIAL)  {  } @@ -183,6 +193,11 @@ void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)  	mCheckPeriod = seconds;  } +void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond) +{ +	mUpdateDownloader.setBandwidthLimit(bytesPerSecond); +} +  void LLUpdaterServiceImpl::startChecking(bool install_if_ready)  {  	if(mUrl.empty() || mChannel.empty() || mVersion.empty()) @@ -201,10 +216,16 @@ void LLUpdaterServiceImpl::startChecking(bool install_if_ready)  		if(!mIsDownloading)  		{ +			setState(LLUpdaterService::CHECKING_FOR_UPDATE); +			  			// Checking can only occur during the mainloop.  			// reset the timer to 0 so that the next mainloop event   			// triggers a check;  			restartTimer(0);  +		}  +		else +		{ +			setState(LLUpdaterService::DOWNLOADING);  		}  	}  } @@ -222,6 +243,8 @@ void LLUpdaterServiceImpl::stopChecking()          mUpdateDownloader.cancel();  		mIsDownloading = false;      } +	 +	setState(LLUpdaterService::TERMINAL);  }  bool LLUpdaterServiceImpl::isChecking() @@ -229,6 +252,16 @@ bool LLUpdaterServiceImpl::isChecking()  	return mIsChecking;  } +LLUpdaterService::eUpdaterState LLUpdaterServiceImpl::getState() +{ +	return mState; +} + +std::string LLUpdaterServiceImpl::updatedVersion(void) +{ +	return mNewVersion; +} +  bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)  {  	bool foundInstall = false; // return true if install is found. @@ -266,6 +299,8 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)  		{  			if(launchInstaller)  			{ +				setState(LLUpdaterService::INSTALLING); +				  				LLFile::remove(update_marker_path());  				int result = ll_install_update(install_script_path(), @@ -333,8 +368,11 @@ void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,  										  std::string const & hash)  {  	stopTimer(); +	mNewVersion = newVersion;  	mIsDownloading = true; -	mUpdateDownloader.download(uri, hash); +	mUpdateDownloader.download(uri, hash, false); +	 +	setState(LLUpdaterService::DOWNLOADING);  }  void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, @@ -342,8 +380,11 @@ void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,  										  std::string const & hash)  {  	stopTimer(); +	mNewVersion = newVersion;  	mIsDownloading = true; -	mUpdateDownloader.download(uri, hash); +	mUpdateDownloader.download(uri, hash, true); +	 +	setState(LLUpdaterService::DOWNLOADING);  }  void LLUpdaterServiceImpl::upToDate(void) @@ -352,6 +393,8 @@ void LLUpdaterServiceImpl::upToDate(void)  	{  		restartTimer(mCheckPeriod);  	} +	 +	setState(LLUpdaterService::UP_TO_DATE);  }  void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  @@ -367,8 +410,12 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  	event["pump"] = LLUpdaterService::pumpName();  	LLSD payload;  	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE); +	payload["required"] = data["required"]; +	payload["version"] = mNewVersion;  	event["payload"] = payload;  	LLEventPumps::instance().obtain("mainlooprepeater").post(event); +	 +	setState(LLUpdaterService::TERMINAL);  }  void LLUpdaterServiceImpl::downloadError(std::string const & message)  @@ -390,6 +437,8 @@ void LLUpdaterServiceImpl::downloadError(std::string const & message)  	payload["message"] = message;  	event["payload"] = payload;  	LLEventPumps::instance().obtain("mainlooprepeater").post(event); + +	setState(LLUpdaterService::FAILURE);  }  void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) @@ -402,6 +451,28 @@ void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)  		sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));  } +void LLUpdaterServiceImpl::setState(LLUpdaterService::eUpdaterState state) +{ +	if(state != mState) +	{ +		mState = state; +		 +		LLSD event; +		event["pump"] = LLUpdaterService::pumpName(); +		LLSD payload; +		payload["type"] = LLSD(LLUpdaterService::STATE_CHANGE); +		payload["state"] = state; +		event["payload"] = payload; +		LLEventPumps::instance().obtain("mainlooprepeater").post(event); +		 +		LL_INFOS("UpdaterService") << "setting state to " << state << LL_ENDL; +	} +	else  +	{ +		; // State unchanged; noop. +	} +} +  void LLUpdaterServiceImpl::stopTimer()  {  	mTimer.stop(); @@ -425,10 +496,13 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)  			LLSD event;  			event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR);  			LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event); +			 +			setState(LLUpdaterService::TERMINAL);  		}  		else  		{  			mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion); +			setState(LLUpdaterService::CHECKING_FOR_UPDATE);  		}  	}   	else  @@ -449,6 +523,11 @@ std::string const & LLUpdaterService::pumpName(void)  	return name;  } +bool LLUpdaterService::updateReadyToInstall(void) +{ +	return LLFile::isfile(update_marker_path()); +} +  LLUpdaterService::LLUpdaterService()  {  	if(gUpdater.expired()) @@ -480,6 +559,11 @@ void LLUpdaterService::setCheckPeriod(unsigned int seconds)  {  	mImpl->setCheckPeriod(seconds);  } + +void LLUpdaterService::setBandwidthLimit(U64 bytesPerSecond) +{ +	mImpl->setBandwidthLimit(bytesPerSecond); +}  void LLUpdaterService::startChecking(bool install_if_ready)  { @@ -496,11 +580,21 @@ bool LLUpdaterService::isChecking()  	return mImpl->isChecking();  } +LLUpdaterService::eUpdaterState LLUpdaterService::getState() +{ +	return mImpl->getState(); +} +  void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb)  {  	return mImpl->setAppExitCallback(aecb);  } +std::string LLUpdaterService::updatedVersion(void) +{ +	return mImpl->updatedVersion(); +} +  std::string const & ll_get_version(void) {  	static std::string version(""); diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 752a6f834b..421481bc43 100644 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -43,12 +43,27 @@ public:  	// Name of the event pump through which update events will be delivered.  	static std::string const & pumpName(void); +	// Returns true if an update has been completely downloaded and is now ready to install. +	static bool updateReadyToInstall(void); +	  	// Type codes for events posted by this service.  Stored the event's 'type' element. -	enum eUpdateEvent { +	enum eUpdaterEvent {  		INVALID,  		DOWNLOAD_COMPLETE,  		DOWNLOAD_ERROR, -		INSTALL_ERROR +		INSTALL_ERROR, +		PROGRESS, +		STATE_CHANGE +	}; +	 +	enum eUpdaterState { +		INITIAL, +		CHECKING_FOR_UPDATE, +		DOWNLOADING, +		INSTALLING, +		UP_TO_DATE, +		TERMINAL, +		FAILURE  	};  	LLUpdaterService(); @@ -61,10 +76,12 @@ public:  				    const std::string& version);  	void setCheckPeriod(unsigned int seconds); +	void setBandwidthLimit(U64 bytesPerSecond);  	void startChecking(bool install_if_ready = false);  	void stopChecking();  	bool isChecking(); +	eUpdaterState getState();  	typedef boost::function<void (void)> app_exit_callback_t;  	template <typename F> @@ -73,6 +90,11 @@ public:  		app_exit_callback_t aecb = callable;  		setImplAppExitCallback(aecb);  	} +	 +	// If an update is or has been downloaded, this method will return the +	// version string for that update.  An empty string will be returned +	// otherwise. +	std::string updatedVersion(void);  private:  	boost::shared_ptr<LLUpdaterServiceImpl> mImpl; diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 04ed4e6364..fbdf9a4993 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -48,7 +48,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 & , std::string const &){}
 +void LLUpdateDownloader::download(LLURI const & , std::string const &, bool){}
  class LLDir_Mock : public LLDir
  {
 @@ -101,6 +101,7 @@ std::string LLUpdateDownloader::downloadMarkerPath(void)  void LLUpdateDownloader::resume(void) {}
  void LLUpdateDownloader::cancel(void) {}
 +void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {}
  int ll_install_update(std::string const &, std::string const &, LLInstallScriptMode)
  {
 | 
