Support changing from non-canary to canary channel in update engine.

Now that we have added support in lsb-release for both the board appid
and canary app id to be specified, we should use the appropriate appid
according to the channel from which we want to download the new payload.

This change in update engine will enable the change from non-canary to
canary channels. This feature when be lit up end to end when the UI for
this scenario is ready.

BUG=chromium:225866
TEST=Unit tests pass. Tested all channel changes on my ZGB.

Change-Id: Ia9c37c72f53f6c69436f0a96e35d2584d84653c8
Reviewed-on: https://gerrit.chromium.org/gerrit/47181
Commit-Queue: Jay Srinivasan <jaysri@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Tested-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 6391208..ad1f95e 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -200,13 +200,8 @@
 
   string delta_okay_str = params->delta_okay() ? "true" : "false";
 
-  // Use the default app_id only if we're asking for an update on the
-  // canary-channel. Otherwise, use the board's app_id.
-  string request_app_id =
-      (download_channel == "canary-channel" ?
-       params->app_id() : params->board_app_id());
   string app_xml =
-      "    <app appid=\"" + XmlEncode(request_app_id) + "\" " +
+      "    <app appid=\"" + XmlEncode(params->GetAppId()) + "\" " +
                 app_versions +
                 app_channels +
                 "lang=\"" + XmlEncode(params->app_lang()) + "\" " +
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index bd94b2d..591a6f6 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -63,14 +63,18 @@
                           "",
                           NULL,
                           stateful_override);
-  app_id_ = GetLsbValue("CHROMEOS_RELEASE_APPID",
-                        OmahaRequestParams::kAppId,
-                        NULL,
-                        stateful_override);
+  string release_app_id = GetLsbValue("CHROMEOS_RELEASE_APPID",
+                                      OmahaRequestParams::kAppId,
+                                      NULL,
+                                      stateful_override);
   board_app_id_ = GetLsbValue("CHROMEOS_BOARD_APPID",
-                              app_id_,
+                              release_app_id,
                               NULL,
                               stateful_override);
+  canary_app_id_ = GetLsbValue("CHROMEOS_CANARY_APPID",
+                               release_app_id,
+                               NULL,
+                               stateful_override);
   app_lang_ = "en-US";
   hwid_ = utils::GetHardwareClass();
 
@@ -277,4 +281,8 @@
   return download_channel_index > current_channel_index;
 }
 
+string OmahaRequestParams::GetAppId() const {
+  return download_channel_ == "canary-channel" ? canary_app_id_ : board_app_id_;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/omaha_request_params.h b/omaha_request_params.h
index ada90a8..a3d08ce 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -33,8 +33,8 @@
       : system_state_(system_state),
         os_platform_(kOsPlatform),
         os_version_(kOsVersion),
-        app_id_(kAppId),
         board_app_id_(kAppId),
+        canary_app_id_(kAppId),
         delta_okay_(true),
         interactive_(false),
         update_disabled_(false),
@@ -68,8 +68,8 @@
         os_version_(in_os_version),
         os_sp_(in_os_sp),
         os_board_(in_os_board),
-        app_id_(in_app_id),
         board_app_id_(in_app_id),
+        canary_app_id_(in_app_id),
         app_version_(in_app_version),
         app_lang_(in_app_lang),
         current_channel_(in_target_channel),
@@ -93,8 +93,8 @@
   inline std::string os_version() const { return os_version_; }
   inline std::string os_sp() const { return os_sp_; }
   inline std::string os_board() const { return os_board_; }
-  inline std::string app_id() const { return app_id_; }
   inline std::string board_app_id() const { return board_app_id_; }
+  inline std::string canary_app_id() const { return canary_app_id_; }
   inline std::string app_lang() const { return app_lang_; }
   inline std::string hwid() const { return hwid_; }
 
@@ -168,6 +168,10 @@
   // i.e. index(target_channel) > index(current_channel).
   bool to_more_stable_channel() const;
 
+  // Returns the app id corresponding to the current value of the
+  // download channel.
+  std::string GetAppId() const;
+
   // Suggested defaults
   static const char* const kAppId;
   static const char* const kOsPlatform;
@@ -265,12 +269,12 @@
   std::string os_sp_;
   std::string os_board_;
 
-  // The app_id identifies the board except when we're on canary-channel.
-  // Whereas the board_app_id always identifies the board irrespective of the
-  // channel we are on. They are required the facilitate the switching from
-  // canary to a non-canary channel.
-  std::string app_id_;
+  // The board app id identifies the app id for the board irrespective of the
+  // channel that we're on. The canary app id identifies the app id to be used
+  // iff we're in the canary-channel. These values could be different depending
+  // on how the release tools are implemented.
   std::string board_app_id_;
+  std::string canary_app_id_;
 
   std::string app_version_;
   std::string app_lang_;
diff --git a/omaha_request_params_unittest.cc b/omaha_request_params_unittest.cc
index 7d81ba7..31ccd66 100644
--- a/omaha_request_params_unittest.cc
+++ b/omaha_request_params_unittest.cc
@@ -89,7 +89,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.hwid());
@@ -113,7 +113,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{58c35cef-9d30-476e-9098-ce20377d535d}", out.app_id());
+  EXPECT_EQ("{58c35cef-9d30-476e-9098-ce20377d535d}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.hwid());
@@ -133,7 +133,7 @@
   EXPECT_TRUE(DoTest(&out, "", ""));
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.target_channel());
@@ -150,7 +150,7 @@
   EXPECT_TRUE(DoTest(&out, "", ""));
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.target_channel());
@@ -168,7 +168,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_TRUE(out.delta_okay());
@@ -187,7 +187,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("ForcedVersion_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("ForcedVersion", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_TRUE(out.delta_okay());
@@ -207,7 +207,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_TRUE(out.delta_okay());
@@ -228,7 +228,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_TRUE(out.delta_okay());
@@ -268,7 +268,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("x86-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.hwid());
@@ -295,7 +295,7 @@
   OmahaRequestParams out(&mock_system_state);
   EXPECT_TRUE(DoTest(&out, "", ""));
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("", out.hwid());
   EXPECT_FALSE(out.delta_okay());
@@ -319,7 +319,7 @@
   OmahaRequestParams out(&mock_system_state);
   EXPECT_TRUE(DoTest(&out, "", ""));
   EXPECT_EQ("x86-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("", out.hwid());
   EXPECT_TRUE(out.delta_okay());
@@ -427,7 +427,7 @@
   EXPECT_EQ("Chrome OS", out.os_platform());
   EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp());
   EXPECT_EQ("arm-generic", out.os_board());
-  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id());
+  EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.GetAppId());
   EXPECT_EQ("0.2.2.3", out.app_version());
   EXPECT_EQ("en-US", out.app_lang());
   EXPECT_EQ("", out.hwid());
@@ -535,4 +535,45 @@
   EXPECT_FALSE(params_.ShouldLockDown());
 }
 
+TEST_F(OmahaRequestParamsTest, BoardAppIdUsedForNonCanaryChannelTest) {
+  ASSERT_TRUE(WriteFileString(
+      kTestDir + "/etc/lsb-release",
+      "CHROMEOS_RELEASE_APPID=r\n"
+      "CHROMEOS_BOARD_APPID=b\n"
+      "CHROMEOS_CANARY_APPID=c\n"
+      "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
+  MockSystemState mock_system_state;
+  OmahaRequestParams out(&mock_system_state);
+  EXPECT_TRUE(DoTest(&out, "", ""));
+  EXPECT_EQ("stable-channel", out.download_channel());
+  EXPECT_EQ("b", out.GetAppId());
+}
+
+TEST_F(OmahaRequestParamsTest, CanaryAppIdUsedForCanaryChannelTest) {
+  ASSERT_TRUE(WriteFileString(
+      kTestDir + "/etc/lsb-release",
+      "CHROMEOS_RELEASE_APPID=r\n"
+      "CHROMEOS_BOARD_APPID=b\n"
+      "CHROMEOS_CANARY_APPID=c\n"
+      "CHROMEOS_RELEASE_TRACK=canary-channel\n"));
+  MockSystemState mock_system_state;
+  OmahaRequestParams out(&mock_system_state);
+  EXPECT_TRUE(DoTest(&out, "", ""));
+  EXPECT_EQ("canary-channel", out.download_channel());
+  EXPECT_EQ("c", out.GetAppId());
+}
+
+TEST_F(OmahaRequestParamsTest, ReleaseAppIdUsedAsDefaultTest) {
+  ASSERT_TRUE(WriteFileString(
+      kTestDir + "/etc/lsb-release",
+      "CHROMEOS_RELEASE_APPID=r\n"
+      "CHROMEOS_CANARY_APPID=c\n"
+      "CHROMEOS_RELEASE_TRACK=stable-channel\n"));
+  MockSystemState mock_system_state;
+  OmahaRequestParams out(&mock_system_state);
+  EXPECT_TRUE(DoTest(&out, "", ""));
+  EXPECT_EQ("stable-channel", out.download_channel());
+  EXPECT_EQ("r", out.GetAppId());
+}
+
 }  // namespace chromeos_update_engine