diff options
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/extensions/update_manifest.cc | 24 | ||||
-rw-r--r-- | chrome/common/extensions/update_manifest.h | 18 | ||||
-rw-r--r-- | chrome/common/extensions/update_manifest_unittest.cc | 38 | ||||
-rw-r--r-- | chrome/common/utility_messages.h | 20 | ||||
-rw-r--r-- | chrome/common/utility_messages_internal.h | 2 |
5 files changed, 90 insertions, 12 deletions
diff --git a/chrome/common/extensions/update_manifest.cc b/chrome/common/extensions/update_manifest.cc index e3f1b4d..e461d7b 100644 --- a/chrome/common/extensions/update_manifest.cc +++ b/chrome/common/extensions/update_manifest.cc @@ -17,7 +17,9 @@ static const char* kExpectedGupdateProtocol = "2.0"; static const char* kExpectedGupdateXmlns = "http://www.google.com/update2/response"; -UpdateManifest::UpdateManifest() {} +UpdateManifest::UpdateManifest() { + results_.daystart_elapsed_seconds = kNoDaystart; +} UpdateManifest::~UpdateManifest() {} @@ -135,6 +137,10 @@ static bool ParseSingleAppTag(xmlNode* app_node, xmlNs* xml_namespace, } xmlNode *updatecheck = updates[0]; + if (GetAttribute(updatecheck, "status") == "noupdate") { + return true; + } + // Find the url to the crx file. result->crx_url = GURL(GetAttribute(updatecheck, "codebase")); if (!result->crx_url.is_valid()) { @@ -180,7 +186,8 @@ static bool ParseSingleAppTag(xmlNode* app_node, xmlNs* xml_namespace, bool UpdateManifest::Parse(const std::string& manifest_xml) { - results_.resize(0); + results_.list.resize(0); + results_.daystart_elapsed_seconds = kNoDaystart; if (manifest_xml.length() < 1) { return false; @@ -222,6 +229,17 @@ bool UpdateManifest::Parse(const std::string& manifest_xml) { return false; } + // Parse the first <daystart> if it's present. + std::vector<xmlNode*> daystarts = GetChildren(root, gupdate_ns, "daystart"); + if (daystarts.size() > 0) { + xmlNode* first = daystarts[0]; + std::string elapsed_seconds = GetAttribute(first, "elapsed_seconds"); + int parsed_elapsed = kNoDaystart; + if (StringToInt(elapsed_seconds, &parsed_elapsed)) { + results_.daystart_elapsed_seconds = parsed_elapsed; + } + } + // Parse each of the <app> tags. std::vector<xmlNode*> apps = GetChildren(root, gupdate_ns, "app"); for (unsigned int i = 0; i < apps.size(); i++) { @@ -231,7 +249,7 @@ bool UpdateManifest::Parse(const std::string& manifest_xml) { ParseError("%s", error.c_str()); return false; } - results_.push_back(current); + results_.list.push_back(current); } return true; diff --git a/chrome/common/extensions/update_manifest.h b/chrome/common/extensions/update_manifest.h index c1e5b2b..be0f643 100644 --- a/chrome/common/extensions/update_manifest.h +++ b/chrome/common/extensions/update_manifest.h @@ -23,6 +23,7 @@ class UpdateManifest { // // <?xml version='1.0' encoding='UTF-8'?> // <gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'> + // <daystart elapsed_seconds='300' /> // <app appid='12345'> // <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' // version='1.2.3.4' prodversionmin='2.0.143.0' @@ -30,6 +31,9 @@ class UpdateManifest { // </app> // </gupdate> // + // The <daystart> tag contains a "elapsed_seconds" attribute which refers to + // the server's notion of how many seconds it has been since midnight. + // // The "appid" attribute of the <app> tag refers to the unique id of the // extension. The "codebase" attribute of the <updatecheck> tag is the url to // fetch the updated crx file, and the "prodversionmin" attribute refers to @@ -44,7 +48,12 @@ class UpdateManifest { GURL crx_url; }; - typedef std::vector<Result> ResultList; + static const int kNoDaystart = -1; + struct Results { + std::vector<Result> list; + // This will be >= 0, or kNoDaystart if the <daystart> tag was not present. + int daystart_elapsed_seconds; + }; UpdateManifest(); ~UpdateManifest(); @@ -55,16 +64,17 @@ class UpdateManifest { // by calling errors(). bool Parse(const std::string& manifest_xml); - const ResultList& results() { return results_; } + const Results& results() { return results_; } const std::string& errors() { return errors_; } private: - ResultList results_; - + Results results_; std::string errors_; // Helper function that adds parse error details to our errors_ string. void ParseError(const char* details, ...); + + DISALLOW_COPY_AND_ASSIGN(UpdateManifest); }; #endif // CHROME_COMMON_EXTENSIONS_UPDATE_MANIFEST_H_ diff --git a/chrome/common/extensions/update_manifest_unittest.cc b/chrome/common/extensions/update_manifest_unittest.cc index 7adc17f..fb7ee0e9 100644 --- a/chrome/common/extensions/update_manifest_unittest.cc +++ b/chrome/common/extensions/update_manifest_unittest.cc @@ -85,6 +85,25 @@ static const char* kSimilarTagnames = " </app>" "</gupdate>"; +// Includes a <daystart> tag. +static const char* kWithDaystart = +"<?xml version='1.0' encoding='UTF-8'?>" +"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" +" <daystart elapsed_seconds='456' />" +" <app appid='12345'>" +" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" +" version='1.2.3.4' prodversionmin='2.0.143.0' />" +" </app>" +"</gupdate>"; + +// Indicates no updates available - this should not be a parse error. +static const char* kNoUpdate = +"<?xml version='1.0' encoding='UTF-8'?>" +"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" +" <app appid='12345'>" +" <updatecheck status='noupdate' />" +" </app>" +"</gupdate>"; TEST(ExtensionUpdateManifestTest, TestUpdateManifest) { UpdateManifest parser; @@ -98,8 +117,8 @@ TEST(ExtensionUpdateManifestTest, TestUpdateManifest) { // Parse some valid XML, and check that all params came out as expected EXPECT_TRUE(parser.Parse(kValidXml)); - EXPECT_FALSE(parser.results().empty()); - const UpdateManifest::Result* firstResult = &parser.results().at(0); + EXPECT_FALSE(parser.results().list.empty()); + const UpdateManifest::Result* firstResult = &parser.results().list.at(0); EXPECT_EQ(GURL("http://example.com/extension_1.2.3.4.crx"), firstResult->crx_url); @@ -113,7 +132,18 @@ TEST(ExtensionUpdateManifestTest, TestUpdateManifest) { // Parse xml with hash value EXPECT_TRUE(parser.Parse(valid_xml_with_hash)); - EXPECT_FALSE(parser.results().empty()); - firstResult = &parser.results().at(0); + EXPECT_FALSE(parser.results().list.empty()); + firstResult = &parser.results().list.at(0); EXPECT_EQ("1234", firstResult->package_hash); + + EXPECT_TRUE(parser.Parse(kWithDaystart)); + EXPECT_FALSE(parser.results().list.empty()); + EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456); + + // Parse a no-update response. + EXPECT_TRUE(parser.Parse(kNoUpdate)); + EXPECT_FALSE(parser.results().list.empty()); + firstResult = &parser.results().list.at(0); + EXPECT_EQ(firstResult->extension_id, "12345"); + EXPECT_EQ(firstResult->version, ""); } diff --git a/chrome/common/utility_messages.h b/chrome/common/utility_messages.h index eccdc14..867131f 100644 --- a/chrome/common/utility_messages.h +++ b/chrome/common/utility_messages.h @@ -50,6 +50,26 @@ struct ParamTraits<UpdateManifest::Result> { } }; +template<> +struct ParamTraits<UpdateManifest::Results> { + typedef UpdateManifest::Results param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.list); + WriteParam(m, p.daystart_elapsed_seconds); + } + static bool Read(const Message* m, void** iter, param_type* p) { + return ReadParam(m, iter, &p->list) && + ReadParam(m, iter, &p->daystart_elapsed_seconds); + } + static void Log(const param_type& p, std::wstring* l) { + l->append(L"("); + LogParam(p.list, l); + l->append(L", "); + LogParam(p.daystart_elapsed_seconds, l); + l->append(L")"); + } +}; + } // namespace IPC #define MESSAGES_INTERNAL_FILE "chrome/common/utility_messages_internal.h" diff --git a/chrome/common/utility_messages_internal.h b/chrome/common/utility_messages_internal.h index 4947079..4933742 100644 --- a/chrome/common/utility_messages_internal.h +++ b/chrome/common/utility_messages_internal.h @@ -64,7 +64,7 @@ IPC_BEGIN_MESSAGES(UtilityHost) // Reply when the utility process has succeeded in parsing an update manifest // xml document. IPC_MESSAGE_CONTROL1(UtilityHostMsg_ParseUpdateManifest_Succeeded, - std::vector<UpdateManifest::Result> /* updates */) + UpdateManifest::Results /* updates */) // Reply when an error occured parsing the update manifest. |error_message| // is a description of what went wrong suitable for logging. |