AU: Send a previous version event after reboot following an update.
The previous version event is sent along with the first update check. This is
best effort -- if the update check doesn't reach the server, the event is lost.
BUG=9198
TEST=unit tests, tested on device
Change-Id: I5ceb7c8e99ae54eb331f6ac58b8977d2a111461c
Review URL: http://codereview.chromium.org/5993007
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 5166315..bb2275d 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -93,11 +93,31 @@
string FormatRequest(const OmahaEvent* event,
const OmahaRequestParams& params,
int ping_active_days,
- int ping_roll_call_days) {
+ int ping_roll_call_days,
+ PrefsInterface* prefs) {
string body;
if (event == NULL) {
body = GetPingBody(ping_active_days, ping_roll_call_days) +
" <o:updatecheck></o:updatecheck>\n";
+ // If this is the first update check after a reboot following a previous
+ // update, generate an event containing the previous version number. If the
+ // previous version preference file doesn't exist the event is still
+ // generated with a previous version of 0.0.0.0 -- this is relevant for
+ // older clients or new installs.
+ string prev_version;
+ if (!prefs->GetString(kPrefsPreviousVersion, &prev_version)) {
+ prev_version = "0.0.0.0";
+ }
+ if (!prev_version.empty()) {
+ body += StringPrintf(
+ " <o:event eventtype=\"%d\" eventresult=\"%d\" "
+ "previousversion=\"%s\"></o:event>\n",
+ OmahaEvent::kTypeUpdateComplete,
+ OmahaEvent::kResultSuccessReboot,
+ prev_version.c_str());
+ LOG_IF(WARNING, !prefs->SetString(kPrefsPreviousVersion, ""))
+ << "Unable to reset the previous version.";
+ }
} else {
// The error code is an optional attribute so append it only if
// the result is not success.
@@ -197,7 +217,8 @@
string request_post(FormatRequest(event_.get(),
params_,
ping_active_days_,
- ping_roll_call_days_));
+ ping_roll_call_days_,
+ prefs_));
http_fetcher_->SetPostData(request_post.data(), request_post.size());
LOG(INFO) << "Posting an Omaha request to " << params_.update_url;
LOG(INFO) << "Request: " << request_post;
diff --git a/omaha_request_action.h b/omaha_request_action.h
index b65d3f8..948bcc7 100644
--- a/omaha_request_action.h
+++ b/omaha_request_action.h
@@ -70,6 +70,7 @@
enum Result {
kResultError = 0,
kResultSuccess = 1,
+ kResultSuccessReboot = 2,
};
OmahaEvent()
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 8fe2482..4ac2b74 100755
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -521,7 +521,11 @@
TEST(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
vector<char> post_data;
- ASSERT_FALSE(TestUpdateCheck(NULL, // prefs
+ NiceMock<PrefsMock> prefs;
+ EXPECT_CALL(prefs, GetString(kPrefsPreviousVersion, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(string("")), Return(true)));
+ EXPECT_CALL(prefs, SetString(kPrefsPreviousVersion, _)).Times(0);
+ ASSERT_FALSE(TestUpdateCheck(&prefs,
kDefaultTestParams,
"invalid xml>",
-1,
@@ -538,6 +542,35 @@
EXPECT_EQ(post_str.find("o:event"), string::npos);
}
+TEST(OmahaRequestActionTest, FormatUpdateCheckPrevVersionOutputTest) {
+ vector<char> post_data;
+ NiceMock<PrefsMock> prefs;
+ EXPECT_CALL(prefs, GetString(kPrefsPreviousVersion, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(string("1.2.3.4")), Return(true)));
+ EXPECT_CALL(prefs, SetString(kPrefsPreviousVersion, ""))
+ .WillOnce(Return(true));
+ ASSERT_FALSE(TestUpdateCheck(&prefs,
+ kDefaultTestParams,
+ "invalid xml>",
+ -1,
+ kActionCodeOmahaRequestXMLParseError,
+ NULL, // response
+ &post_data));
+ // convert post_data to string
+ string post_str(&post_data[0], post_data.size());
+ EXPECT_NE(post_str.find(" <o:ping a=\"-1\" r=\"-1\"></o:ping>\n"
+ " <o:updatecheck></o:updatecheck>\n"),
+ string::npos);
+ EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
+ string::npos);
+ string prev_version_event = StringPrintf(
+ " <o:event eventtype=\"%d\" eventresult=\"%d\" "
+ "previousversion=\"1.2.3.4\"></o:event>\n",
+ OmahaEvent::kTypeUpdateComplete,
+ OmahaEvent::kResultSuccessReboot);
+ EXPECT_NE(post_str.find(prev_version_event), string::npos);
+}
+
TEST(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
vector<char> post_data;
TestEvent(kDefaultTestParams,
diff --git a/prefs.cc b/prefs.cc
index 223fc9b..1bde4cd 100644
--- a/prefs.cc
+++ b/prefs.cc
@@ -19,6 +19,7 @@
const char kPrefsLastActivePingDay[] = "last-active-ping-day";
const char kPrefsLastRollCallPingDay[] = "last-roll-call-ping-day";
const char kPrefsManifestMetadataSize[] = "manifest-metadata-size";
+const char kPrefsPreviousVersion[] = "previous-version";
const char kPrefsResumedUpdateFailures[] = "resumed-update-failures";
const char kPrefsUpdateCheckResponseHash[] = "update-check-response-hash";
const char kPrefsUpdateStateNextDataOffset[] = "update-state-next-data-offset";
diff --git a/prefs_interface.h b/prefs_interface.h
index 81aa770..8d07dde 100644
--- a/prefs_interface.h
+++ b/prefs_interface.h
@@ -13,6 +13,7 @@
extern const char kPrefsLastActivePingDay[];
extern const char kPrefsLastRollCallPingDay[];
extern const char kPrefsManifestMetadataSize[];
+extern const char kPrefsPreviousVersion[];
extern const char kPrefsResumedUpdateFailures[];
extern const char kPrefsUpdateCheckResponseHash[];
extern const char kPrefsUpdateStateNextDataOffset[];
diff --git a/update_attempter.cc b/update_attempter.cc
index 8139687..3ea1c18 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -289,6 +289,7 @@
if (code == kActionCodeSuccess) {
utils::WriteFile(kUpdateCompletedMarker, "", 0);
prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
+ prefs_->SetString(kPrefsPreviousVersion, omaha_request_params_.app_version);
DeltaPerformer::ResetUpdateProgress(prefs_, false);
SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT);