diff options
author | Alex Deymo <deymo@google.com> | 2016-04-18 19:57:58 -0700 |
---|---|---|
committer | Alex Deymo <deymo@google.com> | 2016-05-03 17:17:58 -0700 |
commit | b3fa53bf760bd0a6fd1ef9df28cb425586d733f6 (patch) | |
tree | 457141d09742613dd2b3f64a92d6da4a83a0e390 | |
parent | ed9bd92e00099eddda86b32fd2bb4896cb44cd51 (diff) | |
download | android_system_update_engine-b3fa53bf760bd0a6fd1ef9df28cb425586d733f6.tar.gz android_system_update_engine-b3fa53bf760bd0a6fd1ef9df28cb425586d733f6.tar.bz2 android_system_update_engine-b3fa53bf760bd0a6fd1ef9df28cb425586d733f6.zip |
Parse and expose end-of-life flag.
Omaha update or noupdate response can include _key=value pairs with
arbitrary data. One of those key can be "_eol" with the one of the
values "supported", "security-only" or "eol" which notifies the device
the end-of-life status of the device with respect to updates. This
information is now exposed via GetEolStatus() to the client so it
can be properly displayed in the UI.
Bug: 27924505
TEST=Added unittest. Run `update_engine_client --eol_status` on link.
Change-Id: Icc15f25b4d0b19cc894f5afc52ac7c43c7818982
-rw-r--r-- | Android.mk | 5 | ||||
-rw-r--r-- | UpdateEngine.conf | 3 | ||||
-rw-r--r-- | binder_bindings/android/brillo/IUpdateEngine.aidl | 1 | ||||
-rw-r--r-- | binder_service_brillo.cc | 9 | ||||
-rw-r--r-- | binder_service_brillo.h | 1 | ||||
-rw-r--r-- | client_library/client_binder.cc | 17 | ||||
-rw-r--r-- | client_library/client_binder.h | 10 | ||||
-rw-r--r-- | client_library/client_dbus.cc | 9 | ||||
-rw-r--r-- | client_library/client_dbus.h | 2 | ||||
-rw-r--r-- | client_library/include/update_engine/client.h | 3 | ||||
-rw-r--r-- | common/constants.cc | 1 | ||||
-rw-r--r-- | common/constants.h | 1 | ||||
-rw-r--r-- | common_service.cc | 20 | ||||
-rw-r--r-- | common_service.h | 4 | ||||
-rw-r--r-- | common_service_unittest.cc | 17 | ||||
-rw-r--r-- | dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml | 3 | ||||
-rw-r--r-- | dbus_service.cc | 9 | ||||
-rw-r--r-- | dbus_service.h | 4 | ||||
-rw-r--r-- | omaha_request_action.cc | 24 | ||||
-rw-r--r-- | omaha_request_action.h | 5 | ||||
-rw-r--r-- | omaha_request_action_unittest.cc | 30 | ||||
-rw-r--r-- | omaha_utils.cc | 57 | ||||
-rw-r--r-- | omaha_utils.h | 40 | ||||
-rw-r--r-- | omaha_utils_unittest.cc | 42 | ||||
-rw-r--r-- | update_engine.gyp | 3 | ||||
-rw-r--r-- | update_engine_client.cc | 13 |
26 files changed, 309 insertions, 24 deletions
@@ -315,6 +315,7 @@ LOCAL_SRC_FILES := \ omaha_request_action.cc \ omaha_request_params.cc \ omaha_response_handler_action.cc \ + omaha_utils.cc \ p2p_manager.cc \ payload_state.cc \ proxy_resolver.cc \ @@ -524,7 +525,8 @@ LOCAL_SHARED_LIBRARIES += \ libupdate_engine_client LOCAL_SRC_FILES := \ update_engine_client.cc \ - common/error_code_utils.cc + common/error_code_utils.cc \ + omaha_utils.cc else # !defined(BRILLO) #TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved # out of the DBus interface. @@ -904,6 +906,7 @@ LOCAL_SRC_FILES := \ omaha_request_action_unittest.cc \ omaha_request_params_unittest.cc \ omaha_response_handler_action_unittest.cc \ + omaha_utils_unittest.cc \ p2p_manager_unittest.cc \ payload_consumer/bzip_extent_writer_unittest.cc \ payload_consumer/delta_performer_integration_test.cc \ diff --git a/UpdateEngine.conf b/UpdateEngine.conf index 9cf60428..9238e3a6 100644 --- a/UpdateEngine.conf +++ b/UpdateEngine.conf @@ -57,6 +57,9 @@ <allow send_destination="org.chromium.UpdateEngine" send_interface="org.chromium.UpdateEngineInterface" send_member="GetLastAttemptError"/> + <allow send_destination="org.chromium.UpdateEngine" + send_interface="org.chromium.UpdateEngineInterface" + send_member="GetEolStatus"/> <allow send_interface="org.chromium.UpdateEngineLibcrosProxyResolvedInterface" /> </policy> <policy user="power"> diff --git a/binder_bindings/android/brillo/IUpdateEngine.aidl b/binder_bindings/android/brillo/IUpdateEngine.aidl index 1c0a3e55..6a3295ab 100644 --- a/binder_bindings/android/brillo/IUpdateEngine.aidl +++ b/binder_bindings/android/brillo/IUpdateEngine.aidl @@ -37,4 +37,5 @@ interface IUpdateEngine { String GetRollbackPartition(); void RegisterStatusCallback(in IUpdateEngineStatusCallback callback); int GetLastAttemptError(); + int GetEolStatus(); } diff --git a/binder_service_brillo.cc b/binder_service_brillo.cc index 6a6a16e1..3947ae1d 100644 --- a/binder_service_brillo.cc +++ b/binder_service_brillo.cc @@ -192,12 +192,15 @@ Status BinderUpdateEngineBrilloService::GetLastAttemptError( out_last_attempt_error); } +Status BinderUpdateEngineBrilloService::GetEolStatus(int* out_eol_status) { + return CallCommonHandler(&UpdateEngineService::GetEolStatus, out_eol_status); +} + void BinderUpdateEngineBrilloService::UnregisterStatusCallback( IUpdateEngineStatusCallback* callback) { auto it = callbacks_.begin(); - - for (; it != callbacks_.end() && it->get() != callback; it++) - ; + while (it != callbacks_.end() && it->get() != callback) + it++; if (it == callbacks_.end()) { LOG(ERROR) << "Got death notification for unknown callback."; diff --git a/binder_service_brillo.h b/binder_service_brillo.h index 497b1b06..b3bb81f1 100644 --- a/binder_service_brillo.h +++ b/binder_service_brillo.h @@ -86,6 +86,7 @@ class BinderUpdateEngineBrilloService : public android::brillo::BnUpdateEngine, override; android::binder::Status GetLastAttemptError( int* out_last_attempt_error) override; + android::binder::Status GetEolStatus(int* out_eol_status) override; private: // Generic function for dispatching to the common service. diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc index 321dfc40..6a617223 100644 --- a/client_library/client_binder.cc +++ b/client_library/client_binder.cc @@ -28,8 +28,8 @@ using android::OK; using android::String16; using android::String8; -using android::brillo::ParcelableUpdateEngineStatus; using android::binder::Status; +using android::brillo::ParcelableUpdateEngineStatus; using android::getService; using chromeos_update_engine::StringToUpdateStatus; using chromeos_update_engine::UpdateEngineService; @@ -177,10 +177,7 @@ bool BinderUpdateEngineClient::RegisterStatusUpdateHandler( bool BinderUpdateEngineClient::UnregisterStatusUpdateHandler( StatusUpdateHandler* handler) { - auto it = handlers_.begin(); - - for (; *it != handler && it != handlers_.end(); it++); - + auto it = std::find(handlers_.begin(), handlers_.end(), handler); if (it != handlers_.end()) { handlers_.erase(it); return true; @@ -226,5 +223,15 @@ bool BinderUpdateEngineClient::GetLastAttemptError( return true; } +bool BinderUpdateEngineClient::GetEolStatus(int32_t* eol_status) const { + int out_as_int; + + if (!service_->GetEolStatus(&out_as_int).isOk()) + return false; + + *eol_status = out_as_int; + return true; +} + } // namespace internal } // namespace update_engine diff --git a/client_library/client_binder.h b/client_library/client_binder.h index 72f80dd7..cd857e01 100644 --- a/client_library/client_binder.h +++ b/client_library/client_binder.h @@ -23,14 +23,13 @@ #include <vector> #include <base/macros.h> -#include <utils/StrongPointer.h> #include <utils/String16.h> +#include <utils/StrongPointer.h> #include <brillo/binder_watcher.h> -#include "android/brillo/IUpdateEngine.h" #include "android/brillo/BnUpdateEngineStatusCallback.h" - +#include "android/brillo/IUpdateEngine.h" #include "update_engine/client_library/include/update_engine/client.h" @@ -82,11 +81,14 @@ class BinderUpdateEngineClient : public UpdateEngineClient { bool GetLastAttemptError(int32_t* last_attempt_error) const override; + bool GetEolStatus(int32_t* eol_status) const override; + private: class StatusUpdateCallback : public android::brillo::BnUpdateEngineStatusCallback { public: - StatusUpdateCallback(BinderUpdateEngineClient* client) : client_(client) {} + explicit StatusUpdateCallback(BinderUpdateEngineClient* client) + : client_(client) {} android::binder::Status HandleStatusUpdate( int64_t last_checked_time, diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc index 0d6b7833..5cb63a49 100644 --- a/client_library/client_dbus.cc +++ b/client_library/client_dbus.cc @@ -171,10 +171,7 @@ void DBusUpdateEngineClient::RunStatusUpdateHandlers( bool DBusUpdateEngineClient::UnregisterStatusUpdateHandler( StatusUpdateHandler* handler) { - auto it = handlers_.begin(); - - for (; *it != handler && it != handlers_.end(); it++); - + auto it = std::find(handlers_.begin(), handlers_.end(), handler); if (it != handlers_.end()) { handlers_.erase(it); return true; @@ -230,5 +227,9 @@ bool DBusUpdateEngineClient::GetLastAttemptError( return proxy_->GetLastAttemptError(last_attempt_error, nullptr); } +bool DBusUpdateEngineClient::GetEolStatus(int32_t* eol_status) const { + return proxy_->GetEolStatus(eol_status, nullptr); +} + } // namespace internal } // namespace update_engine diff --git a/client_library/client_dbus.h b/client_library/client_dbus.h index 02a7e84a..a2de5948 100644 --- a/client_library/client_dbus.h +++ b/client_library/client_dbus.h @@ -75,6 +75,8 @@ class DBusUpdateEngineClient : public UpdateEngineClient { bool GetLastAttemptError(int32_t* last_attempt_error) const override; + bool GetEolStatus(int32_t* eol_status) const override; + private: void DBusStatusHandlersRegistered(const std::string& interface, const std::string& signal_name, diff --git a/client_library/include/update_engine/client.h b/client_library/include/update_engine/client.h index 62ac5fb3..7956dbd2 100644 --- a/client_library/include/update_engine/client.h +++ b/client_library/include/update_engine/client.h @@ -115,6 +115,9 @@ class UpdateEngineClient { // Get the last UpdateAttempt error code. virtual bool GetLastAttemptError(int32_t* last_attempt_error) const = 0; + // Get the current end-of-life status code. See EolStatus enum for details. + virtual bool GetEolStatus(int32_t* eol_status) const = 0; + protected: // Use CreateInstance(). UpdateEngineClient() = default; diff --git a/common/constants.cc b/common/constants.cc index f138ce3c..c0bb8742 100644 --- a/common/constants.cc +++ b/common/constants.cc @@ -57,6 +57,7 @@ const char kPrefsNumResponsesSeen[] = "num-responses-seen"; const char kPrefsOmahaCohort[] = "omaha-cohort"; const char kPrefsOmahaCohortHint[] = "omaha-cohort-hint"; const char kPrefsOmahaCohortName[] = "omaha-cohort-name"; +const char kPrefsOmahaEolStatus[] = "omaha-eol-status"; const char kPrefsP2PEnabled[] = "p2p-enabled"; const char kPrefsP2PFirstAttemptTimestamp[] = "p2p-first-attempt-timestamp"; const char kPrefsP2PNumAttempts[] = "p2p-num-attempts"; diff --git a/common/constants.h b/common/constants.h index f0d589dc..660d9a96 100644 --- a/common/constants.h +++ b/common/constants.h @@ -61,6 +61,7 @@ extern const char kPrefsNumResponsesSeen[]; extern const char kPrefsOmahaCohort[]; extern const char kPrefsOmahaCohortHint[]; extern const char kPrefsOmahaCohortName[]; +extern const char kPrefsOmahaEolStatus[]; extern const char kPrefsP2PEnabled[]; extern const char kPrefsP2PFirstAttemptTimestamp[]; extern const char kPrefsP2PNumAttempts[]; diff --git a/common_service.cc b/common_service.cc index f0b818ff..ade5349e 100644 --- a/common_service.cc +++ b/common_service.cc @@ -33,9 +33,10 @@ #include "update_engine/common/utils.h" #include "update_engine/connection_manager_interface.h" #include "update_engine/omaha_request_params.h" +#include "update_engine/omaha_utils.h" #include "update_engine/p2p_manager.h" -#include "update_engine/update_attempter.h" #include "update_engine/payload_state_interface.h" +#include "update_engine/update_attempter.h" using base::StringPrintf; using brillo::ErrorPtr; @@ -325,4 +326,21 @@ bool UpdateEngineService::GetLastAttemptError(ErrorPtr* /* error */, *out_last_attempt_error = static_cast<int>(error_code); return true; } + +bool UpdateEngineService::GetEolStatus(ErrorPtr* error, + int32_t* out_eol_status) { + PrefsInterface* prefs = system_state_->prefs(); + + string str_eol_status; + if (prefs->Exists(kPrefsOmahaEolStatus) && + !prefs->GetString(kPrefsOmahaEolStatus, &str_eol_status)) { + LogAndSetError(error, FROM_HERE, "Error getting the end-of-life status."); + return false; + } + + // StringToEolStatus will return kSupported for invalid values. + *out_eol_status = static_cast<int32_t>(StringToEolStatus(str_eol_status)); + return true; +} + } // namespace chromeos_update_engine diff --git a/common_service.h b/common_service.h index 4ad8862d..1d380bc8 100644 --- a/common_service.h +++ b/common_service.h @@ -131,6 +131,10 @@ class UpdateEngineService { bool GetLastAttemptError(brillo::ErrorPtr* error, int32_t* out_last_attempt_error); + // Returns the current end-of-life status of the device. This value is updated + // on every update check and persisted on disk across reboots. + bool GetEolStatus(brillo::ErrorPtr* error, int32_t* out_eol_status); + private: SystemState* system_state_; }; diff --git a/common_service_unittest.cc b/common_service_unittest.cc index 1c144d1b..0a7bfc34 100644 --- a/common_service_unittest.cc +++ b/common_service_unittest.cc @@ -23,7 +23,9 @@ #include <policy/libpolicy.h> #include <policy/mock_device_policy.h> +#include "update_engine/common/fake_prefs.h" #include "update_engine/fake_system_state.h" +#include "update_engine/omaha_utils.h" using std::string; using testing::Return; @@ -131,4 +133,19 @@ TEST_F(UpdateEngineServiceTest, ResetStatusFails) { UpdateEngineService::kErrorFailed)); } +TEST_F(UpdateEngineServiceTest, GetEolStatusTest) { + FakePrefs fake_prefs; + fake_system_state_.set_prefs(&fake_prefs); + // The default value should be "supported". + int32_t eol_status = static_cast<int32_t>(EolStatus::kEol); + EXPECT_TRUE(common_service_.GetEolStatus(&error_, &eol_status)); + EXPECT_EQ(nullptr, error_); + EXPECT_EQ(EolStatus::kSupported, static_cast<EolStatus>(eol_status)); + + fake_prefs.SetString(kPrefsOmahaEolStatus, "security-only"); + EXPECT_TRUE(common_service_.GetEolStatus(&error_, &eol_status)); + EXPECT_EQ(nullptr, error_); + EXPECT_EQ(EolStatus::kSecurityOnly, static_cast<EolStatus>(eol_status)); +} + } // namespace chromeos_update_engine diff --git a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml index 02287de7..aa995080 100644 --- a/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml +++ b/dbus_bindings/org.chromium.UpdateEngineInterface.dbus-xml @@ -83,5 +83,8 @@ <method name="GetLastAttemptError"> <arg type="i" name="last_attempt_error" direction="out" /> </method> + <method name="GetEolStatus"> + <arg type="i" name="eol_status" direction="out" /> + </method> </interface> </node> diff --git a/dbus_service.cc b/dbus_service.cc index 392555fa..de1f9b56 100644 --- a/dbus_service.cc +++ b/dbus_service.cc @@ -133,8 +133,13 @@ bool DBusUpdateEngineService::GetRollbackPartition( } bool DBusUpdateEngineService::GetLastAttemptError( - ErrorPtr* error, int32_t* out_last_attempt_error){ - return common_->GetLastAttemptError(error, out_last_attempt_error); + ErrorPtr* error, int32_t* out_last_attempt_error) { + return common_->GetLastAttemptError(error, out_last_attempt_error); +} + +bool DBusUpdateEngineService::GetEolStatus(ErrorPtr* error, + int32_t* out_eol_status) { + return common_->GetEolStatus(error, out_eol_status); } UpdateEngineAdaptor::UpdateEngineAdaptor(SystemState* system_state, diff --git a/dbus_service.h b/dbus_service.h index 1486e3ca..12f8cf12 100644 --- a/dbus_service.h +++ b/dbus_service.h @@ -133,6 +133,10 @@ class DBusUpdateEngineService // ErrorCode will be returned. bool GetLastAttemptError(brillo::ErrorPtr* error, int32_t* out_last_attempt_error) override; + + // Returns the current end-of-life status of the device in |out_eol_status|. + bool GetEolStatus(brillo::ErrorPtr* error, int32_t* out_eol_status) override; + private: std::unique_ptr<UpdateEngineService> common_; }; diff --git a/omaha_request_action.cc b/omaha_request_action.cc index 018f9aaa..16338a8c 100644 --- a/omaha_request_action.cc +++ b/omaha_request_action.cc @@ -77,6 +77,9 @@ static const char* kTagPublicKeyRsa = "PublicKeyRsa"; static const char* kOmahaUpdaterVersion = "0.1.0.0"; +// updatecheck attributes (without the underscore prefix). +static const char* kEolAttr = "eol"; + namespace { // Returns an XML ping element attribute assignment with attribute @@ -339,6 +342,7 @@ struct OmahaParserData { bool app_cohortname_set = false; string updatecheck_status; string updatecheck_poll_interval; + map<string, string> updatecheck_attrs; string daystart_elapsed_days; string daystart_elapsed_seconds; vector<string> url_codebase; @@ -386,6 +390,12 @@ void ParserHandlerStart(void* user_data, const XML_Char* element, // There is only supposed to be a single <updatecheck> element. data->updatecheck_status = attrs["status"]; data->updatecheck_poll_interval = attrs["PollInterval"]; + // Omaha sends arbitrary key-value pairs as extra attributes starting with + // an underscore. + for (const auto& attr : attrs) { + if (!attr.first.empty() && attr.first[0] == '_') + data->updatecheck_attrs[attr.first.substr(1)] = attr.second; + } } else if (data->current_path == "/response/daystart") { // Get the install-date. data->daystart_elapsed_days = attrs["elapsed_days"]; @@ -748,6 +758,9 @@ bool OmahaRequestAction::ParseResponse(OmahaParserData* parser_data, if (parser_data->app_cohortname_set) PersistCohortData(kPrefsOmahaCohortName, parser_data->app_cohortname); + // Parse the updatecheck attributes. + PersistEolStatus(parser_data->updatecheck_attrs); + if (!ParseStatus(parser_data, output_object, completer)) return false; @@ -1384,6 +1397,17 @@ bool OmahaRequestAction::PersistCohortData( return true; } +bool OmahaRequestAction::PersistEolStatus(const map<string, string>& attrs) { + auto eol_attr = attrs.find(kEolAttr); + if (eol_attr != attrs.end()) { + return system_state_->prefs()->SetString(kPrefsOmahaEolStatus, + eol_attr->second); + } else if (system_state_->prefs()->Exists(kPrefsOmahaEolStatus)) { + return system_state_->prefs()->Delete(kPrefsOmahaEolStatus); + } + return true; +} + void OmahaRequestAction::ActionCompleted(ErrorCode code) { // We only want to report this on "update check". if (ping_only_ || event_ != nullptr) diff --git a/omaha_request_action.h b/omaha_request_action.h index 1aeaf8a3..2915a6a8 100644 --- a/omaha_request_action.h +++ b/omaha_request_action.h @@ -21,6 +21,7 @@ #include <sys/stat.h> #include <sys/types.h> +#include <map> #include <memory> #include <string> #include <vector> @@ -219,6 +220,10 @@ class OmahaRequestAction : public Action<OmahaRequestAction>, bool PersistCohortData(const std::string& prefs_key, const std::string& new_value); + // Parse and persist the end-of-life status flag sent back in the updatecheck + // tag attributes. The flag will be validated and stored in the Prefs. + bool PersistEolStatus(const std::map<std::string, std::string>& attrs); + // If this is an update check request, initializes // |ping_active_days_| and |ping_roll_call_days_| to values that may // be sent as pings to Omaha. diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc index 496143e5..a7abdece 100644 --- a/omaha_request_action_unittest.cc +++ b/omaha_request_action_unittest.cc @@ -51,8 +51,6 @@ using base::Time; using base::TimeDelta; -using chromeos_update_engine::test_utils::System; -using chromeos_update_engine::test_utils::WriteFileString; using std::string; using std::vector; using testing::AllOf; @@ -355,9 +353,7 @@ bool OmahaRequestActionTest::TestUpdateCheck( ? 0 : 1); loop.PostTask(base::Bind([&processor] { processor.StartProcessing(); })); - LOG(INFO) << "loop.PendingTasks() = " << loop.PendingTasks(); loop.Run(); - LOG(INFO) << "loop.PendingTasks() = " << loop.PendingTasks(); EXPECT_FALSE(loop.PendingTasks()); if (collector_action.has_input_object_ && out_response) *out_response = collector_action.omaha_response_; @@ -1676,6 +1672,32 @@ TEST_F(OmahaRequestActionTest, BadElapsedSecondsTest) { nullptr)); } +TEST_F(OmahaRequestActionTest, ParseUpdateCheckAttributesTest) { + // Test that the "eol" flags is only parsed from the "_eol" attribute and not + // the "eol" attribute. + ASSERT_TRUE( + TestUpdateCheck(nullptr, // request_params + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response " + "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">" + "<ping status=\"ok\"/><updatecheck status=\"noupdate\" " + "_eol=\"security-only\" eol=\"eol\" _foo=\"bar\"/>" + "</app></response>", + -1, + false, // ping_only + ErrorCode::kSuccess, + metrics::CheckResult::kNoUpdateAvailable, + metrics::CheckReaction::kUnset, + metrics::DownloadErrorCode::kUnset, + nullptr, + nullptr)); + string eol_pref; + EXPECT_TRUE( + fake_system_state_.prefs()->GetString(kPrefsOmahaEolStatus, &eol_pref)); + // Note that the eol="eol" attribute should be ignored and the _eol should be + // used instead. + EXPECT_EQ("security-only", eol_pref); +} + TEST_F(OmahaRequestActionTest, NoUniqueIDTest) { brillo::Blob post_data; ASSERT_FALSE(TestUpdateCheck(nullptr, // request_params diff --git a/omaha_utils.cc b/omaha_utils.cc new file mode 100644 index 00000000..6bd75250 --- /dev/null +++ b/omaha_utils.cc @@ -0,0 +1,57 @@ +// +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "update_engine/omaha_utils.h" + +#include <base/logging.h> + +namespace chromeos_update_engine { + +namespace { + +// The possible string values for the end-of-life status. +const char kEolStatusSupported[] = "supported"; +const char kEolStatusSecurityOnly[] = "security-only"; +const char kEolStatusEol[] = "eol"; + +} // namespace + +const char* EolStatusToString(EolStatus eol_status) { + switch (eol_status) { + case EolStatus::kSupported: + return kEolStatusSupported; + case EolStatus::kSecurityOnly: + return kEolStatusSecurityOnly; + case EolStatus::kEol: + return kEolStatusEol; + } + // Only reached if an invalid number is casted to |EolStatus|. + LOG(WARNING) << "Invalid EolStatus value: " << static_cast<int>(eol_status); + return kEolStatusSupported; +} + +EolStatus StringToEolStatus(const std::string& eol_status) { + if (eol_status == kEolStatusSupported || eol_status.empty()) + return EolStatus::kSupported; + if (eol_status == kEolStatusSecurityOnly) + return EolStatus::kSecurityOnly; + if (eol_status == kEolStatusEol) + return EolStatus::kEol; + LOG(WARNING) << "Invalid end-of-life attribute: " << eol_status; + return EolStatus::kSupported; +} + +} // namespace chromeos_update_engine diff --git a/omaha_utils.h b/omaha_utils.h new file mode 100644 index 00000000..86145403 --- /dev/null +++ b/omaha_utils.h @@ -0,0 +1,40 @@ +// +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef UPDATE_ENGINE_OMAHA_UTILS_H_ +#define UPDATE_ENGINE_OMAHA_UTILS_H_ + +#include <string> + +namespace chromeos_update_engine { + +// The end-of-life status of the device. +enum class EolStatus { + kSupported = 0, + kSecurityOnly, + kEol, +}; + +// Returns the string representation of the |eol_status|. +const char* EolStatusToString(EolStatus eol_status); + +// Converts the end-of-life status string to an EolStatus numeric value. In case +// of an invalid string, the default "supported" value will be used instead. +EolStatus StringToEolStatus(const std::string& eol_status); + +} // namespace chromeos_update_engine + +#endif // UPDATE_ENGINE_OMAHA_UTILS_H_ diff --git a/omaha_utils_unittest.cc b/omaha_utils_unittest.cc new file mode 100644 index 00000000..8ceb76bf --- /dev/null +++ b/omaha_utils_unittest.cc @@ -0,0 +1,42 @@ +// +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "update_engine/omaha_utils.h" + +#include <gtest/gtest.h> +#include <vector> + +namespace chromeos_update_engine { + +class OmahaUtilsTest : public ::testing::Test {}; + +TEST(OmahaUtilsTest, EolStatusTest) { + EXPECT_EQ(EolStatus::kEol, StringToEolStatus("eol")); + + // Supported values are converted back and forth properly. + const std::vector<EolStatus> tests = { + EolStatus::kSupported, EolStatus::kSecurityOnly, EolStatus::kEol}; + for (EolStatus eol_status : tests) { + EXPECT_EQ(eol_status, StringToEolStatus(EolStatusToString(eol_status))) + << "The StringToEolStatus() was " << EolStatusToString(eol_status); + } + + // Invalid values are assumed as "supported". + EXPECT_EQ(EolStatus::kSupported, StringToEolStatus("")); + EXPECT_EQ(EolStatus::kSupported, StringToEolStatus("hello, world!")); +} + +} // namespace chromeos_update_engine diff --git a/update_engine.gyp b/update_engine.gyp index 5f24a833..b8eccdc8 100644 --- a/update_engine.gyp +++ b/update_engine.gyp @@ -261,6 +261,7 @@ 'omaha_request_action.cc', 'omaha_request_params.cc', 'omaha_response_handler_action.cc', + 'omaha_utils.cc', 'p2p_manager.cc', 'payload_state.cc', 'proxy_resolver.cc', @@ -344,6 +345,7 @@ ], 'sources': [ 'common/error_code_utils.cc', + 'omaha_utils.cc', 'update_engine_client.cc', ], }, @@ -511,6 +513,7 @@ 'omaha_request_action_unittest.cc', 'omaha_request_params_unittest.cc', 'omaha_response_handler_action_unittest.cc', + 'omaha_utils_unittest.cc', 'p2p_manager_unittest.cc', 'payload_consumer/bzip_extent_writer_unittest.cc', 'payload_consumer/delta_performer_integration_test.cc', diff --git a/update_engine_client.cc b/update_engine_client.cc index 6ade12cf..55d7e649 100644 --- a/update_engine_client.cc +++ b/update_engine_client.cc @@ -32,10 +32,12 @@ #include "update_engine/client.h" #include "update_engine/common/error_code.h" #include "update_engine/common/error_code_utils.h" +#include "update_engine/omaha_utils.h" #include "update_engine/status_update_handler.h" #include "update_engine/update_status.h" #include "update_engine/update_status_utils.h" +using chromeos_update_engine::EolStatus; using chromeos_update_engine::ErrorCode; using chromeos_update_engine::UpdateStatusToString; using chromeos_update_engine::utils::ErrorCodeToString; @@ -273,6 +275,7 @@ int UpdateEngineClient::ProcessFlags() { DEFINE_bool(prev_version, false, "Show the previous OS version used before the update reboot."); DEFINE_bool(last_attempt_error, false, "Show the last attempt error."); + DEFINE_bool(eol_status, false, "Show the current end-of-life status."); // Boilerplate init commands. base::CommandLine::Init(argc_, argv_); @@ -534,6 +537,16 @@ int UpdateEngineClient::ProcessFlags() { } } + if (FLAGS_eol_status) { + int eol_status; + if (!client_->GetEolStatus(&eol_status)) { + LOG(ERROR) << "Error getting the end-of-life status."; + } else { + EolStatus eol_status_code = static_cast<EolStatus>(eol_status); + printf("EOL_STATUS=%s\n", EolStatusToString(eol_status_code)); + } + } + return 0; } |