Add {Get,Set}CohortHint interface.
Export the "cohort hint" getter and setter in the client interfaces
(D-Bus and Binder). The cohort hint is sent to Omaha on every update
check request but can be ignored and/or reset by Omaha on every
response.
Other minor linter fixes to the affected files.
Bug: 31740109
Test: Build with D-Bus and with Binder.
(cherry picked from commit 5b5fa8b412312a41cfd4d7ab475b54d4f730ed2a)
Change-Id: Ieb40c2d4bbe2ce926d54b6348b22f2840d8327db
Reviewed-on: https://chromium-review.googlesource.com/395206
Commit-Ready: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Christopher Book <cbook@chromium.org>
diff --git a/UpdateEngine.conf b/UpdateEngine.conf
index 9238e3a..58cca09 100644
--- a/UpdateEngine.conf
+++ b/UpdateEngine.conf
@@ -38,6 +38,12 @@
send_member="GetChannel"/>
<allow send_destination="org.chromium.UpdateEngine"
send_interface="org.chromium.UpdateEngineInterface"
+ send_member="SetCohortHint"/>
+ <allow send_destination="org.chromium.UpdateEngine"
+ send_interface="org.chromium.UpdateEngineInterface"
+ send_member="GetCohortHint"/>
+ <allow send_destination="org.chromium.UpdateEngine"
+ send_interface="org.chromium.UpdateEngineInterface"
send_member="SetP2PUpdatePermission"/>
<allow send_destination="org.chromium.UpdateEngine"
send_interface="org.chromium.UpdateEngineInterface"
diff --git a/binder_bindings/android/brillo/IUpdateEngine.aidl b/binder_bindings/android/brillo/IUpdateEngine.aidl
index 6a3295a..b1a1b4f 100644
--- a/binder_bindings/android/brillo/IUpdateEngine.aidl
+++ b/binder_bindings/android/brillo/IUpdateEngine.aidl
@@ -28,6 +28,8 @@
void RebootIfNeeded();
void SetChannel(in String target_channel, in boolean powewash);
String GetChannel(in boolean get_current_channel);
+ void SetCohortHint(in String cohort_hint);
+ String GetCohortHint();
void SetP2PUpdatePermission(in boolean enabled);
boolean GetP2PUpdatePermission();
void SetUpdateOverCellularPermission(in boolean enabled);
diff --git a/binder_service_brillo.cc b/binder_service_brillo.cc
index 3947ae1..5e74159 100644
--- a/binder_service_brillo.cc
+++ b/binder_service_brillo.cc
@@ -118,6 +118,22 @@
return ret;
}
+Status BinderUpdateEngineBrilloService::SetCohortHint(
+ const String16& in_cohort_hint) {
+ return CallCommonHandler(&UpdateEngineService::SetCohortHint,
+ NormalString(in_cohort_hint));
+}
+
+Status BinderUpdateEngineBrilloService::GetCohortHint(
+ String16* out_cohort_hint) {
+ string cohort_hint;
+ auto ret =
+ CallCommonHandler(&UpdateEngineService::GetCohortHint, &cohort_hint);
+
+ *out_cohort_hint = String16(cohort_hint.c_str());
+ return ret;
+}
+
Status BinderUpdateEngineBrilloService::SetP2PUpdatePermission(bool enabled) {
return CallCommonHandler(&UpdateEngineService::SetP2PUpdatePermission,
enabled);
diff --git a/binder_service_brillo.h b/binder_service_brillo.h
index b3bb81f..fad0f8c 100644
--- a/binder_service_brillo.h
+++ b/binder_service_brillo.h
@@ -19,6 +19,7 @@
#include <utils/Errors.h>
+#include <memory>
#include <string>
#include <vector>
@@ -68,6 +69,10 @@
bool powerwash) override;
android::binder::Status GetChannel(bool get_current_channel,
android::String16* out_channel) override;
+ android::binder::Status SetCohortHint(
+ const android::String16& cohort_hint) override;
+ android::binder::Status GetCohortHint(
+ android::String16* out_cohort_hint) override;
android::binder::Status SetP2PUpdatePermission(bool enabled) override;
android::binder::Status GetP2PUpdatePermission(
bool* out_p2p_permission) override;
diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc
index 6a61722..e98c225 100644
--- a/client_library/client_binder.cc
+++ b/client_library/client_binder.cc
@@ -73,6 +73,20 @@
return true;
}
+bool BinderUpdateEngineClient::SetCohortHint(const string& in_cohort_hint) {
+ return service_->SetCohortHint(String16{in_cohort_hint.c_str()}).isOk();
+}
+
+bool BinderUpdateEngineClient::GetCohortHint(string* out_cohort_hint) const {
+ String16 out_as_string16;
+
+ if (!service_->GetCohortHint(&out_as_string16).isOk())
+ return false;
+
+ *out_cohort_hint = String8{out_as_string16}.string();
+ return true;
+}
+
bool BinderUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
return service_->SetUpdateOverCellularPermission(allowed).isOk();
}
diff --git a/client_library/client_binder.h b/client_library/client_binder.h
index cd857e0..b1b34da 100644
--- a/client_library/client_binder.h
+++ b/client_library/client_binder.h
@@ -53,6 +53,9 @@
std::string* out_new_version,
int64_t* out_new_size) const override;
+ bool SetCohortHint(const std::string& in_cohort_hint) override;
+ bool GetCohortHint(std::string* out_cohort_hint) const override;
+
bool SetUpdateOverCellularPermission(bool allowed) override;
bool GetUpdateOverCellularPermission(bool* allowed) const override;
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
index 5cb63a4..426412c 100644
--- a/client_library/client_dbus.cc
+++ b/client_library/client_dbus.cc
@@ -72,6 +72,14 @@
return StringToUpdateStatus(status_as_string, out_update_status);
}
+bool DBusUpdateEngineClient::SetCohortHint(const string& cohort_hint) {
+ return proxy_->SetCohortHint(cohort_hint, nullptr);
+}
+
+bool DBusUpdateEngineClient::GetCohortHint(string* cohort_hint) const {
+ return proxy_->GetCohortHint(cohort_hint, nullptr);
+}
+
bool DBusUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
}
diff --git a/client_library/client_dbus.h b/client_library/client_dbus.h
index a2de594..cec1665 100644
--- a/client_library/client_dbus.h
+++ b/client_library/client_dbus.h
@@ -47,6 +47,9 @@
std::string* out_new_version,
int64_t* out_new_size) const override;
+ bool SetCohortHint(const std::string& cohort_hint) override;
+ bool GetCohortHint(std::string* cohort_hint) const override;
+
bool SetUpdateOverCellularPermission(bool allowed) override;
bool GetUpdateOverCellularPermission(bool* allowed) const override;
diff --git a/client_library/include/update_engine/client.h b/client_library/include/update_engine/client.h
index 7956dbd..be87c76 100644
--- a/client_library/include/update_engine/client.h
+++ b/client_library/include/update_engine/client.h
@@ -67,6 +67,10 @@
std::string* out_new_version,
int64_t* out_new_size) const = 0;
+ // Getter and setter for the cohort hint.
+ virtual bool SetCohortHint(const std::string& cohort_hint) = 0;
+ virtual bool GetCohortHint(std::string* cohort_hint) const = 0;
+
// Getter and setter for the updates over cellular connections.
virtual bool SetUpdateOverCellularPermission(bool allowed) = 0;
virtual bool GetUpdateOverCellularPermission(bool* allowed) const = 0;
diff --git a/common_service.cc b/common_service.cc
index ade5349..20f55ab 100644
--- a/common_service.cc
+++ b/common_service.cc
@@ -187,6 +187,37 @@
return true;
}
+bool UpdateEngineService::SetCohortHint(ErrorPtr* error,
+ string in_cohort_hint) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ // It is ok to override the cohort hint with an invalid value since it is
+ // stored in stateful partition. The code reading it should sanitize it
+ // anyway.
+ if (!prefs->SetString(kPrefsOmahaCohortHint, in_cohort_hint)) {
+ LogAndSetError(
+ error,
+ FROM_HERE,
+ StringPrintf("Error setting the cohort hint value to \"%s\".",
+ in_cohort_hint.c_str()));
+ return false;
+ }
+ return true;
+}
+
+bool UpdateEngineService::GetCohortHint(ErrorPtr* error,
+ string* out_cohort_hint) {
+ PrefsInterface* prefs = system_state_->prefs();
+
+ *out_cohort_hint = "";
+ if (prefs->Exists(kPrefsOmahaCohortHint) &&
+ !prefs->GetString(kPrefsOmahaCohortHint, out_cohort_hint)) {
+ LogAndSetError(error, FROM_HERE, "Error getting the cohort hint.");
+ return false;
+ }
+ return true;
+}
+
bool UpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
bool in_enabled) {
PrefsInterface* prefs = system_state_->prefs();
diff --git a/common_service.h b/common_service.h
index 1d380bc..69368fb 100644
--- a/common_service.h
+++ b/common_service.h
@@ -92,6 +92,15 @@
bool in_get_current_channel,
std::string* out_channel);
+ // Sets the current "cohort hint" value to |in_cohort_hint|. The cohort hint
+ // is sent back to Omaha on every request and can be used as a hint of what
+ // cohort should we be put on.
+ bool SetCohortHint(brillo::ErrorPtr* error, std::string in_cohort_hint);
+
+ // Return the current cohort hint. This value can be set with SetCohortHint()
+ // and can also be updated from Omaha on every update check request.
+ bool GetCohortHint(brillo::ErrorPtr* error, std::string* out_cohort_hint);
+
// Enables or disables the sharing and consuming updates over P2P feature
// according to the |enabled| argument passed.
bool SetP2PUpdatePermission(brillo::ErrorPtr* error, bool in_enabled);
diff --git a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
index aa99508..848f775 100644
--- a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
+++ b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml
@@ -44,6 +44,12 @@
<arg type="b" name="get_current_channel" direction="in" />
<arg type="s" name="channel" direction="out" />
</method>
+ <method name="SetCohortHint">
+ <arg type="s" name="cohort_hint" direction="in" />
+ </method>
+ <method name="GetCohortHint">
+ <arg type="s" name="cohort_hint" direction="out" />
+ </method>
<method name="SetP2PUpdatePermission">
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="update_engine_service_set_p2p_update_permission" />
diff --git a/dbus_service.cc b/dbus_service.cc
index de1f9b5..18b5b9e 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -97,6 +97,16 @@
return common_->GetChannel(error, in_get_current_channel, out_channel);
}
+bool DBusUpdateEngineService::GetCohortHint(ErrorPtr* error,
+ string* out_cohort_hint) {
+ return common_->GetCohortHint(error, out_cohort_hint);
+}
+
+bool DBusUpdateEngineService::SetCohortHint(ErrorPtr* error,
+ const string& in_cohort_hint) {
+ return common_->SetCohortHint(error, in_cohort_hint);
+}
+
bool DBusUpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
bool in_enabled) {
return common_->SetP2PUpdatePermission(error, in_enabled);
diff --git a/dbus_service.h b/dbus_service.h
index 12f8cf1..0b63492 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -19,6 +19,7 @@
#include <inttypes.h>
+#include <memory>
#include <string>
#include <base/memory/ref_counted.h>
@@ -91,6 +92,12 @@
bool in_get_current_channel,
std::string* out_channel) override;
+ bool SetCohortHint(brillo::ErrorPtr* error,
+ const std::string& in_cohort_hint) override;
+
+ bool GetCohortHint(brillo::ErrorPtr* error,
+ std::string* out_cohort_hint) override;
+
// Enables or disables the sharing and consuming updates over P2P feature
// according to the |enabled| argument passed.
bool SetP2PUpdatePermission(brillo::ErrorPtr* error,
diff --git a/update_engine_client.cc b/update_engine_client.cc
index 55d7e64..44897e0 100644
--- a/update_engine_client.cc
+++ b/update_engine_client.cc
@@ -233,6 +233,8 @@
"target channel is more stable than the current channel unless "
"--nopowerwash is specified.");
DEFINE_bool(check_for_update, false, "Initiate check for updates.");
+ DEFINE_string(
+ cohort_hint, "", "Set the current cohort hint to the passed value.");
DEFINE_bool(follow, false,
"Wait for any update operations to complete."
"Exit status is 0 if the update succeeded, and 1 otherwise.");
@@ -259,6 +261,7 @@
"Shows whether rollback partition "
"is available.");
DEFINE_bool(show_channel, false, "Show the current and target channels.");
+ DEFINE_bool(show_cohort_hint, false, "Show the current cohort hint.");
DEFINE_bool(show_p2p_update, false,
"Show the current setting for peer-to-peer update sharing.");
DEFINE_bool(show_update_over_cellular, false,
@@ -333,6 +336,27 @@
<< (allowed ? "ENABLED" : "DISABLED");
}
+ // Change/show the cohort hint.
+ bool set_cohort_hint =
+ base::CommandLine::ForCurrentProcess()->HasSwitch("cohort_hint");
+ if (set_cohort_hint) {
+ LOG(INFO) << "Setting cohort hint to: \"" << FLAGS_cohort_hint << "\"";
+ if (!client_->SetCohortHint(FLAGS_cohort_hint)) {
+ LOG(ERROR) << "Error setting the cohort hint.";
+ return 1;
+ }
+ }
+
+ if (FLAGS_show_cohort_hint || set_cohort_hint) {
+ string cohort_hint;
+ if (!client_->GetCohortHint(&cohort_hint)) {
+ LOG(ERROR) << "Error getting the cohort hint.";
+ return 1;
+ }
+
+ LOG(INFO) << "Current cohort hint: \"" << cohort_hint << "\"";
+ }
+
if (!FLAGS_powerwash && !FLAGS_rollback && FLAGS_channel.empty()) {
LOG(ERROR) << "powerwash flag only makes sense rollback or channel change";
return 1;