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.

autoupdatexml.h 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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 Michal Zajaczkowski
  9. */
  10. #ifdef AUTO_UPDATE_SUPPORT
  11. #ifndef AUTOUPDATE_XML_H
  12. #define AUTOUPDATE_XML_H
  13. #include "modules/util/opstrlst.h"
  14. #include "modules/xmlutils/xmlfragment.h"
  15. #include "adjunct/autoupdate/additionchecker.h"
  16. class AdditionCheckerItem;
  17. /**
  18. * This was formerly part of the AutoUpdateURL class.
  19. * The AutoUpdateXML class serves the purpose of generating the autoupdate request XML. This is the only way the request XML should be generated,
  20. * this class should contain all the logic needed to construct a valid XML request for the needed request type.
  21. *
  22. * Since the autoupdate server does two tasks that are quite different, i.e. serving browser and resources updates and resolving additions, the logic
  23. * used to generate the request XML is a bit complicated.
  24. * If you want to request a browser update XML, you expect to get back a browser package, if a newer one is available on the server, as well as resources
  25. * update. Use update levels 1 to 3 for this purpose.
  26. * If you want to request an addition check XML, use the update level that is proper for the given addition type, i.e. from the level 4 up.
  27. * Additionally, if you want to request an addition check XML, you need to specify addition items that will be encoded in the XML, i.e. a list of plugin
  28. * with their mimetypes. These need to be added to the AutoUpdateXML internal list using the AddRequestItem() method before a call to GetRequestXML() is made.
  29. *
  30. * Since this class is meant to exist in one copy held by the AutoUpdateManager, you should always call ClearRequestItems() before requesting a new XML,
  31. * especially before adding new request items.
  32. *
  33. * Note that this class should be used internally by the autoupdate module and you shouldn't use it directly.
  34. *
  35. */
  36. class AutoUpdateXML
  37. {
  38. public:
  39. /*
  40. * _DO_NOT_CHANGE_ the values for this enum, they represent the numerical update levels recognized by the autoupdate server.
  41. * In case you want to add a new addition type, you need to agree that with the core services team and append a new update
  42. * level here.
  43. * Also, the AdjustUpdateLevel() method should be aligned with the changes, as well as the actual XML generation algorithm, see AppendXMLOpera().
  44. *
  45. * A value from this enum is used as a parameter to the GetRequestXML() calls.
  46. *
  47. * The actual behaviour of the autoupdate server may vary due to server changes.
  48. **/
  49. enum AutoUpdateLevel {
  50. /**
  51. * In case the GetRequestXML() method is called with the value UpdateLevelChooseAuto (default parameter value), this class attempts to recognize
  52. * the needed update level automatically. This should work fine most of the time.
  53. */
  54. UpdateLevelChooseAuto = 0,
  55. /**
  56. * Request browser update only, no resources (browser.js, override_downloaded.ini, dictionaries.xml, language files, ...).
  57. */
  58. UpdateLevelUpgradeCheck = 1,
  59. /**
  60. * Request resources update only (browser.js, ...). NOTE, that this has nothing to do with additions, however installed language files
  61. * will be tracked as resources and will be updated with update levels 1 and 2.
  62. */
  63. UpdateLevelResourceCheck = 2,
  64. /**
  65. * This update level means requesting an update of the browser package, if any is available, as well as updates to the resources tracked by the
  66. * autoupdate mechanism (browser.js, ...)
  67. * UpdateLevelDefaultCheck is the level that is chosen when the request XML is generated with the UpdateLevelChooseAuto value and no request items
  68. * have been added to the request.
  69. */
  70. UpdateLevelDefaultCheck = 3,
  71. /**
  72. * Used to resolve language files (dictionaries). This level is used to check availablity of language files that we want to install.
  73. */
  74. UpdateLevelInstallDictionaries = 4,
  75. /**
  76. * Used to resolve plugin files that we want to install.
  77. */
  78. UpdateLevelInstallPlugins = 5,
  79. /**
  80. * Used to get country code for computer's IP address.
  81. */
  82. UpdateLevelCountryCheck = 6,
  83. };
  84. // Introduced by DSK-344553, we need to distinguish XML requests sent for the "main", periodical update checks, and any other requests.
  85. enum RequestType {
  86. // Request sent from the main autoupdate mechanism
  87. RT_Main,
  88. // Any other request (additions, VersionChecker, ...)
  89. RT_Other
  90. };
  91. enum TimeStampItem
  92. {
  93. TSI_BrowserJS,
  94. TSI_OverrideDownloaded,
  95. TSI_DictionariesXML,
  96. TSI_HardwareBlocklist,
  97. TSI_HandlersIgnore,
  98. TSI_LastUpdateCheck,
  99. TSI_LAST_ITEM
  100. };
  101. AutoUpdateXML();
  102. ~AutoUpdateXML();
  103. /**
  104. * Needs to be called before any operation on the AutoUpdateXML class is done. Initializes internal data and needs to succeed.
  105. *
  106. * @return OpStatus::OK if everything went OK, ERR otherwise.
  107. */
  108. OP_STATUS Init();
  109. /**
  110. * In case you want to generate an autoupdate request XML containing description of additions that you want to resolve, you need
  111. * to pass the addition items to this class. Append as many addition items as you like before calling GetRequestXML(), make sure
  112. * to ClearRequestItems() before you start adding new items in order to not to mix old items with the new ones.
  113. *
  114. * Since the autoupdate server can only handle on type of additions per one XML request (according to the update level chosen), you
  115. * cannot mix different addition types with one call to GetRequestXML(), therefore you cannot mix the types while adding them here
  116. * or the call to GetRequestXML() will fail.
  117. *
  118. * @param item - the addition checker item that will be added to the item list used by the next call to GetRequestXML(). Note that
  119. * this class doesn't take the ownership of the addition checker items passed with this call.
  120. *
  121. * @return - OpStatus::OK if adding the new addition item succeeded, ERR otherwise.
  122. */
  123. OP_STATUS AddRequestItem(AdditionCheckerItem* item);
  124. /**
  125. * Clears the current addition item list. Needs to be called before new items are added.
  126. */
  127. void ClearRequestItems();
  128. /**
  129. * Construct and return the autoupdate request XML.
  130. * If you want the XML for update levels 1-3, make sure the addition items list is empty before calling this method (use ClearRequestItems()), and
  131. * set the update level manually via the level parameter, or use the UpdateLevelChooseAuto value to use the default level 3.
  132. * If you want the XML for addition check, add addition items using AddRequestItem() and use UpdateLevelChooseAuto in order to leave choosing the proper
  133. * update level to this class internal logic (see AdjustUpdateLevel()).
  134. *
  135. * @param xml_string - reference to an OpString8 object that will receive the constructed request XML that should be sent directly to the autoupdate server.
  136. * @param level - autoupdate level that should be used to construct the XML. Should be left with the default value UpdateLevelChooseAuto unless you want to
  137. * explicitly choose a different level between 1 and 3.
  138. * @param request_type - see DSK-344553, this should be set correctly to distinguish regular periodic update checks from any other XML requests.
  139. * @param used_level - On exit contains the update lavel determined and used to create the request XML.
  140. *
  141. * @return - OpStatus::OK if everything went OK, ERR if the addition items are not consistent according to their type, the update level does not fit the
  142. * addition items or if any other problem occurred.
  143. */
  144. OP_STATUS GetRequestXML(OpString8 &xml_string, AutoUpdateLevel level = UpdateLevelChooseAuto, RequestType request_type = RT_Other, AutoUpdateLevel* used_level = NULL);
  145. /**
  146. * This method has been introduced as a result of DSK-336588.
  147. * If any of the resource timestamps are set to 0, we need to trigger an immediate resource update check after the browser starts.
  148. * The browserjs timestamp will be set 0 to browser upgrade.
  149. * Note that AutoUpdateXML::GetTimeStamp(TSI_HandlersIgnore) seems to return 0 even after
  150. * an update check, perhaps because we don't always get the resource it describes.
  151. * Note that if the resources list found in AutoUpdateXML::NeedsResourceCheck() includes
  152. * resources that don't get updated with the update check, we might end up sending the
  153. * resource check each and every time Opera starts.
  154. *
  155. * @return - TRUE if a resource update check is needed, FALSE otherwise.
  156. */
  157. BOOL NeedsResourceCheck();
  158. protected:
  159. OP_STATUS SetPref(int which, int value);
  160. virtual int GetTimeStamp(TimeStampItem item);
  161. /**
  162. * Internal information collected by the Collect*() and UpdateFragileData() methods.
  163. * These might be overriden by the ST_AutoUpdateXML class.
  164. *
  165. * See also the EnsureStringsHaveBuffers() method.
  166. */
  167. OpString m_opera_version; // Version of the currently running Opera application
  168. OpString m_build_number; // Build number of the currently running Opera application
  169. OpString m_language; // Language (code) of the currently running Opera application
  170. OpString m_edition; // Special build edition (e.g. t-online) ([ISP] Id=)
  171. OpString m_os_name; // Name of the operating system, i.e. Windows, MacOS, Linux, FreeBSD, as defined by http://www.opera.com/download/index.dml?custom=yes
  172. OpString m_os_version; // Operating system version (e.g. 10.4.3, 5.1)
  173. OpString m_architecture; // Architecture, i386/ppc ...
  174. OpString m_package_type; // Type of package installed (*nix only), i.e. static, shared, gcc3, gcc4
  175. OpString m_gcc_version; // gcc version (*nix only)
  176. OpString m_qt_version; // QT version (*nix only)
  177. int m_timestamp_browser_js; // Timestamp of the current browser.js file
  178. int m_timestamp_override_downloaded_ini; // Timestamp of the current override_downloaded.ini (Site Prefs) file
  179. int m_timestamp_dictionaries_xml; // Timestamp of the current dictionaries.xml file
  180. int m_timestamp_hardware_blocklist; // Timestamp of the current hardware blocklist file (newest if several)
  181. int m_timestamp_handlers_ignore; // Timestamp of the current handlers-ignore.ini file
  182. int m_time_since_last_check; // Time since last check (i.e. current_time - last_update_check_time). This should not be affected by addition requests.
  183. int m_download_all_snapshots; // Set to download all snapshots
  184. /**
  185. * Addition checker items that will be resolved against the autoupdate server are stored here.
  186. */
  187. OpVector<AdditionCheckerItem> m_items;
  188. private:
  189. // Autoupdate debugging in the live client-server environment needs marking some flags
  190. // These are treated as bit fields!
  191. enum DirtyFlag {
  192. // The Time Since Last Check calculated to be negative
  193. DF_TSLC = 0x01,
  194. // operaprefs.ini could not be written into (or: could not save a pref value)
  195. DF_OPERAPREFS = 0x02,
  196. // First Used Version was empty and we tried to change it to "Old Installation"
  197. DF_FIRSTRUNVER = 0x04,
  198. // First Run Timestamp was 0 and we tried to set it to 1
  199. DF_FIRSTRUNTS = 0x08,
  200. // The path of the disk image of the running binary starts with what is the system temp dir, for example.
  201. // the binary was loaded from "c:\tmp\VsourcesDebug\Opera.exe".
  202. // If this flag is set then we probably have problems related to DSK-345746, DSK-345431.
  203. DF_RUNFROMTEMP = 0x10
  204. };
  205. /**
  206. * The current autoupdate XML schema version, i.e. "1.0".
  207. */
  208. static const uni_char* AUTOUPDATE_SCHEMA_VERSION;
  209. /**
  210. * If the opera:config#AutoUpdate|SaveAutoUpdateXML preference is set, the request XML is saved as a file with the name and folder specified by the
  211. * following two consts.
  212. */
  213. static const uni_char* AUTOUPDATE_REQUEST_FILE_NAME;
  214. static const OpFileFolder AUTOUPDATE_REQUEST_FILE_FOLDER;
  215. /**
  216. * Chooses the update level according to the current content of the addition items list contained in the m_items vector.
  217. * Checks the contents of the m_items vector and verifies it agains the update level passed with the call.
  218. * Adjusts the update level in case the passed level is 0 (UpdateLevelChooseAuto).
  219. *
  220. * @param level - The update level that we want to adjust and/or verify. In case the passed level value is UpdateLevelChooseAuto, it gets
  221. * adjusted to a correct level basing on the contents of the m_items vector. In case the passed level value is anything else,
  222. * it gets verified against the contents of the vector.
  223. *
  224. * @returns - OpStatus::OK in case the level was adjusted/verified succesfully.
  225. *
  226. */
  227. OP_STATUS AdjustUpdateLevel(AutoUpdateLevel& level);
  228. /**
  229. * Called during Init(), collects the platform data that is not going to change, i.e. OS name, version, computer architecture and so.
  230. *
  231. * @returns OpStatus::OK if everything went OK, ERR otherwise.
  232. */
  233. OP_STATUS CollectPlatformData();
  234. /**
  235. * Called during Init(), collects the build data that is not going to change, i.e. Opera version, build number and so.
  236. *
  237. * @returns OpStatus::OK if everything went OK, ERR otherwise.
  238. */
  239. OP_STATUS CollectBuildData();
  240. /**
  241. * Verifies the existence of the resource files (currently browser.js, override_downloaded.ini, dictionaries.xml). In case any of the files
  242. * doesn't exist in the filesystem, the corresponding preference representing the timestamp of that resource is set to 0.
  243. * The preferences are: PrefsCollectionUI::BrowserJSTime, PrefsCollectionUI::SpoofTime, PrefsCollectionUI::DictionaryTime, PrefsCollectionUI::HardwareBlocklistTime, PrefsCollectionUI::HandlersIgnoreTime.
  244. * The preference values are set the value received from the autoupdate server during updating of the resources.
  245. *
  246. * @returns - OpStatus::OK if everything went OK, ERR if it was not possible to set a new value of any of the preferences.
  247. */
  248. OP_STATUS CheckResourceFiles();
  249. /**
  250. * Update timestamps: resource timestamps, time since last check. Needs to be called each time before the request XML is generated since the
  251. * timestamps WILL change over time.
  252. *
  253. * @returns - OpStatus:OK if everything went OK, ERR otherwise.
  254. */
  255. OP_STATUS UpdateFragileData();
  256. /**
  257. * Helper methods to generate the actual XML. Since this will change when new types are added, you should rememeber one thing mainly: don't add
  258. * XML representing additions for update levels 1-3 unless the addition is already installed and should be tracked with autoupdate. Each such
  259. * case should be agreed with the core services team, see updating installed dictionaries vs not-updating installed plugins.
  260. */
  261. OP_STATUS AppendXMLOperatingSystem(XMLFragment& fragment, AutoUpdateLevel level);
  262. OP_STATUS AppendXMLPackage(XMLFragment& fragment);
  263. OP_STATUS AppendXMLOpera(XMLFragment& fragment, AutoUpdateLevel level);
  264. OP_STATUS AppendXMLDictionaries(XMLFragment& fragment, AutoUpdateLevel level);
  265. OP_STATUS AppendXMLPlugins(XMLFragment& fragment, AutoUpdateLevel level);
  266. OP_STATUS AppendXMLExistingDictionaries(XMLFragment& fragment, AutoUpdateLevel level);
  267. OP_STATUS AppendXMLNewDictionaries(XMLFragment& fragment, AutoUpdateLevel level);
  268. /**
  269. * Generate the XML string from the XMLFragment prepared with earlier calls to the AppendXML* methods.
  270. */
  271. OP_STATUS EncodeXML(XMLFragment& fragment, OpString8& xml_string);
  272. /**
  273. * If the opera:config#AutoUpdate|SaveAutoUpdateXML preference is set, the autoupdate request XML is saved to a file.
  274. * See AUTOUPDATE_REQUEST_FILE_NAME, AUTOUPDATE_REQUEST_FILE_FOLDER.
  275. * Additionally in debug builds the file contents is opened in a new browser tab.
  276. *
  277. * @returns - OpStatus:OK if everthing went OK, ERR otherwise.
  278. */
  279. OP_STATUS DumpXML(OpString8& xml_string);
  280. /**
  281. * Clears all dirty flags.
  282. */
  283. void ClearDirty();
  284. /**
  285. * Sets the dirty flag indicated by the parameter given.
  286. *
  287. * @param flag - The flag to set
  288. */
  289. void SetDirty(DirtyFlag flag);
  290. /**
  291. * This method implements the autoupdate server "debugging" realised via the <dirty> XML element sent with the
  292. * autoupdate request. Due to certain problems that are hard to track, the client tries to do its bets to detect
  293. * any problems that might arise during construction of the autoupdate XML request and sets appropiate flags, that
  294. * are then sent to the autoupdate server. The flags are packed into an unsingned integer and sent as a plain
  295. * decimal integer, i.e. <dirty>12</dirty>.
  296. * To know the flags meaning, see enum DirtyFlag above.
  297. *
  298. * This method goes through all the places that are suspected to cause problems and tries to check and fix thigns,
  299. * lighting up the flags. Feel free to add any checks here, however do rememeber to sync whatever you do here with
  300. * the Core Operations Services team, that does maintain the autoupdate server.
  301. */
  302. void CheckDirtyness();
  303. /**
  304. * It is possible to have a NULL CStr() pointer from any of the OpString objects above since the
  305. * platform implementations might call Empty() on the OpStrings.
  306. * That is wrong since the XML code uses strlen on the given strings later on and we can expect crashes,
  307. * as it happens on the Linux platform.
  308. *
  309. * Therefore, we make sure that there is ALWAYS a pointer allocated within the OpStrings, even if the
  310. * actual string content is empty.
  311. * This method checks all the strings that collect platform data for buffer presence and sets an epmty buffer
  312. * in case there is no buffer.
  313. *
  314. * REMEMBER to add OpString properties added to this class here if you are not sure that they will have a buffer at
  315. * the time of the XML construction.
  316. */
  317. void EnsureStringsHaveBuffers();
  318. /**
  319. * Whether Init() was called OK.
  320. */
  321. BOOL m_inited;
  322. // DSK-344456 and DSK-344460 introduce the <dirty> XML element, that has the sole purpose of
  323. // telling the autoupdate server that something has gone wrong during preparation of the XML
  324. // autoupdate request.
  325. // The dirty flags are stored here.
  326. unsigned int m_dirty;
  327. };
  328. #endif // AUTOUPDATE_XML_H
  329. #endif // AUTO_UPDATE_SUPPORT