| 
									
										
										
										
											2015-02-12 23:16:25 +08:00
										 |  |  | // Aseprite
 | 
					
						
							|  |  |  | // Copyright (C) 2001-2015  David Capello
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License version 2 as
 | 
					
						
							|  |  |  | // published by the Free Software Foundation.
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | #include "config.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef ENABLE_UPDATER
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "app/check_update.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 23:28:26 +08:00
										 |  |  | #include "app/check_update_delegate.h"
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  | #include "app/pref/preferences.h"
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | #include "base/bind.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-26 23:28:26 +08:00
										 |  |  | #include "base/convert_to.h"
 | 
					
						
							| 
									
										
										
										
											2014-08-20 11:11:19 +08:00
										 |  |  | #include "base/launcher.h"
 | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  | #include "base/version.h"
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <ctime>
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | static const int kMonitoringPeriod = 100; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | namespace app { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CheckUpdateBackgroundJob : public updater::CheckUpdateDelegate | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   CheckUpdateBackgroundJob() | 
					
						
							|  |  |  |     : m_canceled(false) | 
					
						
							|  |  |  |     , m_received(false) { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   virtual ~CheckUpdateBackgroundJob() { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void cancel() | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_canceled = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool isCanceled() const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return m_canceled; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool isReceived() const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return m_received; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void sendRequest(const updater::Uuid& uuid, const std::string& extraParams) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_checker.checkNewVersion(uuid, extraParams, this); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const updater::CheckUpdateResponse& getResponse() const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return m_response; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // CheckUpdateDelegate implementation
 | 
					
						
							|  |  |  |   virtual void onResponse(updater::CheckUpdateResponse& data) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_response = data; | 
					
						
							|  |  |  |     m_received = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool m_canceled; | 
					
						
							|  |  |  |   bool m_received; | 
					
						
							|  |  |  |   updater::CheckUpdate m_checker; | 
					
						
							|  |  |  |   updater::CheckUpdateResponse m_response; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 23:28:26 +08:00
										 |  |  | CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate) | 
					
						
							|  |  |  |   : m_delegate(delegate) | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   , m_preferences(delegate->getPreferences()) | 
					
						
							| 
									
										
										
										
											2015-02-26 23:28:26 +08:00
										 |  |  |   , m_doCheck(true) | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   , m_received(false) | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   , m_inits(m_preferences.updater.inits()) | 
					
						
							|  |  |  |   , m_exits(m_preferences.updater.exits()) | 
					
						
							| 
									
										
										
										
											2014-12-05 21:38:22 +08:00
										 |  |  | #ifdef _DEBUG
 | 
					
						
							|  |  |  |   , m_isDeveloper(true) | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   , m_isDeveloper(m_preferences.updater.isDeveloper()) | 
					
						
							| 
									
										
										
										
											2014-12-05 21:38:22 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  |   , m_timer(kMonitoringPeriod, NULL) | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // Get how many days we have to wait for the next "check for update"
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   double waitDays = m_preferences.updater.waitDays(); | 
					
						
							| 
									
										
										
										
											2015-02-28 22:43:11 +08:00
										 |  |  |   if (waitDays > 0.0) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |     // Get the date of the last "check for updates"
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |     time_t lastCheck = (time_t)m_preferences.updater.lastCheck(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |     time_t now = std::time(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Verify if we are in the "WaitDays" period...
 | 
					
						
							| 
									
										
										
										
											2015-02-28 22:43:11 +08:00
										 |  |  |     if (now < lastCheck+int(double(60*60*24*waitDays)) && | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         now > lastCheck) {                               // <- Avoid broken clocks
 | 
					
						
							|  |  |  |       // So we do not check for updates.
 | 
					
						
							|  |  |  |       m_doCheck = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Minimal stats: number of initializations
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   m_preferences.updater.inits(m_inits+1); | 
					
						
							|  |  |  |   m_preferences.save(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CheckUpdateThreadLauncher::~CheckUpdateThreadLauncher() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  |   if (m_timer.isRunning()) | 
					
						
							|  |  |  |     m_timer.stop(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (m_thread) { | 
					
						
							|  |  |  |     if (m_bgJob) | 
					
						
							|  |  |  |       m_bgJob->cancel(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_thread->join(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Minimal stats: number of exits
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   m_preferences.updater.exits(m_exits+1); | 
					
						
							|  |  |  |   m_preferences.save(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CheckUpdateThreadLauncher::launch() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // In this case we are in the "wait days" period, so we don't check
 | 
					
						
							|  |  |  |   // for updates.
 | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  |   if (!m_doCheck) { | 
					
						
							|  |  |  |     showUI(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (m_uuid.empty()) | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |     m_uuid = m_preferences.updater.uuid(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 23:28:26 +08:00
										 |  |  |   m_delegate->onCheckingUpdates(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   m_bgJob.reset(new CheckUpdateBackgroundJob); | 
					
						
							|  |  |  |   m_thread.reset(new base::thread(Bind<void>(&CheckUpdateThreadLauncher::checkForUpdates, this))); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  |   // Start a timer to monitoring the progress of the background job
 | 
					
						
							|  |  |  |   // executed in "m_thread". The "onMonitoringTick" method will be
 | 
					
						
							|  |  |  |   // called periodically by the GUI main thread.
 | 
					
						
							|  |  |  |   m_timer.Tick.connect(&CheckUpdateThreadLauncher::onMonitoringTick, this); | 
					
						
							|  |  |  |   m_timer.start(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckUpdateThreadLauncher::isReceived() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return m_received; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  | void CheckUpdateThreadLauncher::onMonitoringTick() | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // If we do not receive a response yet...
 | 
					
						
							|  |  |  |   if (!m_received) | 
					
						
							|  |  |  |     return;                     // Skip and wait the next call.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Depending on the type of update received
 | 
					
						
							|  |  |  |   switch (m_response.getUpdateType()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case updater::CheckUpdateResponse::NoUpdate: | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  |       // Clear
 | 
					
						
							|  |  |  |       m_preferences.updater.newVersion(""); | 
					
						
							|  |  |  |       m_preferences.updater.newUrl(""); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case updater::CheckUpdateResponse::Critical: | 
					
						
							|  |  |  |     case updater::CheckUpdateResponse::Major: | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  |       m_preferences.updater.newVersion(m_response.getLatestVersion()); | 
					
						
							|  |  |  |       m_preferences.updater.newUrl(m_response.getUrl()); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  |   showUI(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   // Save the new UUID
 | 
					
						
							|  |  |  |   if (!m_response.getUuid().empty()) { | 
					
						
							|  |  |  |     m_uuid = m_response.getUuid(); | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |     m_preferences.updater.uuid(m_uuid); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Set the date of the last "check for updates" and the "WaitDays" parameter.
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   m_preferences.updater.lastCheck((int)std::time(NULL)); | 
					
						
							|  |  |  |   m_preferences.updater.waitDays(m_response.getWaitDays()); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Save the config file right now
 | 
					
						
							| 
									
										
										
										
											2015-04-24 06:51:53 +08:00
										 |  |  |   m_preferences.save(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-06 12:06:00 +08:00
										 |  |  |   // Stop the monitoring timer.
 | 
					
						
							|  |  |  |   m_timer.stop(); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This method is executed in a special thread to send the HTTP request.
 | 
					
						
							|  |  |  | void CheckUpdateThreadLauncher::checkForUpdates() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // Add mini-stats in the request
 | 
					
						
							|  |  |  |   std::stringstream extraParams; | 
					
						
							|  |  |  |   extraParams << "inits=" << m_inits | 
					
						
							|  |  |  |               << "&exits=" << m_exits; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m_isDeveloper) | 
					
						
							|  |  |  |     extraParams << "&dev=1"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Send the HTTP request to check for updates.
 | 
					
						
							|  |  |  |   m_bgJob->sendRequest(m_uuid, extraParams.str()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m_bgJob->isReceived()) { | 
					
						
							|  |  |  |     m_received = true; | 
					
						
							|  |  |  |     m_response = m_bgJob->getResponse(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-24 23:45:01 +08:00
										 |  |  | void CheckUpdateThreadLauncher::showUI() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bool newVer = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!m_preferences.updater.newVersion().empty()) { | 
					
						
							|  |  |  |     base::Version serverVersion(m_preferences.updater.newVersion()); | 
					
						
							|  |  |  |     base::Version localVersion(VERSION); | 
					
						
							|  |  |  |     newVer = (localVersion < serverVersion); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (newVer) { | 
					
						
							|  |  |  |     m_delegate->onNewUpdate(m_preferences.updater.newUrl(), | 
					
						
							|  |  |  |                             m_preferences.updater.newVersion()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     m_delegate->onUpToDate(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // ENABLE_UPDATER
 |