Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

autoupdater.cpp 52KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. *
  3. * Copyright (C) 1995-2011 Opera Software AS. All rights reserved.
  4. *
  5. * This file is part of the Opera web browser. It may not be distributed
  6. * under any circumstances.
  7. *
  8. * @author Adam Minchinton, Michal Zajaczkowski
  9. */
  10. #include "core/pch.h"
  11. #ifdef AUTO_UPDATE_SUPPORT
  12. #include "adjunct/autoupdate/autoupdater.h"
  13. #include "adjunct/autoupdate/updatablefile.h"
  14. #include "adjunct/autoupdate/updatablesetting.h"
  15. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  16. # include "adjunct/autoupdate/updater/pi/aufileutils.h"
  17. # include "adjunct/autoupdate/updater/audatafile_reader.h"
  18. #endif
  19. #include "adjunct/desktop_pi/DesktopOpSystemInfo.h"
  20. #include "modules/locale/oplanguagemanager.h"
  21. #include "modules/prefs/prefsmanager/prefsmanager.h"
  22. #include "modules/prefs/prefsmanager/collections/pc_network.h"
  23. #include "modules/prefs/prefsmanager/collections/pc_ui.h"
  24. #include "modules/util/opfile/opfile.h"
  25. #ifdef AUTOUPDATE_ENABLE_AUTOUPDATE_INI
  26. #include "modules/prefsfile/prefsfile.h"
  27. #endif // AUTOUPDATE_ENABLE_AUTOUPDATE_INI
  28. #include "modules/libssl/updaters.h"
  29. #include "adjunct/quick/managers/LaunchManager.h"
  30. #ifndef _MACINTOSH_
  31. #include "adjunct/autoupdate/autoupdate_checker/adaptation_layer/ipc.h"
  32. #endif // _MACINTOSH_
  33. #include "adjunct/desktop_util/resources/pi/opdesktopresources.h"
  34. #include "adjunct/desktop_util/resources/pi/opdesktopproduct.h"
  35. #include "adjunct/desktop_util/resources/ResourceDefines.h"
  36. #ifndef _MACINTOSH_
  37. #include "adjunct/autoupdate/autoupdate_checker/adaptation_layer/global_storage.h"
  38. #endif // _MACINTOSH_
  39. #include "modules/util/path.h"
  40. const uni_char* autoupdate_error_strings[] =
  41. {
  42. UNI_L("No error"),
  43. UNI_L("Internal error"),
  44. UNI_L("In progress error"),
  45. UNI_L("Connection error"),
  46. UNI_L("Save error"),
  47. UNI_L("Validation error"),
  48. UNI_L("Update error")
  49. };
  50. OperaVersion AutoUpdater::m_opera_version;
  51. /**
  52. * See autoupdater.h for description of the values below.
  53. */
  54. const int AutoUpdater::MAX_UPDATE_CHECK_INTERVAL_SEC = (7*24*60*60);
  55. const int AutoUpdater::MIN_UPDATE_CHECK_INTERVAL_SEC = (5*60);
  56. const int AutoUpdater::MIN_UPDATE_CHECK_INTERVAL_RUNNING_SEC = (24*60*60);
  57. const int AutoUpdater::UPDATE_CHECK_INTERVAL_DELTA_SEC = (24*60*60);
  58. const int AutoUpdater::AUTOUPDATE_RECHECK_TIMEOUT_SEC = (24*60*60);
  59. const int AutoUpdater::AUTOUPDATE_SSL_UPDATERS_BUSY_RECHECK_TIMEOUT_SEC = 10;
  60. const int AutoUpdater::AUTOUPDATE_RESOURCE_CHECK_BASE_TIMEOUT_SEC = 60;
  61. #ifndef _MACINTOSH_
  62. using namespace opera_update_checker::ipc;
  63. using namespace opera_update_checker::global_storage;
  64. using namespace opera_update_checker::status;
  65. #endif // _MACINTOSH_
  66. AutoUpdater::AutoUpdater():
  67. m_xml_downloader(NULL),
  68. m_autoupdate_xml(NULL),
  69. m_autoupdate_server_url(NULL),
  70. m_update_state(AUSUpToDate),
  71. m_silent_update(TRUE),
  72. m_last_error(AUNoError),
  73. m_update_check_timer(NULL),
  74. m_download_timer(NULL),
  75. m_download_countdown(0),
  76. m_download_retries(0),
  77. m_activated(FALSE),
  78. m_resources_check_only(FALSE),
  79. m_check_increased_update_check_interval(TRUE),
  80. m_time_of_last_update_check(0),
  81. m_update_check_interval(86400),
  82. m_update_check_delay(0),
  83. m_user_initiated(FALSE)
  84. #ifndef _MACINTOSH_
  85. ,m_channel_to_checker(NULL)
  86. ,m_channel_id(0)
  87. ,m_checker_launch_retry_timer(NULL)
  88. ,m_checker_launch_retry_count(0)
  89. ,m_checker_state(CheckerOk)
  90. #endif //_MACINTOSH_
  91. {
  92. }
  93. AutoUpdater::~AutoUpdater()
  94. {
  95. g_pcui->UnregisterListener(this);
  96. OP_DELETE(m_xml_downloader);
  97. OP_DELETE(m_autoupdate_xml);
  98. OP_DELETE(m_autoupdate_server_url);
  99. OP_DELETE(m_update_check_timer);
  100. OP_DELETE(m_download_timer);
  101. #ifndef _MACINTOSH_
  102. OP_DELETE(m_checker_launch_retry_timer);
  103. if (m_channel_to_checker)
  104. m_channel_to_checker->Disconnect();
  105. Channel::Destroy(m_channel_to_checker);
  106. #endif // _MACINTOSH_
  107. }
  108. OP_STATUS AutoUpdater::Init(BOOL check_increased_update_check_interval)
  109. {
  110. OpDesktopResources* resources;
  111. RETURN_IF_ERROR(OpDesktopResources::Create(&resources));
  112. OpAutoPtr<OpDesktopResources> auto_resources(resources);
  113. RETURN_IF_ERROR(g_pcui->RegisterListener(this));
  114. #ifndef _MACINTOSH_
  115. RETURN_IF_ERROR(resources->GetUpdateCheckerPath(m_checker_path));
  116. m_channel_id = opera_update_checker::ipc::GetCurrentProcessId();
  117. op_srand(m_channel_id);
  118. m_channel_to_checker = Channel::Create(true, m_channel_id, Channel::CHANNEL_MODE_READ_WRITE, Channel::BIDIRECTIONAL);
  119. RETURN_OOM_IF_NULL(m_channel_to_checker);
  120. #endif // _MACINTOSH_
  121. m_check_increased_update_check_interval = check_increased_update_check_interval;
  122. m_level_of_automation = static_cast<LevelOfAutomation>(g_pcui->GetIntegerPref(PrefsCollectionUI::LevelOfUpdateAutomation));
  123. int saved_state = g_pcui->GetIntegerPref(PrefsCollectionUI::AutoUpdateState);
  124. m_update_state = static_cast<AutoUpdateState>(saved_state & 0xFFFF); // The lower word is the update state.
  125. #ifndef _MACINTOSH_
  126. m_checker_state = static_cast<CheckerState>(saved_state >> 16); // The higher word is the checker state.
  127. // If couldn't launch the checker last time schedule the new attempt.
  128. if (m_checker_state == CheckerCouldntLaunch)
  129. {
  130. m_checker_launch_retry_timer = OP_NEW(OpTimer, ());
  131. if (m_checker_launch_retry_timer)
  132. {
  133. m_checker_launch_retry_timer->SetTimerListener(this);
  134. m_checker_launch_retry_timer->Start(CHECKER_LAUNCH_RETRY_TIME_MS);
  135. }
  136. }
  137. #endif // _MACINTOSH_
  138. m_time_of_last_update_check = static_cast<time_t>(g_pcui->GetIntegerPref(PrefsCollectionUI::TimeOfLastUpdateCheck));
  139. const int DELTA_PERIOD_MINUTES = 4 * 60;
  140. const int DELTA_RESOLUTION_MINUTES = 10;
  141. /* Random delta needed by the user counting system to detect collisions.
  142. It's required to be wihin +- 4h with 10min. resolution.
  143. Since rand operates on ranges starting from 0 only in order to achieve [-4h; 4h] range
  144. rand from [0h; 7h50min] range is done and 4h is substracted from the result
  145. (+1 below is needed due to how % operator works and -10 min is so that after
  146. rounding the result is still within the expected range).
  147. To achieve 10 minutes resolution the result delta is rounded to the nearest number
  148. being a multiplication of 10. */
  149. m_update_check_random_delta = (op_rand() % (2 * DELTA_PERIOD_MINUTES - DELTA_RESOLUTION_MINUTES + 1)) - DELTA_PERIOD_MINUTES; // In minutes.
  150. // Rounding.
  151. m_update_check_random_delta += m_update_check_random_delta > 0 ? (DELTA_RESOLUTION_MINUTES - 1) : -(DELTA_RESOLUTION_MINUTES - 1);
  152. m_update_check_random_delta = m_update_check_random_delta / DELTA_RESOLUTION_MINUTES * DELTA_RESOLUTION_MINUTES;
  153. m_update_check_random_delta = m_update_check_random_delta == 0 ? DELTA_RESOLUTION_MINUTES : m_update_check_random_delta;
  154. m_update_check_random_delta *= 60; // In seconds.
  155. m_update_check_interval = g_pcui->GetIntegerPref(PrefsCollectionUI::UpdateCheckInterval);
  156. m_update_check_delay = g_pcui->GetIntegerPref(PrefsCollectionUI::DelayedUpdateCheckInterval);
  157. // Allow the version object to read the faked version from the autoupdate.ini file, should there be one.
  158. // This helps testing the autoupdate.
  159. m_opera_version.AllowAutoupdateIniOverride();
  160. if ( (m_update_state < AUSUpToDate) || (m_update_state > AUSError) )
  161. {
  162. // Force up to date state
  163. RETURN_IF_ERROR(SetUpdateState(AUSUpToDate));
  164. }
  165. OpAutoPtr<AutoUpdateXML> autoupdate_xml_guard(OP_NEW(AutoUpdateXML, ()));
  166. RETURN_OOM_IF_NULL(autoupdate_xml_guard.get());
  167. RETURN_IF_ERROR(autoupdate_xml_guard->Init());
  168. OpAutoPtr<AutoUpdateServerURL> autoupdate_server_url_guard(OP_NEW(AutoUpdateServerURL, ()));
  169. RETURN_OOM_IF_NULL(autoupdate_server_url_guard.get());
  170. RETURN_IF_ERROR(autoupdate_server_url_guard->Init());
  171. OpAutoPtr<StatusXMLDownloader> xml_downloader_guard(OP_NEW(StatusXMLDownloader, ()));
  172. RETURN_OOM_IF_NULL(xml_downloader_guard.get());
  173. RETURN_IF_ERROR(xml_downloader_guard->Init(StatusXMLDownloader::CheckTypeUpdate, this));
  174. m_autoupdate_xml = autoupdate_xml_guard.release();
  175. m_autoupdate_server_url = autoupdate_server_url_guard.release();
  176. m_xml_downloader = xml_downloader_guard.release();
  177. return OpStatus::OK;
  178. }
  179. OP_STATUS AutoUpdater::WritePref(PrefsCollectionUI::integerpref which, int val)
  180. {
  181. TRAPD(st, g_pcui->WriteIntegerL(which, val));
  182. RETURN_IF_ERROR(st);
  183. TRAP(st, g_prefsManager->CommitL());
  184. return st;
  185. }
  186. OP_STATUS AutoUpdater::Activate()
  187. {
  188. OP_ASSERT(m_xml_downloader);
  189. if(m_activated)
  190. {
  191. Console::WriteError(UNI_L("AutoUpdate already activated."));
  192. return OpStatus::ERR_NOT_SUPPORTED;
  193. }
  194. m_activated = TRUE;
  195. if (m_level_of_automation < NoChecking || m_level_of_automation > AutoInstallUpdates)
  196. return OpStatus::OK;
  197. // If the user is interested in updates or update notifications, get on with that.
  198. switch(m_update_state)
  199. {
  200. case AUSChecking:
  201. {
  202. // Opera probably exited or crashed while checking
  203. // Set initial state, and schedule new update check.
  204. break;
  205. }
  206. case AUSDownloading:
  207. {
  208. // Opera probably exited or crashed while downloading. If the last check was done less than 1 day ago,
  209. // try parsing the autoupdate xml we already downloaded, if not, schedule another check
  210. if(g_timecache->CurrentTime() - m_time_of_last_update_check < AUTOUPDATE_RECHECK_TIMEOUT_SEC)
  211. {
  212. // This method is to only be run once after the object has been created, expect the XML downloader
  213. // to not exist yet.
  214. SetUpdateState(AUSChecking);
  215. StatusXMLDownloader::DownloadStatus status = m_xml_downloader->ParseDownloadedXML();
  216. if(status == StatusXMLDownloader::SUCCESS)
  217. {
  218. StatusXMLDownloaded(m_xml_downloader);
  219. return OpStatus::OK;
  220. }
  221. }
  222. break;
  223. }
  224. case AUSReadyToInstall:
  225. {
  226. // Illegal state when activated
  227. // Set initial state, and schedule new check
  228. break;
  229. }
  230. case AUSError:
  231. case AUSUpToDate:
  232. case AUSUpdating:
  233. case AUSUnpacking:
  234. case AUSReadyToUpdate:
  235. case AUSUpdateAvailable:
  236. case AUSErrorDownloading:
  237. break;
  238. default:
  239. OP_ASSERT(!"What about this state?");
  240. break;
  241. }
  242. SetUpdateState(AUSUpToDate);
  243. OP_STATUS ret = OpStatus::OK;
  244. if (m_autoupdate_xml->NeedsResourceCheck())
  245. {
  246. // DSK-336588
  247. // If any of the resource timestamps are set to 0, we need to trigger a resource check NOW.
  248. // The browserjs timestamp will be set 0 to browser upgrade.
  249. ret = ScheduleResourceCheck();
  250. }
  251. else
  252. {
  253. // Schedule the next update check according to the schedule.
  254. ret = ScheduleUpdateCheck(ScheduleStartup);
  255. }
  256. if (OpStatus::IsSuccess(ret))
  257. Console::WriteMessage(UNI_L("The autoupdate mechanism activated."));
  258. else
  259. Console::WriteError(UNI_L("Failed to activate the autoupdate mechanism."));
  260. return ret;
  261. }
  262. OP_STATUS AutoUpdater::CheckAndUpdateState()
  263. {
  264. switch(m_update_state)
  265. {
  266. case AUSUpToDate:
  267. {
  268. BroadcastOnUpToDate(IsSilent());
  269. Console::WriteMessage(UNI_L("Up to date."));
  270. Reset();
  271. return ScheduleUpdateCheck(ScheduleRunning);
  272. }
  273. case AUSChecking:
  274. {
  275. BroadcastOnChecking(IsSilent());
  276. Console::WriteMessage(UNI_L("Checking for updates..."));
  277. break;
  278. }
  279. case AUSDownloading:
  280. {
  281. UpdatableResource::UpdatableResourceType update_type = GetAvailableUpdateType();
  282. OpFileLength total_size = GetTotalUpdateSize();
  283. BroadcastOnDownloading(update_type, total_size, 0, 0.0, 0, IsSilent());
  284. Console::WriteMessage(UNI_L("Downloading updates..."));
  285. break;
  286. }
  287. case AUSReadyToUpdate:
  288. {
  289. BroadcastOnReadyToUpdate();
  290. Console::WriteMessage(UNI_L("Ready to update."));
  291. if(m_level_of_automation > NoChecking || !IsSilent())
  292. {
  293. /** Update all resources */
  294. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  295. StartUpdate(TRUE);
  296. #else
  297. StartUpdate(FALSE);
  298. #endif
  299. } else if(m_level_of_automation == NoChecking)
  300. {
  301. /** Only update spoof and browerjs file when in NoChecking mode. */
  302. StartUpdate(FALSE);
  303. }
  304. break;
  305. }
  306. case AUSUpdating:
  307. {
  308. BroadcastOnUpdating();
  309. Console::WriteMessage(UNI_L("Updating..."));
  310. break;
  311. }
  312. case AUSUnpacking:
  313. {
  314. BroadcastOnUnpacking();
  315. Console::WriteMessage(UNI_L("Extracting from downloaded package..."));
  316. break;
  317. }
  318. case AUSReadyToInstall:
  319. {
  320. Console::WriteMessage(UNI_L("Ready to install new version."));
  321. // Call listener
  322. OpString version;
  323. GetAvailablePackageInfo(&version, NULL, NULL);
  324. BroadcastOnReadyToInstallNewVersion(version, IsSilent());
  325. break;
  326. }
  327. case AUSError:
  328. {
  329. // Call listener
  330. BroadcastOnError(m_last_error, IsSilent());
  331. if(m_last_error < (int)ARRAY_SIZE(autoupdate_error_strings))
  332. {
  333. Console::WriteError(autoupdate_error_strings[m_last_error]);
  334. }
  335. // Set initial state
  336. SetUpdateState(AUSUpToDate);
  337. Reset();
  338. // Schedule new update check
  339. return ScheduleUpdateCheck(ScheduleRunning);
  340. }
  341. case AUSErrorDownloading:
  342. {
  343. // Call listener
  344. BroadcastOnDownloadingFailed(IsSilent());
  345. Console::WriteError(UNI_L("Downloading update failed."));
  346. // Increase the time to next update check
  347. IncreaseDelayedUpdateCheckInterval();
  348. // Schedule new download
  349. if(IsSilent())
  350. {
  351. // Go back to up to date state
  352. SetUpdateState(AUSUpToDate);
  353. CheckAndUpdateState();
  354. }
  355. else
  356. {
  357. m_silent_update = TRUE;
  358. SetUpdateState(AUSUpdateAvailable);
  359. //CheckAndUpdateState();
  360. }
  361. break;
  362. }
  363. case AUSUpdateAvailable:
  364. {
  365. Console::WriteMessage(UNI_L("An update is available."));
  366. // Call listener
  367. OpString info_url;
  368. OpFileLength size = 0;
  369. GetAvailablePackageInfo(NULL, &info_url, &size);
  370. UpdatableResource::UpdatableResourceType update_type = GetAvailableUpdateType();
  371. BroadcastOnUpdateAvailable(update_type, size, info_url.CStr(), IsSilent());
  372. BOOL has_package = update_type & UpdatableResource::RTPackage;
  373. if(!has_package)
  374. {
  375. // Update is silent if we dont have a package
  376. m_silent_update = TRUE;
  377. }
  378. if(IsSilent())
  379. {
  380. switch(m_level_of_automation)
  381. {
  382. case NoChecking:
  383. {
  384. /** Only download spoof and browerjs file when in NoChecking mode. */
  385. DownloadUpdate(FALSE);
  386. break;
  387. }
  388. case CheckForUpdates:
  389. {
  390. /** If there is no package, continue updating other resources */
  391. DownloadUpdate(FALSE);
  392. break;
  393. }
  394. case AutoInstallUpdates:
  395. {
  396. /** Get on with downloading the update */
  397. DownloadUpdate(TRUE);
  398. break;
  399. }
  400. }
  401. }
  402. break;
  403. }
  404. default:
  405. {
  406. OP_ASSERT(!"Should never reach this.");
  407. }
  408. }
  409. return OpStatus::OK;
  410. }
  411. OP_STATUS AutoUpdater::CheckForUpdate()
  412. {
  413. if (m_update_state == AUSUpToDate || m_update_state == AUSUpdateAvailable)
  414. {
  415. m_silent_update = FALSE;
  416. return DownloadStatusXML();
  417. }
  418. else
  419. {
  420. BroadcastOnError(AUInProgressError, IsSilent());
  421. return OpStatus::OK;
  422. }
  423. }
  424. UpdatableResource::UpdatableResourceType AutoUpdater::GetAvailableUpdateType() const
  425. {
  426. OP_ASSERT(m_xml_downloader);
  427. int res_type = 0;
  428. UpdatableResource* dl_elm = m_xml_downloader->GetFirstResource();
  429. while (dl_elm)
  430. {
  431. int cur_type = dl_elm->GetType();
  432. res_type |= cur_type;
  433. dl_elm = m_xml_downloader->GetNextResource();
  434. }
  435. return static_cast<UpdatableResource::UpdatableResourceType>(res_type);
  436. }
  437. BOOL AutoUpdater::GetAvailablePackageInfo(OpString* version, OpString* info_url, OpFileLength* size) const
  438. {
  439. OP_ASSERT(m_xml_downloader);
  440. UpdatableResource* dl_elm = m_xml_downloader->GetFirstResource();
  441. while (dl_elm)
  442. {
  443. if(dl_elm->GetType() == UpdatableResource::RTPackage)
  444. {
  445. UpdatablePackage* up = static_cast<UpdatablePackage*>(dl_elm);
  446. if(version)
  447. RETURN_VALUE_IF_ERROR(up->GetAttrValue(URA_VERSION, *version), FALSE);
  448. if(info_url)
  449. RETURN_VALUE_IF_ERROR(up->GetAttrValue(URA_INFOURL, *info_url), FALSE);
  450. if(size)
  451. {
  452. int size_int;
  453. RETURN_VALUE_IF_ERROR(up->GetAttrValue(URA_SIZE, size_int), FALSE);
  454. *size = size_int;
  455. }
  456. return TRUE;
  457. }
  458. dl_elm = m_xml_downloader->GetNextResource();
  459. }
  460. return FALSE;
  461. }
  462. OpFileLength AutoUpdater::GetTotalUpdateSize() const
  463. {
  464. OP_ASSERT(m_xml_downloader);
  465. OpFileLength size = 0;
  466. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  467. while (resource)
  468. {
  469. int size_int;
  470. if (OpStatus::IsSuccess(resource->GetAttrValue(URA_SIZE, size_int)))
  471. size += size_int;
  472. resource = m_xml_downloader->GetNextResource();
  473. }
  474. return size;
  475. }
  476. void AutoUpdater::StatusXMLDownloaded(StatusXMLDownloader* downloader)
  477. {
  478. OP_ASSERT(m_autoupdate_xml);
  479. OP_ASSERT(downloader);
  480. OP_ASSERT(downloader == m_xml_downloader);
  481. OP_ASSERT(m_update_state == AUSChecking);
  482. // Better safe than sorry
  483. if (NULL == downloader)
  484. return;
  485. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  486. DeleteUpgradeFolderIfNeeded();
  487. #endif
  488. // Success for a response from the Autoupdate server so set the flag to say we have
  489. // spoken to this server at least once. Used for stats to detect first runs and upgrades
  490. TRAPD(err, g_pcui->WriteIntegerL(PrefsCollectionUI::AutoUpdateResponded, 1));
  491. // On a successful check, set delayed update check interval back to default
  492. m_update_check_delay = 0;
  493. TRAP(err, g_pcui->WriteIntegerL(PrefsCollectionUI::DelayedUpdateCheckInterval, 0));
  494. TRAP(err, g_prefsManager->CommitL());
  495. // Not much we can do about it now anyway
  496. OpStatus::Ignore(err);
  497. // Check if the server is increasing the update check interval.
  498. // In that case, dont download any packages, to avoid overloading the server
  499. BOOL increased_update_check_interval = FALSE;
  500. UpdatableResource* current_resource = m_xml_downloader->GetFirstResource();
  501. UpdatablePackage* package = NULL;
  502. while (current_resource)
  503. {
  504. UpdatableResource::UpdatableResourceType type = current_resource->GetType();
  505. switch(type)
  506. {
  507. case UpdatableResource::RTSetting:
  508. {
  509. UpdatableSetting* setting = static_cast<UpdatableSetting*>(current_resource);
  510. if (setting->IsUpdateCheckInterval())
  511. {
  512. int new_interval = 0;
  513. if (OpStatus::IsSuccess(setting->GetAttrValue(URA_DATA, new_interval)))
  514. {
  515. if (new_interval > m_update_check_interval)
  516. if(m_check_increased_update_check_interval)
  517. increased_update_check_interval = TRUE;
  518. // we could just wait for PrefsChanged, but it won't be called if operaprefs.ini
  519. // is read-only
  520. m_update_check_interval = new_interval;
  521. // PrefsCollectionUI::UpdateCheckInterval will be updated by UpdateResource
  522. }
  523. }
  524. if (!(setting->CheckResource() && OpStatus::IsSuccess(setting->UpdateResource())))
  525. OP_ASSERT(!"Could not update setting resource!");
  526. m_xml_downloader->RemoveResource(current_resource);
  527. OP_DELETE(current_resource);
  528. current_resource = NULL;
  529. }
  530. break;
  531. case UpdatableResource::RTPackage:
  532. {
  533. if (package)
  534. OP_ASSERT(!"Got more than one package from the server!");
  535. package = static_cast<UpdatablePackage*>(current_resource);
  536. if(AutoInstallUpdates == m_level_of_automation && package->GetShowNotification())
  537. m_silent_update = FALSE;
  538. }
  539. break;
  540. case UpdatableResource::RTPatch:
  541. // Do we know what to do with a patch? Carry on anyway.
  542. OP_ASSERT(!"A patch...?!");
  543. case UpdatableResource::RTSpoofFile:
  544. case UpdatableResource::RTBrowserJSFile:
  545. case UpdatableResource::RTDictionary:
  546. case UpdatableResource::RTHardwareBlocklist:
  547. case UpdatableResource::RTHandlersIgnore:
  548. // A dictionary may be updated with a regular autoupdate check.
  549. // Carry on
  550. break;
  551. case UpdatableResource::RTPlugin:
  552. // We don't expect any plugins with an update check.
  553. OP_ASSERT(!"Didn't expect a plugin with autoupdate check!");
  554. m_xml_downloader->RemoveResource(current_resource);
  555. OP_DELETE(current_resource);
  556. current_resource = NULL;
  557. break;
  558. default:
  559. OP_ASSERT(!"Uknown resource type");
  560. break;
  561. }
  562. current_resource = m_xml_downloader->GetNextResource();
  563. }
  564. if (package)
  565. {
  566. if ((NoChecking == m_level_of_automation && IsSilent()) || increased_update_check_interval)
  567. {
  568. if(!increased_update_check_interval)
  569. Console::WriteError(UNI_L("Did not expect package from server with current autoupdate level."));
  570. else
  571. Console::WriteMessage(UNI_L("Increased update check interval."));
  572. m_xml_downloader->RemoveResource(package);
  573. OP_DELETE(package);
  574. package = NULL;
  575. }
  576. }
  577. if (m_xml_downloader->GetResourceCount() > 0)
  578. {
  579. // Server returned some resources
  580. UpdatableResource::UpdatableResourceType update_type = GetAvailableUpdateType();
  581. if (CheckForUpdates == m_level_of_automation && (update_type & UpdatableResource::RTPackage))
  582. m_silent_update = FALSE;
  583. SetUpdateState(AUSUpdateAvailable);
  584. }
  585. else
  586. SetUpdateState(AUSUpToDate);
  587. CheckAndUpdateState();
  588. }
  589. void AutoUpdater::StatusXMLDownloadFailed(StatusXMLDownloader* downloader, StatusXMLDownloader::DownloadStatus status)
  590. {
  591. OP_ASSERT(m_autoupdate_xml);
  592. OP_ASSERT(downloader);
  593. OP_ASSERT(downloader == m_xml_downloader);
  594. OP_ASSERT(m_update_state == AUSChecking);
  595. AutoUpdateError error = AUInternalError;
  596. switch(status)
  597. {
  598. case StatusXMLDownloader::NO_TRANSFERITEM:
  599. case StatusXMLDownloader::NO_URL:
  600. case StatusXMLDownloader::LOAD_FAILED:
  601. case StatusXMLDownloader::DOWNLOAD_FAILED:
  602. case StatusXMLDownloader::DOWNLOAD_ABORTED:
  603. {
  604. error = AUConnectionError;
  605. break;
  606. }
  607. case StatusXMLDownloader::PARSE_ERROR:
  608. case StatusXMLDownloader::WRONG_XML:
  609. {
  610. error = AUValidationError;
  611. break;
  612. }
  613. }
  614. // Increase delayed update check interval when the request fails.
  615. if(error == AUConnectionError)
  616. {
  617. // Go through the server list
  618. OP_ASSERT(m_autoupdate_server_url);
  619. if (OpStatus::IsSuccess(m_autoupdate_server_url->IncrementURLNo(AutoUpdateServerURL::NoWrap)))
  620. {
  621. // There is more servers to check so increment to the next server and check right away
  622. RETURN_VOID_IF_ERROR(SetUpdateState(AUSUpToDate));
  623. RETURN_VOID_IF_ERROR(DownloadStatusXML());
  624. }
  625. else
  626. {
  627. // Last server in the list so reset back to the start and set a delayed called
  628. RETURN_VOID_IF_ERROR(m_autoupdate_server_url->ResetURLNo());
  629. IncreaseDelayedUpdateCheckInterval();
  630. }
  631. }
  632. SetLastError(error);
  633. SetUpdateState(AUSError);
  634. CheckAndUpdateState();
  635. }
  636. void AutoUpdater::PrefChanged(OpPrefsCollection::Collections id, int pref, int newvalue)
  637. {
  638. if (id == OpPrefsCollection::UI)
  639. {
  640. switch (pref)
  641. {
  642. case PrefsCollectionUI::TimeOfLastUpdateCheck:
  643. m_time_of_last_update_check = static_cast<time_t>(newvalue);
  644. break;
  645. case PrefsCollectionUI::UpdateCheckInterval:
  646. m_update_check_interval = newvalue;
  647. break;
  648. case PrefsCollectionUI::DelayedUpdateCheckInterval:
  649. m_update_check_delay = newvalue;
  650. break;
  651. default:
  652. break;
  653. }
  654. }
  655. }
  656. void AutoUpdater::OnFileDownloadDone(FileDownloader* file_downloader, OpFileLength total_size)
  657. {
  658. OP_ASSERT(m_update_state == AUSDownloading);
  659. UpdatableFile* file = static_cast<UpdatableFile*>(file_downloader);
  660. if (file)
  661. {
  662. UpdatableResource::UpdatableResourceType type = file->GetType();
  663. OpString target_filename;
  664. file->GetTargetFilename(target_filename);
  665. BroadcastOnDownloadingDone(type, target_filename, total_size, IsSilent());
  666. }
  667. OP_STATUS ret = StartNextDownload(file_downloader);
  668. if (OpStatus::IsSuccess(ret))
  669. return;
  670. // Last file
  671. if (ret == OpStatus::ERR_NO_SUCH_RESOURCE)
  672. {
  673. // All files are downloaded, check all
  674. SetUpdateState(AUSReadyToUpdate);
  675. CheckAndUpdateState();
  676. }
  677. else
  678. {
  679. // One or more file downloads failed
  680. SetLastError(AUConnectionError);
  681. SetUpdateState(AUSErrorDownloading);
  682. CheckAndUpdateState();
  683. }
  684. }
  685. void AutoUpdater::OnFileDownloadFailed(FileDownloader* file_downloader)
  686. {
  687. OP_ASSERT(m_update_state == AUSDownloading);
  688. // Set error downloading state
  689. SetLastError(AUConnectionError);
  690. SetUpdateState(AUSErrorDownloading);
  691. CheckAndUpdateState();
  692. }
  693. void AutoUpdater::OnFileDownloadAborted(FileDownloader* file_downloader)
  694. {
  695. }
  696. void AutoUpdater::OnFileDownloadProgress(FileDownloader* file_downloader, OpFileLength total_size, OpFileLength downloaded_size, double kbps, unsigned long time_estimate)
  697. {
  698. OP_ASSERT(m_update_state == AUSDownloading);
  699. UpdatableFile* file = static_cast<UpdatableFile*>(file_downloader);
  700. UpdatableResource::UpdatableResourceType type = UpdatableResource::RTEmpty;
  701. if(file)
  702. {
  703. type = file->GetType();
  704. }
  705. BroadcastOnDownloading(type, total_size, downloaded_size, kbps, time_estimate, IsSilent());
  706. }
  707. void AutoUpdater::DeferUpdate()
  708. {
  709. // Destroy the retry download timer if we have one.
  710. if(m_download_timer)
  711. {
  712. OP_DELETE(m_download_timer);
  713. m_download_timer = NULL;
  714. }
  715. switch(m_update_state)
  716. {
  717. case AUSUpdateAvailable:
  718. {
  719. break;
  720. }
  721. case AUSDownloading:
  722. {
  723. StopDownloads();
  724. SetUpdateState(AUSUpdateAvailable);
  725. //CheckAndUpdateState();
  726. break;
  727. }
  728. default:
  729. {
  730. m_silent_update = TRUE;
  731. SetUpdateState(AUSUpToDate);
  732. CheckAndUpdateState();
  733. }
  734. }
  735. TRAPD(err, g_pcui->WriteIntegerL(PrefsCollectionUI::BrowserJSTime, 0));
  736. OpStatus::Ignore(ScheduleResourceCheck());
  737. }
  738. OP_STATUS AutoUpdater::DownloadUpdate()
  739. {
  740. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  741. m_silent_update = FALSE;
  742. m_download_retries++;
  743. return DownloadUpdate(TRUE);
  744. #else
  745. m_silent_update = TRUE;
  746. m_download_retries++;
  747. return DownloadUpdate(FALSE);
  748. #endif
  749. }
  750. OP_STATUS AutoUpdater::GetDownloadPageURL(OpString& url)
  751. {
  752. OP_ASSERT(m_xml_downloader);
  753. return m_xml_downloader->GetDownloadURL(url);
  754. }
  755. OP_STATUS AutoUpdater::DownloadUpdate(BOOL include_resources_requiring_restart)
  756. {
  757. OP_ASSERT(m_xml_downloader);
  758. if(m_update_state != AUSUpdateAvailable && m_update_state != AUSErrorDownloading)
  759. {
  760. BroadcastOnError(AUInternalError, IsSilent());
  761. return OpStatus::ERR;
  762. }
  763. m_include_resources_requiring_restart = include_resources_requiring_restart;
  764. // Destroy the retry download timer if we have one.
  765. if(m_download_timer)
  766. {
  767. OP_DELETE(m_download_timer);
  768. m_download_timer = NULL;
  769. }
  770. OP_STATUS ret = StartNextDownload(NULL);
  771. if(OpStatus::IsSuccess(ret))
  772. {
  773. SetUpdateState(AUSDownloading);
  774. CheckAndUpdateState();
  775. }
  776. else
  777. {
  778. if(ret == OpStatus::ERR_NO_SUCH_RESOURCE)
  779. {
  780. // No files to download, but continue updating other resources
  781. SetUpdateState(AUSReadyToUpdate);
  782. CheckAndUpdateState();
  783. }
  784. else
  785. {
  786. StopDownloads();
  787. SetLastError(AUConnectionError);
  788. SetUpdateState(AUSErrorDownloading);
  789. CheckAndUpdateState();
  790. }
  791. }
  792. return OpStatus::OK;
  793. }
  794. OP_STATUS AutoUpdater::StartNextDownload(FileDownloader* previous_download)
  795. {
  796. OP_ASSERT(m_xml_downloader);
  797. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  798. BOOL found_previous_download = previous_download == NULL ? TRUE : FALSE;
  799. for(; resource; resource = m_xml_downloader->GetNextResource())
  800. {
  801. if ( resource->GetResourceClass() == UpdatableResource::File
  802. && (m_include_resources_requiring_restart || !resource->UpdateRequiresRestart()))
  803. {
  804. UpdatableFile* file = static_cast<UpdatableFile*>(resource);
  805. // Start with the first download after previous_download
  806. if(!found_previous_download)
  807. {
  808. if(file == previous_download)
  809. {
  810. found_previous_download = TRUE;
  811. }
  812. }
  813. else
  814. {
  815. return file->StartDownloading(this);
  816. }
  817. }
  818. }
  819. return OpStatus::ERR_NO_SUCH_RESOURCE;
  820. }
  821. OP_STATUS AutoUpdater::StopDownloads()
  822. {
  823. OP_ASSERT(m_xml_downloader);
  824. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  825. while(resource)
  826. {
  827. if(resource->GetResourceClass() == UpdatableResource::File)
  828. {
  829. UpdatableFile* file = static_cast<UpdatableFile*>(resource);
  830. file->StopDownload();
  831. }
  832. resource = m_xml_downloader->GetNextResource();
  833. }
  834. return OpStatus::OK;
  835. }
  836. OP_STATUS AutoUpdater::StartUpdate(BOOL include_resources_requiring_restart)
  837. {
  838. OP_ASSERT(m_xml_downloader);
  839. OP_ASSERT(m_update_state == AUSReadyToUpdate);
  840. if(m_update_state != AUSReadyToUpdate)
  841. {
  842. BroadcastOnError(AUInternalError, IsSilent());
  843. return OpStatus::ERR;
  844. }
  845. SetUpdateState(AUSUpdating);
  846. CheckAndUpdateState(); // broadcast updating state
  847. BOOL call_ready_to_install = FALSE;
  848. BOOL waiting_for_unpacking = FALSE;
  849. BOOL update_error = FALSE;
  850. UpdatableResource* dl_elm = m_xml_downloader->GetFirstResource();
  851. for (; dl_elm; dl_elm = m_xml_downloader->GetNextResource())
  852. {
  853. if ( include_resources_requiring_restart
  854. || !dl_elm->UpdateRequiresRestart())
  855. {
  856. if(dl_elm->CheckResource())
  857. {
  858. if(OpStatus::IsSuccess(dl_elm->UpdateResource()))
  859. {
  860. if(dl_elm->UpdateRequiresUnpacking())
  861. {
  862. waiting_for_unpacking = TRUE;
  863. g_main_message_handler->SetCallBack(this, MSG_AUTOUPDATE_UNPACKING_COMPLETE, 0);
  864. }
  865. if(dl_elm->UpdateRequiresRestart())
  866. {
  867. call_ready_to_install = TRUE;
  868. }
  869. OpString message;
  870. message.AppendFormat(UNI_L("Updated %s resource."), dl_elm->GetResourceName());
  871. Console::WriteMessage(message.CStr());
  872. }
  873. else
  874. {
  875. OpString error;
  876. error.AppendFormat(UNI_L("Failed to update %s resource."), dl_elm->GetResourceName());
  877. Console::WriteError(error.CStr());
  878. SetLastError(AUUpdateError);
  879. if(dl_elm->UpdateRequiresRestart())
  880. {
  881. update_error = TRUE;
  882. }
  883. }
  884. }
  885. else
  886. {
  887. OpString error;
  888. error.AppendFormat(UNI_L("Resource check failed for %s resource."), dl_elm->GetResourceName());
  889. Console::WriteError(error.CStr());
  890. SetLastError(AUValidationError);
  891. if(dl_elm->UpdateRequiresRestart())
  892. {
  893. update_error = TRUE;
  894. }
  895. }
  896. }
  897. }
  898. // Clean up resources
  899. OpStatus::Ignore(CleanupAllResources());
  900. if (waiting_for_unpacking)
  901. {
  902. SetUpdateState(AUSUnpacking);
  903. if(call_ready_to_install)
  904. m_state_after_unpacking = AUSReadyToInstall;
  905. else if(update_error)
  906. m_state_after_unpacking = AUSUpdateAvailable;
  907. else
  908. m_state_after_unpacking = AUSUpToDate;
  909. }
  910. else if(call_ready_to_install)
  911. {
  912. SetUpdateState(AUSReadyToInstall);
  913. }
  914. else if(update_error)
  915. {
  916. BroadcastOnError(m_last_error, IsSilent());
  917. SetUpdateState(AUSUpdateAvailable);
  918. return OpStatus::ERR;
  919. }
  920. else
  921. {
  922. BroadcastOnFinishedUpdating();
  923. SetUpdateState(AUSUpToDate);
  924. }
  925. CheckAndUpdateState();
  926. return OpStatus::OK;
  927. }
  928. void AutoUpdater::HandleCallback(OpMessage msg, MH_PARAM_1 par1, MH_PARAM_2 par2)
  929. {
  930. if (msg == MSG_AUTOUPDATE_UNPACKING_COMPLETE)
  931. {
  932. g_main_message_handler->UnsetCallBack(this, MSG_AUTOUPDATE_UNPACKING_COMPLETE);
  933. if (m_state_after_unpacking == AUSUpdateAvailable)
  934. {
  935. BroadcastOnError(m_last_error, IsSilent());
  936. }
  937. else if (m_state_after_unpacking == AUSUpToDate)
  938. {
  939. BroadcastOnFinishedUpdating();
  940. }
  941. SetUpdateState(m_state_after_unpacking);
  942. CheckAndUpdateState();
  943. }
  944. }
  945. OP_STATUS AutoUpdater::CleanupAllResources()
  946. {
  947. OP_ASSERT(m_xml_downloader);
  948. OP_STATUS ret = OpStatus::OK;
  949. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  950. while (resource)
  951. {
  952. ret |= resource->Cleanup();
  953. resource = m_xml_downloader->GetNextResource();
  954. }
  955. return ret;
  956. }
  957. void AutoUpdater::OnTimeOut(OpTimer *timer)
  958. {
  959. if (timer == m_download_timer)
  960. {
  961. m_download_countdown--;
  962. if(m_download_countdown > 0)
  963. {
  964. m_download_timer->Start(1000);
  965. BroadcastOnRestartingDownload(m_download_countdown, m_last_error, IsSilent());
  966. }
  967. else
  968. {
  969. OP_DELETE(m_download_timer);
  970. m_download_timer = NULL;
  971. m_download_retries++;
  972. DownloadUpdate(TRUE);
  973. }
  974. return;
  975. }
  976. if (timer == m_update_check_timer)
  977. {
  978. if(!g_ssl_auto_updaters->Active())
  979. {
  980. OP_DELETE(m_update_check_timer);
  981. m_update_check_timer = NULL;
  982. m_silent_update = TRUE;
  983. RETURN_VOID_IF_ERROR(DownloadStatusXML());
  984. }
  985. else
  986. {
  987. // If the SSL auto update is active, schedule auto update check later
  988. m_update_check_timer->Start(AUTOUPDATE_SSL_UPDATERS_BUSY_RECHECK_TIMEOUT_SEC * 1000);
  989. }
  990. return;
  991. }
  992. #ifndef _MACINTOSH_
  993. if (timer == m_checker_launch_retry_timer)
  994. {
  995. TryRunningChecker();
  996. return;
  997. }
  998. #endif // _MACINTOSH_
  999. OP_ASSERT("Unknown timer!");
  1000. }
  1001. void AutoUpdater::GetDownloadStatus(INT32* total_file_count, INT32* downloaded_file_count, INT32* failed_download_count)
  1002. {
  1003. OP_ASSERT(m_xml_downloader);
  1004. if(total_file_count)
  1005. *total_file_count = 0;
  1006. if(downloaded_file_count)
  1007. *downloaded_file_count = 0;
  1008. if(failed_download_count)
  1009. *failed_download_count = 0;
  1010. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  1011. while (resource)
  1012. {
  1013. if(resource->GetResourceClass() == UpdatableResource::File)
  1014. {
  1015. UpdatableFile* file = static_cast<UpdatableFile*>(resource);
  1016. if(file->DownloadStarted())
  1017. {
  1018. if(downloaded_file_count && file->Downloaded())
  1019. {
  1020. (*downloaded_file_count)++;
  1021. }
  1022. if(failed_download_count && file->DownloadFailed())
  1023. {
  1024. (*failed_download_count)++;
  1025. }
  1026. if(total_file_count)
  1027. {
  1028. (*total_file_count)++;
  1029. }
  1030. }
  1031. }
  1032. resource = m_xml_downloader->GetNextResource();
  1033. }
  1034. }
  1035. BOOL AutoUpdater::CheckAllResources()
  1036. {
  1037. OP_ASSERT(m_xml_downloader);
  1038. UpdatableResource* resource = m_xml_downloader->GetFirstResource();
  1039. int resource_checked_count = 0;
  1040. while (resource)
  1041. {
  1042. if(!resource->CheckResource())
  1043. {
  1044. OpString error;
  1045. error.AppendFormat(UNI_L("Resource check failed for %s resource."), resource->GetResourceName());
  1046. Console::WriteError(error.CStr());
  1047. return FALSE;
  1048. }
  1049. resource_checked_count++;
  1050. resource = m_xml_downloader->GetNextResource();
  1051. }
  1052. return (resource_checked_count > 0) ? TRUE : FALSE;
  1053. }
  1054. #ifndef _MACINTOSH_
  1055. namespace
  1056. {
  1057. BOOL LaunchTheChecker(const uni_char* path, int channel_id)
  1058. {
  1059. const int argc = 18;
  1060. char* argv[argc];
  1061. OperaVersion version;
  1062. version.AllowAutoupdateIniOverride();
  1063. OpString8 tmp_str;
  1064. tmp_str.Empty();
  1065. tmp_str.AppendFormat("%d.%02d.%04d", version.GetMajor(), version.GetMinor(), version.GetBuild());
  1066. argv[0] = op_strdup("-version");
  1067. argv[1] = op_strdup(tmp_str.CStr());
  1068. argv[2] = op_strdup("-host");
  1069. tmp_str.SetUTF8FromUTF16(g_pcui->GetStringPref(PrefsCollectionUI::AutoUpdateGeoServer));
  1070. argv[3] = op_strdup(tmp_str.CStr());
  1071. argv[4] = op_strdup("-firstrunver");
  1072. tmp_str.SetUTF8FromUTF16(g_pcui->GetStringPref(PrefsCollectionUI::FirstVersionRun));
  1073. argv[5] = op_strdup(tmp_str.CStr());
  1074. argv[6] = op_strdup("-firstrunts");
  1075. tmp_str.Empty();
  1076. tmp_str.AppendFormat("%d", g_pcui->GetIntegerPref(PrefsCollectionUI::FirstRunTimestamp));
  1077. argv[7] = op_strdup(tmp_str.CStr());
  1078. argv[8] = op_strdup("-loc");
  1079. tmp_str.Empty();
  1080. OpStringC user = g_pcui->GetStringPref(PrefsCollectionUI::CountryCode);
  1081. OpStringC detected = g_pcui->GetStringPref(PrefsCollectionUI::DetectedCountryCode);
  1082. OpString tmp_loc;
  1083. tmp_loc.AppendFormat("%s;%s;%s;%s", user.HasContent() ? user.CStr() : UNI_L("empty"),
  1084. detected.HasContent() ? detected.CStr() : UNI_L("empty"),
  1085. g_region_info->m_country.HasContent() ? g_region_info->m_country.CStr() : UNI_L("empty"),
  1086. g_region_info->m_region.HasContent() ? g_region_info->m_region.CStr() : UNI_L("empty"));
  1087. tmp_str.SetUTF8FromUTF16(tmp_loc.CStr());
  1088. argv[9] = op_strdup(tmp_str.CStr());
  1089. argv[10] = op_strdup("-lang");
  1090. tmp_str.SetUTF8FromUTF16(g_languageManager->GetLanguage().CStr());
  1091. argv[11] = op_strdup(tmp_str.CStr());
  1092. argv[12] = op_strdup("-pipeid");
  1093. tmp_str.Empty();
  1094. tmp_str.AppendFormat("%d", channel_id);
  1095. argv[13] = op_strdup(tmp_str.CStr());
  1096. argv[14] = op_strdup("-producttype");
  1097. #ifdef _DEBUG
  1098. argv[15] = op_strdup("Debug");
  1099. #else
  1100. switch (g_desktop_product->GetProductType())
  1101. {
  1102. case PRODUCT_TYPE_OPERA:
  1103. argv[15] = op_strdup(""); break;
  1104. case PRODUCT_TYPE_OPERA_NEXT:
  1105. argv[15] = op_strdup("Next"); break;
  1106. case PRODUCT_TYPE_OPERA_LABS:
  1107. argv[15] = op_strdup("Labs");break;
  1108. default:
  1109. argv[15] = op_strdup(""); break;
  1110. }
  1111. #endif // _DEBUG
  1112. /* Send path to SSL certificate file. This is irrelevant on platforms that
  1113. * use OpenSSL and supply the certificate file from memory. The standalone
  1114. * checkers on these platforms will ignore this argument. The checkers that
  1115. * rely only on CURL and need to supply the certificate in a file will
  1116. * expect a -certfile argument with the path. It should be:
  1117. * OPFILE_RESOURCES_FOLDER/cert.pem */
  1118. OpString cert_dir;
  1119. OP_STATUS status = g_folder_manager->GetFolderPath(OPFILE_RESOURCES_FOLDER, cert_dir);
  1120. OpString8 cert_file8;
  1121. if (OpStatus::IsSuccess(status))
  1122. {
  1123. OpString cert_file;
  1124. status += OpPathDirFileCombine(cert_file,
  1125. cert_dir,
  1126. OpStringC(UNI_L("cert.pem")));
  1127. status += cert_file8.SetUTF8FromUTF16(cert_file);
  1128. }
  1129. if (OpStatus::IsSuccess(status))
  1130. {
  1131. argv[16] = op_strdup("-certfile");
  1132. argv[17] = op_strdup(cert_file8.CStr());
  1133. }
  1134. else
  1135. {
  1136. argv[16] = NULL; // Likely an OOM in GetFolderPath or string operations
  1137. argv[17] = NULL; // This will fail the launch
  1138. }
  1139. BOOL valid = TRUE;
  1140. for (int i = 0; i < argc; ++i)
  1141. {
  1142. if (!argv[i])
  1143. {
  1144. valid = FALSE;
  1145. break;
  1146. }
  1147. }
  1148. if (valid)
  1149. valid = g_launch_manager->Launch(path, argc, argv);
  1150. for (int i = 0; i < argc; ++i)
  1151. op_free(argv[i]);
  1152. return valid;
  1153. }
  1154. }
  1155. OP_STATUS AutoUpdater::TryRunningChecker()
  1156. {
  1157. OP_STATUS status = OpStatus::OK;
  1158. OP_DELETE(m_checker_launch_retry_timer);
  1159. m_checker_launch_retry_timer = NULL;
  1160. m_checker_state = CheckerOk;
  1161. BOOL ok = LaunchTheChecker(m_checker_path.CStr(), m_channel_id);
  1162. if (!ok)
  1163. {
  1164. m_checker_state = CheckerCouldntLaunch;
  1165. if (++m_checker_launch_retry_count <= MAX_CHECKER_LAUNCH_RETRIES)
  1166. {
  1167. m_checker_launch_retry_timer = OP_NEW(OpTimer, ());
  1168. if (m_checker_launch_retry_timer)
  1169. {
  1170. m_checker_launch_retry_timer->SetTimerListener(this);
  1171. m_checker_launch_retry_timer->Start(CHECKER_LAUNCH_RETRY_TIME_MS);
  1172. }
  1173. else
  1174. {
  1175. m_checker_launch_retry_count = 0;
  1176. status = OpStatus::ERR_NO_MEMORY;
  1177. }
  1178. }
  1179. else // give up.
  1180. m_checker_launch_retry_count = 0;
  1181. }
  1182. else
  1183. {
  1184. m_checker_launch_retry_count = 0;
  1185. if (m_channel_to_checker)
  1186. m_channel_to_checker->Connect(25); // This is only so the updater is connected and it does not retry. We won't be using its results here.
  1187. }
  1188. SetUpdateState(m_update_state); // Force asving the state.
  1189. return status;
  1190. }
  1191. #endif // _MACINTOSH_
  1192. OP_STATUS AutoUpdater::DownloadStatusXML()
  1193. {
  1194. OP_ASSERT(m_xml_downloader);
  1195. OP_ASSERT(m_autoupdate_xml);
  1196. OP_ASSERT(m_update_state == AUSUpToDate || m_update_state == AUSUpdateAvailable);
  1197. #ifndef _MACINTOSH_
  1198. OP_ASSERT(m_checker_path.Length() > 0);
  1199. #endif // _MACINTOSH_
  1200. if (m_update_state != AUSUpToDate && m_update_state != AUSUpdateAvailable)
  1201. {
  1202. BroadcastOnError(AUInternalError, IsSilent());
  1203. return OpStatus::ERR_NOT_SUPPORTED;
  1204. }
  1205. if (m_resources_check_only)
  1206. Console::WriteMessage(UNI_L("Starting a resource check."));
  1207. else
  1208. Console::WriteMessage(UNI_L("Starting an update check."));
  1209. // Stop the update check timer, if we have one
  1210. OP_DELETE(m_update_check_timer);
  1211. m_update_check_timer = NULL;
  1212. SetUpdateState(AUSChecking);
  1213. CheckAndUpdateState();
  1214. AutoUpdateXML::AutoUpdateLevel autoupdate_level = AutoUpdateXML::UpdateLevelResourceCheck;
  1215. if (!m_resources_check_only)
  1216. {
  1217. if (m_level_of_automation > NoChecking || !IsSilent())
  1218. {
  1219. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  1220. if (!HasDownloadedNewerVersion())
  1221. #endif // AUTOUPDATE_PACKAGE_INSTALLATION
  1222. {
  1223. autoupdate_level = AutoUpdateXML::UpdateLevelDefaultCheck;
  1224. }
  1225. }
  1226. }
  1227. // In case of an error below, a new update check will be scheduled in CheckAndUpdateState().
  1228. // Scheduling an update sets m_resource_check_only to FALSE, so we don't have any retry
  1229. // mechanism for the initial resource check, but we schedule a full update check that
  1230. // will happen when the time comes. A new resource check will be attempted if needed on the
  1231. // next browser start.
  1232. // In case of no error here, we will schedule a new update check after the resource check is
  1233. // over, and that will also set m_resources_check_only to FALSE.
  1234. // However, because we prefer to be rather safe than sorry, we set it explicitly here, so that
  1235. // we don't get stuck in the resource-check-only state somehow.
  1236. m_resources_check_only = FALSE;
  1237. OpString url_string;
  1238. OpString8 xml;
  1239. OP_ASSERT(m_autoupdate_server_url);
  1240. if (OpStatus::IsError(m_autoupdate_server_url->GetCurrentURL(url_string)))
  1241. {
  1242. SetLastError(AUInternalError);
  1243. SetUpdateState(AUSError);
  1244. CheckAndUpdateState();
  1245. return OpStatus::ERR;
  1246. }
  1247. // No addition items are sent with an update request
  1248. m_autoupdate_xml->ClearRequestItems();
  1249. AutoUpdateXML::AutoUpdateLevel used_level;
  1250. if (OpStatus::IsError(m_autoupdate_xml->GetRequestXML(xml, autoupdate_level, AutoUpdateXML::RT_Main, &used_level)))
  1251. {
  1252. SetLastError(AUInternalError);
  1253. SetUpdateState(AUSError);
  1254. CheckAndUpdateState();
  1255. return OpStatus::ERR;
  1256. }
  1257. #ifndef _MACINTOSH_
  1258. // The checker needs to be run when launching Opera for the first time and every time the main update is asked for.
  1259. // It also has to be launched if there is no uuid stored yet.
  1260. BOOL run_checker =
  1261. (used_level == AutoUpdateXML::UpdateLevelDefaultCheck
  1262. || used_level == AutoUpdateXML::UpdateLevelUpgradeCheck
  1263. || g_run_type->m_type == StartupType::RUNTYPE_FIRST
  1264. || g_run_type->m_type == StartupType::RUNTYPE_FIRSTCLEAN
  1265. || g_run_type->m_type == StartupType::RUNTYPE_FIRST_NEW_BUILD_NUMBER)
  1266. && !m_user_initiated;
  1267. if (run_checker)
  1268. if (OpStatus::IsMemoryError(TryRunningChecker()))
  1269. {
  1270. SetLastError(AUInternalError);
  1271. SetUpdateState(AUSError);
  1272. CheckAndUpdateState();
  1273. return OpStatus::ERR_NO_MEMORY;
  1274. }
  1275. #endif // _MACINTOSH_
  1276. // Set time of last check
  1277. m_time_of_last_update_check = g_timecache->CurrentTime();
  1278. OP_STATUS st = WritePref(PrefsCollectionUI::TimeOfLastUpdateCheck, static_cast<int>(m_time_of_last_update_check));
  1279. if (OpStatus::IsError(st))
  1280. {
  1281. SetLastError(AUInternalError);
  1282. SetUpdateState(AUSError);
  1283. CheckAndUpdateState();
  1284. return OpStatus::ERR;
  1285. }
  1286. if (OpStatus::IsError(m_xml_downloader->StartXMLRequest(url_string, xml)))
  1287. {
  1288. m_xml_downloader->StopRequest();
  1289. SetLastError(AUConnectionError);
  1290. SetUpdateState(AUSError);
  1291. CheckAndUpdateState();
  1292. return OpStatus::ERR;
  1293. }
  1294. return OpStatus::OK;
  1295. }
  1296. OP_STATUS AutoUpdater::ScheduleResourceCheck()
  1297. {
  1298. if (AUSChecking == m_update_state)
  1299. {
  1300. // A check is already in progress.
  1301. // We hope to get the new resources along with the check.
  1302. // Ignore this request.
  1303. Console::WriteMessage(UNI_L("Ignoring resource check request."));
  1304. return OpStatus::ERR_NO_ACCESS;
  1305. }
  1306. if (m_update_check_timer)
  1307. {
  1308. // An update check is already scheduled.
  1309. // Forget that, schedule an immediate resource check, the update check
  1310. // will be scheduled after we have finished.
  1311. OP_DELETE(m_update_check_timer);
  1312. m_update_check_timer = NULL;
  1313. Console::WriteMessage(UNI_L("Suspending the update check schedule in order to make a resource check."));
  1314. }
  1315. m_update_check_timer = OP_NEW(OpTimer, ());
  1316. if (!m_update_check_timer)
  1317. {
  1318. Console::WriteError(UNI_L("Could not schedule a resource check."));
  1319. return OpStatus::ERR_NO_MEMORY;
  1320. }
  1321. // Schedule the resource check as required. Note, that this timeout should not be set "too high", since it is
  1322. // responsible for downloading the new browserjs after upgrading Opera and having the old browserjs may cause
  1323. // quite serious problems. It should not also be set "too low" since we might hit the browser startup phase
  1324. // and slow it down.
  1325. int seconds_to_resource_check = CalculateTimeOfResourceCheck();
  1326. m_resources_check_only = TRUE;
  1327. m_update_check_timer->SetTimerListener(this);
  1328. m_update_check_timer->Start(seconds_to_resource_check * 1000);
  1329. Console::WriteMessage(UNI_L("Scheduled an immediate resource check."));
  1330. return OpStatus::OK;
  1331. }
  1332. OP_STATUS AutoUpdater::ScheduleUpdateCheck(ScheduleCheckType schedule_type)
  1333. {
  1334. OP_ASSERT(m_update_state == AUSUpToDate);
  1335. OP_ASSERT(!m_update_check_timer);
  1336. if (m_update_state == AUSUpToDate && !m_update_check_timer)
  1337. {
  1338. m_update_check_timer = OP_NEW(OpTimer, ());
  1339. if (m_update_check_timer)
  1340. {
  1341. int seconds_to_next_check = CalculateTimeOfNextUpdateCheck(schedule_type);
  1342. m_update_check_timer->SetTimerListener(this);
  1343. m_update_check_timer->Start(seconds_to_next_check * 1000);
  1344. m_resources_check_only = FALSE;
  1345. OpString message;
  1346. message.AppendFormat(UNI_L("Scheduled new update check in %d seconds."), seconds_to_next_check);
  1347. Console::WriteMessage(message.CStr());
  1348. return OpStatus::OK;
  1349. }
  1350. }
  1351. Console::WriteError(UNI_L("Failed to schedule new update check."));
  1352. return OpStatus::ERR;
  1353. }
  1354. int AutoUpdater::CalculateTimeOfResourceCheck()
  1355. {
  1356. OP_ASSERT(AUTOUPDATE_RESOURCE_CHECK_BASE_TIMEOUT_SEC > 0);
  1357. OP_ASSERT(m_update_check_delay >= 0);
  1358. int timeout = AUTOUPDATE_RESOURCE_CHECK_BASE_TIMEOUT_SEC + m_update_check_delay;
  1359. return timeout;
  1360. }
  1361. int AutoUpdater::CalculateTimeOfNextUpdateCheck(ScheduleCheckType schedule_type)
  1362. {
  1363. // Set the time the code below will normalize it if needed.
  1364. int time_between_checks_sec = m_update_check_interval + m_update_check_delay + m_update_check_random_delta;
  1365. int seconds_to_next_check = 0;
  1366. // Make sure the time between checks is in range [MIN_UPDATE_CHECK_TIMEOUT, UPDATE_CHECK_INTERVAL_MAX]
  1367. OP_ASSERT(MIN_UPDATE_CHECK_INTERVAL_SEC < MAX_UPDATE_CHECK_INTERVAL_SEC);
  1368. OP_ASSERT(MIN_UPDATE_CHECK_INTERVAL_RUNNING_SEC < MAX_UPDATE_CHECK_INTERVAL_SEC);
  1369. if (ScheduleRunning == schedule_type)
  1370. time_between_checks_sec = MAX(time_between_checks_sec, MIN_UPDATE_CHECK_INTERVAL_RUNNING_SEC + m_update_check_random_delta);
  1371. else if (ScheduleStartup == schedule_type)
  1372. time_between_checks_sec = MAX(time_between_checks_sec, MIN_UPDATE_CHECK_INTERVAL_SEC);
  1373. else
  1374. {
  1375. OP_ASSERT("Unknown ScheduleCheckType!");
  1376. }
  1377. time_between_checks_sec = MIN(time_between_checks_sec, MAX_UPDATE_CHECK_INTERVAL_SEC);
  1378. time_t time_now_sec = g_timecache->CurrentTime();
  1379. time_t time_of_next_scheduled_check = m_time_of_last_update_check + time_between_checks_sec;
  1380. if(time_of_next_scheduled_check < time_now_sec)
  1381. seconds_to_next_check = 0;
  1382. else
  1383. seconds_to_next_check = time_of_next_scheduled_check - time_now_sec;
  1384. // To ensure that we dont check too often.
  1385. #ifdef _DEBUG
  1386. seconds_to_next_check = MAX(seconds_to_next_check, 1);
  1387. #else
  1388. seconds_to_next_check = MAX(seconds_to_next_check, 5);
  1389. #endif
  1390. return seconds_to_next_check;
  1391. }
  1392. OP_STATUS AutoUpdater::ScheduleDownload()
  1393. {
  1394. OP_ASSERT(m_update_state == AUSErrorDownloading);
  1395. OP_ASSERT(!m_download_timer);
  1396. if(m_update_state != AUSErrorDownloading)
  1397. return OpStatus::ERR;
  1398. if(m_download_timer)
  1399. return OpStatus::ERR;
  1400. m_download_timer = OP_NEW(OpTimer, ());
  1401. if(!m_download_timer)
  1402. return OpStatus::ERR_NO_MEMORY;
  1403. m_download_timer->SetTimerListener(this);
  1404. m_download_timer->Start(1000);
  1405. m_download_countdown = 60;
  1406. return OpStatus::OK;
  1407. }
  1408. void AutoUpdater::BroadcastOnUpToDate(BOOL silent)
  1409. {
  1410. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1411. {
  1412. m_listeners.GetNext(iterator)->OnUpToDate(silent);
  1413. }
  1414. }
  1415. void AutoUpdater::BroadcastOnChecking(BOOL silent)
  1416. {
  1417. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1418. {
  1419. m_listeners.GetNext(iterator)->OnChecking(silent);
  1420. }
  1421. }
  1422. void AutoUpdater::BroadcastOnUpdateAvailable(UpdatableResource::UpdatableResourceType type, OpFileLength update_size, const uni_char* update_info_url, BOOL silent)
  1423. {
  1424. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1425. {
  1426. m_listeners.GetNext(iterator)->OnUpdateAvailable(type, update_size, update_info_url, silent);
  1427. }
  1428. }
  1429. void AutoUpdater::BroadcastOnDownloading(UpdatableResource::UpdatableResourceType type, OpFileLength total_size, OpFileLength downloaded_size, double kbps, unsigned long time_estimate, BOOL silent)
  1430. {
  1431. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1432. {
  1433. m_listeners.GetNext(iterator)->OnDownloading(type, total_size, downloaded_size, kbps, time_estimate, silent);
  1434. }
  1435. }
  1436. void AutoUpdater::BroadcastOnDownloadingDone(UpdatableResource::UpdatableResourceType type, const OpString& filename, OpFileLength total_size, BOOL silent)
  1437. {
  1438. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1439. {
  1440. m_listeners.GetNext(iterator)->OnDownloadingDone(type, filename, total_size, silent);
  1441. }
  1442. }
  1443. void AutoUpdater::BroadcastOnDownloadingFailed(BOOL silent)
  1444. {
  1445. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1446. {
  1447. m_listeners.GetNext(iterator)->OnDownloadingFailed(silent);
  1448. }
  1449. }
  1450. void AutoUpdater::BroadcastOnRestartingDownload(INT32 seconds_until_restart, AutoUpdateError last_error, BOOL silent)
  1451. {
  1452. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1453. {
  1454. m_listeners.GetNext(iterator)->OnRestartingDownload(seconds_until_restart, last_error, silent);
  1455. }
  1456. }
  1457. void AutoUpdater::BroadcastOnReadyToUpdate()
  1458. {
  1459. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1460. {
  1461. m_listeners.GetNext(iterator)->OnReadyToUpdate();
  1462. }
  1463. }
  1464. void AutoUpdater::BroadcastOnUpdating()
  1465. {
  1466. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1467. {
  1468. m_listeners.GetNext(iterator)->OnUpdating();
  1469. }
  1470. }
  1471. void AutoUpdater::BroadcastOnFinishedUpdating()
  1472. {
  1473. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1474. {
  1475. m_listeners.GetNext(iterator)->OnFinishedUpdating();
  1476. }
  1477. }
  1478. void AutoUpdater::BroadcastOnUnpacking()
  1479. {
  1480. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1481. {
  1482. m_listeners.GetNext(iterator)->OnUnpacking();
  1483. }
  1484. }
  1485. void AutoUpdater::BroadcastOnReadyToInstallNewVersion(const OpString& version, BOOL silent)
  1486. {
  1487. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1488. {
  1489. m_listeners.GetNext(iterator)->OnReadyToInstallNewVersion(version, silent);
  1490. }
  1491. }
  1492. void AutoUpdater::BroadcastOnError(AutoUpdateError error, BOOL silent)
  1493. {
  1494. for (OpListenersIterator iterator(m_listeners); m_listeners.HasNext(iterator);)
  1495. {
  1496. m_listeners.GetNext(iterator)->OnError(error, silent);
  1497. }
  1498. }
  1499. OP_STATUS AutoUpdater::SetUpdateState(AutoUpdateState update_state)
  1500. {
  1501. #ifndef _MACINTOSH_
  1502. int state = m_checker_state << 16 | update_state;
  1503. #else
  1504. int state = update_state;
  1505. #endif // _MACINTOSH_
  1506. RETURN_IF_LEAVE(g_pcui->WriteIntegerL(PrefsCollectionUI::AutoUpdateState, state));
  1507. TRAPD(err, g_prefsManager->CommitL());
  1508. m_update_state = update_state;
  1509. return OpStatus::OK;
  1510. }
  1511. void AutoUpdater::Reset()
  1512. {
  1513. m_download_retries = 0;
  1514. OP_DELETE(m_update_check_timer);
  1515. m_update_check_timer = NULL;
  1516. OP_DELETE(m_download_timer);
  1517. m_download_timer = NULL;
  1518. }
  1519. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  1520. BOOL AutoUpdater::HasDownloadedNewerVersion()
  1521. {
  1522. AUDataFileReader reader;
  1523. if(OpStatus::IsSuccess(reader.Init()) &&
  1524. OpStatus::IsSuccess(reader.LoadFromOpera()))
  1525. {
  1526. OperaVersion downloaded_version;
  1527. uni_char* version = reader.GetVersion();
  1528. uni_char* buildnum = reader.GetBuildNum();
  1529. OpString version_string;
  1530. if(OpStatus::IsSuccess(version_string.Set(version)) &&
  1531. OpStatus::IsSuccess(version_string.Append(".")) &&
  1532. OpStatus::IsSuccess(version_string.Append(buildnum)) &&
  1533. OpStatus::IsSuccess(downloaded_version.Set(version_string)))
  1534. {
  1535. if(m_opera_version < downloaded_version)
  1536. {
  1537. // Only resource check if we have downloaded a higher version
  1538. return TRUE;
  1539. }
  1540. }
  1541. OP_DELETEA(version);
  1542. OP_DELETEA(buildnum);
  1543. }
  1544. return FALSE;
  1545. }
  1546. #endif // AUTOUPDATE_PACKAGE_INSTALLATION
  1547. #ifdef AUTOUPDATE_PACKAGE_INSTALLATION
  1548. void AutoUpdater::DeleteUpgradeFolderIfNeeded()
  1549. {
  1550. // Create the aufile utils object
  1551. AUFileUtils* file_utils = AUFileUtils::Create();
  1552. if (!file_utils)
  1553. return;
  1554. // If the last installation succedded then clean up the remains of the
  1555. // special upgrade folder
  1556. OpString autoupdate_textfile_path;
  1557. uni_char* temp_folder = NULL;
  1558. if (file_utils->GetUpgradeFolder(&temp_folder) == AUFileUtils::OK)
  1559. {
  1560. // Build the path to the text file
  1561. RETURN_VOID_IF_ERROR(autoupdate_textfile_path.Set(temp_folder));
  1562. RETURN_VOID_IF_ERROR(autoupdate_textfile_path.Append(PATHSEP));
  1563. RETURN_VOID_IF_ERROR(autoupdate_textfile_path.Append(AUTOUPDATE_UPDATE_TEXT_FILENAME));
  1564. // Check if the upgrade folder even exists
  1565. OpFile upgrade_path;
  1566. BOOL exists = FALSE;
  1567. // Build the OpFile
  1568. RETURN_VOID_IF_ERROR(upgrade_path.Construct(temp_folder));
  1569. // If the file doesn't exist kill the folder
  1570. if (OpStatus::IsSuccess(upgrade_path.Exists(exists)) && exists)
  1571. {
  1572. // If the text file exists then don't clean up we can assume they want to do this next time
  1573. // Otherwise kill the folder
  1574. OpFile autoupdate_textfile;
  1575. // reset exists
  1576. exists = FALSE;
  1577. RETURN_VOID_IF_ERROR(autoupdate_textfile.Construct(autoupdate_textfile_path));
  1578. // If the file doesn't exist kill the folder
  1579. if (OpStatus::IsSuccess(autoupdate_textfile.Exists(exists)) && !exists)
  1580. {
  1581. // Delete this entire folder
  1582. RETURN_VOID_IF_ERROR(upgrade_path.Delete(TRUE));
  1583. }
  1584. }
  1585. }
  1586. OP_DELETEA(temp_folder);
  1587. OP_DELETE(file_utils);
  1588. }
  1589. #endif // AUTOUPDATE_PACKAGE_INSTALLATION
  1590. void AutoUpdater::IncreaseDelayedUpdateCheckInterval()
  1591. {
  1592. m_update_check_delay = MIN(m_update_check_delay + UPDATE_CHECK_INTERVAL_DELTA_SEC, MAX_UPDATE_CHECK_INTERVAL_SEC);
  1593. // Don't let increasing the upgrade check time to break any further operation
  1594. OpStatus::Ignore(WritePref(PrefsCollectionUI::DelayedUpdateCheckInterval, m_update_check_delay));
  1595. }
  1596. void Console::WriteMessage(const uni_char* message)
  1597. {
  1598. #ifdef OPERA_CONSOLE
  1599. OpConsoleEngine::Message cmessage(OpConsoleEngine::AutoUpdate, OpConsoleEngine::Verbose);
  1600. cmessage.message.Set(message);
  1601. TRAPD(err, g_console->PostMessageL(&cmessage));
  1602. #endif
  1603. }
  1604. void Console::WriteError(const uni_char* error)
  1605. {
  1606. #ifdef OPERA_CONSOLE
  1607. OpConsoleEngine::Message cmessage(OpConsoleEngine::AutoUpdate, OpConsoleEngine::Error);
  1608. cmessage.message.Set(error);
  1609. TRAPD(err, g_console->PostMessageL(&cmessage));
  1610. #endif
  1611. }
  1612. #endif // AUTO_UPDATE_SUPPORT